OpenSBI设备树

设备树

在前一启动阶段跳转OpenSBI时,可以将设备树的地址通过参数a1传递过来。

OpenSBI相关的配置(opensbi_config)也可以添加到设备树节点中,OpenSBI执行时会解析和使用这些配置,并在启动结束时删除该节点,节点的示例如下:

    chosen {opensbi-config {compatible = "opensbi,config";cold-boot-harts = <&cpu1 &cpu2 &cpu3 &cpu4>;system-suspend-test;};};cpus {#address-cells = <1>;#size-cells = <0>;timebase-frequency = <10000000>;cpu0: cpu@0 {device_type = "cpu";reg = <0x00>;compatible = "riscv";...};cpu1: cpu@1 {device_type = "cpu";reg = <0x01>;compatible = "riscv";...};cpu2: cpu@2 {device_type = "cpu";reg = <0x02>;compatible = "riscv";...};cpu3: cpu@3 {device_type = "cpu";reg = <0x03>;compatible = "riscv";...};cpu4: cpu@4 {device_type = "cpu";reg = <0x04>;compatible = "riscv";...};};uart1: serial@10011000 {...};

其中关于OpenSBI配置节点的属性如下:

  • compatible:强制,值须为**“opensbi,config”**
  • cold-boot-harts:可选,表示哪些HART支持冷启动
  • compatible:可选,如果存在,系统将等待5秒,再进入WFI

设备树导出

以QEMU启动传递给OpenSBI的设备树为例。

方法一

在启动QEMU时,使用 -M virt,dumpdtb=<file.dtb> 参数将设备树以二进制格式.dtb导出到指定文件。

$ qemu-system-riscv64 -M virt,dumpdtb=qemu-virt.dtb -m 256M -nographic \-bios build/platform/generic/firmware/fw_jump.bin

方法二

当执行到fw_platform_init时,将arg1参数地址处的内容导出。

unsigned long fw_platform_init(unsigned long arg0, unsigned long arg1,unsigned long arg2, unsigned long arg3,unsigned long arg4)
{const char *model;void *fdt = (void *)arg1;u32 hartid, hart_count = 0;int rc, root_offset, cpus_offset, cpu_offset, len;root_offset = fdt_path_offset(fdt, "/");......
}

使用GDB的dump命令,假设arg1的地址为0x80060000

(gdb) dump memory qemu-virt.dtb 0x80060000 0x80064000

导出后的dtb文件是二进制格式,使用dtc工具将导出的dtb文件转换为易读的dts格式。

$ dtc -I dtb -O dts -o qemu-virt.dts qemu-virt.dtb

设备树分析

查看qemu-virt.dts设备树的内容如下(有删减):

/dts-v1/;/ {#address-cells = <0x02>;#size-cells = <0x02>;compatible = "riscv-virtio";model = "riscv-virtio,qemu";chosen {bootargs = [00];stdout-path = "/uart@10000000";};uart@10000000 {interrupts = <0x0a>;interrupt-parent = <0x03>;clock-frequency = <0x384000>;reg = <0x00 0x10000000 0x00 0x100>;compatible = "ns16550a";};test@100000 {reg = <0x00 0x100000 0x00 0x1000>;compatible = "sifive,test1\0sifive,test0";};cpus {#address-cells = <0x01>;#size-cells = <0x00>;timebase-frequency = <0x989680>;cpu-map {cluster0 {core0 {cpu = <0x01>;};};};cpu@0 {phandle = <0x01>;device_type = "cpu";reg = <0x00>;status = "okay";compatible = "riscv";riscv,isa = "rv64imafdcsu";mmu-type = "riscv,sv48";interrupt-controller {#interrupt-cells = <0x01>;interrupt-controller;compatible = "riscv,cpu-intc";phandle = <0x02>;};};};memory@80000000 {device_type = "memory";reg = <0x00 0x80000000 0x00 0x10000000>;};soc {#address-cells = <0x02>;#size-cells = <0x02>;compatible = "simple-bus";ranges;interrupt-controller@c000000 {phandle = <0x03>;riscv,ndev = <0x35>;reg = <0x00 0xc000000 0x00 0x4000000>;interrupts-extended = <0x02 0x0b 0x02 0x09>;interrupt-controller;compatible = "riscv,plic0";#interrupt-cells = <0x01>;#address-cells = <0x00>;};clint@2000000 {interrupts-extended = <0x02 0x03 0x02 0x07>;reg = <0x00 0x2000000 0x00 0x10000>;compatible = "riscv,clint0";};};
};

从上面内容可以得出:

  • 平台设备为riscv-virtio,qemu
  • UART兼容ns16550a设备,基地址为0x10000000,这个串口也是OpenSBI的打印终端
  • CLINT本地中断控制器兼容riscv,clint0,基地址为0x02000000
  • PLIC中断控制器兼容riscv,plic0,基地址为0x0c000000
  • 内存空间基地址为0x80000000,其也是OpenSBI固件的链接地址
  • HART个数为1

上面这些信息其实来自QEMU Virt定义的地址空间布局:

static const MemMapEntry virt_memmap[] = {[VIRT_DEBUG] =        {        0x0,         0x100 },[VIRT_MROM] =         {     0x1000,        0xf000 },[VIRT_TEST] =         {   0x100000,        0x1000 },[VIRT_RTC] =          {   0x101000,        0x1000 },[VIRT_CLINT] =        {  0x2000000,       0x10000 },[VIRT_ACLINT_SSWI] =  {  0x2F00000,        0x4000 },[VIRT_PCIE_PIO] =     {  0x3000000,       0x10000 },[VIRT_PLATFORM_BUS] = {  0x4000000,     0x2000000 },[VIRT_PLIC] =         {  0xc000000, VIRT_PLIC_SIZE(VIRT_CPUS_MAX * 2) },[VIRT_APLIC_M] =      {  0xc000000, APLIC_SIZE(VIRT_CPUS_MAX) },[VIRT_APLIC_S] =      {  0xd000000, APLIC_SIZE(VIRT_CPUS_MAX) },[VIRT_UART0] =        { 0x10000000,         0x100 },[VIRT_VIRTIO] =       { 0x10001000,        0x1000 },[VIRT_FW_CFG] =       { 0x10100000,          0x18 },[VIRT_FLASH] =        { 0x20000000,     0x4000000 },[VIRT_IMSIC_M] =      { 0x24000000, VIRT_IMSIC_MAX_SIZE },[VIRT_IMSIC_S] =      { 0x28000000, VIRT_IMSIC_MAX_SIZE },[VIRT_PCIE_ECAM] =    { 0x30000000,    0x10000000 },[VIRT_PCIE_MMIO] =    { 0x40000000,    0x40000000 },[VIRT_DRAM] =         { 0x80000000,           0x0 },
};

代码

OpenSBI在启动时会解析设备树,代码如下:

/** The fw_platform_init() function is called very early on the boot HART* OpenSBI reference firmwares so that platform specific code get chance* to update "platform" instance before it is used.** The arguments passed to fw_platform_init() function are boot time state* of A0 to A4 register. The "arg0" will be boot HART id and "arg1" will* be address of FDT passed by previous booting stage.** The return value of fw_platform_init() function is the FDT location. If* FDT is unchanged (or FDT is modified in-place) then fw_platform_init()* can always return the original FDT location (i.e. 'arg1') unmodified.*/
unsigned long fw_platform_init(unsigned long arg0, unsigned long arg1,unsigned long arg2, unsigned long arg3,unsigned long arg4)
{const char *model;void *fdt = (void *)arg1;u32 hartid, hart_count = 0;int rc, root_offset, cpus_offset, cpu_offset, len;root_offset = fdt_path_offset(fdt, "/");if (root_offset < 0)goto fail;fw_platform_lookup_special(fdt, root_offset);if (generic_plat && generic_plat->fw_init)generic_plat->fw_init(fdt, generic_plat_match);model = fdt_getprop(fdt, root_offset, "model", &len);if (model)sbi_strncpy(platform.name, model, sizeof(platform.name) - 1);if (generic_plat && generic_plat->features)platform.features = generic_plat->features(generic_plat_match);cpus_offset = fdt_path_offset(fdt, "/cpus");if (cpus_offset < 0)goto fail;fdt_for_each_subnode(cpu_offset, fdt, cpus_offset) {rc = fdt_parse_hart_id(fdt, cpu_offset, &hartid);if (rc)continue;if (SBI_HARTMASK_MAX_BITS <= hartid)continue;if (!fdt_node_is_enabled(fdt, cpu_offset))continue;generic_hart_index2id[hart_count++] = hartid;}platform.hart_count = hart_count;platform.heap_size = fw_platform_calculate_heap_size(hart_count);platform_has_mlevel_imsic = fdt_check_imsic_mlevel(fdt);fw_platform_coldboot_harts_init(fdt);/* Return original FDT pointer */return arg1;fail:while (1)wfi();
}

上面代码先解析了平台名、HART个数等,最后调用fw_platform_coldboot_harts_init解析出冷启动的HART ID,如下:

/** The fw_platform_coldboot_harts_init() function is called by fw_platform_init() * function to initialize the cold boot harts allowed by the generic platform* according to the DT property "cold-boot-harts" in "/chosen/opensbi-config" * DT node. If there is no "cold-boot-harts" in DT, all harts will be allowed.*/
static void fw_platform_coldboot_harts_init(void *fdt)
{int chosen_offset, config_offset, cpu_offset, len, err;u32 val32;const u32 *val;bitmap_zero(generic_coldboot_harts, SBI_HARTMASK_MAX_BITS);chosen_offset = fdt_path_offset(fdt, "/chosen");if (chosen_offset < 0)goto default_config;config_offset = fdt_node_offset_by_compatible(fdt, chosen_offset, "opensbi,config");if (config_offset < 0)goto default_config;val = fdt_getprop(fdt, config_offset, "cold-boot-harts", &len);len = len / sizeof(u32);if (val && len) {for (int i = 0; i < len; i++) {cpu_offset = fdt_node_offset_by_phandle(fdt,fdt32_to_cpu(val[i]));if (cpu_offset < 0)goto default_config;err = fdt_parse_hart_id(fdt, cpu_offset, &val32);if (err)goto default_config;if (!fdt_node_is_enabled(fdt, cpu_offset))continue;for (int i = 0; i < platform.hart_count; i++) {if (val32 == generic_hart_index2id[i])bitmap_set(generic_coldboot_harts, i, 1);}}}return;default_config:bitmap_fill(generic_coldboot_harts, SBI_HARTMASK_MAX_BITS);return;
}

由于上面的qemu-virt.dts设备树并未包括OpenSBI节点,因此所有HARTs均允许冷启动。

再结合OpenSBI打印信息看下,其确实是解析了设备数,如Platform NamePlatform HART Count和Domain使用的地址信息等:

OpenSBI v1.5____                    _____ ____ _____/ __ \                  / ____|  _ \_   _|| |  | |_ __   ___ _ __ | (___ | |_) || || |  | | '_ \ / _ \ '_ \ \___ \|  _ < | || |__| | |_) |  __/ | | |____) | |_) || |_\____/| .__/ \___|_| |_|_____/|____/_____|| ||_|Platform Name             : riscv-virtio,qemu
Platform Features         : medeleg
Platform HART Count       : 1
Platform IPI Device       : aclint-mswi
Platform Timer Device     : aclint-mtimer @ 10000000Hz
Platform Console Device   : uart8250
Platform HSM Device       : ---
Platform PMU Device       : ---
Platform Reboot Device    : ---
Platform Shutdown Device  : ---
Platform Suspend Device   : ---
Platform CPPC Device      : ---
Firmware Base             : 0x80000000
Firmware Size             : 327 KB
Firmware RW Offset        : 0x40000
Firmware RW Size          : 71 KB
Firmware Heap Offset      : 0x49000
Firmware Heap Size        : 35 KB (total), 2 KB (reserved), 9 KB (used), 23 KB (free)
Firmware Scratch Size     : 4096 B (total), 408 B (used), 3688 B (free)
Runtime SBI Version       : 2.0Domain0 Name              : root
Domain0 Boot HART         : 0
Domain0 HARTs             : 0*
Domain0 Region00          : 0x0000000010000000-0x0000000010000fff M: (I,R,W) S/U: (R,W)
Domain0 Region01          : 0x0000000002000000-0x000000000200ffff M: (I,R,W) S/U: ()
Domain0 Region02          : 0x0000000080040000-0x000000008005ffff M: (R,W) S/U: ()
Domain0 Region03          : 0x0000000080000000-0x000000008003ffff M: (R,X) S/U: ()
Domain0 Region04          : 0x000000000c000000-0x000000000fffffff M: (I,R,W) S/U: (R,W)
Domain0 Region05          : 0x0000000000000000-0xffffffffffffffff M: () S/U: (R,W,X)

参考

  1. opensbi_config

欢迎关注“安全有理”微信公众号。

安全有理

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/393623.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

只强的Java学习之路8-5

一.搭建mybatis pom.xml文件 <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0"xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation"http://maven.a…

部署Springboot + Vue 项目到远程服务器Windows10系统的详细配置

远程服务器操作系统为Windows系统&#xff0c;Java程序环境&#xff0c;Maven环境都安装有&#xff0c;Mysql ,Redis等都有的前提下 1. mysql数据库导入&#xff0c;非常简单很好操作&#xff0c;这里省略。。比如用HeidiSql 或者Navicat 工具导入数据库 2. 后端javaSpringb…

高职物联网智慧农业实训室建设方案

一、项目概述 随着物联网技术的迅猛发展及其在农业领域的广泛应用&#xff0c;智慧农业已经成为推动农业现代化的关键力量。近年来&#xff0c;国家高度重视物联网技术在农业领域的应用与发展&#xff0c;出台了一系列相关政策支持智慧农业建设。如《数字乡村发展战略纲要》明…

英语疑惑之在树上

在树上&#xff0c;on the tree&#xff0c;我想这个这个介词到底该用in&#xff0c;on or other prep。本来我以为跟on the roof差不多&#xff0c;就是在物体表面&#xff0c;可是百度了一下&#xff0c;可以有on the tree, in the tree, by the tree, at the tree, under th…

基于tcp,html,数据库的在线信息查询系统项目总结

1.项目背景 在线信息查询系统是一种可用于检索和展示各种信息的计算机程序或平台。主要特点包括&#xff1a; 用户接口&#xff1a;通常提供友好的界面&#xff0c;用户可以方便地输入查询条件。 数据存储&#xff1a;系统往往连接到数据库&#xff0c;存储大量信息&#xf…

自动化工具Selenium IDE基本使用——脚本录制

1 简介 Selenium相信大家都知道&#xff0c;在做自动化操作时&#xff0c;要使用浏览器驱动直接控制浏览器操作的时候&#xff0c;大多会结合Selenium框架使用。 但在对网页操作自动化的时候&#xff0c;实际上有一种更轻量的做法&#xff0c;那就是直接使用Selenium IDE&…

【LeetCode每日一题】2024年8月第二周(上)

2024.8.5 困难 链接&#xff1a;600. 不含连续1的非负整数 &#xff08;1&#xff09;题目描述&#xff1a; &#xff08;2&#xff09;示例 &#xff08;3&#xff09;分析 思路1&#xff1a; 题目要求的数值&#xff0c;是将数二进制转换后&#xff0c;不存在连续的1&#x…

SQL时间盲注

目录 1.时间盲注 2使用场景 3.步骤 3.1判断注入点 3.2爆数据库名 3.3爆表名 3.4爆字段名 3.5查询数据 1.时间盲注 时间盲注是指基于时间的盲注&#xff0c;也叫延时注入&#xff0c;根据页面的响应时间来判断是否存在注入。 2使用场景 页面没有回显位置&#xff08;…

安装Supervisor队列进程、管理 Laravel 队列进程

在 CentOS 上安装 Supervisor 并配置 Laravel 的步骤如下&#xff1a; 1.安装 Supervisor&#xff1a; 使用以下命令安装 Supervisor&#xff1a; sudo yum install epel-release sudo yum install supervisor 2.配置 Supervisor&#xff1a; 创建一个新的 Supervisor 配置文…

EasyBoss ERP订单分仓规则优化升级,帮助跨境卖家高效处理TikTok本土店订单

做TikTok本土小店不仅要上货快&#xff0c;订单处理效率也得快&#xff01;效率越高&#xff0c;赚钱的速度就比别人要快&#xff01; 想提高订单效率&#xff0c;少不了EasyBoss ERP的帮忙&#xff0c;最近EasyBoss订单处理模块又有新升级&#xff0c;让老板们体验“快到飞起…

给新手项目经理的几点建议

踏入项目管理的新领域&#xff0c;对于每一位新手项目经理而言&#xff0c;都是一次既激动又充满挑战的旅程。在这个过程中&#xff0c;不仅需要掌握扎实的理论知识&#xff0c;还需要在实践中不断积累经验&#xff0c;提升自我。以下是一些针对新手项目经理的实用建议&#xf…

Stable Diffusion绘画 | 图生图-上传重绘蒙版

上传重绘蒙版&#xff0c;可以弥补局部重绘的缺点&#xff0c;能够更精细的修改画面中的指定区域 使用PS制作的蒙版图片为耳朵下方区域&#xff0c;可以为图片中的女生带上不同款式的耳环。 参数配置&#xff1a; 调整提示词&#xff1a; 生成图片如下所示&#xff1a; 调整提…

大数据面试SQL(一):合并日期重叠的活动

文章目录 合并日期重叠的活动 一、题目 二、分析 三、SQL实战 四、样例数据参考 合并日期重叠的活动 一、题目 已知有表记录了每个品牌的活动开始日期和结束日期&#xff0c;每个品牌可以有多个活动。请编写一个SQL查询合并在同一个品牌举行的所有重叠的活动&#xff0c…

手机在网时长查询接口如何对接?(一)

一、什么是手机在网时长查询接口&#xff1f; 传入手机号码&#xff0c;查询该手机号的在网时长&#xff0c;返回时间区间&#xff0c;支持携号转网号码查询。 二、手机在网时长查询接口适用于哪些场景&#xff1f; 例如&#xff1a;客户画像与精准营销 &#xff08;1&…

ROS 7上实现私网互通方案

一、背景: 第一个私网现状:连接公域网是由tp-link进行拨号链接使用动态公网ip,内部网段是192.168.1.0/24 第二个私网现状:连接公域网是机房的固定公网ip,内部网段为10.0.0.0/16二、目标 安全的打通192.168.1.0/24和10.0.0.0/16的网络, 使得前者局域网中的机器能够安全访…

C#使用Socket实现TCP服务器端

1、TCP服务器实现代码 using System; using System.Collections.Generic; using System.Linq; using System.Net; using System.Net.Sockets; using System.Text; using System.Threading; using System.Threading.Tasks;namespace PtLib.TcpServer {public delegate void Tcp…

浏览器渲染树的形成原理,你真的懂吗?

一、浏览器渲染的基本流程 解析 HTML 当用户在浏览器中输入网址或点击链接时&#xff0c;浏览器会向服务器发送请求获取 HTML 文件。随后&#xff0c;浏览器开始解析 HTML 代码&#xff0c;将其转化为一系列的标签和文本&#xff0c;并构建出 DOM 树。这棵树以层次结构表示了网…

Tensorflow预训练模型转PyTorch

深度学习领域是计算机科学中变化最快的领域之一。大约 5 年前&#xff0c;当我开始研究这个主题时&#xff0c;TensorFlow 被认为是主导框架。如今&#xff0c;大多数研究人员已经转向 PyTorch。 NSDT工具推荐&#xff1a; Three.js AI纹理开发包 - YOLO合成数据生成器 - GLTF/…

无人机无线电监测设备技术分析

随着无人机技术的飞速发展&#xff0c;其在民用、军事、科研及娱乐等领域的广泛应用&#xff0c;对无线电频谱资源的有效管理和监测提出了更高要求。无人机无线电监测设备作为保障空域安全、维护无线电秩序的重要工具&#xff0c;集成了高精度定位、频谱扫描、信号分析、数据处…

《Token-Label Alignment for Vision Transformers》ICCV2023

摘要 这篇论文探讨了数据混合策略&#xff08;例如CutMix&#xff09;在提高卷积神经网络&#xff08;CNNs&#xff09;性能方面的有效性&#xff0c;并指出这些策略在视觉Transformer&#xff08;ViTs&#xff09;上同样有效。然而&#xff0c;发现了一个“token fluctuation…