模块时为了完成某种特定的任务而设计的,其功能比较单一,为了丰富系统的功能,所以模块之间唱歌需要通信,它们之间可以共享数据,变量,也可以调用对方提供的功能参数。
模块2的加载过程如下:
1. 使用insmod 加载模块2
2. 内核为模块2分配空间,然后将模块的代码和数据装入分配的内存中
3. 内核发现符号表中有函数1,函数2可以导出,于是将其内存地址记录在内核符号表中
模块1 在加载进内核时,系统会执行如下操作
1. insmod命令会为模块分配空间,然后将模块的代码和数据装入内存中
2. 内核在模块1的符号表(symtab)中发现一些未解析的函数。这些函数未解析的函数位于模块2的代码中,所以模块1会通过内核符号表,查到相应的函数,并将函数地址填入到模块1 的符号表中。
示例如下:
模块1 函数
add_sub.h
#ifndef _ADD_SUB_H_
#define _ADD_SUB_H_
long add_integer(long a, long b);
long sub_integer(long a, long b);
#endif
add_sub.c
#include<linux/kernel.h>
#include<linux/init.h>
#include<linux/module.h>
#include "add_sub.h"
long add_integer(long a, long b)
{
printk(KERN_ALERT "A+B Success\n");
return a+b;
}
long sub_integer(long a, long b)
{
printk(KERN_ALERT "A-B Success\n");
return a-b;
}
EXPORT_SYMBOL(add_integer);
EXPORT_SYMBOL(sub_integer);
MODULE_LICENSE("Dual BSD/GPL");
Makefile
obj-m := add_sub.o
all:
$(MAKE) -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules
clean:
$(MAKE) -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean
love@ubuntu:~/workspace/LinuxDriver/ModuleCommuication/ADDFile$ make
make -C /lib/modules/4.18.0-25-generic/build M=/home/love/workspace/LinuxDriver/ModuleCommuication/ADDFile modules
make[1]: Entering directory '/usr/src/linux-headers-4.18.0-25-generic'
CC [M] /home/love/workspace/LinuxDriver/ModuleCommuication/ADDFile/add_sub.o
Building modules, stage 2.
MODPOST 1 modules
CC /home/love/workspace/LinuxDriver/ModuleCommuication/ADDFile/add_sub.mod.o
LD [M] /home/love/workspace/LinuxDriver/ModuleCommuication/ADDFile/add_sub.ko
make[1]: Leaving directory '/usr/src/linux-headers-4.18.0-25-generic'
模块2
#include <linux/init.h>
#include <linux/module.h>
#include "../ADDFile/add_sub.h"
static long a =1 ;
static long b =1;
static int AddOrSub = 1;
static int test_init(void)
{
long restult = 0;
printk(KERN_ALERT "Test_init\n");
if(1 == AddOrSub)
{
restult = add_integer(a,b);
}
else
{
restult = sub_integer(a,b);
}
printk(KERN_ALERT "The %s restult is %ld", AddOrSub ==1?"Add":"Sub", restult);
return 0;
}
static void test_exit(void)
{
printk(KERN_ALERT "Test exit\n");
}
module_init(test_init);
module_exit(test_exit);
module_param(a, long , S_IRUGO);
module_param(b, long , S_IRUGO);
module_param(AddOrSub, int ,S_IRUGO);
MODULE_LICENSE("Dual BSD/GPL");
MODULE_AUTHOR("Love Linux");
MODULE_DESCRIPTION("A moudle for testing module params and export_symbol");
MODULE_VERSION("V1.0");
Makefile
obj-m := test.o
all:
$(MAKE) -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules
clean:
$(MAKE) -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean
love@ubuntu:~/workspace/LinuxDriver/ModuleCommuication/TestUT$ make
make -C /lib/modules/4.18.0-25-generic/build M=/home/love/workspace/LinuxDriver/ModuleCommuication/TestUT modules
make[1]: Entering directory '/usr/src/linux-headers-4.18.0-25-generic'
CC [M] /home/love/workspace/LinuxDriver/ModuleCommuication/TestUT/test.o
Building modules, stage 2.
MODPOST 1 modules
WARNING: "add_integer" [/home/love/workspace/LinuxDriver/ModuleCommuication/TestUT/test.ko] undefined!
WARNING: "sub_integer" [/home/love/workspace/LinuxDriver/ModuleCommuication/TestUT/test.ko] undefined!
CC /home/love/workspace/LinuxDriver/ModuleCommuication/TestUT/test.mod.o
LD [M] /home/love/workspace/LinuxDriver/ModuleCommuication/TestUT/test.ko
make[1]: Leaving directory '/usr/src/linux-headers-4.18.0-25-generic'
love@ubuntu:~/workspace/LinuxDriver/ModuleCommuication/TestUT$ sudo insmod test.ko a=3,b=2 AddOrSub=2
[sudo] password for love:
insmod: ERROR: could not insert module test.ko: Invalid parameters
love@ubuntu:~/workspace/LinuxDriver/ModuleCommuication/TestUT$ sudo insmod test.ko a=3 b=2 AddOrSub=2
内核日志
Aug 18 01:48:27 ubuntu kernel: [ 8283.927925] add_sub: loading out-of-tree module taints kernel.
Aug 18 01:48:27 ubuntu kernel: [ 8283.928160] add_sub: module verification failed: signature and/or required key missing - tainting kernel
Aug 18 01:50:40 ubuntu dhclient[4117]: DHCPREQUEST of 192.168.60.130 on ens33 to 192.168.60.254 port 67 (xid=0x4a1f244)
Aug 18 01:50:40 ubuntu dhclient[4117]: DHCPACK of 192.168.60.130 from 192.168.60.254
Aug 18 01:50:40 ubuntu NetworkManager[705]: <info> [1566118240.1302] dhcp4 (ens33): address 192.168.60.130
Aug 18 01:50:40 ubuntu NetworkManager[705]: <info> [1566118240.1310] dhcp4 (ens33): plen 24 (255.255.255.0)
Aug 18 01:50:40 ubuntu NetworkManager[705]: <info> [1566118240.1313] dhcp4 (ens33): gateway 192.168.60.2
Aug 18 01:50:40 ubuntu NetworkManager[705]: <info> [1566118240.1315] dhcp4 (ens33): lease time 1800
Aug 18 01:50:40 ubuntu NetworkManager[705]: <info> [1566118240.1316] dhcp4 (ens33): nameserver '192.168.60.2'
Aug 18 01:50:40 ubuntu NetworkManager[705]: <info> [1566118240.1319] dhcp4 (ens33): domain name 'localdomain'
Aug 18 01:50:40 ubuntu NetworkManager[705]: <info> [1566118240.1321] dhcp4 (ens33): wins '192.168.60.2'
Aug 18 01:50:40 ubuntu NetworkManager[705]: <info> [1566118240.1362] dhcp4 (ens33): state changed bound -> bound
Aug 18 01:50:40 ubuntu dbus-daemon[684]: [system] Activating via systemd: service name='org.freedesktop.nm_dispatcher' unit='dbus-org.freedesktop.nm-dispatcher.service' requested by ':1.11' (uid=0 pid=705 comm="/usr/sbin/NetworkManager --no-daemon " label="unconfined")
Aug 18 01:50:40 ubuntu systemd[1]: Starting Network Manager Script Dispatcher Service...
Aug 18 01:50:40 ubuntu dhclient[4117]: bound to 192.168.60.130 -- renewal in 850 seconds.
Aug 18 01:50:40 ubuntu dbus-daemon[684]: [system] Successfully activated service 'org.freedesktop.nm_dispatcher'
Aug 18 01:50:40 ubuntu systemd[1]: Started Network Manager Script Dispatcher Service.
Aug 18 01:50:40 ubuntu nm-dispatcher: req:1 'dhcp4-change' [ens33]: new request (1 scripts)
Aug 18 01:50:40 ubuntu nm-dispatcher: req:1 'dhcp4-change' [ens33]: start running ordered scripts...
Aug 18 01:51:59 ubuntu kernel: [ 8494.987325] test: `3,b=2' invalid for parameter `a'
Aug 18 01:52:57 ubuntu kernel: [ 8553.183723] Test_init
Aug 18 01:52:57 ubuntu kernel: [ 8553.183728] A-B Success
模块变量
love@ubuntu:/sys/module/test$ cat parameters/a
3
love@ubuntu:/sys/module/test$ cat parameters/b
2
love@ubuntu:/sys/module/test$ cat parameters/AddOrSub
2
love@ubuntu:/sys/module/test$
love@ubuntu:/sys/module/test$ tree -a
.
├── coresize
├── holders
├── initsize
├── initstate
├── notes
│ └── .note.gnu.build-id
├── parameters
│ ├── a
│ ├── AddOrSub
│ └── b
├── refcnt
├── sections
│ ├── .data
│ ├── .gnu.linkonce.this_module
│ ├── __mcount_loc
│ ├── .note.gnu.build-id
│ ├── __param
│ ├── .rodata
│ ├── .rodata.str1.1
│ ├── .strtab
│ ├── .symtab
│ └── .text
├── srcversion
├── taint
├── uevent
└── version
4 directories, 22 files
love@ubuntu:/sys/module/test$ sudo cat sections/.symtab