Linux模組程式設計方法總結
一、編寫一個基本的核心模組
1、編輯原始檔,程式碼hello.c
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
int init_hello_module(void)
{
printk("init_hello_module\n");
return0;
}
void exit_hello_module(void)
{
printk("exit_hello_module\n");
}
MODULE_LICENSE("GPL");
module_init(init_hello_module);
module_exit(exit_hello_module);
Makefile檔案
ifeq ($(KERNELRELEASE),)
$(info 1st)
all:
make-C /lib/modules/$(shell uname -r)/build M=$(shell pwd)
clean:
rm*.o *.ko *.mod.c modules.order
else
$(info 2nd)
obj-m:=hello.o
endif
2.編譯
make
3. 測試sudo insmod hello.ko、sudo rmmod hello、dmesg
3. 原理:
Makefile原理
1、當用戶在shell |
2、解析的第一條語句是 ifeq ($(KERNELRELEASE),) 判斷當前的Makefile中是否有KERNELRELEASE 變數因為當前的Makefile中沒有KERNELRELEASE,所以ifeq 條件成立 |
3、執行第一條規則語句 all: make -C path/to/kernel M=$(shell pwd) 呼叫了make命令,根據 -C 指定的核心頂層原始碼路徑,去解析核心頂層原始碼對應的 Makefile |
4、核心頂層原始碼的makefile中根據 M=$(shell pwd)引數第二次進入當前目錄,解析當前的 Makefile |
5、這時核心Makefile檢查編譯模組所依賴的.o檔案(hello.o)是否存在,如果不存在,根據hello.c生成hello.o |
6、核心Makefile會第三次進入當前目錄,還是走else 分支,這一次因為hello.o已經存在會根據 hello.o生成hello.ko |
二、多個檔案生成一個模組
在同一目錄下增加show.c檔案
#include <linux/kernel.h>
static int a;
int show_addr(void)
{
printk("aaddr = %p\n",&a);
return0;
}
Makefile改為
ifeq ($(KERNELRELEASE),)
$(info 1st)
all:
make-C /lib/modules/$(shell uname -r)/build M=$(shell pwd)
clean:
rm*.o *.ko *.mod.c modules.order
else
$(info 2nd)
obj-m:=helloshow.o
helloshow-y+=hello.o
helloshow-y+=show.o
endif
三、多個模組之間的函式呼叫
Show.c改為如下:
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
static int a;
int show_addr(void)
{
printk("aaddr = %p\n",&a);
return0;
}
int init_show_module(void)
{
printk("init_show_module\n");
show_addr();
return0;
}
void exit_show_module(void)
{
printk("exit_show_module\n");
}
EXPORT_SYMBOL(show_addr);
MODULE_LICENSE("GPL");
module_init(init_show_module);
module_exit(exit_show_module);
Makefile改為如下:
ifeq ($(KERNELRELEASE),)
$(info 1st)
all:
make-C /lib/modules/$(shell uname -r)/build M=$(shell pwd)
clean:
rm*.o *.ko *.mod.c modules.order
else
$(info 2nd)
obj-m:=hello.o show.o
endif
四、模組傳遞引數
1. 在hello.c中增加模組引數定義
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
static int count = 5;
static int a = 100;
static int b = 100;
static char *string = "helloworld";
int init_hello_module(void)
{
printk("init_hello_module\n");
for(;count-->0;)
{
printk("init:stringis %s\n",string);
}
return0;
}
void exit_hello_module(void)
{
printk("exit_hello_module\n");
for(;count-->0;)
{
printk("exit:stringis %s\n",string);
}
}
MODULE_LICENSE("GPL");
module_param(count, int, 0644);
module_param(a, int, 0644);
module_param(b, int, 0644);
module_param(string, charp, 0644);
module_init(init_hello_module);
module_exit(exit_hello_module);
2. 編譯測試模組引數傳遞
方法1,在載入模組的時候修改引數值
方法2,通過sysfs檔案系統的節點修改模組引數值