linux驅動程序分成三類:字符設備,塊設備,網絡設備。
字符設備:能像字節流一樣訪問的設備,通過/dev下的字符設備文件來訪問。
塊設備:按照塊爲單位來訪問數據,比如一塊爲512KB,是通過/dev下的文件系統節點來訪問的。與字符設備的區別是接口不同,除了提供同字符設備一樣的接口外,還提供專門面向塊設備的接口,塊設備必須支持掛裝文件系統,應用程序一般通過文件系統來訪問塊設備上的內容,而不是直接跟塊設備打交道。
網絡設備:不使用/dev下的文件節點來操作,而是通過單獨的網絡接口eth0、eth1等來操作。內核和網絡設備的接口不同於字符和塊設備,有一套專門的函數。
操作模塊的命令:
1 insmod 加載模塊
#sudo insmod ./scull.ko
2 rmmod 卸載模塊
3 lsmod 列出當前內核使用的模塊,或者查看/proc/modules文件
4 depmod 掃描/lib/modules/<kernel version>/目錄下的所有內核模塊,從而給內核模塊生成依賴文件/lib/modules/<kernel version>/modules.dep
5 modprobe 根據depmod生成的modules.dep探測並加載內核模塊,只需要給出模塊名稱自動尋找適合的模塊文件,insmod需要給出模塊的路徑
6 modinfo 查看模塊文件的基本信息
#sudo modinfo scull.ko
內核模塊的編譯方法:
首先要得到內核源代碼,並且成功的編譯過後生成已編譯過的內核源碼樹,即成功執行過make uImage的內核源碼樹。然後編寫驅動代碼後,如果已編譯的內核源碼樹就是此驅動需要運行的內核,則編寫Makefile即可將模塊代碼編譯成模塊:
ifeq($(KERNELRELEASE),)
KERNELDIR ?= /work/sysbuild/linux-2.6.22.6
PWD:=$(shell pwd)
$(MAKE) -C $(KERNELDIR) M=$(PWD) modules
else
obj-m:=hello.o
endif
執行make即可
其中已編譯內核源碼樹目錄爲:/work/sysbuild/linux-2.6.22.6,模塊obj爲hello.o,編譯後生成hello.ko
最簡單的模塊例子:
#include <linux/init.h>
#include <linux/module.h>
MODULE_LICENSE("Dual BSD/GPL");
stataic int hello_init(void)
{
printk("hello world\r\n");
return 0;
}
static void hello_exit(void)
{
printk("goodbye,cruel world\r\n");
}
module_init(hello_init);
module_exit(hello_exit);
可以加載模塊時傳入參數,使用宏module_param(變量名,變量類型,權限)聲明參數,模塊運行期間,參數變量會以文件形式出現在/sys目錄下,例如#ls /sys/module/hello/parameters/ -l
變量類型有:short,ushort,int,uint,long,ulong,charp,bool
使用方法:
static char *chp="test_char_p";
static int num=1;
module_param(num, int, S_IRUGO|S_IWUSR);
module_param(chp, charp, S_IRUGO);
#insmod hello.ko num=3 chp="test"
把模塊集成到內核
1 確保模塊工作正常
2 把模塊文件hello.c複製到內核的指定目錄,例如/drivers/char
3 修改指定目錄的Kconfig和Makefile
Kconfig: config HELLO tristate "New Hello"
Makefile: obj -$(CONFIG_HELLO) += hello.o
4 重新配置內核選中將功能編譯進內核,而不是編譯成模塊
5 重新編譯內核,得到新內核
6 測試新內核,確保內核模塊集成成功
查看系統的設備:
1 查看系統中的字符設備驅動,塊設備驅動及其主設備號
#cat /proc/devices
2 查看系統的啓動信息
#dmesg
3 查看設備的IO內存物理地址
#cat /proc/iomem
4 查看正在使用的中斷號
#cat /proc/interrupts
字符設備驅動體驗:
#insmod ./scull.ko
#cat /proc/devices|grep scull
252 scull
#sudo mknod scull0 c 252 0
#sudo chmod 666 scull0
#cat scull0
#sudo echo test>>scull0
#cat scull0
裝載scull.ko後尋找這個設備的主設備號,創造這個設備的設備文件(c代表字符設備,0代表第一個從設備號),更改文件屬性後操作設備