module代码示例

2021-01-24, updated 2021-09-12

Makefile编写

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
obj-m+=timer_test.o
#SRC="/lib/modules/$(shell uname -r)/build/"

CROSS_COMPILE="/home/bmduser10/develop/realtek/R810/rtl819x/toolchain/msdk-4.4.7-mips-EL-3.10-u0.9.33-m32t-140827/bin/mips-linux"
SRC="/home/bmduser10/develop/realtek/R810/rtl819x/linux-3.10"

all:
    make -C $(SRC) M=$(PWD) modules
clean:
    make -C $(SRC) M=$(PWD) clean

示例

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>

static int __init hello_init (void)
{
    printk("hello,world\n");
    return 0;
}

static void __exit hello_exit (void)

{
    printk("Hello module exit\n");
}

module_init(hello_init);
module_exit(hello_exit);
MODULE_AUTHOR("CXF");
MODULE_LICENSE("Dual BSD/GPL");

模块选项

内核模块是采用如module_param宏的方式定义其参数

原型

1
2
define module_param(name, type, perm)              \
   module_param_named(name, name, type, perm)

详细内容查看内核文件include/linux/moduleparam.h

参数说明

每个模块都在/sys/modules中被分派一个目录。子目录/sys/modules/module/parameters中的每个文件就是该模块所输出的每个参数

示例代码

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
#include <linux/init.h>
#include <linux/module.h>
MODULE_LICENSE("GPL");
int test_param = 0;

static int hello_init(void)
{
    printk("test_param:%d\n", test_param);
    printk("<0> hello world\n");
    return 0;
}
static void hello_exit(void)
{
    printk("<0> goodbye\n");
}

module_param(test_param, int, 0644);
module_init(hello_init); //该宏在模块的目标代码中增加一个特殊的段,用于说明内核初始化函数所在的位置
module_exit(hello_exit); //跟上面的宏对立

加载模块

1
insmod hello_modele test_param=1

查看参数文件权限

1
2
ls /sys/module/hello_module/parameters/test_param -l
-rw-r--r-- 1 root root 4096 Dec 28 10:24 /sys/module/hello_module/parameters/test_param

dmesg查看log

1
2
3
4
5
[523196.784789] test_param:1
[523196.784801] <0> hello world

# 卸载模块时的log
[523210.001052] <0> goodbye
words: 459 tags: