linux驅動之:模組基本知識
阿新 • • 發佈:2019-02-02
作為驅動的開始,我們來看一看:
1. 底層函式和上層函式的不同:
app(c) | 驅動模組 | |
入口函式 | main | 載入函式 |
庫 | 應用層的庫(usr/lib) | 核心API |
執行空間 | 使用者空間(高3G的記憶體) | 核心空間(低1G) |
釋放資源 | 要求釋放 | 必須釋放 |
2.寫一個模組要有的三要素:
- 模組許可證的宣告 MODULE_LICENSE("GPL");
- 模組載入函式 __init 標識,或者module_init(xx)
- 模組解除安裝函式 __exit 標識,或者module_exit(xxx)
3. 模組編譯和裝載的命令:
在linux端的命令如下:
- insmod,將某個模組插入到載入,如果有 printk 可以用 dmesg 檢視
- rmmod,將某個模組從核心中刪除
- lsmod,顯示所有已經被核心調入的模組
- modinfo,關鍵點是 vermagic:3.2.0-29... 是模組執行的核心版本
- modprobe,智慧載入,如果依賴別的模組,會載入上別的模組
新增一個Makefile檔案,檔案內容如下:
ifeq ($(KERNELRELEASE),) KERNELDIR ?= /lib/modules/$(shell uname -r)/build #KERNELDIR ?= ~/wor_lip/linux-3.4.112 PWD := $(shell pwd) modules: $(MAKE) -C $(KERNELDIR) M=$(PWD) modules modules_install: $(MAKE) -C $(KERNELDIR) M=$(PWD) modules_install clean: rm -rf *.o *~ core .depend .*.cmd *.ko *.mod.c .tmp_versions modules* Module* .PHONY: modules modules_install clean else obj-m := hello.o endif
其中需要改動的是:
KERNELDIR :核心所在路徑,如果想要模組在開發板上執行,需要新增製作開發板上的linux核心原始碼所在路徑,就是上邊註釋掉的部分,如果是要在自己的ubuntu中執行,未註釋掉的部分就是。
obj-m:你要生成的xxx.ko ,就要改成 xxx.o
4. 模組編寫的兩種方式:
預設模式
自定義模式
5. 向模組內傳參:--insmod傳參
5.1 宣告
5.1.1 基本資料型別:
基本資料型別包括 bool/invbool/short/int/long/uint/ushort/ulong
module_param(mystring, bool/invbool/short/int/long/uint/ushort/ulong, 0000); 宣告可以從命令列取得引數,括號中的引數一次表示:變數名,變數型別,許可權
0000 的介紹:
數字的大小表示的是 讀寫許可權 , r w x,分別代表可讀,可寫,可執行,最大數字是 6,模組沒有可執行的許可權
這裡還要說明的一點是,這個讀寫許可權表示的是 /sys/modules/ 中模組的名字資料夾下邊的變數名字的檔案, 這裡的檔案可以用cat 來檢視,echo A > B 來寫(寫的時候要先變身,su ),並且起作用 數字的位置表示的是 按從左到右 依次是 ,超級使用者,使用者組,。。5.1.2 char*,...: --指針
module_param(mystring, charp, 0000);
5.1.3 array[]: --陣列,傳參用逗號隔開
module_param_array(array, int/.., &arr_argc, 0000); int/..,陣列中成員的資料型別 arr_argc,用於存放系統記錄使用者傳入的資料個數 注意: 宣告的資料都要進行初始化。5.2 載入的時候傳參的操作:
對基本資料傳參,在insmod的時候,變數名=資料,多個引數空格隔開
對陣列傳參,在insmod的時候,陣列名=陣列成員1的資料,陣列成員2的引數。用的是逗號隔開
module_param module_param_array(array, int/.., &arr_argc, 0000); int/..,陣列中成員的資料型別 arr_argc,用於存放系統記錄使用者傳入的資料個數 注意: 宣告的資料都要進行初始化。