You need to enable JavaScript to run this app. x64 Ubuntu Linux添加自定义hello系统调用编译内核报未定义引用错误如何解决
优惠活动
大模型
产品
解决方案
定价
更多

x64 Ubuntu Linux添加自定义hello系统调用编译内核报未定义引用错误如何解决

5.10.26内核自定义hello系统调用编译链接报错修复方案

报错核心原因

本次undefined reference报错是x86_64架构下系统调用自动命名规则匹配错位、表项配置错误、代码不符合内核规范、构建配置遗漏四个问题叠加导致的,之前操作中的典型错误包括:

  • 混淆了系统调用表的自动前缀逻辑:Linux 5.10+内核在x86_64架构下,会自动为syscall_64.tbl中登记的系统调用追加__x64_前缀生成实际链接的符号,完全不需要手动在表项或函数定义里加这个前缀
  • syscall_64.tbl表项填写格式错误:表项的四列规则为「系统调用号」「ABI类型(64表示64位)」「用户态调用名」「对应内核函数名」,之前误将函数名写成printmsg,和代码里定义的hello相关函数完全不匹配
  • 代码编写不符合内核系统调用规范:裸写asmlinkage long sys_xxx的写法在5.10内核中会被编译规则过滤,无法生成可被链接器识别的标准符号
  • 未将自定义源码加入内核编译列表:hello.c文件没有被内核Makefile关联,实际未参与编译流程,自然无法在链接阶段找到对应符号

分步修复操作

  • 修正syscall_64.tbl配置
    打开arch/x86/entry/syscall_64.tbl,将之前乱改的表项替换为:
    548  64  hello  sys_hello
    
    不要手动添加__x64_前缀,不要把函数名改成printmsg或其他无关名称,保留系统调用号548即可(5.10.26版本中该号未被官方调用占用)
  • 重写hello.c代码,替换原有裸写函数的内容为内核标准系统调用定义:
    #include <linux/kernel.h>
    #include <linux/syscalls.h>
    
    SYSCALL_DEFINE0(hello)
    {
        printk("Hello World\n");
        return 0;
    }
    
    注:SYSCALL_DEFINE0是无参数系统调用的标准定义宏,编译时会自动生成符合x86_64规范的__x64_sys_hello符号,不需要手动写函数名,避免出现前缀套娃的命名错误
  • 关联源码到内核构建流程
    建议将hello.c放置在内核源码的kernel/目录下,编辑同目录下的Makefile,在编译对象列表中追加一行:
    obj-y += hello.o
    
    确保hello.c会被实际编译进内核镜像
  • 清理残留缓存后重新编译
    先执行make clean清除之前修改留下的旧符号配置,再启动内核编译,避免增量编译时的旧符号残留导致重复报错

问题对应说明

最初的报错undefined reference to '__x64___x64_sys_hello'就是两次操作叠加的结果:最初写sys_hello时,内核自动追加__x64_前缀要找__x64_sys_hello,但裸写的sys_hello没有生成对应的标准符号;之后手动给函数再加上__x64_前缀时,内核又自动追加一次前缀,最终链接器要找带双前缀的__x64___x64_sys_hello,自然无法匹配到实际存在的符号。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.29 00:36:08