riscv-6-domain
1.domain机制介绍
domain机制:人为的将SOC内部硬件划分为不同的权限区域,然后分别独立运行,其使用了riscv的权限管理的硬件保护单元。它提供了一种在系统中划分资源和权限的方法,以确保软件实体之间的相互隔离和安全性。
OpenSBI运行在系统的M模式,而不同Domain的上层程序只能工作在S模式或者U模式,即便是Linux Kernel也必须接收OpenSBI的Domain权限限制,domain划分带来一个好处,比如你希望SOC中的一部分core在smp模式下运行linux内核,而另一部分core工作在amp模式下,单独运行裸机程序或者RTOS会非常容易操作,将其划分到不同Domian即可,除此之外,Domian还可以划分内存地址,mmio地址,可以进行较为细致的权限划分。
Opensbi的domain机制通过以下的方式实现:
- Domain ID:每个 domain 都有一个唯一的标识符,称为 Domain ID。它用于区分不同的 domain。
- Hart Mask:OpenSBI 使用 Hart Mask 来表示哪些处理器属于特定的 domain。Hart Mask 是一个位图,每个位代表一个处理器,可以将相应的位设置为 1 表示该处理器属于某个 domain。
- SBI 接口:OpenSBI 提供了一组 SBI(Supervisor Binary Interface)接口,用于 domain 之间的通信和资源管理。这些接口包括中断处理、内存管理、设备访问等,可以由 domain 使用来请求和管理资源。
在目录opensbi/doc
下domian_support.md
文档介绍了如何使用设备树来基于opensbi来划分domain。
具体解释见:基于opensbi为quard_star创建domain | TimerのBlog (yanglianoo.github.io)
2.quard_star的domain实现
dts/quard_star_sbi.dts 添加
1 |
|
分开来解释:
1 | tdomain: trusted-domain { /* 定义domian节点 */ |
定义tdomian
— trust domain
这个使用了cpu7,下级程序的起始地址0xb0000000
,模式为U模式,可以运行freertos
的实时操作系统等
1 | udomain: untrusted-domain { |
定义udomain
,不受信任的域,用于运行Linux系统等
这种模式的划分:
openSBI
运行在系统的M
模式,而不同Domain
的上层程序只能工作在S
模式或者U
模式,即便是Linux Kernel
也必须接收OpenSBI
的Domain
权限限制,domain
划分带来一个好处,比如你希望SOC
中的一部分core
在smp
模式下运行linux
内核,而另一部分core
工作在amp
模式下,单独运行裸机程序或者RTOS
会非常容易操作,将其划分到不同Domian
即可。
3.domain测试代码
新建trust_domain
文件夹,以及在文件夹内新建两个文件link.lds
和 startup.s
trust_domain/link.lds
注意这起始的地址是0xb0000000,与上面 tdomian保持一直,因为信任域设置就从这个地址开始了
1 | OUTPUT_ARCH( "riscv" ) |
trust_domain/startup.s
这里串口输出的是
uart2
,也就是上面定义的tuart
,输出地址为0x10002000
1 | .section .text |
还需要修改 build.sh
将t_fw,写入到了fw.bin的0x400000偏移的地方. — flash
1 | 编译 tdomain |
boot/start.s
这里还要将位与flash中0x400000中的 trust_fw.bin加载到DRAM中。 还是采用了 load_data函数
从
[0x20400000:0x20800000]
–> 加载到[0x80200000:0x80600000]
1 | //load trusted_fw.bin |
run.sh
DEFAULT_VC
来指定了qemu显示的分辨率,还需要新增三个-serial
选项让qemu输出三个串口终端
1 | SHELL_FOLDER=$(cd "$(dirname "$0")";pwd) |
串口1 输出opensbi
串口2 输出:
4.内存布局
加入了trust_domain.bin
后,内存布局如下,首先是flash
的0x400000
上增加了t_domain
,然后需要加载到 DRAM
的0xb0000000