一直想做的事来着,主要参考

  • 于渊的《自己动手写操作系统》
  • james的教程
  • hurlex的教程

计算机启动过程

读取BIOS

按下电源按钮后,计算机首先读取一块ROM芯片,这块芯片里的程序是”基本输入输出系統”(Basic Input/Output System),即BIOS.

硬件自检

BIOS会检查计算机硬件是否满足运行条件,如果硬件出现问题,主板会发出不同含义的蜂鸣,启动中止。

启动顺序

硬件检查完成后,BIOS会将控制权交给下一阶段的启动程序,注意,“下一阶段的启动程序”可能存放在硬盘中,也可能存放在CD/DVD中,或者软盘中等等,可以设置BIOS选择从哪个设备启动。

主引导记录

BIOS找到了“下一阶段的启动程序”所在设备,会读取该设备的第一个扇区,即读取最前面的512字节,称为主引导记录。主引导记录会告诉计算机下一步到哪里去找操作系统。

bootloader

计算机读取”主引导记录”前面446字节的机器码之后,运行事先安装的“启动管理器”bootloader,由用户选择启动哪个操作系统。如果你安装了多个操作系统,那么就要从这步做出选择了。

加载内核

选择操作系统(内核)后,会加载内核,下面就交给内核去处理了。

初体验

启动顺序

前两步交予虚拟机,第三步选择在虚拟机启动时选择软盘启动(此处使用镜像)即可。

主引导记录

写一个简单的主引导记录代码,作用为启动后在屏幕上显示Welcome to siriusOS。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
; 0x0000h--0x7c00h这一段存的是BIOS中断向量和一些BIOS数据等
; BIOS读入MBR后,从0x7c00h处开始执行
org 7c00h

; es:bp表示显示字符串的地址
mov ax, cs
mov es, ax

mov ax, msg
mov bp, ax

; cx 存放字符串长度
mov cx, msgLen

; ah=13h表示向TTY显示字符
; al=01h表示显示方式(字符串是否包含显示属性,01h表示不包含)
mov ax, 1301h

; bh=00h表示页号
; bl=0fh表示颜色
mov bx, 000fh

; dh行
; dl列
mov dh, 5
mov dl, 20

; 中断
int 10h

msg: db "Welcome to siriusOS"

; $ 当前地址, $$ 段开始地址
; equ -> equal
msgLen: equ $ - msg

; 填充剩余部分,这样一共就是512字节即一个扇区
times 510 - ($ - $$) db 0

; 魔数,必须有这两个字节BIOS才确认是MBR
dw 0aa55h

制作软盘并尝试启动

编译主引导记录

1
nasm boot.asm -o boot.bin

制作一个空的软盘镜像empty.img:  

1
dd if=/dev/zero of=empty.img bs=512 count=2880

制作一个包含主引导记录boot.bin的镜像文件siriusOS.img:

1
dd if=boot.bin of=lucasOS.img bs=512 count=1

然后,将empty.img中1个扇区后的数据拷贝到lucasOS.img的后:

1
dd if=empty.img of=lucasOS.img skip=1 seek=1 bs=512 count=2879

最后vmware新建虚拟机中添加软盘启动,网络选择host-only即可

效果如图所示:

启动''

启动''

bootloader

计算机读取”主引导记录”前面446字节的机器码之后,会运行事先安装的“启动管理器”bootloader,由用户选择启动哪个内核,之后就会载入内核,将控制权交给内核。GNU GRUB(GRand Unified Bootloader)就是一种bootloader,满足多重引导规范(The Multiboot Specification),GRUB可选择操作系统分区上的不同内核。

jamesmolloy网站上的下载floppy.img不能下载了,自己做一个带grub的img:

1
2
apt install xorriso
grub-mkrescue -o floppy.img

经过一天的尝试~,这样搞的img不能挂载完将kernel放进去,最后还是找了下james的floppy.img,具体原因暂时不清楚,后续看能不能搞懂了。

bochs

每次尝试都要用vmware的话太过于麻烦,bochs或者qemu都是个不错的选择,这里了解下bochs

编译有点麻烦,方便起见使用apt直接安装(注意下还有个bochs-x):

1
2
apt-get install bochs
apt-get install bochs-x

然后需要写个.bochsrc 配置文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
###############################################################
# Configuration file for Bochs
###############################################################

# how much memory the emulated machine will have
megs: 32

# filename of ROM images
romimage: file=/usr/share/bochs/BIOS-bochs-latest
vgaromimage: file=/usr/share/vgabios/vgabios.bin

# what disk images will be used
floppya: 1_44=siriusOS.img, status=inserted

# choose the boot disk.
boot: floppy

# where do we send log messages?
# log: bochsout.txt

# disable the mouse
mouse: enabled=0

尝试启动下前面的img,效果如图:

启动''

启动''