明日にはでっかい太陽が昇るかもしれません。

「覚悟」とは!! 暗闇の荒野に!!進むべき道を切り開く事だッ!

U-Boot (aarch64) on Qemu を動作させたい (9)

github.com

結論からいうと、公式の 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 にアップしておく。

github.com