可以动态的添加到内核当中,添加后其于内核中的其他部分完全相同,
可以不用重新编译整个内核,可以在内核运行状态下动态的加载和卸载
文件类型为elf格式。
一个最简单的内核模块代码
代码结构如下
myhello.c
#include <linux/module.h>
#include <linux/init.h>
#include <linux/kernel.h>
static int __init myhello_init(void)
{
printk("=============================\n");
printk("=========myhello-init========\n");
printk("=============================\n");
return 0;
}
static void __exit myhello_exit(void)
{
printk("=============================\n");
printk("=========myhello-exit========\n");
printk("=============================\n");
return;
}
module_init(myhello_init);//模块的注册
module_exit(myhello_exit);//模块的卸载
MODULE_LICENSE("GPL");//GPL协议
Makefile分析
KERNEL_DIR=../../ebf_linux_kernel_6ull_depth1/build_image/build
ARCH=arm
CROSS_COMPILE=arm-linux-gnueabihf-
export ARCH CROSS_COMPILE
obj-m := myhello.o
all:
$(MAKE) -C $(KERNEL_DIR) M=$(CURDIR) modules
.PHONE:clean
clean:
$(MAKE) -C $(KERNEL_DIR) M=$(CURDIR) clean
**KERNEL_DIR** 因为是内核模块的编译,因此其编译依赖于内核源码,包括代码中的头文件都是内核源码提供的,该变量用于指定内核代码路径
$(MAKE) -C $(KERNEL_DIR) M=$(CURDIR) modules
$(MAKE) -C $(KERNEL_DIR) 解析后为 make -C ../../ebf_linux_kernel_6ull_depth1/build_image/build
makefile中make -C的含义为 转到-C后面的路径下执行该路径下的makefile
CURDIR指的是前面模块代码的路径 即myhello.c的路径 因此该行的最终意义可以这样理解
在KERNEL_DIR所在目录下执行make modules 附加参数 M=myhello.c的路径 指定编译的内核模块位置
在yocto中添加内核模块
在yocto中添加内核模块,既可以在内核源码中添加,也可以通过recipes添加 ,下面介绍通过recipes添加
在可以的meta-layer下添加recipe,结构如下
在yocto中编译 不需要指定ARCH CROSS_COMPILE及KERNEL_SRC
obj-m := hello.o
SRC := $(shell pwd)
all:
$(MAKE) -C $(KERNEL_SRC) M=$(SRC)
modules_install:
$(MAKE) -C $(KERNEL_SRC) M=$(SRC) modules_install
clean:
rm -f *.o *~ core .depend .*.cmd *.ko *.mod.c
rm -f Module.markers Module.symvers modules.order
rm -rf .tmp_versions Modules.symvers
bb文件
SUMMARY = "Example of how to build an external Linux kernel module"
DESCRIPTION = "${SUMMARY}"
LICENSE = "GPL-2.0-only"
#注意下面的license校验,如果报错的话,请去其他meta目录下搜素COMMON_LICENSE_DIR变量,并将后面的md5值填入下面即可
LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/MIT;md5=0835ade698e0bcf8506ecda2f7b4f302"
inherit module
SRC_URI = "file://Makefile \
file://hello.c \
"
S = "${WORKDIR}"
# The inherit of module.bbclass will automatically name module packages with
# "kernel-module-" prefix as required by the oe-core build environment.
# 注意下面的名字,后续要让模块加到整个系统构建就需要使用
# RPROVIDES:${PN} += "kernel-module-hello"