【问题标题】:Hello world kernel module for android & unknown relocation: 27 when insmod用于 android 和未知重定位的 Hello world 内核模块:insmod 时为 27
【发布时间】:2013-01-25 10:51:59
【问题描述】:

我正在尝试创建一个简单的内核模块。 我正在尝试将消息打印到 dmesg,但我不断收到

insmod: init_module 'hello.ko' 在 android 中失败(执行格式错误)

之后: dmesg: 未知搬迁:27

#include <linux/module.h>
#include <linux/kdb.h>
int init_module(void)
{
    printk(KERN_ALERT "Hello world!\n");
    return 1;
}

void cleanup_module(void)
{
    printk(KERN_INFO "Goodbye world 1.\n");
}
MODULE_AUTHOR("Robert P. J. Day");
MODULE_LICENSE("Dual BSD/GPL");
MODULE_VERSION("2:1.0") ;
MODULE_DESCRIPTION("You have to start somewhere.");

制作文件

    obj-m +=hello.o


KERNELDIR ?= ~/android/kernel/common
#KERNELDIR ?= /lib/modules/$(shell uname -r)/build
PWD := $(shell pwd)
CROSS_COMPILE=~/android-ndk-r8/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-

ARCH=arm
default:
$(MAKE) -C $(KERNELDIR) M=$(PWD) ARCH=arm CROSS_COMPILE=$(CROSS_COMPILE) modules

clean:
$(MAKE) -C $(KERNELDIR) M=$(PWD) clean
rm *.symvers

有人知道为什么吗?以及如何让它发挥作用?

我做了一个 readelf 后发现,当它被编译时,重定位部分指向错误的方向。

Offset     Info    Type            Sym.Value  Sym. Name
00000008  0000171b R_ARM_PLT32       00000000   printk

实际上应该是:

Offset     Info    Type            Sym.Value  Sym. Name
00000008  0000171c R_ARM_CALL       00000000   printk

有人能猜到/知道这是怎么回事吗? 感谢@Chris Stratton 对我的帮助。


我做了一个 readelf 后发现,当它被编译时,重定位部分指向错误的方向。

Offset     Info    Type            Sym.Value  Sym. Name
00000008  0000171b R_ARM_PLT32       00000000   printk

实际上应该是:

Offset     Info    Type            Sym.Value  Sym. Name
00000008  0000171c R_ARM_CALL       00000000   printk

有人能猜到/知道这是怎么回事吗?感谢@Chris Stratton 对我的帮助。

【问题讨论】:

  • 可能是构建系统问题。您确定可以将 ndk 工具链用于内核吗?我的回忆是你过去不能,但也许这已经改变了。将您的模块与您可以找到的任何工作模块进行 objdump/readelf 比较可能是值得的,并查看重定位的类型。
  • 我认为我们已经领先了。我在执行 readelf 时发现的区别是,正在运行的模块的标志是“0x5000000,版本 5 EABI”,而我的模块的标志是“0x4000000,版本 4 EABI”。这有什么影响吗?我找不到任何地方可以改变它。我正在寻找它。如果有人知道,请告诉我。
  • 似乎 EABI 是向后兼容的,所以我有一段时间走错了方向。
  • 现在我发现在我的 hello world 模块重定位部分中偏移量 0x6b8 处的“.rel.text”包含 4 个条目:偏移量信息类型 Sym.Value Sym。名称 00000008 0000211b R_ARM_PLT32 00000000 printk 而在 wifimodule 中 00001c4c 000d421c R_ARM_CALL 00000000 printk
  • 是的,这是错误的重定位。如果我通过十六进制编辑器将十六进制从 R_ARM_PLT32(1B) 更改为 R_ARM_CALL(1C),它会在另一个重定位错误中停止。有人能猜出我可能做错了什么导致错误的重定位吗?

标签: android module linux-kernel kernel kernel-module


【解决方案1】:

原来我不得不使用

make CFLAGS_MODULE=-fno-pic

【讨论】:

    【解决方案2】:

    谢谢,-fno-pic 让我的 dlkm 也能正常工作。开始“真正的”工作......

    顺便说一句,您可以在 shell 中导出 ARCH、SUBARCH、CROSS_COMPILE、KERNELDIR,因此 Makefile 变得非常简单。这还允许通过正确设置 KERNELDIR 更轻松地为本机或目标平台构建 dlkm(本机不需要 ARCH、SUBARCH 或 CROSS_COMPILE 变量。)

    obj-m += hello.o

    全部: 制作 -C $(KERNELDIR) M=$(PWD) 模块

    【讨论】:

      猜你喜欢
      • 2018-12-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-03-28
      • 2012-02-16
      • 2023-04-11
      • 2017-06-17
      • 1970-01-01
      相关资源
      最近更新 更多