opensbi
opensbi copied to clipboard
How to calculate correct FW_JUMP_FDT_ADDR?
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
to0x80000000
-
Image-6.3.0-rc1+
to0x80200000
-
initramfs-6.3.0-rc1+.img
to0x83000000
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!
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
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?