1. c文件
#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
static int kernel_module_init(void) {
printk(KERN_INFO "Hello, World!\n");
return 0;
}
static void kernel_module_exit(void) {
printk(KERN_INFO "Goodbye, World!\n");
}
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Jimmy-Jiang-Junior");
MODULE_DESCRIPTION("A simple example Linux module.");
module_init(kernel_module_init);
module_exit(kernel_module_exit);
2. Makefile
obj-m += kernel_module.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
3. 编译ko后,插入失败问题解决
报错
insmod: ERROR: could not insert module kernel_module.ko: Invalid module format
这是版本不匹配导致的,使用uname -a查看linux版本
正规的思路是找到一个匹配的树莓派软件版本,编译内核模块。如果没法找到匹配的内核版本可以考虑修改./include/linux/vermagic.h文件
最快的方案是直接修改vermagic.h文件最后的define定义
#define VERMAGIC_STRING
#define VERMAGIC_STRING "5.10.0-v8 SMP preempt mod_unload modversions aarch64"
/*
#define VERMAGIC_STRING \
UTS_RELEASE " " \
MODULE_VERMAGIC_SMP MODULE_VERMAGIC_PREEMPT \
MODULE_VERMAGIC_MODULE_UNLOAD MODULE_VERMAGIC_MODVERSIONS \
MODULE_ARCH_VERMAGIC \
MODULE_RANDSTRUCT_PLUGIN
*/
那么怎么找到正确的define定义呢?
在/lib/modules目录下,找到一个能够正常insmod的内核模块,使用modinfo命令查看这个内核的模块的vermagic,将这个vermagic拷贝到vermagic.h文件中即可。
[jimmy@openEuler i2c]$ modinfo i2c-dev.ko
filename: /lib/modules/5.10.0-v8/kernel/drivers/i2c/i2c-dev.ko
license: GPL
description: I2C /dev entries driver
author: Simon G. Vogl <simon@tk.uni-linz.ac.at>
author: Frodo Looijaard <frodol@dds.nl>
srcversion: F21EB653F3B5A8B4FB8CF96
depends:
intree: Y
name: i2c_dev
vermagic: 5.10.0-v8 SMP preempt mod_unload modversions aarch64