如何在RISC-V操作系统中检测可用物理内存?
真实操作系统物理内存检测机制及RISC-V架构实现
一、真实OS的通用内存检测逻辑
真实系统绝不会像xv6那样硬编码内存上限,核心逻辑是从固件或硬件接口获取内存布局数据:
- 系统启动时,固件(比如x86的BIOS/UEFI、RISC-V的OpenSBI)会先扫描整个物理内存,生成一份内存映射表——里面会标记哪些区域是可用内存、哪些是硬件保留、哪些是设备占用
- 内核启动阶段直接读取这份映射表,就能精准确定可用物理内存的范围和总大小
二、RISC-V架构下的内存检测实现
RISC-V平台主要靠OpenSBI或**设备树(Device Tree)**来获取内存信息,两种方式各有应用场景:
1. 基于OpenSBI的内存检测
OpenSBI是RISC-V的标准特权固件,它会在启动内核前完成内存扫描,然后通过两种方式把数据传给内核:
- SBI扩展调用:使用
SBI_MEMORY_INFO扩展提供的sbi_query_memory()函数,内核调用后能拿到所有物理内存区域的起始地址和大小,包括可用区、保留区等 - 启动寄存器传参:OpenSBI会把内存映射表的起始地址放到指定寄存器(比如
a2,随启动参数一起传递),内核直接读这个地址就能解析出完整布局
2. 基于设备树的内存检测
QEMU的virt虚拟机默认会自动生成包含内存节点的设备树,内核可以解析这个设备树的memory节点:
- 设备树里的
memory节点会明确写死物理内存的起始地址和大小,比如:memory@80000000 { device_type = "memory"; reg = <0x0 0xA0000000>; /* 2.5GB内存,起始地址0x80000000 */ }; - 内核启动时,从OpenSBI传递的设备树基地址读取设备树数据,解析
reg属性就能直接拿到内存的范围
三、QEMU中测试RISC-V内存检测的步骤
1. 调整QEMU内存配置
修改xv6的Makefile里的QEMUOPTS,把-m 128M改成其他值,比如-m 256M或者-m 1G,测试不同内存大小的检测效果
2. 实现并验证检测逻辑
- 在xv6内核里添加代码:要么调用OpenSBI的
sbi_query_memory()接口遍历内存区域,统计可用内存;要么解析设备树的memory节点提取内存参数 - 把检测结果打印到控制台,对比QEMU设置的内存大小,确认逻辑是否正确
3. 查看QEMU生成的设备树
可以用QEMU导出设备树文件,再反编译查看细节:
# 启动QEMU时导出设备树到output.dtb qemu-system-riscv64 -machine virt -bios none -kernel kernel -m 256M -dtb output.dtb -nographic # 用dtc工具反编译成可读的dts文件 dtc -I dtb -O dts output.dtb > output.dts
打开output.dts就能看到memory节点的具体内容,确认内存参数是否正确传递给了内核
内容的提问来源于stack exchange,提问作者Jalaj Kumar
相关产品推荐
相关产品推荐

