如何在 QEMU 上构建和运行 Linux 内核模块?

问题描述 投票:0回答:2

我的老师给了我一个linux内核vmlinuz-3.17.2和一个可以加载到qemu的rootfs.ext2。他要求我构建一个最简单的内核模块,打印一个 hello world 作为作业。

  • 首先,我下载内核源代码并运行 make oldconfig
  • 其次,我将配置设置为 PREEMPT 并且没有 modversions (根据qemu中运行的vmlinuz的uname -a),然后进行准备
  • 第三,我编译内核mod并将hello.ko复制到rootfs.ext2中
  • 最后,在 qemu 中,我运行 insmod hello.ko ,它在没有任何提示的情况下退出 并回显 $?返回 0。

但是,我在 dmesg 或 /var/log/messages 中看不到任何内容 有什么问题吗?我该怎么办? 当我成功运行 rmmod hello.ko 时,也没有任何内容可打印。

我的日志级别是 7 4 1 7

我的 hello.c 如下:

#include <linux/init.h>
#include <linux/module.h>

static int __init hello_init(void)
{
    pr_info("Hello World");
    return -1; 
// I changed this to -1 deliberately, Because It seems that the code is not executed.
}

static void __exit hello_exit(void)
{
    printk(KERN_ERR "Goodbye, cruel world\n");
}
MODULE_LICENSE("GPL");

module_init(hello_init);
module_exit(hello_exit);
linux linux-kernel kernel-module qemu
2个回答
2
投票

构建root

Buildroot 是最简单的方法:

在 Ubuntu 16.04 上测试。


0
投票

执行此操作的正确方法是使用 modprobe 而不是 insmod (尽管对于您的示例,考虑到该模块没有任何依赖项,insmod 就足够了)

问题是 modprobe 期望模块位于

/lib/modules
中,但是当您编译模块(使用
make modules
)并安装它们(使用
make modules_install
)时,模块会安装到主机系统的
/lib/modules
目录而不是QEMU 使用的硬盘映像。

这个问题的解决方案是在安装模块时提供变量

INSTALL_MOD_PATH
make。

因此,步骤是:

  1. 找出你的硬盘镜像在哪里,它作为 qemu 的参数给出,通常通过
    -drive file=<img>
    -hda=<img>
  2. 安装:
    sudo mount <img> /mnt
  3. 在内核源目录中运行以下命令:
make modules -j `nproc` 
sudo make modules_install -j `nproc` INSTALL_MOD_PATH=/mnt

完成上述操作后,您应该能够在下次启动 QEMU 实例时加载所有已编译的模块。

注意:如果您只想编译单个模块,可以使用命令

make modules M=<path to module directory> -j `nproc`

© www.soinside.com 2019 - 2024. All rights reserved.