春雨日記 about me tags

G-cluster向けにbusyboxをクロスコンパイルしたメモ

はじめに

G-cluster向けのinitramfsを作ってみようとbusyboxのクロスコンパイルを試みたのですが、いつも使っているクロスコンパイラ(arm-gnu-toolchain-13.2.rel1-x86_64-arm-none-linux-gnueabihf.tar.xz)でうまくビルドできませんでした。

だいぶ時間がかかってしまったので次の被害者を減らすべくメモっておきます。

G-clusterのCPUはARM1176JZFarmv6kzです。1(正直よくわからない)

結論

armv6では、arm-none-linux-gnueabihfなコンパイラを使用してはいけません。

linuxかつsoftfloatな物を選択してください。hardfloatがあるとダメです。

それだけ書いても必要な人の検索にはかからないと思うので以下に失敗を書いておきます。

失敗1: SIGILL

普通にいつものクロスコンパイラでコンパイルするとこのようになります

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
user@debian:~/bb$ export ARCH=arm
user@debian:~/bb$ export CROSS_COMPILE=~/arm-gnu-toolchain-13.2.Rel1-x86_64-arm-none-linux-gnueabihf/bin/arm-none-linux-gnueabihf-
user@debian:~/bb$ make defconfig
user@debian:~/bb$ make menuconfig
# ここでSettings  ---> -- Build Options > 
# Build static binary (no shared libs)を有効化(static link)
user@debian:~/bb$ make -j4

(中略)

Static linking against glibc, can't use --gc-sections
Trying libraries: crypt m resolv rt
 Library crypt is not needed, excluding it
 Library m is needed, can't exclude it (yet)
 Library resolv is needed, can't exclude it (yet)
 Library rt is not needed, excluding it
 Library m is needed, can't exclude it (yet)
 Library resolv is needed, can't exclude it (yet)
Final link with: m resolv

一見正常にコンパイルできたように見えます。

それでは起動してみましょう。ちなみに、起動の際は 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から起動できるようになればカーネルモジュールのチェックなどもステートレスにできるはずなので、完成に一歩近づきました。