操作系统实验一——实现最小内核

实现最小内核
1、实验目的:
构建最小内核
2、实验内容:
安装必要的工具链、编写裸机程序(独立式可执行程序)、构建最小的内核系统。
3、实验环境:
Windows下的Linux-Ubuntu64
4、实验步骤:
一、安装准备工具curl
安装这个是因为在装rust的时候错,显示我没有安装curl,所以要先下载curl。
刚开始我没有在root模式下下载,出现了错误,之后在利用su root指令切换到根模式的时候,我输入密码一直报错,之后改用指令 sudo -i就可以了。出现的错误如下:
在这里插入图片描述

起初直接利用命令sudo apt install curl指令来进行下载,但是出现了如下所示的问题:
在这里插入图片描述

上述问题显示的是没有办法找到下载源,所以考虑换一个下载源,按照csdn博客上的步骤来解决如下:
在这里插入图片描述
在这里插入图片描述在这里插入图片描述

最后成功安装了curl,结果如上图所示。
二、安装Rust
1、下载Rust:curl https://sh.rustup.rs -sSf | sh
这里会出现如上图所示的现象,这里是选择安装的版本,我在这里选择版本1,直接输入1即可。之后出现下载进度条则表示正在进行下载,等待下载完成即可,结果如下:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

验证安装是否成功:输入rustc --version,这里是查看当前rust的版本的意思,如果出现当前的版本号,表示安装成功。
这里我遇到问题了–没有下载rustc,如下图:
在这里插入图片描述
所以先要下载rustc,再验证,结果如下:
在这里插入图片描述
可以看到rust版本号为1.43.0,所以安装成功了。
在这里插入图片描述
2、安装nightly版本:rustup install nightly
在这里插入图片描述
安装结果:
在这里插入图片描述
3、默认使用 nightly 版本:rustup default nightly
成功安装,结果如下所示:
在这里插入图片描述
4、安装 bootimage,xbuild 和 rust-src 等
依次输入如下命令:
cargo install bootimage --version “ˆ0.7.3”
cargo install cargo-xbuild
rustup component add rust-src
rustup component add llvm-tools-preview
1)安装bootimage时出现如下错误:
在这里插入图片描述
根据错误提示可以知道,出现上述问题的原因是提供的“-vers”0.7.3不是有效的semver版本:无法将“ˆ0.7.3”解析为semver。解决方法是将“^0.7.3”改为0.7.3,否则无法识别0.7.3,改好结果如下:
在这里插入图片描述
上述读条就是正在进行下载,这个下载的十分慢,静心等待即可,下载好的结果如下:
在这里插入图片描述
2)安装cargo-xbuild–cargo install cargo-xbuild
在这里插入图片描述
安装结果如下:
在这里插入图片描述
3)安装rust-src :rustup component add rust-src
安装结果如下:
在这里插入图片描述
4)安装llvm-tools-preview:rustup component add llvm-tools-preview
安装结果如下:
在这里插入图片描述
在这里插入图片描述

三、安装其他工具
a)安装QEMU:
输入如下指令:/usr/bin/ruby -e “$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)”
brew install qemu
出现如下所示的问题:找不到目标文件夹
在这里插入图片描述
所以考虑换一种安装方式,即sudo apt-get install qemu,这种方案可行,开始安装:
在这里插入图片描述
成功安装,结果如下所示:
在这里插入图片描述
四、创建裸机程序
1、创建项目cargo new rui_os –bin –edition 2018
在这里插入图片描述
2、编写src/main.rs源码
打开src文件夹下的main.rs文件,写入如下所示代码:
在这里插入图片描述
3、编写Cargo.toml源码
打开Cargo.toml文件,写入如下所示代码:
在这里插入图片描述
4、编译–cargo rustc −− −C link-arg=-nostartfiles

问题1:找不到文Carg0.toml
在这里插入图片描述
解决办法:进入文件夹han_os – cd han_os
在这里插入图片描述
问题1得到了解决。
问题2如下所示:
在这里插入图片描述
出现上述问题是因为我将pdf说明文档中的代码复制过来的时候,多了很多空格出来,并且代码和源代码不一致,所以我就进行了修改,部分如下所示:
在这里插入图片描述
去掉空格之后问题2得到了解决,但又出现了新的问题。

问题3:尝试着改用指令cargo rustc/cargo build时链接器报错
在这里插入图片描述
首先查看当前的目标三元组,即输入rustc --version --verbose
在这里插入图片描述
添加thumbv7em,即输入rustup target add thumbv7em-none-eabihf,这行命令将为目标下载一个标准库和core库,之后就能为这个目标构建独立式可执行程序。但是显示我rustup未下载:
在这里插入图片描述
利用命令sudo apt-get install rustup进行下载,结果如下:
在这里插入图片描述
然后再次使用命令:rustup target add thumbv7em-none-eabihf,提示我没有默认工具链集,解决办法:利用指令rustup toolchain install 1.27.1进行下载。下载结果如下:
在这里插入图片描述
但是仍然不行,所以我放弃了这种解决办法。然后去网上查找解决办法,发现解决链接器报错的方法就是是用指令cargo rustc – -C link-arg= -nostartfiles,测试如下:
在这里插入图片描述
但是为什么我直接复制说明文档中的指令就会报错呢?如下图:
在这里插入图片描述
通过对比我发现,上下两个指令看上去是一样的,但是仔细看会发现是不同的,仔细观察就会发现rustc和C之间那三个短线是有区别的。同时指令当中也不能多出来空格,否则就会报错。下图就是多出一个空格和没有多空格的结果对比:
在这里插入图片描述
编写的裸机程序最终正确运行的结果如下图所示:
在这里插入图片描述

五、实现最小核
1、编写src/main.rs 源码
将说明文档中的程序复制过去即可,但要注意复制过去之后与源码是否一致,如下图所示:
在这里插入图片描述
2、编写x86_64-rui_os.json 源码
在操作系统(xx_os,这里是han_os文件夹)文件夹下面新建一个文件,然后命名为x86_64-han_os.json,当然名称可以随便改。如下图所示:
在这里插入图片描述
然后将说明文档里的内容直接复制进去即可,要注意复制过去之后与源代码是否一致,如下图:
在这里插入图片描述
3、将json文件加入–target选项,并尝试编译我们的内核
输入指令cargo build --target x86_64-han_os.json,报错,rust编译器找不到core或compiler_builtins包:
在这里插入图片描述
改用指令cargo xbuild --target x86_64-han_os.json,这个指令可自动下载并找到cargo xbuild库:
在这里插入图片描述
改用指令之后又出现上述问题,这个问题提示我选择使用nightly的版本,可能是因为我之前nightly版本没有安装好,现在就来解决这个问题。
解决办法:首先我将在root模式下下载的软件在用户模式下又下载了一遍;然后添加rust的路径source $HOME/.cargo/env,即在下载rust的时候注意添加路径,部分操作如下图所示:
在这里插入图片描述
然后进行编译测试,结果如下:
在这里插入图片描述
在这里插入图片描述
重启之后在进行测试可以发现依然是正确的,该问题得到了解决。

4、设置默认目标
为了避免每次使用cargo xbuild时传递 --target参数,可以覆盖默认的编译目标,创建一个名为.cargo/config的cargo配置文件,并添加如下内容:
#in .cargo/config
[build]
target=“x86_64-han_os.json”
在文件管理中选择显示隐藏文件夹,在HOME文件夹中找到名为.cargo的文件夹,在其里面创建一个空白文件,并命名为config,然后添加代码。如下图:
在这里插入图片描述
出现了如下所示的问题:
在这里插入图片描述
尝试着将x86_64-han_os.json文件移动到主目录下进行测试,但是又出现如下所示的问题:
在这里插入图片描述
出现这个错误的原因是config文件中写入的内容不正确,使得x86_64-han_os.json无法被找到,所以说在编写config的时候应该加入x86_64-han_os.json的文件路径,如下图所示:
在这里插入图片描述
修改完成之后再进行测试,发现结果正确,如下图:
在这里插入图片描述
5、向屏幕打印字符
首先对main文件和cargo.toml进行修改,如下所示:
在这里插入图片描述
在这里插入图片描述
在这段代码中,我们预先定义了一个字节字符串(byte string)类型的静态变量(static variable),名为HELLO。我们首先将整数0xb8000转换(cast)为一个裸指针(raw pointer)。这之后,我们迭代HELLO的每个字节,使用enumerate获得一个额外的序号变量i。在for语句的循环体中,我们使用offset偏移裸指针,解引用它,来将字符串的每个字节和对应的颜色字节——0xb代表淡青色——写入内存位置。

6、启动内核
我们需要首先创建引导映像,要将可执行程序转换为可引导的映像(bootable disk image),我们需要把它和引导程序链接。这里,引导程序将负责初始化CPU并加载我们的内核。
编写引导程序并不容易,所以我们不编写自己的引导程序,而是使用已有的bootloader包[5];无需依赖于C语言,这个包基于Rust代码和内联汇编,实现了一个五脏俱全的BIOS引导程序。为了用它启动我们的内核,我们需要将它添加为一个依赖项,在Cargo.toml中添加下面的代码:# in Cargo.toml [dependencies] bootloader = “0.6.0”,如下图所示:
在这里插入图片描述
只添加引导程序为依赖项,并不足以创建一个可引导的磁盘映像;我们还需要内核编译完成之后,将内核和引导程序组合在一起。在这里我们需要使用bootimage工具,它将会在内核编译完毕后,将它和引导程序组合在一起,最终创建一个能够引导的磁盘映像。
在利用cargo bootimage指令进行编译的的时候出现如下所示的问题:
在这里插入图片描述
上述问题描述的是LLVM-style的问题,出现的原因是在cargo.toml文件中;我的修改方法是将cargo.toml中的bootloader改为0.9.11进行尝试,发现上面的问题消失了,如下图:
在这里插入图片描述
出现了新的错误是Error: The bootloader dependency has not the right format: bootloader has no executable,“bootloader”依赖项的格式不正确:bootloader没有可执行文件,即出现了版本不兼容的问题
解决办法:更改下bootimage的版本,改用.0.7.10:
在这里插入图片描述
但是在下载0.7.10版本的时候出现如上图所示的问题,解决办法是将.cargo文件夹中config中的两行内容注释掉,再进行安装,因为这俩行对build重定义了,不注释的话又找不到库了,注释如下图:
在这里插入图片描述
安装结果如下图:
在这里插入图片描述
在这里插入图片描述
安装成功之后再次进行编译测试:
在这里插入图片描述
从上图我们可以发现是成功完成了编译的,之前的问题得到了解决。
事实上,在这行命令背后,bootimage工具执行了三个步骤:编译我们的内核为一个ELF(Executable and Linkable Format)文件;编译引导程序为独立的可执行文件;将内核ELF文件按字节拼接(append by bytes)到引导程序的末端。
当机器启动时,引导程序将会读取并解析拼接在其后的ELF文件。这之后,它将把程序片段映射到分页表(page table)中的虚拟地址(virtual address),清零BSS段(BSS segment),还将创建一个栈。最终它将读取入口点地址(entry point address)——我们程序中_start函数的位置——并跳转到这个位置。

7、在QEMU中启动内核
现在我们可以在虚拟机中启动内核了。为了在QEMU中启动内核,我们使用下面的命令:

qemu-system-x86_64 -drive format=raw,file=bootimage-blog_os.bin
但是直接在han_os中运行的时候出现了如下所示问题:
在这里插入图片描述
解决办法:在HOME/JUNMO2_OS/TARGET/X86_64-BLOG_OS/DEBUG文件夹下面,即bin文件所在的文件夹下打开终端并输入指令,注意需要按照生成的bin文件的文件名来修改输入的命令,如我这里就修改为了han_os。修改之后发现正确,结果如下图所示:
在这里插入图片描述
8、使用cargo run
在cargo配置文件(config文件)中设置runner配置项,即输入如下代码:

in .cargo/config

[target.‘cfg(target_os = “none”)’]
runner = “bootimage runner”
在这里插入图片描述
然后在han_os文件下输入命令cargo run执行,发现报错–无法找到库,如下图所示:
在这里插入图片描述
解决办法:改用指令cargo xrun,原因和利用cargo xbuild类似,修改之后的结果如下图所示:
在这里插入图片描述

5、实验结果:
成功的构建出了内核,并且利用所构建出来的最小内核成功打印出了字符串hello world,说明了这个最小内核是可以正常工作的。

6、反思与总结
经过这次实验,在ubuntu上构建出了一个可以正常工作的最小内核,并且在linux系统上进行了验证,结果是好的,但是在实验的过程中,也遇到了许多问题:下载工具链失败、利用指令编译失败等等,这些问题给我带来了很大的困扰,但是正是这种不断出现问题解决问题的情况,让我在实验过程中保持着很高的积极性,经过自己的努力解决了出现的问题之后,是十分开心的;并且在这次实验中也学到了很多新的知识,收获很多。

  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值