01. 第一個Linux驅動

Linux 驅動哪些部分是必須的

  1. 模塊入口函數
    模塊的入口函數也稱模塊加載函數,當你執行 insmod 或 modprobe 命令加
    載驅動模塊到內核時,驅動模塊的入口函數就會自動被內核執行。 至於模塊入口
    函數需要完成什麼工作,這就你決定了。
  2. 模塊出口函數
    模塊的出口函數也稱爲模塊卸載函數,當你執行 rmmod 命令卸載驅動模塊
    時,驅動模塊的出口函數就會自動被內核執行。 至於模塊出口函數需要完成什麼
    工作,這個也是你決定的。
  3. 模塊許可證聲明
    許可證(LICENSE)聲明該模塊的許可權限,如果不聲明,就會收到內核的警
    告。

Hello驅動源碼

#include <linux/module.h>
#include <linux/kernel.h>

/* 驅動程序的入口函數 */
static int __init hello_init(void)
{
	printk(KERN_WARNING "hello_init!\n");
	printk(KERN_WARNING "Hello,world!\n");
	return 0;
}

/* 驅動程序的出口函數 */
static void __exit hello_exit(void)
{
	printk(KERN_WARNING "hello_exit!\n");
	printk(KERN_WARNING "Goodbye,world!\n");
}

/* 用於修飾入口/出口函數,換句話說,相當於
* 告訴內核驅動程序的入口/出口函數在哪裏
*/
module_init(hello_init);
module_exit(hello_exit);

/* 該驅動支持的協議 */
MODULE_LICENSE("GPL");

hello驅動分析

  1. hello_init 函數就是我們上面所說的模塊入口函數,當執行
    insmod 命令時,該函數就會被調用,顯然就會打印二條語句。
  2. hello_exit 函數就是我們上面所說的模塊出口函數,當執行
    rmmod 命令時,該函數就會被調用,顯然也會打印二條語句。
  3. 模塊入口/出口函數
module_init(hello_init);
module_exit(hello_exit);
  1. 每個函數前面都有static關鍵字,在Linux驅動中,大部分函數都會冠以static關鍵字,它表示該函數只能在本文件內使用,其他文件的函數不能調用它。如果非要用它不可的話,需要將函數導出。
EXPORT_SYMBOL(name)
或者
EXPORT_SYMBOL_GPL(name)
  1. __init 和__exit
    __init 表示用__init 修飾過的函數僅僅在初始化期間內有效,在模塊被加載之
    後,即 insmod 之後,模塊裝器就會將初始化函數丟棄,之後任何函數也沒有辦
    法調用初始化函數,因爲該函數已經從內存中釋放出來。 __exit 同理。
  2. printk 打印等級
    printk 函數共有 7 個打印等級, 默認打印等級爲 4, 級別越小,表示情況越
    緊急,越是要將信息輸出到你的串口終端。 大於 4 的等級將不會出現在串口中斷,
    需要你使用其他方法查看, 比如 dmesg 命令查看。

通用的Makefile

ifneq ($(KERNELRELEASE),)
obj-m := hello.o
else
KDIR := /home/work/linux-3.8_webee210
all:
	make -C $(KDIR) M=$(PWD) modules ARCH=arm CROSS_COMPILE=arm-linux-
clean:
	rm -f *.ko *.o *.mod.o *.mod.c *.symvers *.order
endif

Makefile簡要分析

  1. obj-m := hello.o 這句的意思是, hello.ko 模塊需要從目標文件 hello.o 中構造, -m 的意思是編譯成模塊,而不編譯進內核。
  2. KDIR := /home/work/linux-3.8_webee210 它表示驅動模塊的編譯需要到這個路徑去編譯。
  3. ARCH=arm 代表架構爲 arm 而不是 X86, CROSS_COMPILE=arm-linux-代表交叉編譯工具爲 arm-linux-XXX,如: arm-linux-gcc、 arm-linux-ld 等等。
  4. 清除工作,下面兩行表示表示執行 make clean 的時候,刪除所有符合上面格式的文件。

Hello 驅動測試

  1. 以模塊方式加載驅動到內核:insmod hello.ko
  2. 查看當前已經加載的驅動模塊:lsmod
  3. 從內核中卸載模塊:rmmod hello

內核配置驅動

make meuconfig

Ubuntu會出現以下錯誤

 *** Unable to find the ncurses libraries or the
 *** required header files.
 *** 'make menuconfig' requires the ncurses libraries.
 *** 
 *** Install ncurses (ncurses-devel) and try again.
 *** 
 make[1]: *** [scripts/kconfig/dochecklxdialog] Error 1
 make: *** [menuconfig] Error 2

解決方法:

sudo apt-get install ncurses-dev

將驅動配置到內核步驟:

  1. 拷貝 hello.c 到 Linux 源碼的 drivers/char 目錄下。
  2. 修改 drivers/char 目錄下的 Konfig。
    在這裏插入圖片描述
config Hello
        tristate "Frist Driver --Hello"
        depends on ARCH_S5PV210
        help
          This is frist driver for hello.
  1. 修改 drivers/char 目錄下的 Makefile
    在這裏插入圖片描述
  2. 使用 make menuconfig 命令進行配置。
    進入 Device Driver–>Character devices–>後
    在這裏插入圖片描述
    保存配置後,如上圖所示保存爲,即以模塊方式加載進內核,如果保存
    爲<*>,表示編譯進內核。輸入 make modules 命令就可以編譯模塊了。 如果以
    模塊的方式編譯,那麼可以在相應目錄下找到相應的.ko 文件。比如:
    在 drivers/char/目錄下面,可以找到 hello.ko 文件。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章