




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)
文檔簡介
編譯內(nèi)核、模塊編程編譯內(nèi)核添加系統(tǒng)調(diào)用模塊編程體會用戶空間和系統(tǒng)空間學(xué)習模塊的操作(加載、卸載)本實驗討論內(nèi)容編譯內(nèi)核linux內(nèi)核源碼公開。并可以編譯新內(nèi)核。對redhat9來說,內(nèi)核源碼在/usr/src,對FC7來說,在/usr/src/kernels。[root@localhostroot]#cd/usr/src[root@localhost
src]#lsdebuglinux-2.4linux-2.4.20-8redhat[root@localhostsrc]#cd/usr/src/kernels[root@localhostkernels]#ls2.6.11-1.1369_FC4-i686為什么要編譯內(nèi)核學(xué)習與體會。需要使用新內(nèi)核中的功能。修補系統(tǒng)新發(fā)現(xiàn)的安全漏洞和缺陷,維護系統(tǒng)的正常使用和運行。提高系統(tǒng)性能,包括升級新內(nèi)核,修改現(xiàn)有內(nèi)核。硬件發(fā)生變動,需要在內(nèi)核中進行調(diào)整。編譯內(nèi)核的過程(1)uname–r2.6.11-1到,下載內(nèi)核源碼。linux-.tar.bz2或linux-.tar.gzcplinux-.tar.bz2到/usr/srctarjxvflinux-.tar.bz2解壓。如果是gz文件,則用tarzxvflinux-.tar.gz[root@localhostboot]#cd/usr/src[root@localhost
src]#lskernelslinux-linux-.tar.bz2redhat在FC7上編譯2.6內(nèi)核的過程(2)內(nèi)核源碼/pub/linux/kernel/v2.6/cp/mnt/hgfs/share/linux-.tar.gz/usr/srctarzxvflinux-.tar.gz[root@localhost
src]#lskernelslinux-linux-.tar.gzredhat[root@localhost
src]#cdlinux-[root@localhostlinux-]#lsarchcryptoincludekernelmmscriptsblockDocumentationinitlibnetsecurityCOPYINGdriversipcMAINTAINERSREADMEsoundCREDITSfs
Kbuild
MakefileREPORTING-BUGSusr在FC7上編譯2.6內(nèi)核的過程(2)啟動文件[root@localhost/]cp–rbootboot1//備份boot目錄,最好要這樣。[root@localhost/]#cdboot1[root@localhostboot1]#lsconfig-2.6.11-1.1369_FC4編譯配置文件
lost+foundgrubSystem.map-2.6.11-1.1369_FC4內(nèi)核符號表initrd-2.6.11-1.1369_FC4.imgvmlinuz-2.6.11-1.1369_FC4內(nèi)核映像文件initrd是linux在系統(tǒng)引導(dǎo)過程中使用的一個臨時的根文件系統(tǒng),用來支持兩階段的引導(dǎo)過程。在內(nèi)核之前進入內(nèi)存過程(3)在源碼中添加系統(tǒng)調(diào)用-調(diào)用過程系統(tǒng)調(diào)用總控程序地址掛在0x80號中斷上。通過0x80號中斷進入總控程序,并通過寄存器eax傳入系統(tǒng)調(diào)用號??偪爻绦蛘业较到y(tǒng)調(diào)用向量表sys_call_table(作為基址),再將eax中傳入的系統(tǒng)調(diào)用號×4B找到對應(yīng)系統(tǒng)調(diào)用偏移地址(向量表每個表項占4B),基址+偏移地址即為系統(tǒng)調(diào)用服務(wù)程序入口地址。轉(zhuǎn)到系統(tǒng)調(diào)用服務(wù)程序asmlinkagesys_×××()asmlinkage
表示函數(shù)不通過寄存器,而是通過堆棧獲得并修改參數(shù)。過程(3)在源碼中添加系統(tǒng)調(diào)用[root@localhostlinux-]#vikernel/sys.c在尾部添加:asmlinkage
int
testprint(char*str){
printk("mynameis%s\n",str);return0;}過程(3)在源碼中添加系統(tǒng)調(diào)用[root@localhostlinux-]#viarch/i386/kernel/syscall_table.S.longsys_tee/*315*/.longsys_vmsplice.longsys_move_pages.longsys_getcpu.longsys_epoll_pwait.longsys_testprint/*320*/過程(3)在源碼中添加系統(tǒng)調(diào)用[root@localhostlinux-]#viinclude/asm-i386/unistd.h#defineNR_syscalls320#define__NR_epoll_pwait319#define__NR_testprint320#ifdef__KERNEL__#defineNR_syscalls321在FC7上編譯2.6內(nèi)核的過程(4)編譯過程makemrproper:清除過去編譯留下的中間文件,若是第一次編譯的新內(nèi)核,可以不要這一步。配置編譯選項:用makemenuconfig等,產(chǎn)生編譯配置文件.config產(chǎn)生內(nèi)核映像文件bzImage。并將其放到/boot目錄產(chǎn)生可加載模塊。并將它們加入到/lib/modules目錄。產(chǎn)生System.map文件等文件,將其放到/boot目錄。#makeconfig:基于文本的最為傳統(tǒng)的配置界面,不推薦使用#makemenuconfig:基于文本菜單的配置界面,字符終端下推薦使用#makexconfig:基于圖形窗口模式的配置界面,Xwindow下推薦使用#makeoldconfig:如果只想在原來內(nèi)核配置的基礎(chǔ)上修改一些小地方,用此方法會省去不少麻煩上述幾種方法的目的是一樣的,那就是生成一個.config文件常用的編譯配置方式:選擇相應(yīng)的配置時,有三種選擇,它們分別代表的含義如下:Y--將該功能編譯進內(nèi)核N--不將該功能編譯進內(nèi)核M--將該功能編譯成可以在需要時動態(tài)插入到內(nèi)核中的模塊可用空格鍵在這三者之間切換?;虬磞/m/n進行選擇方括號:只有*、空(不編譯)兩種選擇尖括號:可以是空,"*"和"M"圓括號:在提供的幾項中選擇按兩次ESC鍵可退出;或選擇EXIT用menuconfig方式:#makedep
鏈接程序代碼與函數(shù)庫;實際上讀取配置過程生成的配置文件,來創(chuàng)建對應(yīng)于配置的依賴關(guān)系樹,從而決定哪些需要編譯而那些不需要;#makeclean刪除前面步驟產(chǎn)生的不必要的文件;#makebzImage
開始編譯產(chǎn)生內(nèi)核映像文件;makeall相當于:#makemodules編譯模塊;#makemodules_install
安裝編譯完成的模塊。makeinstall安裝編譯完成的模塊。將bzImage、System.map
復(fù)制到/boot繼續(xù)操作整個編譯過程(1)[root@localhost/]cp–rbootboot1//備份boot目錄[root@localhostlinux-]#makemrproper[root@localhostboot]#cp/boot/config-2.6.21-1.3194.fc7/usr/src/linux-[root@localhostlinux-]#mvconfig-2.6.21-1.3194.fc7.config[root@localhostlinux-]#makeoldconfig[root@localhostlinux-]#viMakefileVERSION=2PATCHLEVEL=6SUBLEVEL=21EXTRAVERSION=.6改為:EXTRAVERSION=.6-jiangjian整個編譯過程(2)[root@localhostlinux-]#makeallNAME=NocturnalMonsterPuppyLDvmlinuxSYSMAPSystem.mapSYSMAP.tmp_System.mapBUILDarch/i386/boot/bzImageRootdeviceis(253,0)Bootsector512bytes.Setupis7353bytes.Systemis1801kBKernel:arch/i386/boot/bzImageisready(#1)整個編譯過程(3)[root@localhostlinux-]#makemodules_install[root@localhostlinux-]#makeinstallsh/usr/src/linux-/arch/i386/boot/install.sh-jiangjianarch/i386/boot/bzImageSystem.map"/boot“[root@localhostlinux-]#vi/boot/grub/menu.lst#hiddenmenu[root@localhostlinux-]#reboot在FC7上編譯2.6內(nèi)核的過程說明(1)[root@localhostboot]#cdlinux-[root@localhost
linux-]#makemrproper
用來保證新內(nèi)核樹無殘留.o或是其他附屬文件;第一次編譯可以不用。[root@localhost/]cp–rbootboot1//備份boot目錄。[root@localhost/]#cdboot1[root@localhostboot1]#lsconfig-2.6.11-1.1369_FC4編譯配置文件
lost+foundgrubSystem.map-2.6.11-1.1369_FC4內(nèi)核符號表initrd-2.6.11-1.1369_FC4.imgvmlinuz-2.6.11-1.1369_FC4內(nèi)核映像文件在FC7上編譯2.6內(nèi)核的過程說明(2)[root@localhostboot]#cd/boot[rootboot]#cpconfig-2.6.11-1.1369_FC4/usr/src/linux-/.config[root
linux-]#makeoldconfig
接著修改新源代碼目錄/usr/src/linux-/下的Makefile文件。將EXTRAVERSION=.1改為EXTRAVERSION=.1-jiangjian在新內(nèi)核源碼目錄/usr/src/linux-/下:#makeall//最關(guān)鍵最長的一步,就是編譯產(chǎn)生內(nèi)核映像和模塊。#makemodules_install
//將模塊安裝到/lib/modules/<內(nèi)核版本號>#makeinstall//將內(nèi)核映像等文件復(fù)制到/boot,并修改引導(dǎo)程序grub的配置。在FC7上編譯2.6內(nèi)核的過程說明(3)[root@localhostboot]#lsconfig-2.6.11-1.1369_FC4System.map-2.6.11-1.1369_FC4grubSystem.map--jiangjianinitrd-2.6.11-1.1369_FC4.imgvmlinuzinitrd--jiangjian.imgvmlinuz-2.6.11-1.1369_FC4lost+foundvmlinuz--jiangjianSystem.map[root@localhostboot]#llvmlinuzlrwxrwxrwx1rootroot2611月2417:05vmlinuz->vmlinuz--jiangjian[root@localhostboot]#ll
System.maplrwxrwxrwx1rootroot2911月2417:05System.map->System.map--jiangjian在FC7上編譯2.6內(nèi)核的過程說明(4)[root@localhostboot]#vi/boot/grub/menu.lst
(RH9是grub.conf)修改grub配置文件在hiddenmenu上加注釋符#,注釋掉該句(RH9不需要)#reboot
//重啟,從新內(nèi)核啟動[root@localhost~]#uname-r-jiangjian啟動后,查看內(nèi)核版本:修改后的/boot/grub/menu.lst
#grub.confgeneratedbyanaconda##Notethatyoudonothavetorerungrubaftermakingchangestothisfile#NOTICE:Youhavea/bootpartition.Thismeansthat#allkernelandinitrdpathsarerelativeto/boot/,eg.#root(hd0,0)#kernel/vmlinuz-versionroroot=/dev/VolGroup00/LogVol00#initrd/initrd-version.img#boot=/dev/sdadefault=1timeout=10splashimage=(hd0,0)/grub/splash.xpm.gz#hiddenmenutitleFedoraCore(-jiangjian) root(hd0,0) kernel/vmlinuz--jiangjianroroot=/dev/VolGroup00/LogVol00rhgbquiet initrd/initrd--jiangjian.imgtitleFedoraCore(2.6.11-1.3194.fc7) root(hd0,0) kernel/vmlinuz-2.6.11-1.1369_FC4roroot=/dev/VolGroup00/LogVol00rhgbquiet initrd/initrd-2.6.11-1.1369_FC4.img在FC7上編譯2.6內(nèi)核的過程說明(5)在新內(nèi)核測試新添加的系統(tǒng)調(diào)用sys_testprint()[root@localhost~]#uname-r-jiangjian[root@localhost~]#cattestprint.c#include<unistd.h>#include<sys/syscall.h>#include<stdio.h>intmain(){
intret;ret=syscall(320,"jiangjian");
printf("returnvalueis%d\n",ret);return0;}在新內(nèi)核測試新添加的系統(tǒng)調(diào)用sys_testprint()[root@localhost~]#gcc
testprint.c-otestprint[root@localhost~]#./testprintreturnvalueis0[root@localhost~]#dmesgmynameisjiangjian模塊編程模塊是linux操作系統(tǒng)的特有機制??梢栽诓恍枰獙?nèi)核進行重新編譯和引導(dǎo)的情況下,動態(tài)地加載和卸載模塊,也就是所謂LKM(可加載模塊,LoadableKernelModules)。將該模塊作為linux內(nèi)核空間的擴展來執(zhí)行。通過insmod命令手工加載,通過rmmod來手工卸載。內(nèi)核也可以通過守護進程kerneld動態(tài)加載和卸載模塊。嵌入式系統(tǒng)等采用微內(nèi)核。UNIX系統(tǒng)采用宏內(nèi)核。linux采用折衷方案,內(nèi)核實現(xiàn)最基本功能,其他部分采用模塊方式,根據(jù)需要加載模塊。模塊工作在內(nèi)核空間。微內(nèi)核和宏內(nèi)核模塊工作在內(nèi)核空間。模塊是一個目標文件(*.o,在2.6內(nèi)核中是.ko),不能單獨運行。不是一個獨立的進程。模塊由一組函數(shù)和數(shù)據(jù)結(jié)構(gòu)組成,作為獨立程序編譯??梢圆捎脛討B(tài)加載或是靜態(tài)加載。不能使用c庫函數(shù),只能使用內(nèi)核函數(shù),比如不能用printf,只能用printk()。內(nèi)核??臻g有限,一般4KB到8KB,所以不要定義過多自動變量,如需要大的結(jié)構(gòu),建議使用動態(tài)分配的空間。不能進行浮點運算。模塊的特性內(nèi)核符號表管理。內(nèi)核將資源登記在符號表(symboltable)中,模塊加載時,模塊就可以通過內(nèi)核符號表使用內(nèi)核的資源,解決資源引用問題。Linux支持模塊堆棧(modulestacking)的概念,一個模塊可以請求其他模塊為之服務(wù)。同時,當通過init_module()調(diào)用加載新模塊時,該模塊定義的符號(包括函數(shù)和全局變量等),此時也被導(dǎo)出,供其他以后可能加載的模塊使用。Linux內(nèi)核對加載的內(nèi)核模塊進行管理內(nèi)核符號表管理。通過/proc/ksyms文件(在2.6內(nèi)核中是/proc/kallsyms),可以查看內(nèi)核符號表中各類符號及其地址。如:Linux內(nèi)核對加載的內(nèi)核模塊進行管理[root@localhostsimple]#cat/proc/ksyms|grepprintkc011c2a0printk_R1b7d4074c03d7b88tux_Dprintk_Ra12c9a12c03d7b84tux_TDprintk_Rc0ce7778維持內(nèi)核模塊的引用計數(shù)。引用數(shù)為0才允許卸載該模塊。Linux內(nèi)核對加載的內(nèi)核模塊進行管理[root@localhostsimple]#lsmod|tail-4jbd518922[ext3]BusLogic1007963sd_mod134528scsi_mod1071283[usb-storageBusLogicsd_mod]模塊名稱模塊大小引用計數(shù)。lsmod(listmodules)用來查看當前內(nèi)核加載的模塊最小的模塊結(jié)構(gòu)也必須包括兩個函數(shù):init_modules():加載模塊時被調(diào)用,可以啟動模塊加載期間的操作;cleanup_modules():卸載模塊時被調(diào)用,停止相關(guān)操作。模塊通過加入新函數(shù)來實現(xiàn)期望的功能,每個新函數(shù)必須在該模塊加載到內(nèi)核中時進行注冊,在模塊卸載時注銷;注冊在init_modules()中完成;注銷在cleanup_modules()中完成。模塊的組織結(jié)構(gòu)(2.4內(nèi)核)#include<linux/module.h>//聲明是一個模塊#include<linux/kernel.h>//說明是個內(nèi)核功能int
init_module()//用到了module.h{...//加載時,初始化模塊的編碼} //read()、ioctl()等函數(shù)...voidcleanup_module()//用到了module.h{...//卸載時,注銷模塊的編碼}初步印象:沒有main函數(shù)#gcc?O2?Wall?DMODULE?D_KERNEL_?c
filename.c
filename.c為自己編寫的模塊程序源代碼文件-Wall顯示所有的警告消息,發(fā)生警報時取消編譯,即將警報看作出錯;
?Dmacro:其功能類似于在源碼中的#define;-O2:對編譯進行優(yōu)化,比-O更好的優(yōu)化,編譯速度較之更慢一些,但產(chǎn)生可執(zhí)行文件的執(zhí)行速度更快;-g:產(chǎn)生調(diào)試信息,gcc允許-g和-O2同時使用。KERNEL前后各有兩個短橫杠。模塊的編譯許多情況下,頭文件和源文件會單獨存放在不同的目錄中。例如,假設(shè)存放源文件的子目錄名為./src,而包含文件則放在層次的其他目錄下,如./inc。當我們在./src
目錄下進行編譯工作時,如何告訴GCC到哪里找頭文件呢?方法如下所示:
$gcc
test.c–I../inc-otest
上面的命令告訴GCC包含文件存放在./inc目錄下,在當前目錄的上一級。如果在編譯時需要的包含文件存放在多個目錄下,可以使用多個-I來指定各個目錄:
$gcc
test.c–I../inc–I../../inc2-otest
這里指出了另一個包含子目錄inc2,較之前目錄它還要在再上兩級才能找到。lsmod:查看加載的模塊,實際使用的是/proc/modules文件。insmod:加載模塊。rmmod;卸載模塊。dmesg:查看日志信息。實際上是用/var/log/messages文件。以上命令只能由超級用戶執(zhí)行。產(chǎn)生模塊文件以后的操作模塊的加載方式:用insmod手工加載模塊;請求kerneld加載。insmod在/lib/modules/kernel-version中找到請求加載的模塊,然后執(zhí)行:
create_module(),init_module()執(zhí)行完insmod后,用dmesg查看日志,然后可以在/proc/modules文件中看到加載的模塊?;蚴鞘褂胠smod查看。模塊的加載
模塊的卸載:用rmmod卸載模塊;cleanup_module()斷開內(nèi)核模塊鏈表中的鏈接。模塊的卸載該模塊只要兩個函數(shù):init_module()cleanup_module()編寫一個簡單的內(nèi)核模塊#defineMODULE//MODULE需要寫在module.h之前#include<linux/kernel.h>//表示內(nèi)核模塊,printk需要#include<linux/module.h>//一個模塊,init_module等需要//處理CONFIG_MODVERSIONS
#ifCONFIG_MODVERSIONS==1#defineMODVERSIONS#include<linux/modversions.h>#endif
int
init_module()//初始化模塊
{
printk("Hello!Thisisatestingmodule!\n");return0;}voidcleanup_module()//取消init_module()函數(shù)所做的操作
{
printk("Sorry!Thetestingmoduleisunloadingnow!\n");}
[root@linux/]#gcc–O2–Wall–DMODULE–D__KERNEL__?c-I/usr/src/linux/include/simple_module.c[root@linux/]#ls
//在當前目錄下查看生成的目標文件testmodule.o
[root@linux/]#insmod–f
testmodule.o
//-f表示強行加載,為什么?
Hello!Thisisatestingmodule!
[root@linux/]#rmmodtestmodule
Sorry!Thetestingmoduleisunloadingnow!模塊的加載和卸載報“gcc和linux內(nèi)核版本沖突”,解決方法:1.使用insmod–f強行加載2.修改/usr/include/linux/version.h:將2.4.20改為2.4.20-8報“MODULE重復(fù)定義”,為什么?解決方法:1.去掉源程序中的”defineMODULE”2.去掉編譯選項的“-DMODULE”printk()在純字符界面(純console)上有輸出,但是在圖形界面的模擬終端無輸出。此程序注意三個問題上面的程序執(zhí)行結(jié)果(1)[root@localhostsimple]#lsmakefile
simple_module.c
simple_module.o[root@localhostsimple]#lsmod|grep
simple_module[root@localhostsimple]#cat/proc/modules|grep
simple_module[root@localhostsimple]#insmodsimple_moduleinsmod:simple_module:nomodulebythatnamefound[root@localhostsimple]#insmodsimple_module.oWarning:loadingsimple_module.owilltaintthekernel:nolicenseSeehttp:///lkml/#export-taintedforinformationabouttaintedmodulesModulesimple_moduleloaded,withwarningsinsmod要加*.o上面的程序執(zhí)行結(jié)果(2)[root@localhostsimple]#lsmod|grep
simple_modulesimple_module8920(unused)[root@localhostsimple]#cat/proc/modules|grep
simple_modulesimple_module8920(unused)[root@localhostsimple]#dmesg|tail-1Hello!Thisisatestingmodule!上面的程序執(zhí)行結(jié)果(3)[root@localhostsimple]#rmmodsimple_module.ormmod:modulesimple_module.oisnotloaded[root@localhostsimple]#rmmodsimple_module[root@localhostsimple]#lsmod|grep
simple_module[root@localhostsimple]#dmesg|tail-2Hello!Thisisatestingmodule!Sorry!Thetestingmoduleisunloadingnow![root@localhostsimple]#grepSorry/var/log/messagesNov2501:45:32localhostkernel:Sorry!Thetestingmoduleisunloadingnow!rmmod不要加*.o另外注意lsmod和/proc/modules的關(guān)系:實際上lsmod就是查看/proc/modules[root@localhostsimple]#cat/proc/modulessimple_module8920(unused)vmblock119524vmxnet127160(unused)vmmemctl80040(unused)vmhgfs474241nls_iso8859-135161(autoclean)nls_cp43751161(autoclean)vfat130041(autoclean)fat388080(autoclean)[vfat]注意:寄存器cr3用于存放當前進程的“頁表目錄結(jié)構(gòu)”,訪問該寄存器須在內(nèi)核空間進行。再看一個復(fù)雜的例子,看出模塊在內(nèi)核空間工作的特點。#include<stdio.h>voidGetCr3(){
int
iValue;__asm____volatile__("movl%%cr3,%0":"=r"(iValue));
printf("thevalueofcr3is:%d",iValue);}intmain(){GetCr3();return0;}用戶模式下,程序出錯!#defineMODULE#include<linux/module.h>int
init_module(){
int
iValue;__asm____volatile__("movl%%cr3,%0":"=r"(iValue));printk("Cr3:%d\n",iValue);return0;}voidcleanup_module(){
printk("UninstallGetCr3.\n");}采用模塊實現(xiàn)上一實驗沒有實現(xiàn)的功能__asm____volatile__("movl%%cr3,%0":"=r"(iValue));printk("Cr3:%d\n",iValue);CR3:內(nèi)存頁面目錄信息;movx
source,destination:GNU匯編器使用AT&T語法,其中源和目的操作數(shù)的順序和Intel順序是相反的;x如果是l/w/b,分別代表32位長字/16位字值/8位字節(jié)值;內(nèi)聯(lián)匯編(inlineassembly):將匯編語言函數(shù)直接放在c和c++語言程序中;本來用asm(“assemblycode”),但是ANSIC中asm另有他用,所以按ANSIC約定編碼,必須使用__asm__替換關(guān)鍵字asm;__volatile__表示不希望編譯器優(yōu)化內(nèi)聯(lián)匯編代碼。__asm____volatile__("movl%%cr3,%0":"=r"(iValue));基本asm格式有缺陷:所有輸入值和輸出值必須使用c程序的全局變量,不能在asm段中使用局部變量;另外內(nèi)聯(lián)代碼中不能改變?nèi)魏渭拇嫫鞯闹担ㄈ绻a中有改變,代碼前后要有保存和恢復(fù)寄存器的操作)采用擴展asm格式,此時必須采用新格式:asm(“assembly
code”:output
location:input
operands:changedregisters)輸出位置:包含內(nèi)聯(lián)匯編代碼的輸出值的寄存器和內(nèi)存地址的列表。輸出和輸入值列表的格式:”constraint”(variable)variable是程序中聲明的變量名;”=“表示只能寫入操作數(shù),variable是個輸出值;”r”表示通過任何可用的通用寄存器;%0表示第一個輸出值內(nèi)存地址或是對應(yīng)寄存器。%1表示下一個輸出值,依次類推。__asm____volatile__("movl%%cr3,%0":"=r"(iValue));Linux下的AT&T語法(即GNUas匯編語法)起源于AT&T貝爾實驗室,是在當時用于實現(xiàn)Unix系統(tǒng)的處理器操作碼語法之上而形成的,AT&T語法和Intel語法主要區(qū)別如下:AT&T使用$表示立即數(shù),Intel不用,因此表示十進制2時。AT&T為$2,而Intel就是2。AT&T在寄存器前加%,比如eax寄存器表示為%eaxAT&T處理操作數(shù)的順序和Intel相反,比如,movl%eax,%ebx是將eax中的值傳遞給ebx,而Intel是這樣的mov
ebx,eaxAT&T在助記符的后面加上一個單獨字符表示操作中數(shù)據(jù)的長度,比如movl$foo,%eax等同于Intel的mov
eax,wordptr
fooDFLAGS=-D_KERNEL_-DMODULE-I/usr/src/linux/includeGetCr3.o:GetCr3.c
gcc-c$(DFLAGS)GetCr3.cclean:
rm-f*.oMakefile文件注意:編譯后,加載模塊insmodGetCr3.c時,報“Warning:loadingGetCr3.owilltaintthekernel:nolicense”,在GetCr3.c程序中加”MODULE_LICENSE(“GPL”)”,詳見教材P302。模塊程序和普通程序比較普通程序模塊程序入口和出口main()init_module()cleanup_module()編譯鏈接gccgcc–c–D__KERNEL__-DMDULE運行直接運行insmod調(diào)試gdbkdb
kgdb
2.6內(nèi)核模塊編程#include<linux/init.h>#include<linux/module.h>MODULE_LICENSE("GPL");staticint
hello_init(void){
printk(KERN_ALERT"hello,world!\n");return0;}staticvoidhello_exit(void){
printk(KERN_ALERT"goodbye!\n");return;}
module_init(hello_init);module_exit(hello_exit);#include<linux/init.h>#include<linux/module.h>MODULE_LICENSE("GPL");staticint
hello_init(void){
printk(KERN_ALERT"hello,world!\n");return0;}staticvoidhello_exit(void){
printk(KERN_ALERT"goodbye!\n");return;}
module_init(hello_init);module_exit(hello_exit);KERN_ALERT用于需要立即采取動作的情況。之所以把優(yōu)先級定得較高,是怕無法輸出到控制臺。和后面的字符串之間不能有逗號。最好以“\n”結(jié)尾printk()和printf()最大的不同點在于不支持浮點數(shù)。2.4內(nèi)核模塊的編譯只需要內(nèi)核源碼頭文件,產(chǎn)生的模塊文件為*.o;2.6內(nèi)核模塊的編譯需要配置過的內(nèi)核源碼,產(chǎn)生的模塊文件為*.ko;2.4內(nèi)核中默認非靜態(tài)全局變量和函數(shù)在模塊加載之后會輸出到內(nèi)核符號表中去。2.6內(nèi)核中不會,如果輸出符號,要用:EXPORT_SYMBOL(name)EXPORT_SYMBOL_GPL(name)2.6內(nèi)核模塊編程和2.4內(nèi)核的不同之處2.6內(nèi)核模塊編程-Makefile文件ifneq($(KERNELRELEASE),)obj-m:=hello.oelseKERNELDIR?=/lib/modules/$(shelluname-r)/buildPWD:=$(shellpwd)default: $(MAKE)-C$(KERNELDIR)M=$(PWD)modulesclean: $
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
- 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 邁出成功第一步的計算機基礎(chǔ)考試試題及答案
- 汽車美容師全球市場動態(tài)試題及答案
- 2024小學(xué)語文試題及答案大集合
- 第2講 磁場對運動電荷的作用-2026版大一輪高考物理復(fù)習
- 語文書寫技巧掌握六年級題試題及答案
- 歸納2024古代文學(xué)史的試題及答案
- 皮膚測試的科學(xué)依據(jù)試題及答案
- 提升汽車美容師能力的考試重點與試題答案
- 2024汽車美容師應(yīng)急處理能力試題及答案
- 計算機基礎(chǔ)考試試題及答案分析
- 網(wǎng)絡(luò)與信息安全管理組織機構(gòu)設(shè)置及工作職責
- 自身免疫相關(guān)性腦病
- TCI 324-2024 冠心病患者防治精準護理技術(shù)規(guī)范
- 危重癥患者留置管路管理
- 重慶市高2025屆高三第二次質(zhì)量檢測 化學(xué)試卷(含答案)
- 20S515 鋼筋混凝土及磚砌排水檢查井
- DB37T 1389-2024鋼箱梁頂推施工技術(shù)規(guī)范
- AQ 1020-2006 煤礦井下粉塵綜合防治技術(shù)規(guī)范(正式版)
- 《創(chuàng)傷失血性休克中國急診專家共識(2023)》解讀
- 心電監(jiān)護儀的使用幻燈片
- 尿源性膿毒血癥診療指南
評論
0/150
提交評論