學(xué)會(huì)Linux Kernel熟練Linux
在當(dāng)今社會(huì)Linux越來(lái)越成為主流,你了解Linux系統(tǒng)么?本文為你介紹Linux Kernel,Linux Kernel有一個(gè)很好的特性,可以支持在運(yùn)行是進(jìn)行擴(kuò)展。這意味著系統(tǒng)啟動(dòng)運(yùn)行是,我們?nèi)匀豢梢韵騆inux kernel添加功能。這種運(yùn)行時(shí)可以被添加到kernel的代碼稱(chēng)為Module(模塊)。
Linux Kernel支持好幾種模塊類(lèi)型,包括設(shè)備驅(qū)動(dòng)程序。每個(gè)模塊由目標(biāo)代碼組成,不是一個(gè)完整的可執(zhí)行程序。系統(tǒng)運(yùn)行時(shí),我們可以通過(guò)insmod將模塊連接到正在運(yùn)行的內(nèi)核中去。也可以使用lsmod列出已加載模塊,rmmod或modprobe –r 移除模塊。
Linux系統(tǒng)將設(shè)備分為三種基本類(lèi)型:字符設(shè)備,塊設(shè)備,網(wǎng)絡(luò)接口。
字符設(shè)備是能夠像字節(jié)流一樣被訪問(wèn)的設(shè)備,一般只能順序訪問(wèn)。其操作類(lèi)似文件操作。
塊設(shè)備上能夠容納文件系統(tǒng),可以通過(guò)文件系統(tǒng)隨機(jī)訪問(wèn)。其操作也類(lèi)似于文件操作。
網(wǎng)絡(luò)接口是負(fù)責(zé)數(shù)據(jù)包的傳輸和接收的,一般無(wú)法影射到文件系統(tǒng)的節(jié)點(diǎn)。它與內(nèi)核的通信跟前面兩種設(shè)備不同,而是通過(guò)socket方式。在系統(tǒng)和驅(qū)動(dòng)程序之間定義有專(zhuān)門(mén)的數(shù)據(jù)結(jié)構(gòu)(sk_buff)進(jìn)行數(shù)據(jù)的傳遞。系統(tǒng)里支持對(duì)發(fā)送數(shù)據(jù)和接收數(shù)據(jù)的緩存,提供流量控制機(jī)制,提供對(duì)多協(xié)議的支持。
在編寫(xiě)模塊的時(shí)候,應(yīng)該注意,模塊僅僅被連接到內(nèi)核,所以它只能調(diào)用由內(nèi)核導(dǎo)出的那些函數(shù),而不能調(diào)用其他的本模塊未定義的函數(shù)。
在Linux kernel2.6.X下進(jìn)行模塊開(kāi)發(fā)時(shí),需要預(yù)先準(zhǔn)備好“kernel tree(內(nèi)核樹(shù))”,即獲得與本系統(tǒng)相同的內(nèi)核的源代碼并編譯出目標(biāo)文件。
一個(gè)最簡(jiǎn)單的hello world驅(qū)動(dòng)例子:
- hello_world.c:
- #include <linux/init.h>
- #include <linux/module.h>
- MODULE_LICENSE("Dual BSD/GPL");
- static int hello_init(void)
- {
- printk(KERN_ALERT "Hello, world\n");
- return 0;
- }
- static void hello_exit(void)
- {
- printk(KERN_ALERT "Goodbye, cruel world\n");
- }
- module_init(hello_init);
- module_exit(hello_exit);
- Makefile:
- obj-m := hello.o
- KERNELDIR ?= /lib/modules/$(shell uname -r)/build
- PWD := $(shell pwd)
- default:
- $(MAKE) -C $(KERNELDIR) M=$(PWD) modules
其中,源文件中的module_init和module_exit指定了模塊被加載時(shí)執(zhí)行的初始化函數(shù)和卸載時(shí)執(zhí)行的清理函數(shù)。另外可以使用module_param指定加載模塊時(shí)可以設(shè)置的參數(shù)。Makefile中的obj-m指定了使用make modules時(shí)候構(gòu)造*.ko目標(biāo)文件時(shí)使用的*.o目標(biāo)文件。
Linux Kernel的了解,讓你學(xué)好Linux。
【編輯推薦】