亚洲av成人无遮挡网站在线观看,少妇性bbb搡bbb爽爽爽,亚洲av日韩精品久久久久久,兔费看少妇性l交大片免费,无码少妇一区二区三区

  免費(fèi)注冊(cè) 查看新帖 |

Chinaunix

  平臺(tái) 論壇 博客 文庫(kù)
最近訪問板塊 發(fā)新帖
查看: 3074 | 回復(fù): 3
打印 上一主題 下一主題

Linux設(shè)備驅(qū)動(dòng)程序之讀書筆記(二)轉(zhuǎn) [復(fù)制鏈接]

論壇徽章:
0
跳轉(zhuǎn)到指定樓層
1 [收藏(0)] [報(bào)告]
發(fā)表于 2009-11-30 20:34 |只看該作者 |倒序?yàn)g覽
Linux設(shè)備驅(qū)動(dòng)程序之讀書筆記(二)
                  ——第二章調(diào)試技術(shù)中的printk

在Linux中系統(tǒng)信息的顯示有以下3種情況:
1、如果系統(tǒng)中只運(yùn)行klogd,那么可以通過klogd -c 重新啟動(dòng)klogd并設(shè)置console_loglevel,然后小于console_loglevel的所有信息都會(huì)打印到控制臺(tái);
2、如果系統(tǒng)中只運(yùn)行syslogd,那么消息不會(huì)傳遞到用戶空間,只能通過讀/proc/kmsg來察看消息;
3、如果系統(tǒng)中同時(shí)允許klogd和syslogd,那么在根據(jù)console_loglevel將消息篩選打印到控制臺(tái)的前提下,任何消息都會(huì)被追加到文件/var/log/messages中。

在Linux下寫驅(qū)動(dòng)程序的過程中肯定要用到printk語(yǔ)句輸出信息,printk與普通printf語(yǔ)句的差別之一就是,printk根據(jù)附加的不同的日志級(jí)別(loglevel),或者說是消息級(jí)別,來表示的嚴(yán)重程度對(duì)消息進(jìn)行分類。
比如:printk(KERN_DEBUG “Hi, My printk!”);
上述語(yǔ)句所要輸出的信息就是調(diào)試級(jí)別的。需要注意的是KERN_DEBUG和后面引號(hào)中的內(nèi)容之間不能用逗號(hào)隔開,否則編譯時(shí)會(huì)報(bào)錯(cuò)!

Linux在頭文件<linux/kernel.h>中定義了8種可用的日志級(jí)別字符串,根據(jù)嚴(yán)重程度排序如下:
KERN_EMERG      KERN_ALERT       KERN_CRIT  KERN_ERR
KERN_WARNING KERN_NOTICE     KERN_INFO  KERN_DEBUG

未指定日志級(jí)別的printk語(yǔ)句采用默認(rèn)級(jí)別,也就是在kernel/printk.c中被指定的宏DEFAULT_MESSAGE_LOGLEVEL,這個(gè)宏通常就是KERN_WARNING。

另外,控制臺(tái)(一般是指文本終端,也有可能是串口)也有一個(gè)表示級(jí)別的整數(shù)變量,叫做console_loglevel,它在系統(tǒng)啟動(dòng)后的初始值是DEFAULT_CONSOLE_LOGLEVEL。

內(nèi)核會(huì)將程序中信息的日志級(jí)別與console_loglevel進(jìn)行比較,只有當(dāng)信息的日志級(jí)別小于console_loglevel這個(gè)整數(shù)變量的值時(shí),信息才會(huì)在當(dāng)前控制臺(tái)上顯示出來。

因此,我們需要事先將系統(tǒng)的console_loglevel調(diào)到一個(gè)適當(dāng)?shù)臄?shù)值,以便控制臺(tái)正確顯示我們所需要的信息。比如上面語(yǔ)句中的“Hi, My first printk!”,若不修改console_loglevel的值,就無法在控制終端上顯示。

修改方法有兩種:一是通過sys_syslog系統(tǒng)調(diào)用進(jìn)行修改;二是用dmesg進(jìn)行修改或者修改/proc/sys/kernel/printk文件中的第一行,比如dmesg -n 1(命令中的1就是要設(shè)置的console_loglevel值,其實(shí)上面所說的KERN_EMERG到KERN_DEBUG也就是從0到7的整數(shù)值)。其中前者是臨時(shí)性的,每當(dāng)系統(tǒng)重啟后console_logleve就會(huì)回到默認(rèn)狀態(tài),而后者卻是永久性的,只要用dmesg修改了console_loglevel的值,那么以后它就一直是這個(gè)值了。
我選擇前者,因?yàn)椴幌肴我飧淖兿到y(tǒng)的狀態(tài),而且Linux Device Drvier3的作者也提供了一個(gè)叫做setlevel的小程序,可以通過由這個(gè)程序編譯得到的可執(zhí)行文件來設(shè)置console_loglevel,非常方便。
但現(xiàn)在的問題是,Linux Device Driver3提供的setlevel.c在2.6.20內(nèi)核上編譯通不過,在編譯時(shí)提示:expected declaration specifiers or ‘…’ before syslog

setlevel.c中的代碼如下:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
/* #include <unistd.h> */ /* conflicting on the alpha */
#define __LIBRARY__ /* _syscall3 and friends are only available through this */
#include <linux/unistd.h>

/* define the system call, to override the library function */
_syscall3(int, syslog, int, type, char *, bufp, int, len);

int main(int argc, char **argv)
{
    int level;

    if (argc==2) {
       level = atoi(argv[1]); /* the chosen console */
    } else {
        fprintf(stderr, "%s: need a single arg\n",argv[0]); exit(1);
    }
    if (syslog(8,NULL,level) < 0) {
        fprintf(stderr,"%s: syslog(setlevel): %s\n",
                argv[0],strerror(errno));
        exit(1);
    }
    exit(0);
}

問題很顯然出現(xiàn)在_syscall3上。
程序中_syscall3(int, syslog, int, type, char *, bufp, int, len)這條語(yǔ)句的作用是告訴編譯器,需要的系統(tǒng)調(diào)用是syslog,返回值是int,而后面的字符串則是syslog需要的3個(gè)參數(shù)及其類型。
而setlevel.c之所以編譯通不過,是因?yàn)長(zhǎng)inux Device Driver3的作者是在2.6.10的Linux內(nèi)核中寫的這個(gè)程序,但是2.6.20的Linux內(nèi)核中卻并沒有定義_syscall3這個(gè)函數(shù)。(我在Red Hat 9.0(2.4的內(nèi)核)中編譯過setlevel.c,可以正常通過。)
于是只要在setlevel.c中調(diào)用_syscall3之前定義它的原型,那么setlevel.c就可以正常編譯和使用了。增加代碼后的setlevel.c如下:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <sys/syscall.h>  /*需要加上這個(gè)頭文件,否則編譯不能通過*/

#define __syscall_return(type, res) \
do { \
       if ((unsigned long)(res) >= (unsigned long)(-125)) { \
              errno = -(res); \
              res = -1; \
       } \
       return (type) (res); \
} while (0)

#define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3) \
type name(type1 arg1,type2 arg2,type3 arg3) \
{ \
long __res; \
__asm__ volatile ("int $0x80" \
       : "=a" (__res) \
       : "0" (__NR_##name),"b" ((long)(arg1)),"c" ((long)(arg2)), \
                "d" ((long)(arg3))); \
__syscall_return(type,__res); \
}

_syscall3(int,syslog, int,type, char *,bufp, int,len);

int main(int argc, char **argv)
{
    int level;
    if (argc==2) {
       level = atoi(argv[1]); /* the chosen console */
    } else {
        fprintf(stderr, "%s: need a single arg\n",argv[0]); exit(1);
    }
    if (syslog(8,NULL,level) < 0) {
        fprintf(stderr,"%s: syslog(setlevel): %s\n",
                argv[0],strerror(errno));
        exit(1);
    }
    exit(0);
}

評(píng)分

參與人數(shù) 1可用積分 +15 收起 理由
dreamice + 15 我很贊同

查看全部評(píng)分

論壇徽章:
3
金牛座
日期:2014-06-14 22:04:062015年辭舊歲徽章
日期:2015-03-03 16:54:152015年迎新春徽章
日期:2015-03-04 09:49:45
2 [報(bào)告]
發(fā)表于 2009-11-30 20:38 |只看該作者
希望能夠繼續(xù),呵呵

論壇徽章:
0
3 [報(bào)告]
發(fā)表于 2009-11-30 20:47 |只看該作者

回復(fù) #2 dreamice 的帖子

同樣也期待你的解牛系列,呵呵~~

論壇徽章:
0
4 [報(bào)告]
發(fā)表于 2009-12-01 21:20 |只看該作者
感謝并關(guān)注,
您需要登錄后才可以回帖 登錄 | 注冊(cè)

本版積分規(guī)則 發(fā)表回復(fù)

  

北京盛拓優(yōu)訊信息技術(shù)有限公司. 版權(quán)所有 京ICP備16024965號(hào)-6 北京市公安局海淀分局網(wǎng)監(jiān)中心備案編號(hào):11010802020122 niuxiaotong@pcpop.com 17352615567
未成年舉報(bào)專區(qū)
中國(guó)互聯(lián)網(wǎng)協(xié)會(huì)會(huì)員  聯(lián)系我們:huangweiwei@itpub.net
感謝所有關(guān)心和支持過ChinaUnix的朋友們 轉(zhuǎn)載本站內(nèi)容請(qǐng)注明原作者名及出處

清除 Cookies - ChinaUnix - Archiver - WAP - TOP