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?