rust写操作系统 rCore tutorial 学习笔记:实验指导五 驱动与文件

这是 os summer of code 2020 项目每日记录的一部分:
每日记录github地址(包含根据实验指导实现的每个阶段的代码):https://github.com/yunwei37/os-summer-of-code-daily

这里参考的是rCore tutorial的第三版:https://github.com/rcore-os/rCore-Tutorial

lab5 学习报告

lab5 涉及:

  • 设备树的概念和读取
  • virtio 总线协议
  • 块设备驱动的实现
  • 将块设备托管给文件系统

这一部分其实在 lab4 的实验中就已经可以部分接触到了(笑

设备树

设备树涉及这样一个问题,我们从哪里读取设备信息?

在 RISC-V 中,这个一般是由 bootloader,即 OpenSBI 固件完成的:它来完成对于包括物理内存在内的各外设的扫描,将扫描结果以设备树二进制对象(DTB,Device Tree Blob)的格式保存在物理内存中的某个地方。而这个放置的物理地址将放在 a1 寄存器中。

将会把 HART ID (HART,Hardware Thread,硬件线程,可以理解为执行的 CPU 核)放在 a0 寄存器上。

使用这两个参数,只需要把 rust_main 函数增加两个参数即可:

os/src/main.rs


#[no_mangle]
pub extern "C" fn rust_main(_hart_id: usize, dtb_pa: PhysicalAddress) -> ! {
    memory::init();
    interrupt::init();
    drivers::init(dtb_pa);
    
    println!("{} {}",_hart_id,dtb_pa);

    ...
}

打印输出结果:

0 PhysicalAddress(0x82200000)

设备树:

每个设备在物理上连接到了父设备上最后再通过总线等连接起来构成一整个设备树,在每个节点上都描述了对应设备的信息,如支持的协议是什么类型等等。而操作系统就是通过这些节点上的信息来实现对设备的识别的。

一个设备节点上会有几个标准属性:

  • compatible:该属性指的是该设备的编程模型
  • model:指的是设备生产商给设备的型号
  • reg:用 reg 段来自定义存储一些信息

解析设备树

可以直接调用 rCore 中 device_tree 库,然后遍历树上节点即可:

os/src/drivers/device_tree.rs


/// 递归遍历设备树
fn walk(node: &Node) {
    // 检查设备的协议支持并初始化
    if let Ok(compatible) = node.prop_str("compatible") {
        if compatible == "virtio,mmio" {
            virtio_probe(node);
        }
    }
    // 遍历子树
    for child in node.children.iter() {
        walk(child);
    }
}

/// 整个设备树的 Headers(用于验证和读取)
struct DtbHeader {
    magic: u32,
    size: u32,
}

在开始的时候,有一步来验证 Magic Number:

这一步是一个保证系统可靠性的要求,是为了验证这段内存到底是不是设备树。

/// 遍历设备树并初始化设备
pub fn init(dtb_va: VirtualAddress) {
    let header = unsafe { &*(dtb_va.0 as *const DtbHeader) };
    // from_be 是大小端序的转换(from big endian)
    let magic = u32::from_be(header.magic);
    if magic == DEVICE_TREE_MAGIC {
        let size = u32::from_be(header.size);
        // 拷贝数据,加载并遍历
        let data = unsafe { slice::from_raw_parts(dtb_va.0 as *const u8, size as usize) };
        if let Ok(dt) = DeviceTree::load(data) {
            walk(&dt.root);
        }
    }
}

virtio

挂载到 QEMU

为了让 QEMU 挂载上我们虚拟的存储设备,我们这里选了 QEMU 支持的 virtio 协议。

virtio:

VirtIO is a standardized interface which allows virtual m

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值