内核模块编译记录

1 基本的模块编译问题

1
2
3
4
5
obj-m+=hello.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

在vscode终端使用最简单的模块进行编译,发现既没有报错,也没有hello.ko文件产生。

可以看到M= modules,没有显示当前文件夹

1
echo $(PWD)

输出PWD环境变量显示PWD: command not found,即该环境变量不存在,故使用shell命令的形式

1
2
3
4
5
6
7
8
obj-m += hello.o

KDIR := /lib/modules/$(shell uname -r)/build # 内核源代码路径
all:
make -C $(KDIR) M=$(shell pwd) modules
clean:
rm -f *.ko *.o *.mod.o *.mod.c *.symvers

编译成功

后在ubuntu自带的终端编译,发现第一种方法也可以,代表只是vscode终端的问题。在vscode终端使用fish,发现也可以编译成功,证明只是vscode bash的问题。 还是用shell命令吧

pci_device_id以NULL结尾

1
2
3
4
5
6
7
8
9
static const struct pci_device_id xlinux_id_table[] = {{.vendor = 0x10ee,
.device = 0x7024,
.subvendor = PCI_ANY_ID,
.subdevice = PCI_ANY_ID,
0,
0},
{
0,
}};

pci_device_id赋值格式参照PCI_VDEVICE宏展开代码

1
2
3
4
5
6
7
8
9
10
struct pci_device_id {
__u32 vendor, device; /* Vendor and device ID or PCI_ANY_ID*/
__u32 subvendor, subdevice; /* Subsystem ID's or PCI_ANY_ID */
__u32 class, class_mask; /* (class,subclass,prog-if) triplet */
kernel_ulong_t driver_data; /* Data private to the driver */
};

#define PCI_VDEVICE(vend, dev) \
.vendor = PCI_VENDOR_ID_##vend, .device = (dev), \
.subvendor = PCI_ANY_ID, .subdevice = PCI_ANY_ID, 0, 0

内核加载时输出两条警告
第一条表示为内核树外模块,不用管

modulename: loading out-of-tree module taints kernel
第二个数字签名问题,不知道有啥影响
在makefile中加入CONFIG_MODULE_SIG=n好像也没用
使用以下命令就没出现这个提示了

1
2
/home/hpc/Desktop/tmp/linux-4.19.150/scripts/sign-file sha512 /home/hpc/Desktop/tmp/linux-4.19.150/certs/signing_key.pem /home/hpc/Desktop/tmp/linux-4.19.150/certs/signing_key.x509 xlinux.ko
# 其中/home/hpc/Desktop/tmp/linux-4.19.150为源码地址