《核心模组》PPT课件.ppt
《《核心模组》PPT课件.ppt》由会员分享,可在线阅读,更多相关《《核心模组》PPT课件.ppt(72页珍藏版)》请在三一办公上搜索。
1、Driver,核心模組 vs 應用程式,應用程式啟動後從頭到尾都只執行同一件任務.模組被載入核心之後必須先向核心註冊它自己.init_module()函式(模組的入口點)任務是將模組的功能準備好 以便事後可被invocation(調用).cleanup_module()在模組離開之前必須要被呼叫.模組只能與核心連結所以模組只能呼叫核心所提供的程式 ex:printfk().由於上一點,模組的原始碼不能引入一般的標頭檔.有關核心相關事物放在/usr/src/linux下的 include/linux 與 include/asm/目錄下的標頭檔.,使用者空間與核心空間,模組存活在kernel sp
2、ace(核心空間)而應用程式存在user space(使用者空間).作業系統必須負責讓程式得以獨立運作並保護系統資源避免非授權的存取.由CPU來保護系統軟體所以CPU本身提供了不同層級的作業模式(operating modality).Unix系統提供兩個層級而現在CPU也至少有兩種層級,故Unix系統只使用最高與最低層級,Unix核心運作在最高層級(supervisor mode)應用程式運作在最低層級(user mode).execution mode:包括kernel-space 與user-space分別有各自的memory mapping(記憶體對應關係)的關係與各自的address
3、 space(定址空間).,insmod,載入 insmod對模組的作用:將模組內的任何unresolved symbol(懸置 符號)連結到目前核心(函式庫)的符號表.核心如何支援insmod?依賴定義在kernel/module.c的system call函式:1)sys_create_module():配置一塊可以容納模組的核心記憶空間.2)sys_get_kernel_syms():傳回核心符號表,解決模組的懸置符號.3)sys_init_module():將insmod改好的relocated object code移到 預先配置的核心空間.系統呼叫大略表:kernel/目錄執行 e
4、grep“sys_.*)$”*.c,版本依存性,模組與連結對象核心息息相關每當升級何新版本時模組就必須再新版本核心下重新編譯一次.編譯器會在ELF(executable Linking and Format).的.modifo(chap 11)區定義_module_kernel_version符號insmod會依照此符號與當時的核心作比較.定義在.可使用insmod f來略過版本檢查.針對特定版本的核心來編譯模組必須引入該版本核心的標頭檔再Makefile定義一個KERNELDIR環境變數讓他指另一個不同的位置.,核心符號表,模組化驅動程式所需的核心全域項目(函式與變數)的位置都紀錄在符號表裡
5、 可從/proc/ksyms取的此表.若模組能被順利載入核心,模組所釋放的符號也會成為核心符號的一部分.模組所釋出的符號可以被新模組使用新模組可以疊在其他模組之上.ex:msdos檔案系統得仰賴fat模組所釋出的符號,模組的生與死,init_module()會註冊模組所提供的任何facility(功能性).模組可以註冊許多不同類型的facility,對於每一個facility都有一個特定的核心函式來完成其註冊程序.傳給核心註冊函式的引數:facility註冊名稱,指標(指向此facility的資料結構).facility種類:序列阜,雜項裝置,/proc檔案,作業領域(executable d
6、omain),管制線路(line discipline).,Init_module的錯誤處置,註冊失敗:系統沒有足夠空間或某資源已被其他驅動程式佔用模組自己要負責回復(undo)到註冊失敗之前的狀態,如果init_module()在中途失敗,模組必須自己主動註銷(unregister)那些已經註冊成功的facility.不能藉由重新載入模組來重新註冊facility,也不太可能註銷他們,因為需要當初註冊所用的相同指標.使用goto解決.,卸載模組,使用rmmod可卸載(unload)沒用的模組.原理:rmmod觸發delete_module()system call,如果模組的用量為零,則de
7、lete_module()會呼叫模組本身的cleanup_module();否則回傳作錯誤代碼.cleanup_module()必須負責註銷該模組的每一項facility.,實際的初始化與清理函式,命名模組函式,須引入 module_init(my_init);module_exit(my_cleanup);my_init取代init_module(),my_cleanup取代cleanup_module();所以可使每個初始函式與清理函式都有自己專屬的名稱,以方便除錯.,資源的運用,大部分驅動程式的工作大概就在讀寫I/O port或I/O memory(統稱 I/O region)核心都應該
8、保證驅動程式能獨占存取其I/O port以免受到其他驅動程式的干擾/proc/ioports與/proc/iomem檔案可取得以註冊的系統資源,User-space驅動程式(1/2),優點 可使用完整的c函式庫.可使用傳統的debugger.若user-space driver當掉,直接kill就可以.user-space記憶體可被“置換(swappable)”,而kernel-space不可能,因此較大的程式不會排擠其他程式所使用的RAM,除非此裝置正在使用.user-space driver也能容許目標裝置同時被多個行程所存取.,User-space驅動程式(2/2),缺點:在user-s
9、pace內無法使用”中斷”.不能直接存取I/O memory.必須先呼叫ioperm()或iopl()才能存取I/O port.回應時間較緩慢,因為應用程式要傳輸資料給硬體而硬體也要回應應用程式(context switch)若驅動程式已被“置換(swap)”到磁碟上,那回應時間就更長了 大部分重要裝置不能在user-space上予以有效控制,ex:網路介面,I/O memory(1/3),int check_region(unsigned long start,unsigned long len);用來檢查某段範圍的I/O位址是否被佔用.struct resource*request_reg
10、ion(unsigned long start,unsigned long len,char*nam);要求註冊該位址區.若核心同意,此函式會回傳一個non-NULL指標.,I/O memory(2/3),void release_region(unsigned long start.unsigned long len);將取得的I/O 位址歸還給系統.,I/O memory(3/3),取得,釋放特定一段的I/O memory region int check_mem_region(usigned long start,unsigned long len);int request_mem_re
11、gion(unsigned long start,unsigned long len,char*name);int release_mem_region(unsigned long start,unsigned long len);,決定組態參數(1/4),驅動程式所需的某些參數會因系統而異,ex:I/O 位址,記憶區範圍有時候必須傳遞參數給驅動程式,才能幫助他找到目標裝置或啟動,關閉特定功能.對於某些裝置,如裝置品牌,型號等也有可能影響驅動程式的行為.將正確的參數傳遞給驅動程式(configuring),是驅動程式在初始化期間必須完成的工作.參數值可在載入期間由insmod或modprobe
12、傳給模組,決定組態參數(2/4),modprobe可從一各組態檔(/etc/modules.conf)讀入參數值.使用者可在命令列指定參數值ex:#insmod skull skull_ival=666 skull_sval=“beast”在insmod能夠改變模組參數之前,模組本身必須以MODULE_PARM()巨集(定義在linux/module.h)宣告可被修改的參數.MODULE_PARM()需要兩個引數,一是變數名稱,二是變數型別.,決定組態參數(3/4),int skull_ival=0;char*skull_sval;MODULE_PARM(skull_ival,“I”);MOD
13、ULE_PARM(skull_sval,“s”);參數型別有五種:b(1-byte),h(2-byte短整數),i(整數),l(長整數),s(字串).,決定組態參數(4/4),MODULE_PARM_DESC()巨集,可讓程式設計師用來描述模組參數的意義.static int skull_port_bse=0 x300;MODULE_PARM(skull_port_base,”i”);MODULE_DESC(skull_port_base,”skull I/O base(default 0 x300);可使用objdump,modinfo指令來檢視參數指令.,訊息除錯法(1/4),printk
14、()函式通用的除錯技巧,對應用程式而言使用printf();對於核心程式而言則使用printk().printk()能讓你指定訊息的loglevel(等級),共分為八纇.定義在裡.KERN_EMERG:緊急訊息,出現在系統崩潰前.KERN_ALERT:危險通知,發生在需要立即採 取行動的事件.KERN_CRIT:嚴重狀況,涉及硬體或軟體故障,訊息除錯法(2/4),KERN_ERR:錯誤狀況回報,通常回報硬體上的困難.KERN_WARNING:緊急訊息,程度上不影響系統.NERN_NOTICE:通知,意料中會發生且值得注意的 狀況.KERN_INFO:資訊性訊息,driver在啟動階段所印出 的
15、硬體資訊.KERN_DEBUG:供除錯用途的訊息.,訊息除錯法(3/4),上述代號展開後分別成為:,之類的字串,括弧內數字越低表示等級越高.ex:printk(KERN_DEBUG“HI”);不同等級的訊息會被輸出到不同的地點,有可能是目前的操控台(console)或者是某種文字終端機(Xterm視窗,Telnet或SSH連線).任何等值低於console_loglevel的變數訊息都會被顯示在操控台上(console).不過若系統上同時執行klogd與syslogd不管console_loglevel的值為何,所有核心訊息都會被加入/var/log/messages.,訊息除錯法(4/4),
16、如果沒跑klogd,則訊息不會流入user-space,除非主動讀取/proc/kmsg.修改console_loglevel的值 使用sys_syslog()利用klogd的 c選項.本書範例:misc-progs/setlevel.c,2.1.31版本開始,可以直接透/proc/sys/kernel/printk檔案來修改或檢視console_levle的值.#echo 8/proc/sys/kernel/printk,核心訊息的輸出流程(1/2),printk()會將訊息寫入一個環型queue,長度為LOG_BUF_LEN(定義在kernel/printk.c),且喚醒 正在等待訊息的行
17、程(使用syslog().正在讀取/proc/kmesg的行程.在環型queue被填滿時,printk()將會繞回原點,將新訊息覆蓋在最就訊息上,其優點:固定記憶體,既使沒跑日誌紀錄引擎(klogd,syslogd)也不至於消耗所有的記憶體.核心內部到處都可以直接呼叫printk().,核心訊息的輸出流程(2/2),klogd所取得的核心訊息會被轉交給syslogd,由它依據/etc/syslog.conf來決定如何處裡收到的訊息.若系統沒跑klogd,核心訊息將會一值留在環型佇列,直到有人讀取它或者是被新訊息蓋掉.若不希望driver所發出得訊息擾亂的系統的日誌檔,可以用-f選項來從新啟動k
18、logd並將其訊息寫入特定檔案.,kernel,/proc/kmsg,klogd,/dev/log,syslogd,syslog.conf,查詢除錯法(1/6)(使用/proc檔案系統),/proc是靠軟體模擬出來的特殊檔案系統,並不實際存在於硬碟上,而是核心提供給user-space的資訊窗口.在proc/下的每一個檔案,接聯繫到核心內的專屬函式,這些函式在使用者讀取檔案時,及時產生檔案的內容.ex:以/proc/modules為例,當你讀取它時它會顯示目前載入哪些模組,但此檔案系統的長度都為0.,查詢除錯法(2/6)(使用/proc檔案系統),Linux許多系統工具,如ps,top,upt
19、ime等都是從/proc取得它們所需要的資訊.建立/proc檔案:driver必須製作一備查程式,讓它在檔案被存取時,及時供應資料,核心也會配置一記憶頁給它備查程式介面:int(*read_proc)(char*page,char*start,off_t offset,int count,int*eof,void*data);,read(),/proc,備查函式,記憶頁,User-space,查詢除錯法(3/6)(使用/proc檔案系統),page指標:指向核心預先配置的記憶頁*start與offset:若檔案超過一記憶頁大小,可利用分批傳輸的方式,先將*start指向page再利用offse
20、t指向下一各位元組.skcull程式中有對read_proc的實作:,查詢除錯法(4/6)(使用/proc檔案系統),定義好read_proc作業方式後,必須為它在/proc下設置一個入口點,使用create_proc_read_entry().若希望使用者能透過/proc/scullmem取得該函式提供的資料,則driver需宣告如下:,static void scull_create_proc()create_proc_read_entry(“scullmem”,0/*預設模式(0 x444)*/,NULL/*上層目錄(*proc_dir_entry)*/,scull_read_procm
21、em,NULL/*提供給read_proc使用的資料*/);,/proc入口點名稱,檔案權限,入口點上層目錄,read_proc作業方法的指標,傳給read_proc的資料的指標,查詢除錯法(5/6)(使用/proc檔案系統),第三參數的說明:在/proc檔案系統下的每一個子目錄,都有各自 專屬的proc_dir_entry結構來描述.ex:描述/proc/driver子目錄的結構為 proc_root_driver,描述/proc/bus子目錄的結 構為proc_bus.若此引數設定為NULL代表入口點設置在/proc 目錄下.,查詢除錯法(6/6)(使用/proc檔案系統),在模組被載卸之
22、前必須先移除相關的/proc入口點,使用remove_proc_entry(),/移除/proc/scullmem;remove_pcor_entry(“scullmem”,NULL);/移除/proc/driver/scullmem;remove_proc_entry(“scullmem”,proc_root_driver);/移除/proc/scull/scullmem;remove_proc_entry(“scullmem”,scull_procdir);,觀測除錯法,strace,檢驗位於kernel-space的程式碼.能顯示出由user-space程式所發出的所有system ca
23、ll.#strace ls/dev/dev/scull0,排除重大系統錯誤(1/2),除了監視,除錯技術,驅動程式可能還是意料之外的bug存在,嚴重可能造成system fault.fault(失誤)不等於panic(死當),失誤通常會摧毀目前的行程,系統本身能正常.若fault發生在process context之外,或是破壞系統的關鍵部分,即有可能早成panic.oops訊息:往往發生在不當的操作指標所引起,如dereference(提領)或者是誤用指標的值.,排除重大系統錯誤(2/2),page fault:在protect mode(保護模式)下,所使用的是virtual addres
24、s(虛擬記憶體),藉由page table換算出physical address(實體位置),若程式提領一個無效指標,分頁機制則沒有辦法算出實體位置,因而發生page fault.若在user-space發生提領無效,後果頂多是無法”page in“該位址.若發生在kernel則迫使核心發出oops訊息.,Ksymoops用法,ksymoops用法:systme.map檔(-v)/usr/src/linux/system.map模組清單(-l):/proc/modules核心符號表(-k):/proc/ksyms映像檔(-v):模組object檔存放位置(-o):,gdb使用,gdb使用:指令
25、:gdb/usr/src/linux/vmlinux/proc/kcore(gdb)x/i Ex:(gdb)x/20i 0 xc8002060參考網址:http:/es-sun2.fernuni-hagen.de/cgi-bin/info2html?(gdb)Top,其他核心除錯器,kdbkgdb,核心的計時間隔,中斷CPU暫停目前工作,然後執行ISR來處理中斷.(CH9)計時器中斷,固定間隔觸發的中斷事件,核心依據HZ(定義在)的值來設定間隔長度,硬體平台不同,值也不同.每次發生計時器中斷,jiffies變數的值就會被遞增一次,宣告在,型別為unsigned long volatile,核心
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 核心模组 核心 模组 PPT 课件
链接地址:https://www.31ppt.com/p-5584779.html