G-cluster向けにbusyboxをクロスコンパイルしたメモ
はじめに
G-cluster向けのinitramfsを作ってみようとbusyboxのクロスコンパイルを試みたのですが、いつも使っているクロスコンパイラ(arm-gnu-toolchain-13.2.rel1-x86_64-arm-none-linux-gnueabihf.tar.xz)でうまくビルドできませんでした。
だいぶ時間がかかってしまったので次の被害者を減らすべくメモっておきます。
G-clusterのCPUはARM1176JZF
のarmv6kz
です。1(正直よくわからない)
結論
armv6では、arm-none-linux-gnueabihf
なコンパイラを使用してはいけません。
linuxかつsoftfloatな物を選択してください。hardfloatがあるとダメです。
それだけ書いても必要な人の検索にはかからないと思うので以下に失敗を書いておきます。
失敗1: SIGILL
普通にいつものクロスコンパイラでコンパイルするとこのようになります
|
|
一見正常にコンパイルできたように見えます。
それでは起動してみましょう。ちなみに、起動の際は https://zenn.dev/miwarin/articles/d2fb1532185891 に倣ってinitramfsを生成しています。
-
U-bootからの起動手順(今後共通)
1 2 3 4 5
loady 0x4800000 # ymodemで転送しているがusb等を使用しても可 env set bootargs root=/dev/ram0 rdinit=/sbin/init initrd=0x4800000,8M nand read 4000000 0x400000 0x800000; bootm ${RAM}
-
結果
Starting kernel ... [ 0.000000] Booting Linux on physical CPU 0x0 [ 0.000000] Linux version 5.15.94-g4114b8015b54 (user@user-VirtualBox) (arm-none-linux-gnueabihf-gcc (Arm GNU Toolchain 12.2.Rel1 (Build arm-12.24)) 12.2.1 20221205, GNU ld (Arm GNU Toolchain 12.2.Rel1 (Build arm-12.24)) 2.39.0.20221210) #1 Wed Feb 15 18:39:45 JST 2023 [ 0.000000] CPU: ARMv6-compatible processor [410fb767] revision 7 (ARMv7), cr=00c5387d [ 0.000000] CPU: VIPT aliasing data cache, VIPT aliasing instruction cache [ 0.000000] OF: fdt: Machine model: Cavium Celestial CNC1800L [ 0.000000] earlycon: uart0 at MMIO 0x801f1000 (options '115200n8') (中略) [ 4.266000] Freeing unused kernel image (initmem) memory: 288K [ 4.272000] Kernel memory protection not selected by kernel config. [ 4.278000] Run /sbin/init as init process [ 4.286000] Kernel panic - not syncing: Attempted to kill init! exitcode=0x00000004 [ 4.286000] CPU: 0 PID: 1 Comm: init Not tainted 5.15.94-g4114b8015b54 #1 [ 4.286000] Hardware name: Cavium Celestial CNC1800L [ 4.286000] Backtrace: [ 4.286000] [<c09ebb74>] (dump_backtrace) from [<c09ebd90>] (show_stack+0x18/0x1c) [ 4.286000] r7:00000000 r6:c0b3bda8 r5:00000000 r4:c0b4c850 [ 4.286000] [<c09ebd78>] (show_stack) from [<c09f0970>] (dump_stack+0x28/0x30) [ 4.286000] [<c09f0948>] (dump_stack) from [<c09ec0b4>] (panic+0xf4/0x30c) [ 4.286000] r5:00000000 r4:c0dad2e8 [ 4.286000] [<c09ebfc0>] (panic) from [<c002debc>] (do_exit+0x870/0x908) [ 4.286000] r3:c10b2000 r2:00000000 r1:00000004 r0:c0b3bda8 [ 4.286000] r7:00000000 [ 4.286000] [<c002d64c>] (do_exit) from [<c002edc4>] (do_group_exit+0x44/0xac) [ 4.286000] r7:00000048 [ 4.286000] [<c002ed80>] (do_group_exit) from [<c003c808>] (get_signal+0x1b0/0x95c) [ 4.286000] r5:c1099f44 r4:c1098000 [ 4.286000] [<c003c658>] (get_signal) from [<c0012dd4>] (do_work_pending+0x114/0x574) [ 4.286000] r10:00000000 r9:c1098000 r8:c1099f44 r7:00000000 r6:00000000 r5:c1099fb0 [ 4.286000] r4:c1098000 [ 4.286000] [<c0012cc0>] (do_work_pending) from [<c00082e0>] (slow_work_pending+0xc/0x20) [ 4.286000] Exception stack(0xc1099fb0 to 0xc1099ff8) [ 4.286000] 9fa0: 00000000 001495a6 beec0ef4 00164137 [ 4.286000] 9fc0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 [ 4.286000] 9fe0: 00000000 beec0e5c 00110855 0003ee04 60000030 ffffffff [ 4.286000] r10:00000000 r9:c1098000 r8:00000000 r7:00c5387d r6:ffffffff r5:60000030 [ 4.286000] r4:0003ee04 [ 4.286000] ---[ end Kernel panic - not syncing: Attempted to kill init! exitcode=0x00000004 ]---
カーネルパニックになってしまいました。
exitcode=0x00000004
との事ですが、これはSIGILL
です。2
SIGILLといえば Illegal Instruction の意味であり、CPUが非対応の命令を使用していた事がわかります。
おそらく、どこでもarmv6と指定していないためarmv7用のコードが生成されていたと考えられます。
それでは、armv6kzと指定してコンパイルしてみましょう。
失敗2: sorry, unimplemented: Thumb-1 ‘hard-float’ VFP ABI
CPUの指定は、menuconfigの
Settings ---> -- Build Options > Additional CFLAGS
に直接書く事で行うようです。
-march=armv6kz
でarmv6kzを指定してみます。
するとmake
で以下のエラーが出ました。
In file included from /home/user/arm-gnu-toolchain-13.2.Rel1-x86_64-arm-none-linux-gnueabihf/arm-none-linux-gnueabihf/libc/usr/include/byteswap.h:25,
from include/platform.h:168,
from include/libbb.h:13,
from include/busybox.h:8,
from applets/applets.c:9:
/home/user/arm-gnu-toolchain-13.2.Rel1-x86_64-arm-none-linux-gnueabihf/arm-none-linux-gnueabihf/libc/usr/include/bits/byteswap.h: In function ‘__bswap_16’:
/home/user/arm-gnu-toolchain-13.2.Rel1-x86_64-arm-none-linux-gnueabihf/arm-none-linux-gnueabihf/libc/usr/include/bits/byteswap.h:35:1: sorry, unimplemented: Thumb-1 ‘hard-float’ VFP ABI
35 | {
| ^
make[1]: *** [scripts/Makefile.build:198: applets/applets.o] Error 1
make: *** [Makefile:372: applets_dir] Error 2
調べた結果、armv6ではthumb命令セットかつvfpで使用できないようです。
arm命令セットではどうか-march=armv6kz -marm
で検証した所、ビルドは通るもののSIGILLでpanicしてしまいました。
つまり、armv6ではfpuを使用できないようです。
ではsoftfloatでやってみます…
失敗3: fatal error: gnu/stubs-soft.h: No such file or directory
-march=armv6kz -mfloat-abi=soft
でsoftfloatにしてみました。
make
結果
CC applets/applets.o
In file included from /home/user/arm-gnu-toolchain-13.2.Rel1-x86_64-arm-none-linux-gnueabihf/arm-none-linux-gnueabihf/libc/usr/include/features.h:527,
from /home/user/arm-gnu-toolchain-13.2.Rel1-x86_64-arm-none-linux-gnueabihf/arm-none-linux-gnueabihf/libc/usr/include/bits/libc-header-start.h:33,
from /home/user/arm-gnu-toolchain-13.2.Rel1-x86_64-arm-none-linux-gnueabihf/arm-none-linux-gnueabihf/libc/usr/include/limits.h:26,
from /home/user/arm-gnu-toolchain-13.2.Rel1-x86_64-arm-none-linux-gnueabihf/lib/gcc/arm-none-linux-gnueabihf/13.2.1/include/limits.h:205,
from /home/user/arm-gnu-toolchain-13.2.Rel1-x86_64-arm-none-linux-gnueabihf/lib/gcc/arm-none-linux-gnueabihf/13.2.1/include/syslimits.h:7,
from /home/user/arm-gnu-toolchain-13.2.Rel1-x86_64-arm-none-linux-gnueabihf/lib/gcc/arm-none-linux-gnueabihf/13.2.1/include/limits.h:34,
from include/platform.h:157,
from include/libbb.h:13,
from include/busybox.h:8,
from applets/applets.c:9:
/home/user/arm-gnu-toolchain-13.2.Rel1-x86_64-arm-none-linux-gnueabihf/arm-none-linux-gnueabihf/libc/usr/include/gnu/stubs.h:7:11: fatal error: gnu/stubs-soft.h: No such file or directory
7 | # include <gnu/stubs-soft.h>
| ^~~~~~~~~~~~~~~~~~
compilation terminated.
make[1]: *** [scripts/Makefile.build:198: applets/applets.o] Error 1
make: *** [Makefile:372: applets_dir] Error 2
gnu/stubs-soft.h: No such file or directory
がでました。クロスコンパイラのディレクトリを探してみたのですが、stub.h
でincludeしてあるにもかかわらず、そもそも内臓されていないようです。
調べてみましたが
- Armの
13.2.Rel1
- Armの
12.2.Rel1
- linaroの
7.5
のgnueabihfコンパイラには含まれていませんでした。
成功
softfloatを使用するならばhfでないコンパイラを使用する方が良いのかと、gcc-arm-linux-gnueabi
を用いてmakeした所、無事に動作しました。
[ 4.308000] cfg80211: failed to load regulatory.db
[ 4.316000] Freeing unused kernel image (initmem) memory: 288K
[ 4.322000] Kernel memory protection not selected by kernel config.
[ 4.328000] Run /sbin/init as init process
mount: mounting /dev/pts on /dev/pts failed: No such file or directory
Please press Enter to activate this console.
~ #
ただ近年armelのサポートが大幅に少なくなっており、linuxかつsoftfloatなコンパイラがArmのサイトから無くなっていたりしています。
私が使用したdebianのgcc-arm-linux-gnueabi
はgcc 12.2.0でlinuxかつsoftfloatな数少ない選択肢ですが、linaroの7.5などでも動作すると思います。
終わりに
実は今G-clusterの自動検証システムをRustで実装している所で、YMODEMを用いてカーネルを起動させるところまで完成しております。
initramfsから起動できるようになればカーネルモジュールのチェックなどもステートレスにできるはずなので、完成に一歩近づきました。