ko undefined!排除故障流程。

防盗链接:https://blog.youkuaiyun.com/Sharpneo/article/details/142676672

内核模块编译时,出现*.ko undefined!如何解决##

若我们需要将demo.c编译成demo.ko时出现了ERROR: “xxx” [*/demo.ko] undefined!

  1. 确保内核模块的Makefile编写无误。
  2. 其次检查:
    内核中是否已经使用EXPORT_SYMBOL(xxx);导出对应符号。
    并且是否在demo.c添加了函数申明,或者#include包含符号的头文件。

若内核中使用EXPORT_SYMBOL_GPL(xxx);来导出对应符号,那么demo.c中必须使用MODULE_LICENSE("GPL");或者MODULE_LICENSE("Dual BSD/GPL");来添加相关证书。

  1. 然后检查内核模块导出符号上下文中是否存在宏定义开关,若存在宏定义开关,检查Linux编译目录的.config文件是否打开对应选项。

  2. 最后:
    若上述步骤都没问题,比较容易遗漏的地方就是Makefile。查看xxx符号所在文件的当前目录下的Makefile。

    .
    ├── br_if.c
    ├── ...
    ├── Kconfig
    ├── Makefile
    └── netfilter
    

    比如我们要查看的xxx符号位于br_if.c,那么这时候需要注意同目录下的Makefile文件如下(忽略无关内容)。

    obj-$(CONFIG_BRIDGE) += bridge.o
    
    bridge-y	:= br.o br_device.o br_fdb.o br_forward.o br_if.o br_input.o \
    			br_ioctl.o br_stp.o br_stp_bpdu.o \
    			br_stp_if.o br_stp_timer.o br_netlink.o \
    			br_netlink_tunnel.o br_arp_nd_proxy.o
    //...
    

    可以看到br_if.o被包含在bridge-y中,bridge-y为bridge.o的依赖项,若要将bridge.o编入内核,还需要启动CONFIG_BRIDGE选项。

如何查找编译选项位置:

https://www.kernelconfig.io/ (可能需要梯子)中可以搜索具体版本的某编译选项在menuconfig配置菜单中的位置。

kiki@kiki-virtual-machine:~/Desktop/rwProcMem_module$ ./build.sh rm -f *.ko *.o *.mod.o *.mod.c *.symvers *.order .*.cmd .*.d .*.tmp .*.mod *.mod rm -rf .tmp_versions make -C /home/kiki/Desktop/oneplus/out M=/home/kiki/Desktop/rwProcMem_module LLVM=1 LLVM_IAS=1 ARCH=arm64 SUBARCH=arm64 \ CC=clang LD=ld.lld OBJCOPY=llvm-objcopy OBJDUMP=llvm-objdump NM=llvm-nm modules make[1]: 进入目录“/home/kiki/Desktop/oneplus/out” CC [M] /home/kiki/Desktop/rwProcMem_module/sys.o LD [M] /home/kiki/Desktop/rwProcMem_module/rwProcMem37.o MODPOST /home/kiki/Desktop/rwProcMem_module/Module.symvers ERROR: modpost: "module_layout" [/home/kiki/Desktop/rwProcMem_module/rwProcMem37.ko] undefined! ERROR: modpost: "copy_from_kernel_nofault" [/home/kiki/Desktop/rwProcMem_module/rwProcMem37.ko] undefined! ERROR: modpost: "cpu_hwcaps" [/home/kiki/Desktop/rwProcMem_module/rwProcMem37.ko] undefined! ERROR: modpost: "snprintf" [/home/kiki/Desktop/rwProcMem_module/rwProcMem37.ko] undefined! ERROR: modpost: "strncat" [/home/kiki/Desktop/rwProcMem_module/rwProcMem37.ko] undefined! ERROR: modpost: "d_path" [/home/kiki/Desktop/rwProcMem_module/rwProcMem37.ko] undefined! ERROR: modpost: "strlcpy" [/home/kiki/Desktop/rwProcMem_module/rwProcMem37.ko] undefined! ERROR: modpost: "sscanf" [/home/kiki/Desktop/rwProcMem_module/rwProcMem37.ko] undefined! ERROR: modpost: "memcpy" [/home/kiki/Desktop/rwProcMem_module/rwProcMem37.ko] undefined! ERROR: modpost: "strchr" [/home/kiki/Desktop/rwProcMem_module/rwProcMem37.ko] undefined! ERROR: modpost: "strcmp" [/home/kiki/Desktop/rwProcMem_module/rwProcMem37.ko] undefined! ERROR: modpost: "__kmalloc" [/home/kiki/Desktop/rwProcMem_module/rwProcMem37.ko] undefined! ERROR: modpost: "kobject_del" [/home/kiki/Desktop/rwProcMem_module/rwProcMem37.ko] undefined! ERROR: modpost: "__list_del_entry_valid" [/home/kiki/Desktop/rwProcMem_module/rwProcMem37.ko] undefined! ERROR: modpost: "__arch_copy_to_user" [/home/kiki/Desktop/rwProcMem_module/rwProcMem37.ko] undefined! ERROR: modpost: "find_get_pid" [/home/kiki/Desktop/rwProcMem_module/rwProcMem37.ko] undefined! ERROR: modpost: "put_pid" [/home/kiki/Desktop/rwProcMem_module/rwProcMem37.ko] undefined! ERROR: modpost: "gic_nonsecure_priorities" [/home/kiki/Desktop/rwProcMem_module/rwProcMem37.ko] undefined! ERROR: modpost: "cpu_hwcap_keys" [/home/kiki/Desktop/rwProcMem_module/rwProcMem37.ko] undefined! ERROR: modpost: "arm64_const_caps_ready" [/home/kiki/Desktop/rwProcMem_module/rwProcMem37.ko] undefined! ERROR: modpost: "memset" [/home/kiki/Desktop/rwProcMem_module/rwProcMem37.ko] undefined! ERROR: modpost: "kmalloc_order_trace" [/home/kiki/Desktop/rwProcMem_module/rwProcMem37.ko] undefined! ERROR: modpost: "kimage_voffset" [/home/kiki/Desktop/rwProcMem_module/rwProcMem37.ko] undefined! ERROR: modpost: "vabits_actual" [/home/kiki/Desktop/rwProcMem_module/rwProcMem37.ko] undefined! ERROR: modpost: "si_meminfo" [/home/kiki/Desktop/rwProcMem_module/rwProcMem37.ko] undefined! ERROR: modpost: "memstart_addr" [/home/kiki/Desktop/rwProcMem_module/rwProcMem37.ko] undefined! ERROR: modpost: "up_read" [/home/kiki/Desktop/rwProcMem_module/rwProcMem37.ko] undefined! ERROR: modpost: "find_vma" [/home/kiki/Desktop/rwProcMem_module/rwProcMem37.ko] undefined! ERROR: modpost: "down_read" [/home/kiki/Desktop/rwProcMem_module/rwProcMem37.ko] undefined! ERROR: modpost: "mmput" [/home/kiki/Desktop/rwProcMem_module/rwProcMem37.ko] undefined! ERROR: modpost: "get_task_mm" [/home/kiki/Desktop/rwProcMem_module/rwProcMem37.ko] undefined! ERROR: modpost: "pid_task" [/home/kiki/Desktop/rwProcMem_module/rwProcMem37.ko] undefined! ERROR: modpost: "__arch_copy_from_user" [/home/kiki/Desktop/rwProcMem_module/rwProcMem37.ko] undefined! ERROR: modpost: "kfree" [/home/kiki/Desktop/rwProcMem_module/rwProcMem37.ko] undefined! ERROR: modpost: "cdev_del" [/home/kiki/Desktop/rwProcMem_module/rwProcMem37.ko] undefined! ERROR: modpost: "class_destroy" [/home/kiki/Desktop/rwProcMem_module/rwProcMem37.ko] undefined! ERROR: modpost: "device_destroy" [/home/kiki/Desktop/rwProcMem_module/rwProcMem37.ko] undefined! ERROR: modpost: "device_create" [/home/kiki/Desktop/rwProcMem_module/rwProcMem37.ko] undefined! ERROR: modpost: "cdev_add" [/home/kiki/Desktop/rwProcMem_module/rwProcMem37.ko] undefined! ERROR: modpost: "cdev_init" [/home/kiki/Desktop/rwProcMem_module/rwProcMem37.ko] undefined! ERROR: modpost: "alloc_chrdev_region" [/home/kiki/Desktop/rwProcMem_module/rwProcMem37.ko] undefined! ERROR: modpost: "unregister_chrdev_region" [/home/kiki/Desktop/rwProcMem_module/rwProcMem37.ko] undefined! ERROR: modpost: "kmem_cache_alloc_trace" [/home/kiki/Desktop/rwProcMem_module/rwProcMem37.ko] undefined! ERROR: modpost: "kmalloc_caches" [/home/kiki/Desktop/rwProcMem_module/rwProcMem37.ko] undefined! ERROR: modpost: "printk" [/home/kiki/Desktop/rwProcMem_module/rwProcMem37.ko] undefined! ERROR: modpost: "__class_create" [/home/kiki/Desktop/rwProcMem_module/rwProcMem37.ko] undefined! make[3]: *** [../scripts/Makefile.modpost:168:/home/kiki/Desktop/rwProcMem_module/Module.symvers] 错误 1 make[3]: *** 正在删除文件“/home/kiki/Desktop/rwProcMem_module/Module.symvers” make[2]: *** [/home/kiki/Desktop/oneplus/Makefile:1850:modules] 错误 2
06-23
### Linux 内核模块编译时出现 modpost 错误的解决方案 当在编译 Linux 内核模块时遇到 `modpost` 未定义符号问题,通常是因为模块之间缺少正确的符号版本信息或符号依赖关系未正确解析。以下是解决此问题的详细方法: #### 确保符号版本信息的传递 从 Linux 内核 2.6.26 版本开始,存在一个已知的问题,即模块加载时无法找到符号版本信息[^1]。为了解决这一问题,需要确保模块编译过程中正确传递了符号版本信息。具体做法是将依赖模块的 `Module.symvers` 文件放置在当前路径下,或者通过 `KBUILD_EXTRA_SYMBOLS` 变量指定其路径。 #### 修改 Makefile 文件 在编译目标模块时,可以通过设置 `KBUILD_EXTRA_SYMBOLS` 来指定符号文件的路径。例如,在模块 `caller` 的 Makefile 中添加以下内容: ```makefile KBUILD_EXTRA_SYMBOLS := /path/to/mod_a/Module.symvers ``` 这里 `/path/to/mod_a/Module.symvers` 是依赖模块 `mod_a` 的符号文件路径。确保路径为绝对路径以避免解析错误。 #### 符号文件搜索路径 内核模块编译时会按照以下顺序搜索 `Module.symvers` 文件: 1. 内核源码路径,例如 `/usr/src/kernels/linux-2.6.28.10`。 2. `M=` 参数指定的路径,等效于变量 `KBUILD_EXTMOD` 的值。 3. `KBUILD_EXTRA_SYMBOLS` 指定的路径。 #### 示例代码:Makefile 配置 以下是一个完整的 Makefile 示例,展示如何配置 `KBUILD_EXTRA_SYMBOLS`: ```makefile obj-m += caller.o KDIR ?= /lib/modules/$(shell uname -r)/build PWD := $(shell pwd) KBUILD_EXTRA_SYMBOLS := /path/to/exporter_1/Module.symvers /path/to/exporter_2/Module.symvers all: $(MAKE) -C $(KDIR) M=$(PWD) modules clean: rm -rf *.o *.ko *.mod.c *.symvers *.order ``` #### 编译与加载模块 完成上述配置后,重新编译模块并加载。例如: ```bash make clean make insmod exporter_1.ko insmod exporter_2.ko insmod caller.ko ``` 如果一切配置正确,模块应能成功加载,并且不会出现 `no symbol version for` 的错误[^4]。 #### 解决编译器相关问题 如果问题出现在 macOS 平台上,并且默认编译器为 `clang`,可能会导致未定义符号问题。可以尝试切换到 `gcc` 编译器。具体步骤如下: 1. 安装最新版本的 `gcc`: ```bash brew install gcc ``` 2. 在 `.bash_profile` 文件中设置别名: ```bash alias gcc=/usr/local/bin/gcc-9 alias cc=/usr/local/bin/gcc-9 alias g++=/usr/local/bin/g++-9 alias c++=/usr/local/bin/c++-9 ``` 3. 重新加载配置文件并测试: ```bash source ~/.bash_profile gcc --version ``` #### 注意事项 - 确保所有依赖模块均已正确加载,否则目标模块可能因符号未解析而失败。 - 如果使用的是交叉编译环境,请确保工具链支持正确的符号解析。 --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值