日本综合一区二区|亚洲中文天堂综合|日韩欧美自拍一区|男女精品天堂一区|欧美自拍第6页亚洲成人精品一区|亚洲黄色天堂一区二区成人|超碰91偷拍第一页|日韩av夜夜嗨中文字幕|久久蜜综合视频官网|精美人妻一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
LinuxScull:強(qiáng)大的內(nèi)核可擴(kuò)展性和自適應(yīng)性(linuxscull)

linux scull是一種Linux內(nèi)核的可擴(kuò)展性和自適應(yīng)性的操作系統(tǒng)。與傳統(tǒng)的Linux內(nèi)核相比,Scull內(nèi)核具有更高的可擴(kuò)展性和自適應(yīng)性,使其在各種應(yīng)用場景下都具有很好的表現(xiàn)。

Scull內(nèi)核的可擴(kuò)展性

Scull內(nèi)核的可擴(kuò)展性主要表現(xiàn)在兩個(gè)方面,即可擴(kuò)展的體系結(jié)構(gòu)和動(dòng)態(tài)擴(kuò)展能力。

可擴(kuò)展的體系結(jié)構(gòu)

Scull內(nèi)核的體系結(jié)構(gòu)是可擴(kuò)展的,這意味著它能夠擴(kuò)展到不同類型的處理器架構(gòu)上。這種體系結(jié)構(gòu)的可擴(kuò)展性非常重要,因?yàn)樗軌蜃孲cull內(nèi)核在不同平臺上工作,并且也能夠充分利用各種不同類型的處理器架構(gòu)。

動(dòng)態(tài)擴(kuò)展能力

Scull內(nèi)核還擁有強(qiáng)大的動(dòng)態(tài)擴(kuò)展能力,這使得它能夠通過添加新的模塊來擴(kuò)展其功能,同時(shí)保證系統(tǒng)的穩(wěn)定性和安全性。Scull內(nèi)核的模塊系統(tǒng)使得Scull內(nèi)核更具可擴(kuò)展性,同時(shí)能夠支持更多的設(shè)備和驅(qū)動(dòng)程序。

Scull內(nèi)核的自適應(yīng)性

Scull內(nèi)核的自適應(yīng)性主要表現(xiàn)在兩個(gè)方面,即動(dòng)態(tài)性和適應(yīng)性。

動(dòng)態(tài)性

Scull內(nèi)核具有動(dòng)態(tài)性,可以適應(yīng)不同的系統(tǒng)資源需求,并且能夠通過調(diào)整內(nèi)存管理和進(jìn)程調(diào)度等策略來優(yōu)化系統(tǒng)性能。這種動(dòng)態(tài)性非常重要,因?yàn)榭梢源_保系統(tǒng)的高效和穩(wěn)定性,同時(shí)能夠減少資源浪費(fèi)。

適應(yīng)性

Scull內(nèi)核還具有適應(yīng)性,能夠適應(yīng)不同的應(yīng)用場景和不同的使用者需求。例如,Scull內(nèi)核可以為不同的設(shè)備驅(qū)動(dòng)程序提供不同的速率和優(yōu)先級,從而保證其具有更高的可靠性和性能。

結(jié)論

Linux Scull內(nèi)核具有強(qiáng)大的可擴(kuò)展性和自適應(yīng)性,這使得它能夠應(yīng)對不同類型的操作系統(tǒng)需求,并且能夠在不斷變化的市場中保持其競爭優(yōu)勢。雖然Scull內(nèi)核的開發(fā)和部署需要更多的資源和投入,但是它能夠提供更好的性能和系統(tǒng)穩(wěn)定性,使得企業(yè)和用戶都能夠從中受益。

成都網(wǎng)站建設(shè)公司-創(chuàng)新互聯(lián)為您提供網(wǎng)站建設(shè)、網(wǎng)站制作、網(wǎng)頁設(shè)計(jì)及定制高端網(wǎng)站建設(shè)服務(wù)!

如何調(diào)試驅(qū)動(dòng)開發(fā)過程中的Oops

驅(qū)動(dòng)程序開發(fā)的一個(gè)重大難點(diǎn)就是不易調(diào)試。本文目的就是介紹驅(qū)動(dòng)開發(fā)中常用的幾種直接和間接的調(diào)試手段,它們是:

1、利用printk

2、查看OOP消息

3、利用strace

4、利用內(nèi)核內(nèi)置的hacking選項(xiàng)

5、利用ioctl方法

6、利用/proc 文件鬧笑系統(tǒng)

7、使用kgdb

前兩種如下:

一、利用printk

這是驅(qū)動(dòng)開發(fā)中最樸實(shí)無華,同時(shí)也是最常用和有效的手段。scull驅(qū)動(dòng)的main.c第338行如下,就是使用printk進(jìn)行調(diào)試的例子,這樣的例子相信大家在閱讀驅(qū)動(dòng)源碼時(shí)隨處可見。

338 //printk(KERN_ALERT “wakeup by signal in process %d\n”, current->pid);

printk的功能與我們經(jīng)常在應(yīng)用程序中使用的printf是一樣的,不同之處在于printk可以在打印字符串前面加上內(nèi)核定義的宏,例如上面例子中的KERN_ALERT(注意:宏與字符串之間沒有逗號)。

#define KERN_EMERG “”

#define KERN_ALERT “”

#define KERN_CRIT “”

#define KERN_ERR “”

#define KERN_WARNING “”

#define KERN_NOTICE “”

#define KERN_INFO “”

#define KERN_DEBUG “”

#define DEFAULT_CONSOLE_LOGLEVEL 7

這個(gè)宏是用來定義需要打印的字符串的級別。值越小,級別越高。內(nèi)核中有個(gè)參數(shù)用來控制是否將printk打印的字符串輸出到控制臺(屏幕或者/sys/log/syslog日志文件)

# cat /proc/sys/kernel/printk

之一個(gè)6表示級別高于(小于)6的消息才會被輸出到控制臺,第二個(gè)4表示如果調(diào)用printk時(shí)沒有指定消息級別(宏)則消息的級銀孝別為4,第三個(gè)1表示接受的更高(最小)級別是1,第四個(gè)7表示系統(tǒng)啟動(dòng)時(shí)之一個(gè)6原來的初值是7。

因此,如果你發(fā)現(xiàn)在控制臺上看不到你程序中某些printk的輸出,請使用echo 8 > /proc/sys/kernel/printk來解決。

在復(fù)雜驅(qū)動(dòng)的開發(fā)過程中,為了調(diào)試會在源碼中加入成百上千的printk語句。而當(dāng)調(diào)試完畢形成最終產(chǎn)品的時(shí)候必然會將這些printk語句刪除想想驅(qū)動(dòng)的使用者而不是開發(fā)者吧。記?。杭核挥?,勿施于人),這個(gè)工作量是不小的。最要命的是,如果我們將調(diào)試用的printk語句刪除后,用戶又報(bào)告驅(qū)動(dòng)有bug,所以我們又不得不手工將這些上千條的printk語句再重新加上。oh,my god,殺了我吧。所以,我們需要一種能方便地打開和關(guān)閉調(diào)試信息的手段。哪里能找到這種手段呢?哈哈,遠(yuǎn)在天邊,近在眼前??纯磗cull驅(qū)動(dòng)或者leds驅(qū)動(dòng)的源代碼吧!

#define LEDS_DEBUG

#undef PDEBUG

#ifdef LEDS_DEBUG

#ifdef __KERNEL__

#define PDEBUG(fmt, args…) printk( KERN_EMERG “l(fā)eds: ” fmt, ## args)

#else

#define PDEBUG(fmt, args…) fprintf(stderr, fmt, ## args)

#endif

#else

#define PDEBUG(fmt, args…)

#endif

#undef PDEBUGG

#define PDEBUGG(fmt, args…)

這樣一來,在開發(fā)驅(qū)動(dòng)的過程中,如果想打印調(diào)試消息,我們就可以用PDEBUG(“address of i_cdev is %p\n”, inode->i_cdev);,如果不想看到該調(diào)試消息,就只需要簡單的將PDEBUG改為PDEBUGG即可。而當(dāng)我們調(diào)試完畢形成最終產(chǎn)品時(shí),只需要簡單地將第1行注釋掉即可。

上邊那一段代碼中的__KERNEL__是內(nèi)核中定義的宏,當(dāng)我們編譯內(nèi)核(包括模塊)時(shí),它會被定義。當(dāng)然如果你不明白代碼中的…和##是什么意思的話,就請認(rèn)真查閱一下gcc關(guān)于預(yù)處理部分的資料吧!如果你實(shí)在太懶不愿意去查閱的話,那就充當(dāng)VC工程師把上面的代碼copy到你的代碼中去吧。

二、查看OOP消息

OOP意為驚訝。當(dāng)鋒彎稿你的驅(qū)動(dòng)有問題,內(nèi)核不驚訝才怪:嘿!小子,你干嗎亂來!好吧,就讓我們來看看內(nèi)核是如何驚訝的。

根據(jù)faulty.c(單擊下載)編譯出faulty.ko,并 inod faulty.ko。執(zhí)行echo yang >/dev/faulty,結(jié)果內(nèi)核就驚訝了。內(nèi)核為什么會驚訝呢?因?yàn)閒aulty驅(qū)動(dòng)的write函數(shù)執(zhí)行了*(int *)0 = 0,向內(nèi)存0地址寫入,這是內(nèi)核絕對不會容許的。

52 ssize_t faulty_write (struct file *filp, const char __user *buf, size_t count,

loff_t *pos)

54 {

*(int *)0 = 0;

return 0;

58 }

1 Unable to handle kernel NULL pointer dereference at virtual address

2 pgd = c

3 *pgd=, *pte=, *ppte=

4 Internal error: Oops: 817 PREEMPT

5 Modules linked in: faulty scull

6 CPU: 0 Not tainted (2.6.22.6 #4)

7 PC is at faulty_write+0×10/0×18

8 LR is at vfs_write+0xc4/0×148

9 pc : lr : psr: a

10 sp : c3871f44 ip : c3871f54 fp : c3871f50

11 r10:c r9 : cr8 :

12 r7 :r6 : c3871f78 r5 :r4 : c38e5160

13 r3 : c3871f78 r2 :r1 :r0 :

14 Flags: NzCv IRQs on FIQs on Mode SVC_32 Segment user

15 Control: c000717f Table:DAC:

16 Process sh (pid: 745, stack limit = 0xc)

17 Stack: (0xc3871f44 to 0xc)

18 1f40:c3871f74 c3871f54 c0088eb8 bf00608cc38e5180 c38e5160

19 1f60: c3871fc3871fa4 c3871f78 c0088ffc c0088e000000

20 1f80:004 c002c0ec3871fa8

21 1fa0: c002bf40 c0088fc

22 1fc0:021765c

23 1fe0:beac 401adb

24 Backtrace:

25 (faulty_write+0×0/0×18 ) from (vfs_write+0xc4/0×148)

26 (vfs_write+0×0/0×148) from (sys_write+0x4c/0×74)

27 r7:r6:c3871f78 r5:c38e5160 r4:c38e5180

28 (sys_write+0×0/0×74) from (ret_fast_syscall+0×0/0x2c)

29 r8:c002c0e4 r7:r6:r5:r4:

30 Code: e1a0c00d e92dd800 e24cb004 e3a00000 (e)

1行驚訝的原因,也就是報(bào)告出錯(cuò)的原因;

2-4行是OOP信息序號;

5行是出錯(cuò)時(shí)內(nèi)核已加載模塊;

6行是發(fā)生錯(cuò)誤的CPU序號;

7-15行是發(fā)生錯(cuò)誤的位置,以及當(dāng)時(shí)CPU各個(gè)寄存器的值,這最有利于我們找出問題所在地;

16行是當(dāng)前進(jìn)程的名字及進(jìn)程ID

17-23行是出錯(cuò)時(shí),棧內(nèi)的內(nèi)容

24-29行是棧回溯信息,可看出直到出錯(cuò)時(shí)的函數(shù)遞進(jìn)調(diào)用關(guān)系(確保CONFIG_FRAME_POINTER被定義)

30行是出錯(cuò)指令及其附近指令的機(jī)器碼,出錯(cuò)指令本身在小括號中

反匯編faulty.ko( arm-linux-objdump -D faulty.ko > faulty.dis ;cat faulty.dis)可以看到如下的語句如下:

c :

7c: e1a0c00dmov ip, sp

80: e92ddstmdb sp!, {fp, ip, lr, pc}

84: e24cbsub fp, ip, #; 0×4

88: e3amov r0, #0 ; 0×0

8c: e str r0,

90: e89daldmia sp, {fp, sp, pc}

定位出錯(cuò)位置以及獲取相關(guān)信息的過程:

9 pc : lr : psr: a

25 (faulty_write+0×0/0×18 ) from (vfs_write+0xc4/0×148)

26 (vfs_write+0×0/0×148) from (sys_write+0x4c/0×74)

出錯(cuò)代碼是faulty_write函數(shù)中的第5條指令((0xbf00608c-0xbf00607c)/4+1=5),該函數(shù)的首地址是0xbf00607c,該函數(shù)總共6條指令(0×18),該函數(shù)是被0xc0088eb8的前一條指令調(diào)用的(即:函數(shù)返回地址是0xc0088eb8。這一點(diǎn)可以從出錯(cuò)時(shí)lr的值正好等于0xc0088eb8得到印證)。調(diào)用該函數(shù)的指令是vfs_write的第49條(0xc4/4=49)指令。

達(dá)到出錯(cuò)處的函數(shù)調(diào)用流程是:write(用戶空間的系統(tǒng)調(diào)用)–>sys_write–>vfs_write–>faulty_write

OOP消息不僅讓我定位了出錯(cuò)的地方,更讓我驚喜的是,它讓我知道了一些秘密:1、gcc中fp到底有何用處?2、為什么gcc編譯任何函數(shù)的時(shí)候,總是要把3條看上去傻傻的指令放在整個(gè)函數(shù)的最開始?3、內(nèi)核和gdb是如何知道函數(shù)調(diào)用棧順序,并使用函數(shù)的名字而不是地址? 4、我如何才能知道各個(gè)函數(shù)入棧的內(nèi)容?哈哈,我漸漸喜歡上了讓內(nèi)核驚訝,那就再看一次內(nèi)核驚訝吧。

執(zhí)行 cat /dev/faulty,內(nèi)核又再一次驚訝!

1 Unable to handle kernel NULL pointer dereference at virtual addres

2 pgd = c3a88000

3 *pgd=33a79031, *pte=, *ppte=

4 Internal error: Oops: 13 PREEMPT

5 Modules linked in: faulty

6 CPU: 0 Not tainted (2.6.22.6 #4)

7 PC is at vfs_read+0xe0/0×140

8 LR is at 0xffffffff

9 pc : lr : psr:

10 sp : c38d9f54 ip :c fp : ffffffff

11 r10:r9 : c38d8000 r8 :

12 r7 :r6 : ffffffff r5 : ffffffff r4 : ffffffff

13 r3 : ffffffff r2 :r1 : c38d9f38 r0 :

14 Flags: nzCv IRQs on FIQs on Mode SVC_32 Segment user

15 Control: c000717f Table: 33aDAC:

16 Process cat (pid: 767, stack limit = 0xc38d8258)

17 Stack: (0xc38d9f54 to 0xc38da000)

18 9f40:c3c105a0 c3c10580

19 9f60: c38d9fc38d9fa4 c38d9f78 c0088f88 c0088bb00000

20 9f80:2023 bef07cc002c0ec38d9fa8

21 9fa0: c002bf40 c0088f4cbef07cbef07c000000

22 9fc0:bef07c

23 9fe0:bef07c6cc 401adab

24 Backtrace: invalid frame pointer 0xffffffff

25 Code: ebffff86 ee1a07000 da(e594500c)

26 Segmentation fault

不過這次驚訝卻令人大為不解。OOP竟然說出錯(cuò)的地方在vfs_read(要知道它可是大拿們千錘百煉的內(nèi)核代碼),這怎么可能?哈哈,萬能的內(nèi)核也不能追蹤函數(shù)調(diào)用棧了,這是為什么?其實(shí)問題出在faulty_read的43行,它導(dǎo)致入棧的r4、r5、r6、fp全部變?yōu)榱?xffffffff,ip、lr的值未變,這樣一來faulty_read函數(shù)能夠成功返回到它的調(diào)用者——vfs_read。但是可憐的vfs_read(忠實(shí)的APTCS規(guī)則遵守者)并不知道它的r4、r5、r6已經(jīng)被萬惡的faulty_read改變,這樣下去vfs_read命運(yùn)就可想而知了——必死無疑!雖然內(nèi)核很有能力,但缺少了正確的fp的幫助,它也無法追蹤函數(shù)調(diào)用棧。

36 ssize_t faulty_read(struct file *filp, char __user *buf,

size_t count, loff_t *pos)

38 {

int ret;

char stack_buf;

41

memset(stack_buf, 0xff, 20);

if (count > 4)

count = 4;

ret = copy_to_user(buf, stack_buf, count);

if (!ret)

return count;

return ret;

50 }

:

0: e1a0c00dmov ip, sp

4: e92ddstmdb sp!, {r4, r5, r6, fp, ip, lr, pc}

8: e24cbsub fp, ip, #; 0×4

c: e24ddsub sp, sp, #; 0×4,這里為stack_buf在棧上分配1個(gè)字的空間,局部變量ret使用寄存器存儲,因此就不在棧上分配空間了

10: e24b501csub r5, fp, #; 0x1c

14: e1amov r4, r1

18: e1amov r6, r2

1c: e3a010ffmov r1, #; 0xff

20: e3amov r2, #20 ; 0×14

24: e1amov r0, r5

28: ebfffffebl//這里在調(diào)用memset

78: e89daldmia sp, {r3, r4, r5, r6, fp, sp, pc}

這次OOP,深刻地認(rèn)識到:

內(nèi)核能力超強(qiáng),但它不是,也不可能是萬能的。所以即使你能力再強(qiáng),也要和你的team member搞好關(guān)系,否則在關(guān)鍵時(shí)候你會倒霉的;

出錯(cuò)的是faulty_read,vfs_read卻做了替罪羊。所以人不要被表面現(xiàn)象所迷惑,要深入看本質(zhì);

內(nèi)核本來超級健壯,可是你寫的驅(qū)動(dòng)是內(nèi)核的組成部分,由于它出錯(cuò),結(jié)果整體。所以當(dāng)你加入一個(gè)團(tuán)隊(duì)的時(shí)候一定要告誡自己,雖然你的角色也許并不重要,但你的疏忽大意將足以令整個(gè)非常牛X的團(tuán)隊(duì)。反過來說,當(dāng)你是team leader的時(shí)候,在選團(tuán)隊(duì)成員的時(shí)候一定要慎重、慎重、再慎重,即使他只是一個(gè)小角色。

關(guān)于linux scull的介紹到此就結(jié)束了,不知道你從中找到你需要的信息了嗎 ?如果你還想了解更多這方面的信息,記得收藏關(guān)注本站。

香港服務(wù)器選創(chuàng)新互聯(lián),香港虛擬主機(jī)被稱為香港虛擬空間/香港網(wǎng)站空間,或者簡稱香港主機(jī)/香港空間。香港虛擬主機(jī)特點(diǎn)是免備案空間開通就用, 創(chuàng)新互聯(lián)香港主機(jī)精選cn2+bgp線路訪問快、穩(wěn)定!


分享文章:LinuxScull:強(qiáng)大的內(nèi)核可擴(kuò)展性和自適應(yīng)性(linuxscull)
轉(zhuǎn)載注明:http://www.dlmjj.cn/article/djoohep.html