1. 程式人生 > >linux下gcc程式設計09-編寫核心helloworld模組

linux下gcc程式設計09-編寫核心helloworld模組

一。核心動態模組介紹

    Linux核心給開發者提供了靈活的模組載入方式,開發者可根據需要適當地選擇靜態或動態的方式將模組加入核心當中。靜態載入的時候我們只需將驅動檔案新增到對應的資料夾中並修改相應的Makefile和Kconfig即可,但是通過動態載入模組的方式,如果只是編譯一個小的驅動檔案而對核心大動干戈,那樣編譯的時間不僅長而且修改核心配置檔案也是一件多餘的工作。那麼我們是否可以在不修改核心的前提下單獨編譯它是如何編譯核心的呢?下面我們就通過分析它的Makefile入手簡單介紹一個編譯驅動(模組)檔案的新方法。

動態模組生成檔案字尾名為 *.ko

核心模組的相關操作

  1. 載入核心模組:insmod
  2. 解除安裝核心模組:rmmod
  3. 檢視核心模組:lsmod

二。動態模組helloworld開發

本人習慣於使用開發工具強大的程式碼補全功能 覺得效率會更高 所以我這裡使用clion開發 完成後拷貝到linux編譯

clion開發環境配置
主要使用clion的提示 下載核心的原始碼解壓  找到include目錄 

接下來新建一個 c的庫專案  裡面有 CMakeLists.txt新增引入標頭檔案

新增include_directories後 寫程式碼依然是沒有提示的 需要重新載入一個cmake Header Search PAths就有了新包含的標頭檔案了

接下來新建一個hello.c 寫程式碼就有提示拉 出錯可以不管 反正window編譯不了的
 

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

MODULE_LICENSE("GPL");
static void hello_init(){
    printk(KERN_INFO"***********hello world init");
}
static void hello_exit(){
    printk(KERN_INFO"***********hello world exit");
}
module_init(hello_init);
module_exit(hello_exit);

拷貝到linux某個目錄新建 Makefile(不能使用小寫的makefile)
DIRS變量表示核心原始碼的目錄 一般安裝的centos都沒有 使用 yum -y install kernel-devel安裝 
如果uanme -r和原始碼的版本號不對應 生成的ko是無法動態載入的
make -C 表示進入原始碼目錄編譯 然後呼叫modules目標 傳入一個引數M=當前目錄  跳轉到當前目錄去make
obj-m:=hello.o表示當前生成的目標檔案 會生成一個同名的hello.ko

obj-m := hello.o
DIRS :=/usr/src/kernels/3.10.0-862.14.4.el7.x86_64
all:
	make -C $(DIRS) M=$(PWD) modules
clean:
	rm -Rf *.o *.ko *.mod.c *.order *.symvers

執行make執行 檢視是否生成hello.ko 
載入(如果原始碼和當前系統版本不匹配 是會出現下面錯誤)

[root@localhost kernel]# insmod hello.ko
insmod: ERROR: could not insert module hello.ko: Invalid module format

正確後可以使用 
tail -f /var/log/messages檢視是否正常列印了 載入初始化函式

[root@localhost kernel]# tail -20 /var/log/messages
Oct 18 16:34:09 localhost kernel: Hardware name: VMware, Inc. VMware Virtual Platform/440BX Desktop Reference Platform, BIOS 6.00 05/19/2017
Oct 18 16:34:09 localhost kernel: Call Trace:
Oct 18 16:34:09 localhost kernel: [<ffffffff84d0d768>] dump_stack+0x19/0x1b
Oct 18 16:34:09 localhost kernel: [<ffffffff8470f5db>] load_module+0x275b/0x2bc0
Oct 18 16:34:09 localhost kernel: [<ffffffff849767a0>] ? ddebug_proc_write+0xf0/0xf0
Oct 18 16:34:09 localhost kernel: [<ffffffff8470b1e3>] ? copy_module_from_fd.isra.43+0x53/0x150
Oct 18 16:34:09 localhost kernel: [<ffffffff8470fbf6>] SyS_finit_module+0xa6/0xd0
Oct 18 16:34:09 localhost kernel: [<ffffffff84d1f7d5>] system_call_fastpath+0x1c/0x21
Oct 18 16:34:59 localhost kernel: ***********hello world exit
Oct 18 16:34:59 localhost kernel: ***********hello world init

接下來可以使用 rmmod刪除模組  可以使用lsmod顯示所有載入的模組