鱼C论坛

 找回密码
 立即注册
查看: 6951|回复: 8

[已解决]编译内核模块成功但无法加载, Invalid module format

[复制链接]
发表于 2021-12-28 21:26:35 | 显示全部楼层 |阅读模式
20鱼币
本帖最后由 rt3 于 2021-12-28 22:07 编辑

编译内核模块成功但无法加载:
insmod: ERROR: could not insert module ./mymod.ko: Invalid module format

dmesg 的 报错信息:
[ 5180.365546] module: x86/modules: Skipping invalid relocation target, existing value is nonzero for type 1, loc 00000000df2a29e3, val ffffffffc14970b6

make 命令:
make -C /lib/modules/$(uname -r)/build M=${PWD}

Makefile 文件:
ARCH = x86_64
KERN_VER = $(shell uname -r)
KERN_DIR = /lib/modules/${KERN_VER}/build
KBUILD_CFLAGS:= -Wall 
EXTRA_CFLAGS += -mcmodel=kernel
obj-m:=mymod.o
module_install:
        cp ./mymod.ko /lib/modules/${KERN_VER}

mymod.c:
#include <linux/module.h>
#include <linux/timer.h>
#include <linux/errno.h>

static int sec=5;
module_param(sec, int, S_IRUGO|S_IWUSR);
MODULE_PARM_DESC(sec,"Set the interval.");
static void mymod_timer(unsigned long data);
static DEFINE_TIMER(timer,mymod_timer);
static void mymod_timer(unsigned long data) {
    printk(KERN_INFO"mymod:timer\n");
    mod_timer(&timer, jiffies+sec*HZ);
}

static int mymod_init(void) {
    printk(KERN_INFO"mymod:init\n");
    if(sec<=0){
        printk(KERN_INFO"Invalid interval sec=%d\n",sec);
        return-EINVAL;
    }
    mod_timer(&timer, jiffies+sec*HZ);
    return 0;
}

static void mymod_exit(void){
    del_timer(&timer);
    printk(KERN_INFO"mymod:exit\n");
}
module_init(mymod_init);
module_exit(mymod_exit);
MODULE_AUTHOR("Hiroshi Shimamoto");
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("My module");

内核版本:
5.15.11-200.fc35.x86_64

thx
最佳答案
2021-12-28 21:26:36
我弄明白了,先说一下出问题的原因
因为你现在正在运行的内核和你编译内核模块用的内核源码不匹配
也就是说Makefile一定是要用这个
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

我试了,我下载了一个内核源码,用这个源码来编译内核模块
可以生成 hello.ko 文件,但是不能用 insmod 载入内核执行,报错信息和你的一样

也就是说你要把编译生成的内核模块载入当前正在运行的这个内核执行
编译内核模块的时候必须要使用和当前正在运行的这个内核匹配的内核源码
在我这边,这个和当前正在运行的内核匹配的内核源码放在这里
安装好系统以后就放在这里了,是安装脚本放在这里的
/lib/modules/$(shell uname -r)/build

你可能会说,你找不到和当前正在运行的这个内核匹配的内核源码
没关系,下载一个内核源码,编译生成内核,然后运行生成的这个内核
这样就有了匹配的内核源码了

这个方法我也试了,没问题

这里说一下需要注意的几点
vmlinuz-linux 和 initramfs-linux.img 这两个文件放在哪里都无所谓
但是内核模块必须放在这个目录下面
因为你新编译的内核和现在正在运行的内核的版本应该是不一样吧,所以不会冲突
这个目录下面,一个内核版本对应一个目录
/lib/modules

vmlinuz-linux 就是 bzImage
这个文件在内核源码的这个目录下面,把 bzImage 的名字改成 vmlinuz-linux 也行
不改也可以,无所谓
这个目录
arch/x86/boot
$ ls arch/x86/boot/bzImage
arch/x86/boot/bzImage
$ 

还有,这个文件必须重新生成,不能使用boot目录下面的那个
initramfs-linux.img

开机的时候用grub命令手动引导新内核
当然你可以配置grub自动引导新内核,这也无所谓
如果你打算一直使用这个新内核的话
我就不打算一直使用新编译的这个内核,我就是试了试
我这边把 bzImage 和 initramfs-linux.img 放在了 /mnt/sdc1/boot 下面

大概就这些

最佳答案

查看完整内容

我弄明白了,先说一下出问题的原因 因为你现在正在运行的内核和你编译内核模块用的内核源码不匹配 也就是说Makefile一定是要用这个 我试了,我下载了一个内核源码,用这个源码来编译内核模块 可以生成 hello.ko 文件,但是不能用 insmod 载入内核执行,报错信息和你的一样 也就是说你要把编译生成的内核模块载入当前正在运行的这个内核执行 编译内核模块的时候必须要使用和当前正在运行的这个内核匹配的内核源码 在我 ...
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2021-12-28 21:26:36 | 显示全部楼层    本楼为最佳答案   
我弄明白了,先说一下出问题的原因
因为你现在正在运行的内核和你编译内核模块用的内核源码不匹配
也就是说Makefile一定是要用这个
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

我试了,我下载了一个内核源码,用这个源码来编译内核模块
可以生成 hello.ko 文件,但是不能用 insmod 载入内核执行,报错信息和你的一样

也就是说你要把编译生成的内核模块载入当前正在运行的这个内核执行
编译内核模块的时候必须要使用和当前正在运行的这个内核匹配的内核源码
在我这边,这个和当前正在运行的内核匹配的内核源码放在这里
安装好系统以后就放在这里了,是安装脚本放在这里的
/lib/modules/$(shell uname -r)/build

你可能会说,你找不到和当前正在运行的这个内核匹配的内核源码
没关系,下载一个内核源码,编译生成内核,然后运行生成的这个内核
这样就有了匹配的内核源码了

这个方法我也试了,没问题

这里说一下需要注意的几点
vmlinuz-linux 和 initramfs-linux.img 这两个文件放在哪里都无所谓
但是内核模块必须放在这个目录下面
因为你新编译的内核和现在正在运行的内核的版本应该是不一样吧,所以不会冲突
这个目录下面,一个内核版本对应一个目录
/lib/modules

vmlinuz-linux 就是 bzImage
这个文件在内核源码的这个目录下面,把 bzImage 的名字改成 vmlinuz-linux 也行
不改也可以,无所谓
这个目录
arch/x86/boot
$ ls arch/x86/boot/bzImage
arch/x86/boot/bzImage
$ 

还有,这个文件必须重新生成,不能使用boot目录下面的那个
initramfs-linux.img

开机的时候用grub命令手动引导新内核
当然你可以配置grub自动引导新内核,这也无所谓
如果你打算一直使用这个新内核的话
我就不打算一直使用新编译的这个内核,我就是试了试
我这边把 bzImage 和 initramfs-linux.img 放在了 /mnt/sdc1/boot 下面

大概就这些
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2021-12-29 18:30:49 | 显示全部楼层
首先,这个代码在我这边编译是报错的,原因是定时器回调函数的参数类型
我这边是这样的
static void mymod_timer(struct timer_list *unused);

我改成这样就可以通过编译了,也可以使用 insmod 添加到内核执行
这个代码没有问题,说明是你的编译环境的问题
你是如何搭建编译环境的?

这个代码在我这边没有问题
#include <linux/module.h>
#include <linux/timer.h>
#include <linux/errno.h>

static int sec = 5;
module_param(sec, int, S_IRUGO | S_IWUSR);
MODULE_PARM_DESC(sec, "Set the interval.");

static void mymod_timer(struct timer_list *unused);
static DEFINE_TIMER(timer, mymod_timer);

//static void mymod_timer(unsigned long data) {
static void mymod_timer(struct timer_list *unused) {
    printk(KERN_INFO "mymod:timer\n");
    mod_timer(&timer, jiffies + sec * HZ);
}

static int mymod_init(void) {
    printk(KERN_INFO "mymod:init\n");
    if(sec <= 0) {
        printk(KERN_INFO "Invalid interval sec=%d\n", sec);
        return -EINVAL;
    }
    mod_timer(&timer, jiffies + sec * HZ);
    return 0;
}

static void mymod_exit(void) {
    del_timer(&timer);
    printk(KERN_INFO "mymod:exit\n");
}

module_init(mymod_init);
module_exit(mymod_exit);

MODULE_AUTHOR("Hiroshi Shimamoto");
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("My module");
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2021-12-29 18:31:20 | 显示全部楼层
Makefile
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
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2021-12-29 20:35:19 | 显示全部楼层
$ uname -r
5.15.11-arch2-1
$ 
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2021-12-29 22:13:33 | 显示全部楼层
本帖最后由 rt3 于 2021-12-30 10:06 编辑

有个帖子多发了一遍, 删了
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2021-12-29 22:23:35 | 显示全部楼层

或者举例说明keyring-ima-signer的用法也行。
这是Fedora下的一个小工具,Arch下有没有不确定
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2021-12-30 10:03:35 | 显示全部楼层

照2L的 方法做了还是报错
insmod: ERROR: could not insert module mymod.ko: Invalid module format
gcc 的 配置
使用内建 specs。
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/usr/libexec/gcc/x86_64-redhat-linux/11/lto-wrapper
OFFLOAD_TARGET_NAMES=nvptx-none
OFFLOAD_TARGET_DEFAULT=1
目标:x86_64-redhat-linux
配置为:../configure --enable-bootstrap --enable-languages=c,c++,fortran,objc,obj-c++,ada,go,d,lto --prefix=/usr --mandir=/usr/share/man --infodir=/usr/share/info --with-bugurl=http://bugzilla.redhat.com/bugzilla --enable-shared --enable-threads=posix --enable-checking=release --enable-multilib --with-system-zlib --enable-__cxa_atexit --disable-libunwind-exceptions --enable-gnu-unique-object --enable-linker-build-id --with-gcc-major-version-only --with-linker-hash-style=gnu --enable-plugin --enable-initfini-array --with-isl=/builddir/build/BUILD/gcc-11.2.1-20211203/obj-x86_64-redhat-linux/isl-install --enable-offload-targets=nvptx-none --without-cuda-driver --enable-gnu-indirect-function --enable-cet --with-tune=generic --with-arch_32=i686 --build=x86_64-redhat-linux --with-build-config=bootstrap-lto --enable-link-serialization=1
线程模型:posix
Supported LTO compression algorithms: zlib zstd
gcc 版本 11.2.1 20211203 (Red Hat 11.2.1-7) (GCC) 
screenfetch -n 的输出
[root@fedora ~]# screenfetch -n
 root@fedora
 OS: Fedora 
 Kernel: x86_64 Linux 5.15.11-200.fc35.x86_64
 Uptime: 6h 58m
 Packages: 1887
 Shell: bash
 Resolution: No X Server
 DE: GNOME 41.2
 WM: Not Found
 GTK Theme: Adwaita [GTK2/3]
 Icon Theme: Adwaita
 Font: Cantarell 11
 Disk: 391G / 455G (88%)
 CPU: Intel Core i5-3230M @ 4x 3.2GHz [65.0°C]
 GPU: Mesa Intel(R) HD Graphics 4000 (IVB GT2)
 RAM: 3107MiB / 3805MiB
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2021-12-30 11:52:26 | 显示全部楼层
没听说过这个
keyring-ima-signer
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-12-22 10:31

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表