【问题标题】:How to builld OS/ABI for SystemV using crosstool-ng如何使用 crosstool-ng 为系统构建 OS/ABI
【发布时间】:2017-09-16 21:45:10
【问题描述】:

我正在尝试为我的DNS-320L NAS 构建一个内核模块。

我已经在 Debian lenny chroot 环境中构建了 crosstool-ng,但是在我编译了我的内核模块并尝试安装它之后,我得到:

insmod: error inserting 'kernel/net/ip4/ipip.ko': -1 Invalid module format

当我使用 readelf 检查一个工作内核模块时,我得到:

~/ct-ng-build$ readelf -h ~/ct-ng-build/kernel/orig/ipip.ko 
ELF Header:
  Magic:   7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00 
  Class:                             ELF32
  Data:                              2's complement, little endian
  Version:                           1 (current)
  OS/ABI:                            UNIX - System V
  ABI Version:                       0
  Type:                              REL (Relocatable file)
  Machine:                           ARM
  Version:                           0x1
  Entry point address:               0x0
  Start of program headers:          0 (bytes into file)
  Start of section headers:          6696 (bytes into file)
  Flags:                             0x5000000, Version5 EABI
  Size of this header:               52 (bytes)
  Size of program headers:           0 (bytes)
  Number of program headers:         0
  Size of section headers:           40 (bytes)
  Number of section headers:         51

但我的模块有一些不同之处:

~/ct-ng-build$ readelf -h ~/ct-ng-build/kernel/modules/lib/modules/2.6.31.8/kernel/net/ipv4/ipip.ko 
ELF Header:
  Magic:   7f 45 4c 46 01 01 01 61 00 00 00 00 00 00 00 00 
  Class:                             ELF32
  Data:                              2's complement, little endian
  Version:                           1 (current)
  OS/ABI:                            ARM
  ABI Version:                       0
  Type:                              REL (Relocatable file)
  Machine:                           ARM
  Version:                           0x1
  Entry point address:               0x0
  Start of program headers:          0 (bytes into file)
  Start of section headers:          6280 (bytes into file)
  Flags:                             0x600, GNU EABI, software FP, VFP
  Size of this header:               52 (bytes)
  Size of program headers:           0 (bytes)
  Number of program headers:         0
  Size of section headers:           40 (bytes)
  Number of section headers:         23
  Section header string table index: 20

我的cross_compile环境是:

$ echo $CROSS_COMPILE 
arm-none-eabi-


make CROSS_COMPILE=${CROSS_COMPILE} INSTALL_PATH=~/ct-ng-build/kernel/install INSTALL_MOD_PATH=~/ct-ng-build/kernel/modules INSTALL_FW_PATH=~/ct-ng-build/kernel/firmware

我的 gcc 编译好了:

$  ${CROSS_COMPILE}gcc -v
Using built-in specs.
Target: arm-none-eabi
Configured with: ~/ct-ng-build/targets/src/gcc-4.3.2/configure --build=x86_64-build_unknown-linux-gnu --host=x86_64-build_unknown-linux-gnu --target=arm-none-eabi --prefix=~/x-tools/arm-none-eabi --with-local-prefix=~/x-tools/arm-none-eabi/arm-none-eabi//sys-root --disable-multilib --disable-libmudflap --with-sysroot=~/x-tools/arm-none-eabi/arm-none-eabi//sys-root --with-newlib --enable-threads=no --disable-shared --with-pkgversion=crosstool-NG-1.9.0 --with-arch=armv5te --with-tune=arm926ej-s --disable-__cxa_atexit --with-gmp=~/ct-ng-build/targets/arm-none-eabi/build/static --with-mpfr=~/ct-ng-build/targets/arm-none-eabi/build/static --enable-target-optspace --disable-nls --enable-symvers=gnu --enable-languages=c,c++
Thread model: single
gcc version 4.3.2 (crosstool-NG-1.9.0)

任何想法如何将 OS/ABI 设置为“UNIX - System V”并将标志设置为“0x5000000,Version5 EABI”而不是“Arm”和“0x600,GNU EABI,软件 FP,VFP”?

还是有其他问题?

谢谢!

--- 编辑 ---- 我专门尝试针对我现有的 NAS 操作系统:

Kernel  2.6.31.8 #1 armv5tel
C library   gcc-4.3-mt-1.44.0 

# /lib/libc-2.8.so 
GNU C Library stable release version 2.8, by Roland McGrath et al.
Copyright (C) 2008 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.
There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A
PARTICULAR PURPOSE.
Compiled by GNU CC version 4.3.2.

到目前为止,我只能使用 crosstool-ng-1.9.0 构建一个 crosstool-ng 环境,但它生成了上面的二进制文件。

我尝试按照 3.17.2 ARM Options 设置 -mabi=apcs-gnu,但 C 库无法编译并出现奇怪的“缺少标头”错误(我可能会再试一次 - 可能与我的 chroot 环境有关)。

【问题讨论】:

  • 原始工具链是使用特定版本的 crosstool-NG 构建的,并不意味着您必须这样做。您确实希望匹配目标的 C 库类型(例如 glibc 或 uClibc)和版本号,并使用相同内核版本的内核头文件。工具链组件的版本号可能有一些余地,例如gcc 编译器和 binutils,但 crosstool-NG 应该允许你指定你想要的版本,只要你在那个时间段内不会太旧或太新。
  • 我已经尝试编译 crosstool-ng-13.2,但它无法编译 gcc 4.3.2 和 gcc 4.3.3 共享编译器(以及最终编译器)。我将再次尝试编译 19.0。 (之前编译过——至少ct-ng构建过程保留了x-tools目标目录下的日志和配置)。
  • 您需要仔细检查您的工具链是否真的适用于 EABI,而不是 OABI。我为内核模块做了类似的readelf,它产生了与您的“工作内核模块”基本相同的结果。我生成该模块的工具链是用于 EABI。 IOW 我的回答是倒退的,stackoverflow.com/questions/10780648/… 似乎证实了这一点。但是您的工具链前缀 arm-none-eabi- 与它是 OABI 的想法相矛盾。
  • 我已恢复为针对“arm-none-linux-gnu”的 crosstool-NG-1.9.0(根据上面的 eabi 工具链),但它现在无法编译工具链!我在 C 库中收到“内部编译器错误”。我将从新的 tarball 源和新的 1.9.0 arm-none-linux 示例配置中再次尝试。

标签: arm linux-device-driver cross-compiling nas


【解决方案1】:

使用 crosstool-NG 构建新的工具链,但将其配置为 OABI 而不是 EABI。
Configuring crosstool-NG

直到并包括 Lenny 在内的所有 debian 版本(用于 ARM)都是 OABI。

参考:https://wiki.embeddedarm.com/wiki/EABI_vs_OABI

即使您的工具链前缀是 arm-none-eabi-,它生成的二进制文件看起来也像 OABI。
我有 OABI 二进制文件产生相同的readelf 输出,以及 EABI 二进制文件具有与您想要的相同的readelf 输出(“UNIX - System V”)。

question 描述了与您的情况类似但相反的情况,即他的工具链正在生成 EABI 二进制文件,但他需要 OABI。

显然您的工具链是为生成 OABI 而构建的,但使用了误导性前缀。
您需要使用 crosstool-NG 构建一个新的工具链,但将其配置为 EABI 而不是 OABI。
除非启用Use obsolete features,否则较新版本的 crosstool-NG 实际上会强制选择 EABI,从而使 OABI 的配置变得困难。


附录

您说“但是为 OABI 而不是 EABI 配置它。”但是如何配置呢?

使用 crosstool-NG v1.18 安装,我可以指定 & 构建
* Linux 内核版本 2.6.31.14,
* gcc 版本 4.3.2,
* binutils 版本 2.18a 2.19.1a,
* glibc 2.8 版。

为了取消选择Target options ---> Use EABI(取消选择意味着使用OABI),
我首先要选择Paths and misc options ---> Use obsolete features

在这个版本的 crosstool-NG 中,Use EABI 被自动选中。


Use EABI 菜单项的描述有:

Set up the toolchain so that it generates EABI-compliant binaries.

If you say 'n' here, then the toolchain will generate OABI binaries.
OABI has long been deprecated, and is now considered legacy.

由于 OABI 在此版本的 crosstool-NG 中被认为已弃用,因此配置符号 ARCH_ARM_EABI_FORCE 处于活动状态,除非指定了 Use obsolete features

【讨论】:

  • 我现在正在尝试 crosstool-ng 1.4。您说“但是为 OABI 而不是 EABI 配置它。”但是如何?我唯一的 EABI 选项是一个复选框,它定义了“# CT_ARCH_ARM_EABI is not set”或“CT_ARCH_ARM_EABI=y”
  • “我正在尝试 crosstool-ng 1.4” -- 那不是一个相当旧的版本吗?好像您正在尝试直接编辑 .config 文件。你为什么不使用menuconfig?见Configuring crosstool-NG
  • 很抱歉给您带来了错误的印象——我一直在使用 menuconfig 但我找不到任何 OABI 的设置。我正在尝试 v1.4,因为它是用于构建现有内核的版本(“Linux 版本 2.6.31.8 (jack@swtest6) (gcc 版本 4.3.2 (sdk3.3-ct-ng-1.4.1) ) # 2012 年 8 月 22 日星期三 16:55:05 CST")。
  • 好吧,如果您现有的工具链是使用“CT_ARCH_ARM_EABI=y”构建的,那么您想要反之,“# CT_ARCH_ARM_EABI is not set”。
  • 目前我什至无法构建 CT 工具链。还在尝试,见上面的 cmets。
【解决方案2】:

我在这里提取一些最终的 cmets:

正如@sawdust 建议的那样,我在以下 CT-NG 环境中使用 EABI:

crosstool-NG version: 1.9.0
gcc 4.3.2
binutils 2.19.1
libc 2.8
gmp 4.3.2
mpfr 2.4.2

为了让 GCC 编译器能够编译, 我不得不做一些 hack! 即:

  • targets/src/glibc-2.8/nscd 中删除res_hconf.c(一次,在提取源之后)
  • nscd/Makefile 中的对象列表中删除res_hconf
  • ~/x-tools/arm-unknown-linux-gnueabi/arm-unknown-linux-gnueabi//sys-root/usr/include/gnu 中创建一个从stubs-.hstubs-32.h 的软链接(在构建开始之后)。

我只需要下载正确的 Linux 内核并安装它。缺少的命令是:

make ARCH=arm kirkwood_defconfig

此后我只需要使用make ARCH=arm menuconfig 来定制东西。

gcc -v 说:

Using built-in specs.
Target: arm-unknown-linux-gnueabi
Configured with: ~/ct-ng-build/targets/src/gcc-4.3.2/configure --build=x86_64-build_unknown-linux-gnu --host=x86_64-build_unknown-linux-gnu --target=arm-unknown-linux-gnueabi --prefix=~/x-tools/arm-unknown-linux-gnueabi --with-sysroot=~/x-tools/arm-unknown-linux-gnueabi/arm-unknown-linux-gnueabi//sys-root --enable-languages=c,c++ --disable-multilib --with-arch=armv5te --with-tune=arm926ej-s --with-float=soft --disable-shared --with-pkgversion=crosstool-NG-1.9.0 --disable-sjlj-exceptions --enable-__cxa_atexit --disable-libmudflap --disable-libgomp --disable-libssp --with-gmp=~/ct-ng-build/targets/arm-unknown-linux-gnueabi/build/static --with-mpfr=~/ct-ng-build/targets/arm-unknown-linux-gnueabi/build/static --enable-threads=posix --enable-target-optspace --with-local-prefix=~/x-tools/arm-unknown-linux-gnueabi/arm-unknown-linux-gnueabi//sys-root --disable-nls --enable-symvers=gnu --enable-c99 --enable-long-long
Thread model: posix
gcc version 4.3.2 (crosstool-NG-1.9.0) 

最后,为了生成 SYSV 模块,我不得不破解内核 arch/arm/Makefile 以从 EABI 部分中删除 -mabi=aapcs-linux 设置。

现在错误是:

"modprobe: can't load module ntfs (kernel/fs/ntfs/ntfs.ko): unknown symbol in module, or unknown parameter

这是另一个问题:D

我仍然无法构建一个可以工作的内核模块(可能因为黑客!)但也可能是因为我没有兼容的内核 .config NAS。

最后的改动是:

  • 不使用展开
  • 禁用某些内核调试和跟踪
  • 使用 SLAB 代替 SLUB

通过跟踪 dmsg 消息选择更改。

现在可以加载生成的编译内核模块,前提是它们与编译内核兼容。

(警告说明:当我开始添加iptables 模块时,我遇到了一点麻烦,因为我的网络连接被锁定了!小心!幸运的是,这些模块在重新启动时没有重新加载。)强>

【讨论】:

  • "但也可能是因为我没有兼容 NAS 的内核 .config" -- 并不是我做过类似的事情,但我是给人的印象是 System.map 文件很突出。
  • 实际上,我的构建不会生成 System.map(因此它也不会生成 modules.dep。我从其他地方复制了一个)。
  • 在这种情况下,dmesg 提供了所有线索。比如满足各种缺失符号后(不强制展开等):“ieee80211_crypt_tkip: Unknown symbol wireless_send_event”
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-08-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多