11.1. 命令行——输出

本章代码对应 commit :8b2476d3892ea5689420cbb1460210ba29bee6bc

打包程序

创建 usr/rust/src/bin/shell.rs

#![no_std]
#![no_main]

#[macro_use]
extern crate rust;

// IMPORTANT: Must define main() like this
#[no_mangle]
pub fn main() -> i32 {
    println!("Rust user shell");
    loop {}
}

修改 Makefile,将用户程序和 shell 打包成 img :

# in Makefile

usr_path := usr

export SFSIMG = $(usr_path)/rcore32.img


# in usr/Makefile
.PHONY: all clean rust build
all: rust build
build: $(out_img)

$(out_img): rust
    @rcore-fs-fuse $@ $(out_dir) zip

rcore-fs-fuse:
ifeq ($(shell which rcore-fs-fuse),)
    @echo Installing rcore-fs-fuse
    @cargo install rcore-fs-fuse --git https://github.com/rcore-os/rcore-fs --rev c611248
endif

执行 make 生成的 rcore32.img 就是我们的目标文件。

解析文件

rcore32.img 里面目前只包含了 shell ,以后可以添加更多的文件。现在我们需要将其中的 shell 解析出来并且加入到线程中:

这样文件的解析和加载就完成了。看似简单,但是其中最复杂的 fs crate 我们尚未实现。现在我们来填这个坑吧。

文件系统

实现命令行的过程其实包含了实现一个简单的文件系统,创建目录 fs :

可以将之前生成的 rcore32.img 理解为一块磁盘,里面包含了我们所需要的程序(ELF 格式)。这里将存储磁盘文件的内存范围初始化为虚拟磁盘(Membuf),然后通过 look_up 函数查找虚拟磁盘中的目标内容的起始位置。找到后利用其元数据(metadata)确定长度,最后将该范围内的 ELF 程序读取,最后加载运行。

执行 make run ,可以看到:

此时命令行已经可以正常输出文本了,但是我们目前还不能输入任何信息,而这将是我们下一章的工作。

Last updated

Was this helpful?