
ARM用のビッグエンディアンLinuxディストリビューションを作成しようとしています。私はGentooを使用しているので、クロスコンパイルはこれより簡単ではありません。私はこれらすべてを構築しましたが、カーネルの起動に停止しました。
私の目標は、AllWinner A10 CPUを搭載したCubieboardです。私はu-bootをブートローダーとして使用します。 u-bootはビッグエンディアンARMをサポートしていないため、コントロールをカーネルに渡す前にパッチを適用しました。
diff -Naur u-boot-2016.01-1/arch/arm/lib/bootm.c u-boot-2016.01-2/arch/arm/lib/bootm.c
--- u-boot-2016.01-1/arch/arm/lib/bootm.c 2016-01-12 15:06:54.000000000 +0100
+++ u-boot-2016.01-2/arch/arm/lib/bootm.c 2017-07-09 14:13:29.675865446 +0200
@@ -315,7 +315,16 @@
0, machid, r2);
} else
#endif
+ {
+ {
+ unsigned long v;
+ __asm volatile ("mrc p15, 0, %0, c1, c0, 0\n\t"
+ "orr %0, %0, #(1 << 7)\n\t" /* Switch to bigendian */
+ "mcr p15, 0, %0, c1, c0, 0" : "=&r" (v));
+ }
+
kernel_entry(0, machid, r2);
+ }
}
#endif
}
最初はいくつかの異なる構文を使用しましたが、最終的にはAPEXブートローダ(arm-kernel-shim)で動作することが知られているコードを使用しました。 (それにもかかわらず、レジスタは私が持っているものとARMドキュメントから読み取ったものと同じです。)
また、u-bootにはリトルエンディアンバイトシーケンスが必要なので、これには別のツールチェーンtargetを用意しましたarm-linux-gnueabihf
。私が知る限り、u-boot自体は正常に起動します。
(メインライン)カーネルはターゲットのツールチェーンを使用してコンパイルされますarmeb-linux-gnueabihf
。コンパイルされたイメージ(arch/arm/boot/Image
カーネルソース/ビルドツリー)からブータブルイメージをビルドしました(mkimage
u-bootビルドを使用)。
mkimage -C none -A arm -T kernel -n Linux-4.9.9-gentoo -d /usr/armeb-linux-gnueabihf/usr/src/linux/arch/arm/boot/Image -ep 0x48000000 -a 0x48000000 /usr/armeb-linux-gnueabihf/boot/uimage
また、カーネルからDTBファイルを取得しました。
cp /usr/armeb-linux-gnueabihf/usr/src/linux/arch/arm/boot/dts/sun4i-a10-cubieboard.dtb /usr/armeb-linux-gnueabihf/boot/
すべてをµSDカードにロードして起動しようとすると、シリアルコンソールに次の出力が表示されます。
U-Boot SPL 2016.01 (Jul 16 2017 - 13:52:00)
DRAM: 1024 MiB
CPU: 1008000000Hz, AXI/AHB/APB: 3/2/2
Trying to boot from MMC
U-Boot 2016.01 (Jul 16 2017 - 13:52:00 +0200) Allwinner Technology
CPU: Allwinner A10 (SUN4I)
I2C: ready
DRAM: 1 GiB
MMC: SUNXI SD/MMC: 0
In: serial
Out: serial
Err: serial
SCSI: SUNXI SCSI INIT
SATA link 0 timeout.
AHCI 0001.0100 32 slots 1 ports 3 Gbps 0x1 impl SATA mode
flags: ncq stag pm led clo only pmp pio slum part ccc apst
Net: eth0: ethernet@01c0b000
starting USB...
USB0: USB EHCI 1.00
USB1: USB OHCI 1.0
USB2: USB EHCI 1.00
USB3: USB OHCI 1.0
scanning bus 0 for devices... 1 USB Device(s) found
scanning bus 2 for devices... 1 USB Device(s) found
Hit any key to stop autoboot: 0
=> setenv bootargs console=tty0 console=ttyS0,115200 earlyprintk hdmi.audio=EDID:0 disp.screen0_output_mode=EDID:1280x800p60 root=PARTUUID=AC9D6C6F-01 rootwait panic=10
=> ext2load mmc 0 0x48000000 boot/uimage
5025856 bytes read in 592 ms (8.1 MiB/s)
=> ext2load mmc 0 0x51000000 boot/sun4i-a10-cubieboard.dtb
28542 bytes read in 237 ms (117.2 KiB/s)
=> bootm 0x48000000 - 0x51000000
## Booting kernel from Legacy Image at 48000000 ...
Image Name: Linux-4.9.9-gentoo
Image Type: ARM Linux Kernel Image (uncompressed)
Data Size: 5025792 Bytes = 4.8 MiB
Load Address: 48000000
Entry Point: 48000000
Verifying Checksum ... OK
## Flattened Device Tree blob at 51000000
Booting using the fdt blob at 0x51000000
Loading Kernel Image ... OK
Loading Device Tree to 49ff6000, end 49ffff7d ... OK
Starting kernel ...
進行もなく、出力もなく、何もありません。私の質問はここでどのように行くことができるかということです。私が何かを逃しているのでしょうか、何か間違っているのでしょうか(または何かをしていないのでしょうか)?
私も成功せずにいくつか試してみました。
APEXと同様に、カーネルイメージの単語交換(
undefined instruction
起動時に発生)圧縮カーネルイメージを使用して、
FDTの代わりに従来のFEXファイルを使用してください。
2017/07/21アップデート:トラブルシューティングに部分的に成功しました。 Tom Riniのコメントからヒントを得て、zImageをuImageにパッケージ化してカーネルを起動可能にしました。 initプログラム(簡単なHello WorldコンパイルされたBEまたはLE)をカスタマイズすることで、Tom Riniのもう1つの疑いを確認しました。もともとカーネルはビッグエンディアンではなくリトルエンディアンでした。この問題を解決するために、カーネルの上部に次の2行を追加しました.config
。
CONFIG_ARCH_SUPPORTS_BIG_ENDIAN=y
CONFIG_CPU_BIG_ENDIAN=y
私のインスピレーションは以下から来ていますNvidia Jetson TK1の使い方。また、arch/arm/mach-sunxi/Kconfig
A10セクションの最後に次の行を追加しました。
select ARCH_SUPPORTS_BIG_ENDIAN
カーネル自体がCPUをビッグエンディアンモードに切り替えるので、これがビッグエンディアンカーネルを構築して起動するのに十分であることがわかりました。しかし、指示を通してそれを行いますsetend
。その範囲は、ユーザー空間ではなくカーネル自体にのみ適用されます(Murray Jensenの回答リンクで説明されています)。
私はこれを試みます:
例外を介してカーネルの圧縮解除器エントリポイントにジャンプするか(失敗した場合)
プロセスがビッグエンディアンとして生成されるようにカーネルをパッチします(そこでは地雷原のにおいがしますが…)。