从零制作操作系统——环境搭建以及HelloWorld
起因
最近在学习操作系统,尝试自己照着书搓一个出来。
环境搭建
基础环境
我们的操作系统在x86平台的Linux下进行编写和运行。编辑器用的VIM。
我的系统是Fedora 36,当然你也可以使用Ubuntu或者其他Linux发行版。不用过于担心,这些发行版之间对本实验接下来的操作影响并不大,仅是包的安装方式不同。如果在安装环境的过程中有任何问题,相信你可以通过搜索引擎来解决。
安装Nasm
访问Nasm官网下载地址
- https://www.nasm.us/pub/nasm/releasebuilds/2.16.01/linux/
这里我选择nasm-2.16.01-0.fc36.x86_64.rpm这个版本
通过终端进入下载目录,然后执行以下命令进行安装
sudo rpm -ivh nasm-2.16.01-0.fc36.x86_64.rpm
验证是否安装成功:
nasm -v
如果出现版本信息则恭喜你已经成功装上Nasm了
NASM version 2.16.01 compiled on Dec 21 2022
安装KVM&QEMU
KVM是Linux内核的开源虚拟化平台,它对于你的硬件有些要求:
- 带有 Intel VT-x 的 Intel 处理器或带有 AMD- v 的 AMD 处理器
在编写代码之前请确保你的处理器支持虚拟化技术,你可以通过以下命令验证:
grep -E --color '(vmx|svm)' /proc/cpuinfo
其中vmx扩展是Intel处理器的标志,而svm是AMD处理器的标志。
如果输出的flags中出现上述标志,则说明你的处理器支持虚拟化技术并开启了相应功能。
如果没有,请不要先着急,这不一定意味着处理器不支持该项技术,很大可能是没有开启。请在BIOS相关设置中启用该选项。(至于操作请根据主板型号自行网络搜索)
然后还要检测KVM内核是否已经加载
lsmod | grep -i kvm
依赖检测完成了,接下来就是安装虚拟化主包了
sudo dnf install -y qemu-kvm libvirt virt-install bridge-utils virt-manager
除此之外还要安装一些虚拟化模块
sudo dnf install -y libvirt-devel virt-top libguestfs-tools guestfs-tools
然后启用守护进程
sudo systemctl start libvirtd && sudo systemctl enable libvirtd
最后安装QEMU
sudo dnf install qemu
查看有哪些qemu命令被安装
ls /usr/bin/qemu-*
我们在之后主要使用qemu-system-x86_64
这个命令。
此部分由于我的PC已经安装了QEMU,所以仅参考了Fedora官方文档。
HelloWorld
编写代码
如果说我们上来要写什么的话,对于程序员来讲莫过于HelloWorld。所以接下来我们将构建一个最简陋的程序,尽管它不能够被称之为OS,仅在屏幕上输出HelloWorld,但是这个程序具有操作系统的一些基础特性,对我们后面操作来讲仍有巨大意义。
创建一个存放项目的目录,并进入该目录
mkdir myos && cd myos
创建一个汇编文件boot.asm
touch boot.asm
接下来我们要在这个文件中编写汇编代码,在此之前你需要有一个编辑器,它可以是VSCode,也可以是Vim或者其它编辑器(哪个习惯用哪个)。
我们在该文件中编写如下代码
org 07c00h
mov ax,cs
mov ds,ax
mov es,ax
call DispStr
jmp $
DispStr:
mov ax,BootMessage
mov bp,ax
mov cx,16
mov ax,01301h
mov bx,000ch
mov dl,0
int 10h
ret
BootMessage: db "Hello, OS World!"
times 510-($-$$) db 0
dw 0xaa55
我们来对代码进行解释:
- 在NASM,任何不被
[]
括起来的标签或变量名都被认为是地址 $
表示当前行被汇编后的地质,$$
表示一个section的开始被汇编后的地址。此程序只有一个section ,所以它也就是程序被编译后开始的地址。$-$$
表示本行距离程序开始处的相对距离times 510-($-$$) db 0
表示将0重复510-($-$$)
遍,也就是在剩下的空间中不断填0,直到程序有510字节。dw 0xaa55
结束标志,占2字节,与上面加起来一共512字节
把这段代码编译下,得到一个512字节的boot.bin
nasm boot.asm -o boot.bin
将它写入到镜像
dd if=boot.bin of=boot.img bs=512 count=1
使用QEMU去运行它
qemu-system-x86_64 -fda output.img
现在你可以看到效果了
编写脚本
在编译运行的时候我们并不想要每次都输入这么长的shell命令。所以干脆直接编写个脚本文件,每次需要重新编译运行时,直接执行该文件即可
创建run.sh
文件
touch run.sh
使用编辑器编辑文件,内容如下
nasm boot.asm -o boot.bin
dd if=boot.bin of=output.img bs=512 count=1
qemu-system-x86_64 -fda output.img
赋予权限
chmod x+u run.sh
然后运行
./run.sh