前言
最近一直想学一下操作系统,但是一直没有太多时间,趁最近快过年了,腾出一点时间。买了一本《操作系统镜像还原》。想着自己实现一下操作系统。其实还有一个日本作家的《30自制操作系统》听说也挺不错的。里面还有图形界面。但是那本书,是用的作者自己写的汇编编译器和c编译器。比较一下。还是选择这本《操作系统镜像还原》,看下面书评,说对小白非常友好,讲的非常细。以至于变成太过于唠叨了。想了想,正好适合我。太唠叨的地方,略过不看就行,但是要是一卸作者认为很简单的点,他略过不写了。但是读者没有弄懂,后面找相关资料去弄懂,也是一件麻烦事。
1.配置环境
书上用的环境有点老了,Linux版本是centos6.3,现在centos有些版本已经停止支持了。下载比较麻烦。这里我推荐Ubuntu,还有书上推荐的是Vmware box。这个是免费的。但是我这边用的是Vmware tool。至于环境具体咋安装,我想书上也已经说的比较清楚了,这里就不赘述了。
3.记录一下理解的思路
首先BIOS这个程序会运行,这个程序是写在rom里面的,无法擦除。开机就启动。负责检查各种设备的情况 并且建立中断向量表。之后BIOS就将0柱面0磁头1扇区加载到0x7c00这个位置,至于为啥是这个位置,就是历史原因了。我们的MBR就放在0x7c00这个位置。之后,BIOS还会检测一下最后两个字节是否为0x55和0xaa。如果是就加载MBR
填写中断例程**
2.编写MBR主引导
SECTION MBR vstart=0x7c00 ;起始地址编译在0x7c00
mov ax,cs
mov ds,ax
mov es,ax
mov ss,ax
mov fs,ax
mov sp,0x7c00
;ah = 0x06 al = 0x00 想要调用int 0x06的BIOS提供的中断对应的函数 即向上移动即完成清屏功能
;cx dx 分别存储左上角与右下角的左边 详情看int 0x06函数调用
mov ax,0x600
mov bx,0x700
mov cx,0
mov dx,0x184f
;调用BIOS中断
int 0x10
mov ah,3
mov bh,0
;获取光标位置 需要打印信息
int 0x10
mov ax,message
mov bp,ax
mov cx,5
mov ax,0x1301
mov bx,0x71;白底蓝字好cooi
int 0x10 ;写字符串
jmp $ ;无限循环 一直跳转到当前命令位置
;字符串声明
message db "1 MBR"
times 510 - ($ - $$) db 0 ;这个times相当于masm的dup的意思,起到重复定义,定义512-2
db 0x55,0xaa
这个调用BIOS的中断,将字符串显示在屏幕上。这里调用的是当AH为A时,就是显示字符串。
AH | 功 能 | 调用参数 | 返回参数 / 注释 |
1 | 置光标类型 | (CH)0―3 = 光标开始行 (CL)0―3 = 光标结束行 | |
2 | 置光标位置 | BH = 页号 DH = 行 DL = 列 | |
3 | 读光标位置 | BH = 页号 | CH = 光标开始行 CL = 光标结束行 DH = 行 DL = 列 |
4 | 置显示页 | AL = 显示页号 | |
5 | 屏幕初始化或上卷 | ||
6 | 屏幕初始化或上卷 | AL = 上卷行数 AL =0全屏幕为空白 BH = 卷入行属性 CH = 左上角行号 CL = 左上角列号 DH = 右下角行号 DL = 右下角列号 | |
7 | 屏幕初始化或下卷 | AL = 下卷行数 AL = 0全屏幕为空白 BH = 卷入行属性 CH = 左上角行号 CL = 左上角列号 DH = 右下角行号 DL = 右下角列号 | |
8 | 读光标位置的属性和字符 | BH = 显示页 | AH = 属性 AL = 字符 |
9 | 在光标位置显示字符及其属性 | BH = 显示页 AL = 字符 BL = 属性 CX = 字符重复次数 | |
A | 在光标位置只显示字符 | BH = 显示页 AL = 字符 CX = 字符重复次数 | |
E | 显示字符(光标前移) | AL = 字符 BL = 前景色 | 光标跟随字符移动 |
13 | 显示字符串 | ES:BP = 串地址 CX = 串长度 DH, DL = 起始行列 BH = 页号 AL = 0,BL = 属性 串:Char,char,……,char AL = 1,BL = 属性 串:Char,char,……,char AL = 2 串:Char,attr,……,char,attr AL = 3 串:Char,attr,……,char,attr | 光标返回起始位置 光标跟随移动 光标返回起始位置 光标跟随串移动 |
3.写入镜像
这里我们先用nasm编译我们编写的代码,得到一个mbr.bin文件
nasm -o mbr.bin mbr.S
之后我们再用dd命令将bin文件写入镜像
dd if=mbr.bin of=hd60M.img bs=512 count=1 conv=notrunc
4.运行
bin/bochs -f bochsrc.disk