DTS与DTB可以通过DTC与FDTDUMP进行编译与反编译。
1.9.4.1 使用U-Boot借助DTB启动内核
现今的内核版本使用了Device Tree:
内核不再包含对硬件的描述,它以二进制的形式单独存储在另外的位置
2)Bootloader需要加载两个二进制文件:内核镜像和DTB
内核镜像仍然是uImage或者zImage
DTB文件在arch/arm/boot/dts中,每一个board对应一个.dts文件
3)Bootloader通过r2寄存器来传递DTB地址,通过修改DTB可以修改内存信息,kernel command line,以及潜在的其它信息
启动过程总的归纳为:
kernel入口处获取到uboot传过来的.dtb镜像的基地址
通过early_init_dt_scan()函数来获取kernel初始化时需要的bootargs和cmd_line等系统引导参数
调用unflatten_device_tree函数来解析dtb文件,构建一个由device_node结构连接而成的单向链表,并使用全局变量of_allnodes保存这个链表的头指针
内核获取of_allnodes链表信息来初始化内核其他子系统、设备等
1.9.5 FSBL中的L2 LIM相关步骤解释
Enable 15 of the 16 L2 ways (this removes almost all of the L2 LIM memory)
Ways为L2缓存hash时允许冲突的长度,此处FSBL允许L2缓存拥有长度为15的hash冲突长度。
1.9.6 OpenSBI的作用与具体案例(openSBI下的RISC-V裸机实现串口输出)OpenSBI不仅起到了引导启动的作用,还提供了M-mode转换到S-mode的实现,同时,在S-mode下的操作系统内核可以通过这一实现访问M-mode的服务。
随后会介绍如何利用该服务在控制台输出Hello。
准备工作:
编译openSBI
安装qemu
安装交叉编译工具链
完善工程目录
├──build.sh ##编译脚本(编译了s与main.c,通过link.ld链接)
├──entry.s ##入口函数(执行的入口函数,设置了堆的地址,并跳转到main)
├──fw_bin ##可执行的固件脚本
│├──fw_jump.elf ##opensbi
│├──hello.elf ##编译完成的固件
│└──run.sh ##直接运行的脚本
├──link.ld ##链接文件(规定了程序的布局)
├──main.c ##主函数(调用openSBI,可以在S-mode访问M-mode的串口输出服务。)
├──readme.md
└──sbi.h##sbi调用api
(5)在此文件夹下输入./run.sh即能在控制台看到输出的Hello
在进行M-mode服务访问时,采用ECALL进行SYSCALL
在SYSCALL过程中,ECALL会使用a0 与a7寄存器,分别保存调用参数和调用号。
在RISC-V架构中,S-mode不直接参与时钟中断和软件中断,而是使用ECALL来请求M-mode设置定时器或在代理处理器中断。
openSBI提供的服务接口如下表(串行输出至控制台仅使用了sbi_console_putchar接口)
Appendix: A. 依照MSEL,ZSBL和FSBL的下一阶段启动媒介
B. 被ZSBL加载的FSBL地址