如何使用 crosstool-ng 为系统构建 OS/ABI
How to builld OS/ABI for SystemV using crosstool-ng
我正在尝试为我的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 OS:
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 库无法编译并出现奇怪的 "missing headers" 错误(我可能会再试一次 - 可能与我的 chroot 环境有关)。
使用 crosstool-NG 构建新的工具链,但针对 OABI 而不是 EABI 配置它。
参见 Configuring crosstool-NG。
All debian releases (for ARM) upto and including Lenny were OABI.
参考:https://wiki.embeddedarm.com/wiki/EABI_vs_OABI
即使您的工具链前缀是 arm-none-eabi-
,它生成的二进制文件看起来也像 OABI。
我有产生相同 readelf
输出的 OABI 二进制文件,以及具有与您想要的相同 readelf
输出 ("UNIX - System V") 的 EABI 二进制文件。
这个 question 描述了一个与您相似但相反的情况,即他的工具链正在生成 EABI 二进制文件,但他需要 OABI。
显然,您的工具链是为生成 OABI 而构建的,但使用了误导性前缀。
您需要使用 crosstool-NG 构建一个新的工具链,但将其配置为 EABI 而不是 OABI。
较新版本的 crosstool-NG 实际上通过强制 selection EABI 使 OABI 的配置变得困难,除非启用 Use obsolete features
。
附录
You say "but configure it for OABI rather than EABI.", but how?
使用crosstool-NG v1.18安装,我可以指定&build
* Linux 内核版本 2.6.31.14,
* gcc 版本 4.3.2,
* binutils 版本 2.18a 2.19.1a,
* glibc 版本 2.8。
为了unselect Target options
---> Use EABI
(unselecting表示使用OABI),
我先得select Paths and misc options
---> Use obsolete features
.
在此版本的 crosstool-NG 中,Use EABI
会自动 selected。
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
指定。
我在这里提取一些最后的评论:
正如@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 编译器进行编译, 我不得不进行一些修改!
即:
- 从
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-.h
创建软 link 到 stubs-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
我仍然无法构建一个可用的内核模块(可能 因为 的 hacks!)但也可能是因为我没有NAS 的兼容内核 .config
。
最后的改动是:
- 不使用展开
- 禁用一些内核调试和跟踪
- 使用 SLAB 代替 SLUB
更改是通过跟踪 dmsg 消息选择的。
现在可以加载生成的编译内核模块,如果它们与编译内核兼容的话。
(警告注意事项:当我开始添加 iptables
模块时遇到了一点麻烦,当时我被锁定在我的网络连接之外!小心!幸运的是模块没有重新加载重启时。)
我正在尝试为我的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 OS:
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 库无法编译并出现奇怪的 "missing headers" 错误(我可能会再试一次 - 可能与我的 chroot 环境有关)。
使用 crosstool-NG 构建新的工具链,但针对 OABI 而不是 EABI 配置它。
参见 Configuring crosstool-NG。
All debian releases (for ARM) upto and including Lenny were OABI.
参考:https://wiki.embeddedarm.com/wiki/EABI_vs_OABI
即使您的工具链前缀是 arm-none-eabi-
,它生成的二进制文件看起来也像 OABI。
我有产生相同 readelf
输出的 OABI 二进制文件,以及具有与您想要的相同 readelf
输出 ("UNIX - System V") 的 EABI 二进制文件。
这个 question 描述了一个与您相似但相反的情况,即他的工具链正在生成 EABI 二进制文件,但他需要 OABI。
显然,您的工具链是为生成 OABI 而构建的,但使用了误导性前缀。
您需要使用 crosstool-NG 构建一个新的工具链,但将其配置为 EABI 而不是 OABI。
较新版本的 crosstool-NG 实际上通过强制 selection EABI 使 OABI 的配置变得困难,除非启用 Use obsolete features
。
附录
You say "but configure it for
OABIrather thanEABI.", but how?
使用crosstool-NG v1.18安装,我可以指定&build
* Linux 内核版本 2.6.31.14,
* gcc 版本 4.3.2,
* binutils 版本 2.18a 2.19.1a,
* glibc 版本 2.8。
为了unselect Target options
---> Use EABI
(unselecting表示使用OABI),
我先得select Paths and misc options
---> Use obsolete features
.
在此版本的 crosstool-NG 中,Use EABI
会自动 selected。
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
指定。
我在这里提取一些最后的评论:
正如@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 编译器进行编译, 我不得不进行一些修改!
即:
- 从
targets/src/glibc-2.8/nscd
中删除res_hconf.c
(一次,在源被提取后) - 从
nscd/Makefile
中的对象列表中删除 - 从
~/x-tools/arm-unknown-linux-gnueabi/arm-unknown-linux-gnueabi//sys-root/usr/include/gnu
中的stubs-.h
创建软 link 到stubs-32.h
(构建开始后)。
res_hconf
我只需要下载正确的 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
我仍然无法构建一个可用的内核模块(可能 因为 的 hacks!)但也可能是因为我没有NAS 的兼容内核 .config
。
最后的改动是:
- 不使用展开
- 禁用一些内核调试和跟踪
- 使用 SLAB 代替 SLUB
更改是通过跟踪 dmsg 消息选择的。
现在可以加载生成的编译内核模块,如果它们与编译内核兼容的话。
(警告注意事项:当我开始添加 iptables
模块时遇到了一点麻烦,当时我被锁定在我的网络连接之外!小心!幸运的是模块没有重新加载重启时。)