You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Yocto/Bitbake下多源文件内核模块无法正常构建问题咨询

问题:Yocto/Bitbake构建多文件内核模块无输出异常

在Yocto/Bitbake环境中构建多源文件Linux内核模块时出现异常:

  • 仅使用hello.c(保留代码注释,不启用testprint.c/h)时,模块加载、卸载能正常输出printk内容;
  • 移除注释启用testprint.c/h后,模块加载、卸载无任何输出,但Bitbake构建无报错或警告;
  • 仅取消hello.c的注释但保留Makefile中hello-objs行注释时,Bitbake会报testprint未定义错误(此情况符合预期)。

测试模块目录结构

test-mod
|- files
|--- COPYING
|--- Makefile
|--- hello.c
|--- testprint.c
|--- testprint.h
|- test-mod_0.1.bb

代码文件内容

hello.c

// works when the below /* */ comments are in place
#include <linux/module.h>
/* #include "testprint.h" */

int init_module(void)
{
    printk("Hello World!
");
    /* testprint(); */
    return 0;
}

void cleanup_module(void)
{
    printk("Goodbye Cruel World!
");
}

MODULE_LICENSE("GPL");

testprint.h

void testprint(void);

testprint.c

#include "testprint.h"
#include <linux/module.h>

MODULE_LICENSE("GPL");

void testprint(void)
{
    printk("howdy
");
}

Makefile

obj-m := hello.o
# hello-objs := testprint.o

SRC := $(shell pwd)
all:
    $(MAKE) -C $(KERNEL_SRC) M=$(SRC) I=$(INC)

modules_install:
    $(MAKE) -C $(KERNEL_SRC) M=$(SRC) I=$(INC) modules_install

clean:
    rm -f *.o *~ core .depend .*.cmd *.ko *.mod.c

test-mod_0.1.bb

SUMMARY = "Example of how to build an external Linux kernel module"
LICENSE = "GPLv2"
LIC_FILES_CHKSUM = "file://COPYING;md5=12f884d2ae1ff87c09e5b7ccc2c4ca7e"

inherit module

SRC_URI = "file://Makefile \
           file://hello.c \
           file://testprint.c \
           file://testprint.h \
           file://COPYING \
          "

S = "${WORKDIR}"

问题排查与修复

1. Makefile多源文件配置错误

内核模块由多个源文件组成时,必须通过hello-objs指定组成最终.ko文件的所有目标文件。你当前注释了hello-objs := testprint.o,导致testprint.o未被链接到hello.ko中,模块实际未包含testprint的执行逻辑。

修复: 取消Makefile中该行的注释:

obj-m := hello.o
hello-objs := testprint.o

这会告诉内核构建系统,hello.ko由hello.o和testprint.o共同链接生成。

2. printk语句格式错误

你的printk字符串直接跨行书写(如printk("Hello World! ");),属于C语言语法错误,会导致编译异常或运行时消息无法正常输出。此外,未指定日志级别可能导致消息被系统日志过滤规则拦截,无法显示到控制台。

修复: 修改所有printk语句,添加换行符\n并指定日志级别:

  • hello.c修改后:
    #include <linux/module.h>
    #include "testprint.h"
    
    int init_module(void)
    {
        printk(KERN_INFO "Hello World!\n");
        testprint();
        return 0;
    }
    
    void cleanup_module(void)
    {
        printk(KERN_INFO "Goodbye Cruel World!\n");
    }
    
    MODULE_LICENSE("GPL");
    
  • testprint.c修改后:
    #include "testprint.h"
    #include <linux/module.h>
    
    void testprint(void)
    {
        printk(KERN_INFO "howdy!\n");
    }
    
    注:多个源文件中只需保留一个MODULE_LICENSE("GPL")即可,重复定义不影响功能但属于冗余代码。

3. 验证方法

模块加载后如果控制台仍无输出,可通过dmesg命令查看内核日志缓冲区,确认消息是否已被正确输出。


内容的提问来源于stack exchange,提问作者gutelfuldead

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.15 21:10:27