u-bootを使用してARMから起動するビッグエンディアンLinuxビルドをインポートする

u-bootを使用してARMから起動するビッグエンディアンLinuxビルドをインポートする

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カーネルソース/ビルドツリー)からブータブルイメージをビルドしました(mkimageu-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/KconfigA10セクションの最後に次の行を追加しました。

select ARCH_SUPPORTS_BIG_ENDIAN

カーネル自体がCPUをビッグエンディアンモードに切り替えるので、これがビッグエンディアンカーネルを構築して起動するのに十分であることがわかりました。しかし、指示を通してそれを行いますsetend。その範囲は、ユーザー空間ではなくカーネル自体にのみ適用されます(Murray Jensenの回答リンクで説明されています)。

私はこれを試みます:

  • 例外を介してカーネルの圧縮解除器エントリポイントにジャンプするか(失敗した場合)

  • プロセスがビッグエンディアンとして生成されるようにカーネルをパッチします(そこでは地雷原のにおいがしますが…)。

ベストアンサー1

私はまだARMについてよくわかりませんが、これ「CP15システム制御レジスタ(SCR)のEEビットは、例外が発生したときに設定されたエンディアン(つまり、オペレーティングシステム自体のエンディアン)を決定します。...したがって、ロードされたカーネルイメージを例外を通じて何とか供給する必要があるようです。つまり、そのアドレスに直接移動することはできません(U-Bootのように -boot_jump_linux()参照)。これ)。

おすすめ記事