1. 程式人生 > >linux驅動之:模組基本知識

linux驅動之:模組基本知識

作為驅動的開始,我們來看一看:

1. 底層函式和上層函式的不同:

app(c) 驅動模組
入口函式 main 載入函式
應用層的庫(usr/lib) 核心API
執行空間 使用者空間(高3G的記憶體) 核心空間(低1G)
釋放資源 要求釋放 必須釋放

2.寫一個模組要有的三要素:

  1. 模組許可證的宣告 MODULE_LICENSE("GPL");
  2. 模組載入函式    __init 標識,或者module_init(xx)
  3. 模組解除安裝函式    __exit 標識,或者module_exit(xxx)
--   其他還可以有:模組的作者,描述,模組匯出符號,引數等資訊宣告         MODULE_AUTHOR("DDD");         MODULE_DESCRIPTION("DDD");         MODULE_SUPPORTED_DEVICE("Test...");

3. 模組編譯和裝載的命令:

在linux端的命令如下:

  • insmod,將某個模組插入到載入,如果有 printk 可以用 dmesg 檢視
  • rmmod,將某個模組從核心中刪除
  • lsmod,顯示所有已經被核心調入的模組
  • modinfo,關鍵點是 vermagic:3.2.0-29... 是模組執行的核心版本
  • modprobe,智慧載入,如果依賴別的模組,會載入上別的模組
寫了一個 .c檔案,如何生成一個模組的方法:

新增一個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,用於存放系統記錄使用者傳入的資料個數 注意:     宣告的資料都要進行初始化。