opensbi icon indicating copy to clipboard operation
opensbi copied to clipboard

How to calculate correct FW_JUMP_FDT_ADDR?

Open gsomlo opened this issue 1 year ago • 2 comments

For (at least) the generic platform, FW_JUMP_FDT_ADDR defaults to 0x0x82200000: https://github.com/riscv-software-src/opensbi/blob/master/platform/generic/objects.mk#L35

The recommended "algorithm" to determine if that's enough, shown in docs/firmware/fw_jump.md: https://github.com/riscv-software-src/opensbi/blob/master/platform/generic/objects.mk#L35 seems broken/insufficient in my case.

I have built a 6.3.0-rc1+ kernel with Fedora's default config file at: http://fedora.riscv.rocks:3000/rpms/kernel/src/branch/f37-riscv64/kernel-riscv64-fedora.config

Running the test on the resulting vmlinux file produces:

$ objdump -h linux/vmlinux | sort -k 5,5 | awk -n '/^ +[0-9]+ /{addr="0x"$3; size="0x"$5; printf "0x""%x\n",addr+size}' | tail -1
0x216ea20

which is clearly less than 0x2200000.

I built opensbi with (DTS source: nexys_video_fed.dts):

make CROSS_COMPILE=riscv64-unknown-linux-gnu- PLATFORM=generic FW_FDT_PATH=~/DTS/nexys_video_fed.dtb

I'm loading:

  • fw_jump.bin to 0x80000000
  • Image-6.3.0-rc1+ to 0x80200000
  • initramfs-6.3.0-rc1+.img to 0x83000000

The result is a crash during early boot, which I have narrowed down to some of the tracing initialization callback addresses being clobbered in the kernel's memor range:

[    0.000000] trace event string verifier disabled
[    0.000000] rcu: Hierarchical RCU implementation.
[    0.000000] rcu:     RCU restricting CPUs from NR_CPUS=32 to nr_cpu_ids=4.
[    0.000000]  Rude variant of Tasks RCU enabled.
[    0.000000]  Tracing variant of Tasks RCU enabled.
[    0.000000] rcu: RCU calculated value of scheduler-enlistment delay is 10 jiffies.
[    0.000000] rcu: Adjusting geometry for rcu_fanout_leaf=16, nr_cpu_ids=4
[    0.000000] Unable to handle kernel paging request at virtual address ffffff8071010000
[    0.000000] Oops [#1]
[    0.000000] Modules linked in:
[    0.000000] CPU: 0 PID: 0 Comm: swapper/0 Not tainted 6.3.0-rc1+ #14
[    0.000000] Hardware name: freechips,rocketchip-unknown (DT)
[    0.000000] epc : 0xffffff8071010000
[    0.000000]  ra : event_init+0x2a/0x76
[    0.000000] epc : ffffff8071010000 ra : ffffffff8013c7e6 sp : ffffffff81e03e90
[    0.000000]  gp : ffffffff82069238 tp : ffffffff81e111c0 t0 : 0000000000000000
[    0.000000]  t1 : 000000000000002e t2 : 0000000000000008 s0 : ffffffff81e03eb0
[    0.000000]  s1 : 0000000000000000 a0 : ffffffff81e13e60 a1 : ffffffff81e13a18
[    0.000000]  a2 : ffffffff81f1ca78 a3 : 0000000000000000 a4 : 0000000000000000
[    0.000000]  a5 : 0100000071010000 a6 : 0000000000000000 a7 : 0000000000000007
[    0.000000]  s2 : ffffffff813ff470 s3 : ffffffff80e8b168 s4 : ffffffff81e13a18
[    0.000000]  s5 : ffffffff81f1ca38 s6 : ffffffff81f1ca78 s7 : ffffffff80e8e388
[    0.000000]  s8 : ffffffff8141bed8 s9 : 00000000000000b8 s10: 0000000000000000
[    0.000000]  s11: 0000000000000000 t3 : 000000000000002a t4 : 0000000000000000
[    0.000000]  t5 : ffffffff80e95688 t6 : 0000000000000000
[    0.000000] status: 0000000200000100 badaddr: ffffff8071010000 cause: 000000000000000c
[    0.000000] Code: Unable to access instruction at 0xffffff807100ffec.
[    0.000000] ---[ end trace 0000000000000000 ]---
[    0.000000] Kernel panic - not syncing: Attempted to kill the idle task!
[    0.000000] ---[ end Kernel panic - not syncing: Attempted to kill the idle task! ]---

If I add FW_JUMP_FDT_ADDR=0x82400000 to the opensbi build command line, the kernel boots without error.

Does the method recommended at: https://github.com/riscv-software-src/opensbi/blob/master/platform/generic/objects.mk#L35 perhaps fail to account for the additional kernel offset (e.g., it being loaded at 0x80200000 instead of 0x80000000, the latter of which is where fw_jump.bin itself is supposed to go)?

Thanks in advance for any clarification!

gsomlo avatar Mar 13 '23 14:03 gsomlo

Prefer fw_dynamic.bin if the booting stage before OpenSBI can load FDT at the appropriate location and tell it's location to OpenSBI.

In fact, QEMU and U-Boot use only fw_dynamic.bin as default firmware.

The problem with fw_jump.bin is it uses fixed location for FDT and next booting stage which does not work on lot of platforms. On some platforms, the DRAM does not even start at 0x80000000.

Regards, Anup

avpatel avatar Mar 13 '23 14:03 avpatel

Thanks @avpatel for the quick reply!

I think the TL;DR version of my post above is that, given the generic defaults of: https://github.com/riscv-software-src/opensbi/blob/master/platform/generic/objects.mk#L25 , https://github.com/riscv-software-src/opensbi/blob/master/platform/generic/objects.mk#L33 , and https://github.com/riscv-software-src/opensbi/blob/master/platform/generic/objects.mk#L35 ,

the instructions here: https://github.com/riscv-software-src/opensbi/blob/master/docs/firmware/fw_jump.md?plain=1#L51 and here: https://github.com/riscv-software-src/opensbi/blob/master/docs/firmware/fw_jump.md?plain=1#L56

should use > 0x2000000 (and not > 0x2200000, which includes both the opensbi blob and the kernel, not just the latter).

What do you think?

gsomlo avatar Mar 13 '23 15:03 gsomlo