一、系统简介
本操作系统是一个使用rust语言实现,基于32位的x86CPU的分时操作系统。
项目地址(求star):GitHub - CaoGaorong/os-in-rust: 使用rust实现一个操作系统内核
详细文档:自制操作系统 · 语雀
1. 项目特性
在本项目的实现上,我认为该项目有一下特性:
特性 |
说明 |
rust语言实现 |
市面上很多操作系统项目使用的C语言实现,我这里使用的rust实现,可以保证这个项目的代码由我手写实现。也体现了该项目的独特和新颖。 |
基于x86 CPU |
x86是市面上最常见的CPU,基于这种通用大众化的CPU,也能说明本项目用到的知识的通用。 |
拥有OS的基本功能 |
本项目在实现操作系统的功能上,算得上是“麻雀虽小,五脏俱全”。基本操作系统的核心功能都实现了:
这里只是对系统的基本介绍,详细的介绍可以看下面更加详细的介绍。 |
mbr启动、Loader引导 |
本系统使用比较古老的BIOS启动,手写Mbr启动,并且手动实现Loader对系统进行引导。(mbr和loader均为rust实现) |
没使用任何第三方crate |
在市面上很多rust的系统引用了很多第三方的crate,比如blog_os和rCore os。本系统不使用任何第三方crate,所有功能都使用rust的core手动实现。 |
2. 项目结构介绍
如下图是该项目的文件结构:
下面我挑几个重点的模块介绍:
模块名称 |
模块类型 |
模块介绍 |
build |
makefile生成 |
make之后生成的文件 |
cat |
用户程序(独立进程) (写入到文件系统,然后shell可以加载成为一个进程运行) |
自制的cat程序,把文件系统中的文本文件内容输出到控制台 |
echo |
自制echo程序,把echo命令跟着的字符串输出到控制台 |
|
grep |
自制grep程序,根据输入内容,进行过滤,然后输出到控制台 |
|
common |
操作系统内核 源码 |
common包,loader、loader2、kernel都会用到的常用工具 |
mbr |
mbr启动(16位),该模块就两个功能:
|
|
loader |
loader启动(16位):
|
|
loader2 |
loader2启动(32位):
|
|
kernel |
进入内核的最终实现,包括中断、内存管理、线程进程管理、文件系统等等操作系统核心,都在这个模块 |
|
rrt |
Rust RunTime library |
我自制简单的用户程序运行时库,模仿了crt。为用户程序封装了_start入口和exit的调用。 |
target |
cargo生成 |
rust使用cargo生成的二进制文件。忽略 |
tests |
单元测试 |
在这个项目实现中,我写的简单的单元测试 |
3. 项目环境介绍
这里我介绍一下项目的开发环境和运行环境。
开发环境(最终是生成一个32位的基于x86的操作系统二进制文件):
名称 |
值 |
版本信息 |
操作系统 |
MacOS |
Ventura 13.0.1 |
CPU |
Apple M1 |
|
编译器 |
rustc |
|
包管理工具 |
cargo |
|
自动化工具 |
make |
GNU Make 3.81 |
elf文件二进制提取工具 |
x86_64-linux-gnu-objcopy |
GNU objcopy (GNU Binutils) 2.41 |
elf文件dump工具 |
x86_64-linux-gnu-objdump |
GNU objdump (GNU Binutils) 2.41 |
运行环境(把这个x86的32位的操作系统镜像运行在虚拟机中):
名称 |
值 |
环境版本信息 |
虚拟机 |
qemu-system-x86_64 |
QEMU emulator version 8.2.1 |
虚拟机2 |
bochs |
Bochs x86 Emulator 2.8 |
这里不得不说rust的跨平台开发能力太好了,我在Mac M1上开发,生成一个 x86 的 ELF文件。然后在启动一个qemu虚拟机运行。
4. 项目运行效果
这里给大家展示一下我的操作系统的基本功能。
下面我从这几个方面来展示:
- 内置命令
- 文件系统操作
- 从文件系统加载进程
- Shell多进程通信(管道)
4.1. 内置命令
先看内置命令,目前我的系统内置了如下命令(排除文件系统操作和加载可执行文件):
命令名称 |
命令用途 |
命令展示 |
pwd |
展示当前工作目录 |
|
ps |
查询当前的所有任务 |
|
clear |
清屏 |
|
ctrl + l快捷键 |
清屏 |
|
ctrl + u快捷键 |
删除当前行的输入 |
这是一些基础并且跟功能无关的命令。下面请看我们使用操作系统中,最常用的文件系统相关的命令。
4.2. 文件系统命令
我们使用一个操作系统,最常用的一定是文件系统相关的命令,比如「文件的增、删、改、查」、「目录的增、删、改、查」。我在本系统中基本都实现了,如下表所示:
命令名称 |
命令用途 |
命令展示 |
ls |
展示当前目录下的所有文件。 |
这里的 |
ls -l |
展示当前目录下的文件细节 |
file_type中,"-"表示普通文件,"d"表示文件夹 |
cd |
切换当前工作目录 |
|
mkdir |
在当前工作目录下,创建一个目录 |
|
rmdir |
删除某个目录名称 |
|
touch |
创建一个普通文件 |
创建了一个名为"file"的普通文件 |
看到这里可能会问,怎么没有读写文件的命令?我们一般使用cat
命令读取文件,并且我们会使用echo hello > hello.txt
来写入文件。
这个cat
和echo
命令是我写的用户程序,这种程序是属于从硬盘加载后作为进程执行的。因此这个放到下一节。
4.3. 从文件系统加载进程
上面讲的都是内置的命令,都比较简单而且固定。下面就是要从文件系统加载可执行程序执行了。
在上面讲项目结构中,我提到我实现了3个用户程序,作为小工具:
这三个小工具分别是:
cat
:把一个文件的内容输出到控制台echo
:把命令后面跟着的字符串输出到屏幕grep
:使用正泽匹配过滤输入,然后把过滤后的结果输出
本小结,我就展示cat
和echo
实现读、写一个文件。
命令名称 |
展示效果 |
echo |
我这里先创建「hello.txt」文件,然后把"hello"字符串写入到 hello.txt文件中 |
cat |
我这里使用 |
">"和">>"输出到文件 |
这里使用echo 和 ">>" 追加 数据到 hello.txt文件中 |
这里我简单展示了echo
和cat
的执行效果。
这里得注意,echo
和cat
是两个在文件系统的文件,这里体现出来的是 把 可执行文件 从文件系统加载到内存,然后成为一个独立的用户进程执行的过程。
4.4. Shell多进程通信(管道)
另外我们在Shell常用的一个功能就是“管道”,这个也是进程间通信的一种方