内核模块编译方法
新功能加载
分为静态加载和动态加载两部分。
1.静态加载
将新的驱动代码即.c文件加到内核源码的相应驱动目录下(即同一目录下),并修改同一目录下的Makefile和Kconfig文件,并且在make menuconfig图形化界面下选中该文件<*>,以保证可以编译进内核源码。这种方法在内核启动时候就会运行该驱动代码。
2.动态加载
2.1新功能代码即.c文件放在内核源码的相应驱动目录下(即同一目录下),与静态加载类似,区别在于make menuconfig图形化界面下选中该文件,然后make uImage,再make modules编译模块,会生成相应的.ko文件。这种方式要看内核源码指定的是哪个平台的就编译成哪个平台的。
2.2当新的驱动代码不在内核源码目录下即不在同一目录下时,需要在编写新的Makefile来配合内核源码里的Makefile一起变异成.ko模块。这种方式编译时候既可以生成Ubuntu环境下的又可以生成开发板的,主要看使用的编译工具是哪一种。此种方式的Makefile编写模板如下:
ifeq ($(KERNELRELEASE),)
ifeq ($(ARCH), arm)
KERNEL_DIR ?= /home/linux/fs4412/linux-3.14
ROOTFS_DIR ?= /opt/4412/rootfs
else
KERNEL_DIR ?= /lib/modules/$(shell uname -r)/build
endif
CUR_DIR = $(shell pwd)
modules:
$(MAKE) -C $(KERNEL_DIR) M=$(CUR_DIR) modules
modules_install:
$(MAKE) -C $(KERNEL_DIR) M=$(CUR_DIR) modules INSTALL_MOD_PATH=$(ROOTFS_DIR) modul
clean:
rm -rf *.o *.ko *.mod .*.cmd *.mod.* modules.order Module.symvers .tmp_versions
else
obj-m += myhello.o
obj-m += xyz.o
xyz-objs += test.o func.o
endif
动态加载的两种方式,加载方式都是使用insmod xxx.ko即可,在电脑上Linux中命令行是不显示内核信息的,需要用dmesg命令来查看加载的打印信息。lsmod 可以查看加载了哪些模块,(lsmod | grep 关键字)用来查找某一个模块。rmmod xxx 用来卸载模块。用dmesg查看加载信息时太多,可以使用sudo dmesg -C命令来清楚直线内核的打印信息。
多源文件编译
当动态加载不在同一目录下时,且新的源文件不止一个时,也可以在同一个Makefile中实现。比如生成两个模块,一个是一个文件生成,另一个有多个文件生成。Makefile中编写如下:
obj-m += myhello.o
obj-m += xyz.o
xyz-objs += test.o func.o
内核模块的其他宏
MODULE_AUTHOR("…"); //添加作者信息
MODULE_DESCRIPTION("…"); //添加模块代码的描述
MODULE_ALIAS("…"); //给文件起个别名
modinfo xxx.ko //可以查看某个模块的宏说明