动态模块加载
一、内核模块介绍
在 Linux 中,.ko 文件是 内核模块(Kernel Object) 的扩展名。内核模块是一种可以 在不重新编译整个内核的情况下动态加载或卸载的代码单元,用于扩展内核功能,例如添加对新硬件设备的驱动支持、文件系统支持或内核特性。模块通过 insmod、rmmod 等命令进行加载与卸载, 加载后它就成为内核的一部分,在内核态中运行。
二、编写程序
1. 编写C程序
在源码的驱动目录下新建文件ko_test:
bash
cd linux-5.4/drivers/
mkdir ko_test
cd ko_test
touch ko.c该文件下输入如下内容,内容和上一节一致,只是为演示动态模块加载:
c
// SPDX-License-Identifier: GPL-2.0
/*
* My first linux kernel code.
*
* Copyright (C) 2025 by DuRuofu
*
* This module serves no practical purpose and is solely for testing purposes.
*/
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/types.h>
static int __init fcode_init(void)
{
pr_info("=============>%s runing<=============\n", __func__);
return 0;
}
static void __exit fcode_exit(void)
{
pr_info("=============>%s runing<=============\n", __func__);
}
module_init(fcode_init);
module_exit(fcode_exit);
MODULE_AUTHOR("duruofu");
MODULE_DESCRIPTION("This is my first linux kernel code for testing.");
MODULE_LICENSE("GPL");2. 编写Makefile
在ko_test目录下新建Makefile文件:
CROSS_PREFIX := ~/work/d1s/riscv64-wangzai-linux-gnu-gcc/bin/riscv64-unknown-linux-gnu-
KERNEL_DIR := ~/work/d1s/linux-5.4/
arch := riscv
obj-m := ko.o
cc := $(CROSS_PREFIX)gcc
ld:=$(CROSS_PREFIX)ld
.PHONY:all
all:
make ARCH=$(arch) CC=$(cc) LD=$(ld) -C $(KERNEL_DIR) M=$(shell pwd) modules V=1
.PHONY:clean
clean:
make ARCH=$(arch) CC=$(cc) LD=$(ld) -C $(KERNEL_DIR) M=$(shell pwd) clean这份 Makefile 用于在内核源码外部编译一个内核模块 ko.c。它通过 -C $(KERNEL_DIR) 进入内核源码目录,调用内核自带的模块编译规则, 用交叉编译工具链 (riscv64-unknown-linux-gnu-) 编译出 ko.ko 模块。执行 make 编译即可。
三、编译并配置动态加载
注意需要先编译内核,确保源码目录下生成了内核的可执行文件。
1. 编译
在模块目录下执行:
make会生成一系列的文件:

这个ko.ko就是可以动态加载的文件了
2. 配置内核支持动态加载
倚旧是这经典的几步:
cd linux-5.4
export ARCH=riscv
export CROSS_COMPILE=/home/duruofu/work/d1s/riscv64-wangzai-linux-gnu-gcc/bin/riscv64-unknown-linux-gnu-
make wangzai_d1s_rtl8723ds_defconfig
make menuconfig勾选支持模块动态加载:

内核里面的模块也是可以在menuconfig里配置为模块编译的,这点需要注意。
编译内核,并重新制作启动卡烧录即可。
四、测试模块动态加载
1.拷贝编译好的动态模块到开发板
这里在windows上使用adb :

在目录下执行:.\adb.exe shell:

通过ADB上传我们编译好的动态模块,使用push命令(注意退出shell):
.\adb.exe push \\wsl.localhost\Ubuntu-20.04-Build-Linux\home\duruofu\work\d1s\linux-5.4\drivers\ko_test\ko.ko /这里的文件目录根据自己的实际情况填写:

成功后,使用串口终端进行测试:

执行命令insmod ko.ko,加载模块:
可以看到模块被加载了
执行命令rmmod ko.ko,卸载模块:
