U-Boot (aarch64) on Qemu を動作させたい (9)
結論からいうと、公式の U-Boot をターゲット向けビルドのモジュールのまま Qemu 上で起動することができるようになった。
ここでの公式は、オリジナル U-Boot に NXP のカスタマイズが入った今回のターゲットボードである LS1046A RDB 向け U-Boot を指す。
前回 PTE の情報がなにかおかしそう、というところまでわかっていたが、リロケーション前に early_mmu_setup()
の set_ttbr_tcr_mair()
で設定する TCR の値がリロケーション後のメモリマップと合っていないっぽいことがわかった。
get_tcr()
で、メモリマップに定義されたアドレスの最大値からアドレス幅を求めて、 T0SZ の値を出しているのだが、リロケーション前のアドレスマップは LS1046A RDB で定義されている 480 GiB の DDR Region3 領域を使用しないようになっていたため、リロケーション前に設定した TCR (T0SZ) を使用したリロケーション後の PTE アクセスで不整合が発生していたように見える。
なので、リロケーション前のアドレスマップにも DDR Region3 領域を追加すると無事プロンプトが使えるところまで起動させることができるようになった。
... 省略 ... DRAM: Detected UDIMM [1155/19018] 1.9 GiB (DDR4, 32-bit, CL=1, ECC off) Waking secondary cores to start from fbd1f000 Not all cores (0xf) are up (0x1) Did not wake secondary cores Using SERDES1 Protocol: 4403 (0x1133) Using SERDES2 Protocol: 21849 (0x5559) ERROR: Stopped after 0 portals ERROR: Stopped after 0 portals NAND: fsl_ifc_chip_init: address did not match any chip selects 0 MiB MMC: FSL_SDHC: 0 MMC: no card present mmc_init: -123, time 1002 *** Warning - MMC init failed, using default environment EEPROM: wait_for_sr_state: failed sr=a1 cr=f8 state=202 i2c_init_transfer: failed for chip 0x53 retry=0 wait_for_sr_state: failed sr=a1 cr=f8 state=202 i2c_init_transfer: failed for chip 0x53 retry=1 wait_for_sr_state: failed sr=a1 cr=f8 state=202 i2c_init_transfer: failed for chip 0x53 retry=2 i2c_init_transfer: give up i2c_regs=0x2180000 Read failed. In: serial Out: serial Err: serial AHCI 0000.0000 1 slots 1 ports ? Gbps 0x0 impl SATA mode flags: Found 0 device(s). SCSI: Net: MMC read: dev # 0, block # 18432, count 128 ... MMC: no card present mmc_init: -123, time 1001 MMC: block number 0x4880 exceeds max(0x0) Fman1: Data at 00000000fbc25d30 is not a firmware PCIe0: pcie@3400000 Endpoint: no link PCIe1: pcie@3500000 Endpoint: no link PCIe2: pcie@3600000 Endpoint: no link No ethernet found. Hit any key to stop autoboot: 0 => q Unknown command 'q' - try 'help'
だが、 SDHCが未実装だったり、コアが 1 つしか動作していなかったりと、エミュレーションとしては不十分だが、 U-Boot の機能実装に対するテストが行えるようにはなったのではないかと思う。
と、ここまでは NXP の提供する NXP-SDK v2.0 update 17.03 に含まれる U-Boot で確認していたのだが、冒頭のリポジトリの最新コードを使用すると、リロケーション前のアドレスマップに対する修正なしに (Qemu で動かすための修正なしに!) すんなり起動してしまった。。
最新のコードでもアドレスマップに対する変更は入っていないし、(そもそもNXP-SDK v2.0 のコードも実機で動作しているものなのでアドレスマップが間違っているということはないと思うし、) どの差分が影響しているかは追っていないが、実機向けのバイナリがそのまま Qemu で起動できたのはとても嬉しかった。
最終目標は、仕事で使用しているカスタムボードのバイナリを動作させることだが、ベースシステムのバイナリを動作させられたという重要なマイルストーンを達成したので GitHub にアップしておく。