qemu - qemu-riscv 如何将 Device Tree Blob 传递给 guest 内核?

标签 qemu riscv device-tree

qemu-system-riscv中的默认BIOS(OpenSBI)如何将设备树 Blob 传递给 guest ?
我可以从documentation看到为 qemu-system-arm 'virt' 平台,当使用 Linux 引导协议(protocol)时,QEMU 将设备树 Blob (dtb) 的地址传递给 r0 中的 guest ,或者在裸机 guest 内核的硬编码地址处。
源码在hw/riscv/virt.c QEMU 存储库中显示为 RISC-V 'virt' 平台生成了一个设备树 Blob(通过 create_fdt 函数),但是我找不到任何文档描述如何将其传递给 guest 。任何帮助表示赞赏。

最佳答案

How does the default bios (OpenSBI) in qemu-system-riscv pass the Device Tree Blob to a guest?


它没有。该机制类似于所有 qemu“virt”机器。在这种特殊情况下,qemu 负责生成和加载已编译的 dtb。
实际上,您只能依靠 RAM 和 FLASH 地址,所有其他信息都应从 Qemu 生成的 DTB 中获取。
从 qemu/hw/riscv/boot.c 引用:
riscv_load_fdt
/*
* We should put fdt as far as possible to avoid kernel/initrd overwriting
* its content. But it should be addressable by 32 bit system as well.
* Thus, put it at an 16MB aligned address that less than fdt size from the
* end of dram or 3GB whichever is lesser.
*/

OpenSBI 期望通过“a1”传递 fdt 地址,除非您使用 dtb 内置编译 OpenSBI FW_FDT_PATH , 看:

opensbi/docs/firmware/fw.md


opensbi/docs/firmware/fw_payload.md


fdt 的地址目前在编译时不能直接设置(OpenSBI v0.9)。
传递到下一个模式的 fdt 的地址可以用 改变。 FW_PAYLOAD_FDT_ADDR .
所以 FW_FDT_PATH FW_PAYLOAD_FDT_ADDR 分别影响 fdt。
Qemu 在 riscv_setup_rom_reset_vec 和其他设置中设置重置向量 fdt_load_addr
接下来发生的事情取决于 OpenSBI 模式(dtb 可以由 OpenSBI 重新分配),但您可以查看 opensbi/sbi_hart.c 中的 sbi_hart_switch_mode:
register unsigned long a0 asm("a0") = arg0;
register unsigned long a1 asm("a1") = arg1;
__asm__ __volatile__("mret" : : "r"(a0), "r"(a1));
__builtin_unreachable();
终于看到https://www.sifive.com/blog/all-aboard-part-6-booting-a-risc-v-linux-kernel对于 RISC-V 内核启动过程:
Early Boot in Linux
When Linux boots, it expects the system to be in the following state:
a0 contains a unique per-hart ID. We currently map these to Linux CPU IDs, 
so they're expected to be contiguous and close to 0.
a1 contains a pointer to the device tree, represented as a binary flattened
device tree (DTB).
更新:
例如,您可以看到以下内容:

build-qemu/qemu-system-riscv64 -machine virt -m 2G -nographic -bios opensbi/build/platform/generic/firmware/fw_jump.bin


并使用 FW_OPTIONS=0x2 编译 OpenSBI:
Domain0 Name              : root
Domain0 Boot HART         : 0
Domain0 HARTs             : 0*
Domain0 Region00          : 0x0000000002000000-0x000000000200ffff (I)
Domain0 Region01          : 0x0000000080000000-0x000000008003ffff ()
Domain0 Region02          : 0x0000000000000000-0xffffffffffffffff (R,W,X)
Domain0 Next Address      : 0x0000000080200000
Domain0 Next Arg1         : 0x0000000082200000
Domain0 Next Mode         : S-mode
Domain0 SysReset          : yes

关于qemu - qemu-riscv 如何将 Device Tree Blob 传递给 guest 内核?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68234769/

相关文章:

linux-kernel - qemu 和 gdb 的问题

docker - qemu-irix无法在Alpine 3.10(GCC 8.3)下构建

linux - QEMU 和 KVM 问题

assembly - 为什么 ARM 内核在使用 ELF 和二进制文件时表现不同

gcc - 对 'malloc' 等的 undefined reference

gdb - 如何用GDB调试交叉编译的QEMU程序?

riscv - RISC V LD 错误 - (.text+0xc4) : relocation truncated to fit: R_RISCV_JAL against `*UND*'

未探测到 Linux serdev mfd 驱动程序

operating-system - DTS 文件说明 - 别名

linux - 如何在设备树(.dts)文件中指定uart的设备名称?