1. 程式人生 > >在Ubuntu 18.04環境下編寫一個簡單的核心模組

在Ubuntu 18.04環境下編寫一個簡單的核心模組

我們首先來看看核心模組的定義

模組是具有獨立功能的程式,可以單獨編譯,但是不能單獨執行。模組在執行時,會被連結到核心,作為核心的一部分在核心空間執行。模組通常由一組函式和資料結構組成,用來實現一種檔案系統、驅動程式或其他核心上層的功能。

實驗環境: Ubuntu 18.04 + 4.15.0 實驗環境

編寫模組

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

static int __init lkp_init(void)
{
	printk("<1>Hello, World! from the kernel space...\n"
); return 0; } static void __exit lkp_cleanup(void) { printk("<1>Good Bye, World! leaving kernel space...\n"); } module_init(lkp_init); // 註冊模組 module_exit(lkp_cleanup); // 登出模組 MODULE_LICENSE("GPL"); //告訴核心該模組具有GNU公共許可證
  • module.h標頭檔案中包含了對模組的結構定義以及模組的版本控制
  • kernel.h包含了常用的核心函式
  • init.h包含巨集__init和__exit,__init告訴編譯器,這個函式或者變數僅用於初始化,編譯程式將所有的__init程式碼儲存到特殊的記憶體段中,初始化結束後,記憶體被釋放
  • module_init()/exit(),向核心註冊/登出模組提供新功能

編寫Makefile檔案

什麼是Makefile檔案?

Makefile檔案就是用一組約定好的語法規則,告訴make命令,怎麼樣連結和編譯程式,帶來的好處就是自動化編譯。

在當前目錄下,建立Makefile檔案,比如可以用命令

touch Makefile

在檔案中輸入以下程式碼

# Makefile 4.0
obj-m := testKernel.o
CURRENT_PATH := $(shell pwd)
LINUX_KERNEL := $(shell uname -r)
LINUX_KERNEL_PATH := /usr/src/linux-headers-$(LINUX_KERNEL)

all:
	make -C $(LINUX_KERNEL_PATH) M=$(CURRENT_PATH) modules
clean:
	make -C $(LINUX_KERNEL_PATH) M=$(CURRENT_PATH) clean
  • obj-m := 這是一個賦值語句,說明要使用目標檔案testKernel.o建立一個模組
  • 後面幾條語句都是常見的shell命令

編譯檔案

直接在當前目錄下,在控制檯中輸入make。對於ubuntu自帶的原始的核心檔案,遇到如下錯誤 編譯錯誤 按照提示,缺少庫檔案,我們只需要安裝一個即可。

sudo apt-get install libelf-dev

安裝完成之後,再次編譯 成功 至此,編譯完成,會在當前目錄生成以下檔案 在這裡插入圖片描述

插入模組,並且執行

使用insmod插入核心模組

insmod testKernel.ko

檢測是否正確插入

lsmod | grep testKernel

模組使用的函式printk()會預設列印系統檔案/var/log/syslog(之前ubuntu的版本本日誌存放在/var/log/messages),輸入以下命令,檢視messages是否輸出了我們想要的資訊。 結果

解除安裝模組

使用rmmod命令解除安裝模組

rmmod testKernel

從如下訊息中,可以看出解除安裝成功 結束 以上就是一個簡單的核心模組從編譯到解除安裝的過程