驅動學習學習筆記(二)--------字元裝置驅動基礎
驅動學習----字元裝置驅動基礎
驅動開發步驟
(1)驅動原始碼編寫、Makefile編寫、編譯
(2)insmod裝載模組、測試、rmmod解除安裝模組
編譯完成後得到了
1、核心原始碼樹。2、編譯ok的zImage
簡單的模組原始碼分析
常用命令
(1) lsmod:list module
(2) insmod:install module
(3) modinfo,加xxx.ko,其中有個depends,如usb的wifi,wifi依賴usb
(5) 剩下的後面再說,modprobe,depmod
insmod命令,執行到module_init巨集對應的函式
rmmod,對應module_exit
寫程式注意規範性,加static,避免和核心裡原有函式重複
模組中常用巨集
(1)MODULE_LICENSE,模組許可證。一般宣告GPL,最好不要少,否則可能會出現莫名其妙的錯誤(譬如一些明視訊記憶體在的函式提升找不到)。
(2)MODULE_AUTHOR
(3)MODULE_DESCRIPTION
(4)MODULE_ALIAS別名
函式修飾符
(1)__init,巨集定義,將被修飾的函式放入.init.text段中去(本來預設情況下函式是被放入.text段中)。
(2)__exit
printk
printf是C庫函式,是在應用層程式設計中使用
printk是核心原始碼中的一個普通函式
列印級別的設定
編譯驅動的Makefile
(1)KERN_DIR變數,編譯模組的核心原始碼樹的目錄
(2)obj-m += module_test.o,將module_test.c檔案編譯成一個模組
(3)make -C $(KERN_DIR) M=pwd
modules 實際編譯模組
利用make -C進入到核心原始碼樹目錄下,借用核心原始碼中定義的模組編譯規則去編譯這個模組,編譯完成後把生成的檔案還拷貝到當前目錄下
實踐
2個檔案:module_test.c + Makefile
// module_test.c
var foo = 'bar';
// An highlighted block
#include <linux/module.h> // module_init module_exit
#include <linux/init.h> // __init __exit
// 模組安裝函式
static int __init chrdev_init(void)
{
printk(KERN_INFO "chrdev_init helloworld init\n");
return 0;
}
// 模組解除安裝函式
static void __exit chrdev_exit(void)
{
printk(KERN_INFO "chrdev_exit helloworld exit\n");
}
module_init(chrdev_init);
module_exit(chrdev_exit);
// MODULE_xxx這種巨集作用是用來新增模組描述資訊
MODULE_LICENSE("GPL"); // 描述模組的許可證
MODULE_AUTHOR("aston"); // 描述模組的作者
MODULE_DESCRIPTION("module test"); // 描述模組的介紹資訊
MODULE_ALIAS("alias xxx"); // 描述模組的別名資訊
Makefile
#ubuntu的核心原始碼樹
#KERN_VER = $(shell uname -r)
#KERN_DIR = /lib/modules/$(KERN_VER)/build
obj-m += module_test.o
all:
make -C $(KERN_DIR) M=`pwd` modules
.PHONY: clean
clean:
make -C $(KERN_DIR) M=`pwd` modules clean
編譯完得到module_test.ko是想要的
載入,解除安裝,資訊檢視
modinfo module_test.ko
sudo insmod module_test.ko
lsmod
rmmod module_test
dmesg檢視insmod和rmmod的列印資訊