简述

在一切开始之前,请允许我先简要地介绍一下关于这个实验的一切

它是关于什么的

这一系列日志将是我对大二下学期操作系统实验课程中实验的一个整体回顾与记录。

当然,在我写下这些的时候,我还完全不知道这份日志可以做到怎样的完成度,但我仍希望在我写下这些文字的暑假里能够以一系列详实、可复现的日志作为我对过去这一个学期里的这样一门有趣的课程的一个交代。

它有什么用

我希望,通过这一系列日志,可以

  • 记录我完成一个简单操作系统的全部过程
  • 记录在完成操作系统实验中可能遇到的难题和它们的解决方案
  • 作为一份简易操作系统的简易教程,帮助我自己或是别人复现这个实验

那么,准备好了吗?
我们开始吧!

环境搭建

在介绍具体的安装方法前,先在此列出所有需要的环境,方便快速对照安装

必须的

由于实验的需要,以下环境是必须准备

  • Linux环境:由于代码编译和虚拟机运行需要依赖Linux环境,因此需要准备一个Linux设备,在我的实现中使用了VMWare WorkStationUbuntu 20.04 LTS的组合
  • QEMU:安装在Linux环境下的虚拟机,用来运行编写的操作系统
  • C/C++编译环境:代码编译需要,下列不完全
    • CMake:编写makefile需要
    • GCC/LLVM:编译器,在我最初的实现中使用了GCC,但是由于操作系统涉及到很多*bare-metal C++*也就是脱离C/C++标准库的代码,GCC在编译的时候会遇到一些棘手的问题,这些问题当然在LLVM中也会遇到,但相对GCC更好解决一些,故在我的实现中最后改为了使用LLVM作为编译器
  • NASM:汇编代码编译器

建议的

为了提升在实验过程中的编写、调试等体验,以下环境是可选的,并且在我的实现中安装

Windows

  • VSCode:现代IDE,可选安装如下插件
    • ASM Code Lens或其他asm插件:提供asm语法高亮
    • C/C++:提供C/C++语法高亮
    • CMake, CMake Language Support, CMake Tools:提供CMake支持
    • Hex Editor:调试时查看生成的二进制文件
    • GitLens:优秀的Git可视化管理工具,提供了比VSCode原生更丰富的功能,包括分支等
    • Remote-SSH等Remote家族:提供远程连接Linux环境支持,使得可以在Windows环境下直接编写Linux环境中的代码并且进行编译等基本操作
  • Windows 11:提供了更漂亮的PWS/CMD工具
  • Windows终端Microsoft Store中提供的开源的漂亮的命令行工具,用于连接Linux shell
  • IDA:在调试bug的时候用于打开.o文件看看里面发生了什么奇怪的错误

Linux

  • git:不多解释了,基本上啥都要用到这个
  • ZSH:终端美化
    • powerlevel10k:个人使用的主题
  • pwndbg:好用的GDB工具

Ubuntu安装指南

Ubuntu版本以进行实验时的20.04LTS版本为例,其他版本的安装方式基本相同

前往Ubuntu官网处下载对应版本的镜像文件

镜像下载页

下载页面会随时间改变,如果需要下载旧版本Ubuntu,可以进入alternative downloads页面下载

下载得到一个文件名如ubuntu-20.04.4-desktop-amd64.iso的镜像文件

有了镜像文件以后,就可以进入下一步,在虚拟机中使用该镜像安装系统了

由于我在实验中使用的是VMWare Workstation,此处以VMWare Workstation Pro 16为例进行介绍,其他虚拟机可以使用搜索引擎查询对应Linux配置方式

在VMWare Workstation中安装Ubuntu的步骤如下:

  1. 创建新的虚拟机
  2. 配置选择自定义(高级)
  3. 硬件兼容性选择Workstation 16.2.x
  4. 选择稍后安装操作系统
  5. 安装的系统选择LinuxUbuntu 64位
  6. 设置名称位置
  7. 根据CPU设置处理器内核数
  8. 内存大小设置为4~8GiB
  9. 网络类型设置为NAT
  10. I/O控制器类型选择为LSI Logic
  11. 虚拟磁盘类型选择SCSI
  12. 磁盘选择创建新虚拟磁盘
  13. 自由设置其他内容

硬件配置如下

图 4

为了从上一步下载的镜像文件中安装系统,需要编辑虚拟机设置,在CD/DVD的连接栏选择使用ISO映像文件并设置为上一步中下载的镜像文件,同时勾选启动时连接

如果设备中没有找到CD/DVD,需要通过下方添加添加一个CD/DVD驱动器

在启动虚拟机之前,由于在某些情况下虚拟机的显示分辨率会太低导致显示不出安装界面的下一步按钮,因此在启动之前可以在虚拟机设置中调整显示器分辨率。

这里将显示器设备中的监视器一栏设置为指定监视器设置并设置最大分辨率为当前显示器的分辨率

如果这一步没有产生效果,并且在安装时确实遇到了无法点击按钮的情况,可以在第一步选择Try Ubuntu进入桌面

之后右键在Display Settings中设置分辨率和缩放

如果没有合适的缩放,可以开启Fractional Scaling进行小数位缩放,可以多出125%、150%和175%的缩放比设置

设置好后启动虚拟机,进入.iso文件中的系统,启动后会自动进入Ubuntu安装程序

如果这一步无法启动,检查CD/DVD是否设置为启动时连接

安装步骤如下:

  1. 安装程序中选择Install Ubuntu进入安装
  2. 检查键盘布局是否正确,具体测试方式为在输入栏中测试键盘各个键输入是否符合预期
  3. 选择Minimal installation进行最小安装,同时可以取消勾选Download updates while installing Ubuntu,避免因为遇到无法访问的情况卡住安装,更新可以在后续换源后进行,这里可以不着急
  4. 简便起见,在Installation type步骤可以直接选择Erase disk and install Ubuntu,如果有自己的分区喜好,可以选择Something else,具体分区方式网上有完备介绍,可以跟随教程设置,完成后选择Install Now
  5. 时区选择Shanghai
  6. 设置用户名密码
  7. 点选Continue执行安装即可

在安装完成之后,系统会提示是否重启系统,由于需要关闭CD/DVD驱动器以免再次进入安装系统,在这一步不进行重启系统,关闭该通知进入系统桌面,右上角菜单选择关机,关机过程中会有一个提示移出安装媒介并按回车键,直接按回车关机即可

关机后进入编辑虚拟机设置页,移出CD/DVD设备或是取消勾选该设备的启动时连接

完成后启动虚拟机进入安装好的系统,开机后使用安装时设置的用户密码登录,初次启动会有一些提示框,基本一直下一步即可进入桌面

进入系统以后同样会遇到分辨率问题,可以参照上文调整分辨率和缩放

一切准备好之后,就可以进行下一步的换源操作了

此处以清华源为例进行配置,同样也可以选择企业提供的镜像源,如阿里源,在一定程度上企业源会比大学镜像源更加可靠,可以酌情选择

换源实质上就是更改系统所使用的软件源的配置文件,因此要做的事就只有两件:

  • 去使用的源的网站获取当前版本的配置文件
  • 修改系统中原本的配置文件

清华源中给出的Ubuntu 20.04 LTS版本的配置文件如下,复制该配置文件内容

1
2
3
4
5
6
7
8
9
10
11
12
13
# 默认注释了源码镜像以提高 apt update 速度,如有需要可自行取消注释
deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ focal main restricted universe multiverse
# deb-src https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ focal main restricted universe multiverse
deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ focal-updates main restricted universe multiverse
# deb-src https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ focal-updates main restricted universe multiverse
deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ focal-backports main restricted universe multiverse
# deb-src https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ focal-backports main restricted universe multiverse
deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ focal-security main restricted universe multiverse
# deb-src https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ focal-security main restricted universe multiverse

# 预发布软件源,不建议启用
# deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ focal-proposed main restricted universe multiverse
# deb-src https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ focal-proposed main restricted universe multiverse

对于不同版本的Ubuntu,配置文件会有所不同,体现在链接后面的focal字样,该字段是Ubuntu的版本号,例如Ubuntu 18.04的版本号就是仿生鱼bionic而Ubuntu 22.04LTS版本号为jammy

如果选择了错误的配置文件,会使得后续apt update环节出现奇怪的错误,因此一定要选择版本对应的配置文件

在终端中输入

1
sudo vim /etc/apt/sources.list

如果还没有安装vim,可以

  • 改成使用vi而不是vim,在换源后再安装vim
  • 执行sudo apt-get update && sudo apt-get install vim安装vim继续

首先注释掉原先的内容,然后在文件尾追加上文中复制的配置文件,之后保存退出

在vim中使用I进入编辑模式,使用ESC退出编辑模式

在非编辑模式下输入:wq保存并退出,输入:q退出,输入:q!放弃更改退出

在vim中可以使用如下方式批量添加注释

  1. Ctrl+V进入列选择模式
  2. J / K / / 移动光标选中行
  3. Shift+I(这一步会让光标移到选中列的第一行第一个字符之前,但实际上光标在所有选中行的第一个字符之前)
  4. Shift+3(输入注释符#
  5. ESC退出

保存了新的配置文件以后,执行如下命令执行更新

1
sudo apt-get update

执行了更新之后就完成了换源的全部步骤,可以进入下一步安装其他软件环境了!

安装C/C++环境

终端执行以下命令

1
2
sudo apt install binutils
sudo apt install gcc

或者使用一行命令

1
sudo apt install binutils && sudo apt install gcc

检查是否安装成功

1
gcc -v

如果输出gcc的版本号则表明安装成功

安装NASM

首先检查已经安装的nasm版本

1
nasm -v

如果已经是2.15^版本则可以跳过本节,如果不是的话则需要安装2.15^版本的nasm

首先根据网上教程的指引,下载压缩包

1
2
$ wget https://www.nasm.us/pub/nasm/releasebuilds/2.15.05/nasm-2.15.05.tar.xz
Download time (Average speed) - `nasm-2.15.05.tar.xz` saved [995732/995732]

然后进行解压和配置文件生成

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
$ tar -xvf nasm-2.15.05.tar.xz
nasm-2.15.05/
nasm-2.15.05/AUTHORS
...
nasm-2.15.05/doc/nasmlogw.png

$ cd nasm-2.15.05/

$ ./configure
checking for prefix by checking for nasm... no
...
configure: creating ./config.status
config.status: creating Makefile
config.status: creating doc/Makefile
config.status: creating config/config.h

上面的bash代码不要直接复制,其包含了输出的显示

只有 $ 后的内容才需要输入,其他的内容为预期的输出显示

最后进行make安装

1
2
make
sudo make install

安装LLVM

如果打算使用LLVM作为编译器,则可以参照官网安装指南进行安装,下面给出脚本安装方式

1
sudo bash -c "$(wget -O - https://apt.llvm.org/llvm.sh)"

安装后的clang可能不叫作clang,因此直接执行clang -v可能会报错未安装

输入clang后按TAB两次可以看到安装了的clang版本,例如clang-14clang++-14,这样输入clang-14 -v就能够显示版本了

之后在编写makefile的时候也要注意不要将编译器写为单独的clang,而是带后缀的安装了的版本

安装其他工具

终端执行以下命令

1
2
3
4
5
6
7
8
9
10
sudo apt install git
sudo apt install qemu
sudo apt install cmake
sudo apt install libncurses5-dev
sudo apt install bison
sudo apt install flex
sudo apt install libssl-dev
sudo apt install libc6-dev-i386
sudo apt install gcc-multilib
sudo apt install g++-multilib

或是输入一行指令

1
sudo apt install git && sudo apt install qemu && sudo apt install cmake && sudo apt install libncurses5-dev && sudo apt install bison && sudo apt install flex && sudo apt install libssl-dev && sudo apt install libc6-dev-i386 && sudo apt install gcc-multilib && sudo apt install g++-multilib

通过设置Ubuntu环境下的SSH,可以让Windows能够通过SSH连接到Ubuntu环境的shell,从而可以在Windows环境下完成大部分操作

除此之外,通过VSCode中的Remote插件,可以在Windows环境下编写Ubuntu中的文件

如果你希望在Ubuntu中完成所有代码的编写,则这一步不是必须的

通过如下命令安装ssh

1
sudo apt-get install ssh

之后配置密钥登录所必须的文件目录和文件并设置权限

1
2
3
4
mkdir ~/.ssh && cd ~/.ssh
touch authorized_keys
chmod 600 ~/.ssh/authorized_keys
chmod 700 ~/.ssh

通过修改sshd配置文件关闭密码登录并打开密钥登录

打开sshd_config文件

1
sudo vim /etc/ssh/sshd_config

之后在# Authentication:下修改如下键值,同时如果有注释则关闭注释

1
2
PubkeyAuthentication yes
PasswordAuthentication no

保存退出后重启sshd服务

1
service sshd restart

之后,需要在VMWare Workstation里转发22端口到虚拟机

为了完成这个任务,需要先获取虚拟机的ip地址

1
2
3
4
$ ip a
...
inet 192.168.XXX.XXX/24 brd 192.168.XXX.255 scope global dynamic noprefixroute ens33
...

可以看到输出中给出的ipv4地址,这里假设为192.168.85.130,记住该地址

进入VMWare Workstation中的 编辑-虚拟网络编辑器-更改设置-VMnet8 NAT模式-NAT设置,添加端口转发规则

主机端口 类型 虚拟机IP地址 虚拟机端口 描述
22 TCP 192.168.85.130 22 SSH

保存并应用设置就完成了端口转发的添加

最后,为了能够让Windows能够顺利连接上虚拟机,需要在Windows环境下生成密钥并且拷贝公钥到上文中创建的authorized_keys文件中

下述操作将在Windows环境中进行

首先,需要在Windows环境下安装OpenSSH,参照Microsoft官方文档给出的指南,可以使用Powershell安装OpenSSH

以管理员身份运行Powershell并且检查OpenSSH的安装情况

1
Get-WindowsCapability -Online | Where-Object Name -like 'OpenSSH*'

如果两者均没有安装,则会返回如下输出

1
2
3
4
5
Name  : OpenSSH.Client~~~~0.0.1.0
State : NotPresent

Name : OpenSSH.Server~~~~0.0.1.0
State : NotPresent

之后,根据需要安装对应未安装的组件

1
2
3
4
5
# Install the OpenSSH Client
Add-WindowsCapability -Online -Name OpenSSH.Client~~~~0.0.1.0

# Install the OpenSSH Server
Add-WindowsCapability -Online -Name OpenSSH.Server~~~~0.0.1.0

这两者都应该返回如下输出

1
2
3
Path          :
Online : True
RestartNeeded : False

之后,使用终端生成密钥

1
2
3
ssh-keygen -t rsa
# Or
ssh-keygen -t ed25519

根据提示设置对应的文件位置(默认为%USERPROFILE%\.ssh\id_rsa)以及密码

然后使用cat命令显示公钥内容,假定公钥文件为C:\Users\Linloir\.ssh\id_ed25519.pub

1
cat C:\Users\Linloir\.ssh\id_ed25519.pub

会返回一个类似如下的输出

1
ssh-ed25519 AAAAC3N******************TzC6 linloir@******

拷贝该输出,并回到Linux操作

如果希望在Windows和Linux虚拟机间复制内容,可以在VMWare中安装VMWare Tools或Open VM Tools

如果VMWare Tools安装选项为灰色,可以参照网上的博客进行如下操作

  1. 关闭虚拟机
  2. 打开虚拟机设置
  3. 如果在前序步骤删除了CD/DVD设备,则添加回来
  4. 取消勾选CD/DVD设备的 启动时连接,同时勾选 使用物理驱动器-自动检测
  5. 重启虚拟机

在测试过程中,安装VMWare Workstation自带的VMWare Tools会提示建议安装Open VM Tools

可以结束安装并参照官方文档或是Github页面中的指南使用sudo apt-get install open-vm-tools-desktop安装

Linux终端中使用vim修改authorized_keys文件

1
vim ~/.ssh/authorized_keys

进入编辑模式粘贴上文中复制的密钥内容后保存退出

最后可以在Windows环境下使用下述命令测试连接到虚拟机

<username>中填写Linux用户名,<ip>填写前文中获得的虚拟机ip地址

1
ssh <username>@<ip>

如果连接成功,则证明完成了SSH的全部配置内容,同样,也完成了Ubuntu环境的全部配置!

接下来,可以直接进入下一节或是跟随教程完成Windows下使用工具的配置和安装

Windows环境配置指南

如果希望在Linux环境下完成所有代码编写与调试,可以跳过此节

为了提升代码编写体验,在本节中将会介绍如何在Windows环境下配置和使用VSCode以及其插件,从而能够在Windows环境下使用VSCode编写Linux中的代码

同样,还会介绍通过Windows终端连接Linux终端的方式,并在Windows环境下配置Linux环境中的ZSH终端以及powerlevel10k主题

前往VSCode官网下载并安装VSCode

安装完成后进入VSCode页面,在左侧栏中有一积木样图标,点击进入VSCode的插件安装页

搜索并安装以下插件,具体安装的插件可以根据自己的喜好选择,其中Remote家族为连接虚拟机所需要的插件

  • C/C++ (Microsoft)
  • Chinese (Simplified)(简体中文) Language Pack For Visual Studio Code (Microsoft)
  • CMake Tools (Microsoft)
  • Hex Editor (Microsoft)
  • Remote - SSH (Microsoft)
  • Remote - SSH:Editing Configuration Files (Microsoft)
  • The Netwide Assembler (NASM) (Right)

在完成了Remote家族插件的安装后,侧边栏会有一远程连接的图标,点击可以进入远程资源管理器

选择SSH Target以添加虚拟机,之后在SSH TARGETS菜单处点击添加键,在弹出窗口中输入

1
ssh <username>@<ip>

在弹出的Select SSH configuration file to update页面中选择默认选项,也即直接按回车

之后在左侧SSH TARGETS菜单栏能够看到新添加的地址,鼠标移至其上方,点击其右侧文件夹图标在新窗口中打开

Select the platform for the remote host窗口中选择Linux

之后输入在上文 配置SSH 中生成密钥步骤中设置的密码即完成连接

快试试在侧边栏中的文件页面中打开Ubuntu中的项目文件夹吧!

在我的实验中,在Windows中使用了Windows Terminal,在Linux中使用了ZSH+powerlevel10k的组合,你也可以根据你的喜好设置自己的终端和主题

首先,在Windows Terminal中使用ssh连接到虚拟机终端

之后,根据ZSH Wiki页面的教程安装ZSH

1
2
3
4
5
6
7
8
9
10
11
12
# 安装
$ sudo apt install zsh

# 验证安装
$ zsh --version
zsh 5.8 # 或者是更新的版本

# 设置为默认shell
$ chsh -s $(which zsh)

# 退出登录
$ exit

然后重新使用ssh登录,初次进入会进行设置,可以根据自己的喜好进行设置或者直接选择Populate your ~/.zshrc with the configuration recommended by the system administrator and exit进行默认设置

关于各个设置项作用将会在日后更新(如果有空)

之后依据Oh My Zsh官网来安装Oh-My-Zsh框架

1
sh -c "$(wget https://raw.github.com/ohmyzsh/ohmyzsh/master/tools/install.sh -O -)"

完成设置就代表着Zsh安装完成,可以进行后续主题安装

在安装powerlevel10k主题前,需要安装其依赖的字体

双击打开下载的字体文件进行安装,之后进入Windows Terminal设置配置文件默认值外观字体,选择MesloLGS NF字体

然后使用git安装该主题

1
git clone --depth=1 https://github.com/romkatv/powerlevel10k.git ${ZSH_CUSTOM:-$HOME/.oh-my-zsh/custom}/themes/powerlevel10k

可以使用gitee加速下载

1
git clone --depth=1 https://gitee.com/romkatv/powerlevel10k.git ${ZSH_CUSTOM:-$HOME/.oh-my-zsh/custom}/themes/powerlevel10k

~/.zshrc中设置ZSH_THEME="powerlevel10k/powerlevel10k并重启Zsh

1
2
vim ~/.zshrc
exec zsh

之后根据设置向导设置主题即可得到一个漂亮的终端啦

目前为止,环境已经基本配置完成了
接下来就让我们开始愉快的操作系统实验之旅吧!