模塊20135304——劉世鵬

編譯生成新內核

1、實踐原理

Linux模塊是一些能夠做爲獨立程序來編譯的函數和數據類型的集合。之因此提供模塊機制,是由於Linux自己是一個單內核。單內核因爲全部內容都集成在一塊兒,效率很高,但可擴展性和可維護性相對較差,模塊機制可彌補這一缺陷。linux

Linux模塊能夠經過靜態或動態的方法加載到內核空間,靜態加載是指在內核啓動過程當中加載;動態加載是指在內核運行的過程當中隨時加載。shell

一個模塊被加載到內核中時,就成爲內核代碼的一部分。模塊加載入系統時,系統修改內核中的符號表,將新加載的模塊提供的資源和符號添加到內核符號表中,以便模塊間的通訊。函數

2、實踐過程

(一)簡單模塊——姓名post

1.編寫模塊代碼測試

2.編譯模塊this

接下來寫Makefile。spa

三、加載測試卸載模塊指針

 

 sudo insmod lsp.kocode

dmesgblog

 

 

 

 

(二)進程

1.編寫模塊代碼

模塊構造函數:執行insmod或modprobe指令加載內核模塊時會調用的初始化函數。函數原型必須是module_init(),括號內是函數指針

模塊析構函數:執行rmmod指令卸載模塊時調用的函數。函數原型是module_exit()

模塊許可聲明:函數原型是MODULE_LICENSE(),告訴內核該程序使用的許可證,否則在加載時它會提示該模塊污染內核。通常會寫GPL。

 

頭文件module.h,必須包含此文件;

頭文件kernel.h,包含經常使用的內核函數;

頭文件init.h包含宏_init和_exit,容許釋放內核佔用的內存。

 

寫一個簡單的代碼,用來向內核輸出進程信息。

複製代碼
#include<linux/kernel.h>
#include<linux/module.h>
#include<linux/init.h>
#include<linux/sched.h>

static struct task_struct *pcurrent;

static int __init print_init(void)
{
    printk(KERN_INFO "print current task info\n");
    printk("pid\ttgid\tprio\tstate\n");
    for_each_process(pcurrent){
        printk("%d\t",pcurrent->pid);
        printk("%d\t",pcurrent->tgid);
        printk("%d\t",pcurrent->prio);
        printk("%ld\n",pcurrent->state);
    }
    return 0;
}
static void __exit print_exit(void)
{
    printk(KERN_INFO "Finished\n");
}

module_init(print_init);
module_exit(print_exit);
複製代碼

2.編譯模塊

接下來寫Makefile。

(其中,all到make的過程當中要使用「回車+Tab」鍵)

複製代碼
obj-m:=proclist.o
CURRENT_PATH:=$(shell pwd)
LINUX_KERNEL_PATH:= /usr/src/linux-headers-3.13.0-32-generic
all:
    make -C $(LINUX_KERNEL_PATH) M=$(CURRENT_PATH) modules
clean:
    make -C $(LINUX_KERNEL_PATH) M=$(CURRENT_PATH) clean
複製代碼

第一行:本身寫的.c的文件名+」.o」。

第三行的LINUX_KERNEL_PATH後面要寫你本身的內核版本對應的內核源碼包地址.

解釋一下make命令:

make -C $(LINUX_KERNEL_PATH) 指明跳轉到內核源碼目錄下讀取那裏的Makefile

M=$(CURRENT_PATH) 代表返回到當前目錄繼續執行當前的Makefile。

make以後的執行時這樣的:

生成了好多文件:

三、加載模塊

sudo insmod proclist.ko

輸入密碼後便可。此時已經加載了模塊。

四、測試模塊

Dmesg:看內核信息

 

3、遇到的問題

1. linux的內核版本

uname –r

 

位數

2.內核位置

 

相關文章
相關標籤/搜索