使用Rust开发操作系统(UEFI抽象文件系统)

本文介绍如何使用Rust在UEFI环境下编写操作系统,主要内容包括建立基础异常处理、封装文件操作(如打开、读写、Seek等)、简化QEMU启动过程。文章详细讲解了设计思路和具体实现,旨在为UEFI开发提供更友好的抽象层。
摘要由CSDN通过智能技术生成

在上一篇文章中我们介绍了rust在uefi中的基本使用,在本章中我们开始编写UEFI基础设施,主要包括File结构和uefi编译脚本用来简化内核文件读取和qemu启动过程

建立基础异常

在标准库中为我们提供了Result,但是在UEFI开发中将Result分成了2种,UEFI服务执行的Result和用户自定义的Result,在本节中我们仿照标准库的io::Result建立我们自己的Result

设计思路

我们设计的Result除了满足我们程序基本的使用以外还要兼容UEFI服务的Result因此我们可以通过type来重新命令2种Result,其次我们要兼容UEFI服务的错误,但是还是要区分UEFI异常和UEFI应用异常,因此我们需要设计一个枚举Repr来区分两种异常

根据Result我们可以轻松定义出如下结构

// 表示UEFI服务使用的Result
pub type UefiResult<T> = uefi::Result<T>;
// 表示UEFI应用程序使用的Result
pub type Result<T> = core::result::Result<T, Error>;

第二个ResultError为我们自定义的ErrorError分为2种UEFI执行中的错误以及应用程序自定义的错误,因此我们可以使用一个枚举来完成

// 用于表示异常的种类,分为UEFI执行错误和UEFI应用程序错误
#[derive(Debug)]
enum Repr {
    /// UEFI服务错误
    Uefi(Efi),
    /// UEFI应用错误
    Custom(Custom),
}

Repr中包含2个结构体EfiCustom结构定义如下

#[derive(Debug, Clone)]
struct Custom {
	/// UEFI应用执行错误类型
    kind: ErrorKind,
    /// UEFI应用执行错误说明
    err_msg: String,
}

#[derive(Debug, Clone)]
struct Efi {
	/// UEFI服务执行结果状态码
    status: Status,
    /// UEFI状态对应说明,如果为None使用默认的提示信息,
    err_msg: Option<String>,
}

// 用于表示UEFI应用异常类型
#[derive(Clone, Copy, Debug, PartialOrd, PartialEq)]
pub enum ErrorKind {
	/// 文件未找到
    NotFound,
    /// 在读取文件中读取到了EOF
    UnexpectedEof,
    /// 无效的文件
    InvalidFile,
    /// 无效的文件模式
    InvalidFileMode,
    /// UEFI错误,包含错误码
    UefiErrorCode,
    /// 终止
    Interrupted,
}

CustomEfi主要的不同在于kind为我们自定义的错误类型,Status表示UEFI服务执行错误的状态码(Status其实是Rust与C的枚举的映射,但是uefi-rs中不是简单地与C枚举映射因为会产生UB(undefined behaviour),而是采取了newtype_enum宏进行处理)

紧接着我们为2种结构提供as_str()方法,ErrorKind的实现比较简单,以下的部分代码

impl ErrorKind {
    pub fn as_str(&self) -> &'static str {
        match *self {
            ErrorKind::NotFound => "entity not found",
            ErrorKind::UnexpectedEof => "unexpected end of file",
            ....
        }
  }
}

但是实现Efi结构的as_str是有些不同了,我们不能写出这样的代码

impl Efi {
    pub fn as_str(&self) -> &'static str {
        match self.status {
        	Status:: WARN_UNKNOWN_GLYPH => "The string contained characters that could not be rendered and were skipped."
        	.....
        }
     }
}

在上面我们也提到了,如果简单的看源码Status确实像枚举,但是其实是结构体,因此我们要判断为Status中具体的值

Status:: WARN_UNKNOWN_GLYPH为例,经过宏扩展后结果为pub struct WARN_UNKNOWN_GLYPH(pub usize),因此我们要以结构体的思路来处理

考虑到完整性列出了所有Status的结果

const ERROR_BIT: usize = 1 << (core::mem::size_of::<usize>() * 8 - 1);


impl Efi {
    pub fn as_str(&self) -> &'static str {
        match self.status.0 {
            0 => "The operation completed successfully.",
            1 => "The string contained characters that could not be rendered and were skipped.",
            2 => "The handle was closed, but the file was not deleted.",
            3 => "The handle was closed, but the data to the file was not flushed properly.",
            4 => "The resulting buffer was too small, and the data was truncated.",
            5 => "The data has not been updated within the timeframe set by local policy.",
            6 => "The resulting buffer contains UEFI-compliant file system.",
            7 => "The operation will be processed across a system reset.",
            ERROR_BIT | 1 => "The image failed to load.",
            ERROR_BIT | 2 => "A parameter was incorrect.",
            ERROR_BIT | 3 => "The operation is not supported.",
            ERROR_BIT | 4 => "The buffer was not the proper size for the request.The buffer is not large enough to hold the requested data.",
            ERROR_BIT | 5 => "The required buffer size is returned in the appropriate parameter.",
            ERROR_BIT | 6 => "There is no data pending upon return.",
            ERROR_BIT | 7 => "The physical device reported an error while attempting the operation.",
            ERROR_BIT | 8 => "The device cannot be written to.",
            ERROR_BIT | 9 => "A resource has run out.",
            ERROR_BIT | 10 => "An inconstency was detected on the file system.",
            ERROR_BIT | 11 => "There is no more space on the file system.",
            ERROR_BIT | 12 => "The device does not contain any medium to perform the operation.",
            ERROR_BIT | 13 => "The medium in the device has changed since the last access.",
            ERROR_BIT | 14 => "The item was not found.",
            ERROR_BIT | 15 => "Access was denied.",
            ERROR_BIT | 16 => "The server was not found or did not respond to the request.",
            ERROR_BIT | 17 => "A mapping to a device does not exist.",
            ERROR_BIT | 18 => "The timeout time expired.",
            ERROR_BIT | 19 => "The protocol has not been started.",
            ERROR_BIT | 20 => "The protocol has already been started.",
            ERROR_BIT | 21 => "The operation was aborted.",
            ERROR_BIT | 22 => "An ICMP error occurred during the network operation.",
            ERROR_BIT | 23 => "A TFTP error occurred during the network operation.",
            ERROR_BIT | 24 => "A protocol error occurred during the network opera
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值