#写在最前
笔者在动手写此操作系统时是一名大学本科大二的学生,可能文章中会有好多地方我没有解释清楚,可能也会有许多地方出现错误,我恳请各位读者能提出质疑和纠正我的错误,谢谢!
参考书籍:
- 《30天自制操作系统》川合秀实
- 《ORANGE’S:一个操作系统的实现》
##开发环境
笔者采用以下开发环境
- Apple Macbook Air
- Ubuntu 12.04 LTS(32 bit)
##读者准备
毕竟是动手写一个操作系统,对读者的要求也会相应要求高一些,对计算机编程0基础的读者还是不建议直接看这个系列的文章。希望读者能有 汇编语言、C 语言的基础,对操作系统最好有了解(推荐书籍《操作系统概念》),另外由于开发是在 Ubuntu 的环境中进行的,读者最好对 Linux 的命令、操作等比较熟悉。
#环境搭建
##安装Bochs 等
Bochs是一个x86硬件平台的开源模拟器。它可以模拟各种硬件的配置。Bochs模拟的是整个PC平台,包括I/O设备、内存和BIOS。更为有趣的是,甚至可以不使用PC硬件来运行Bochs。事实上,它可以在任何编译运行Bochs的平台上模拟x86硬件。通过改变配置,可以指定使用的CPU(386、486或者586),以及内存大小等。一句话,Bochs是电脑里的“PC”。根据需要,Bochs还可以模拟多台PC,此外,它甚至还有自己的电源按钮。
我们所写的操作系统就是模拟在 Bochs 来运行和调试的。
我们使用以下的命令来安装 bochs 等一些工具
sudo apt-get install vgabios bochs bochs-x bximage bochs-sdl
#第一个 Hello World
##创建软盘镜像
- 使用bximage 命令
- 按照以下来进行配置
1 |
|
- 最终我们得到了一个名叫『helloworld.img』的文件,它就是我们创建的软盘镜像
##操作系统源码
- hello.asm
1 | org 07c00h |
- 下面我们来逐行分析这段汇编代码
org 07c00h
指定程序的起始地址,告诉编译器程序从这里开始
org是Origin的缩写:起始地址源。在汇编语言源程序的开始通常都用一条org伪指令来实现规定程序的起始地址。
mov ax, cs
将 cs(代码段寄存器)中的值赋值给 ax 寄存器
mov ds, ax
将 ax 中的值赋值给 ds( 一个段寄存器)
mov es, ax
将 ax 中的值赋值给 es()
call DispStr
跳转执行到 DispStr
jump $
死循环
mov ax, Str
将 Str 的首地址放入 ax
mov bp, ax
将 ax 的值赋给 bp(栈底指针)
mov cx, 13
将13放入 ax 寄存器
mov ax, 01301h
ax 寄存器高位AH=13,低位 AL=01h
mov bx, 000ch
将000ch 放入 bx 寄存器
mov dl, 0
将光标设置为0行0列
int 10h
调用10h 中断
- int 10h 中断功能介绍
AH | 功能 | 调用参数 | 返回参数 |
---|---|---|---|
1 | 置光标类型 | (CH)0―3 = 光标开始行 (CL)0―3 = 光标结束行 |
无 |
2 | 置光标位置 | BH = 页号 DH = 行 DL = 列 |
无 |
3 | 读光标位置 | BH = 页号 | CH = 光标开始行 CL = 光标结束行 DH = 行 DL = 列 |
4 | 读光笔位置 | AH=0 光笔未触发 AH=1 光笔触发 CH=象素行 BX=象素列 DH=字符行 DL=字符列 |
|
5 | 显示页 | AL = 显示页号 | |
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 |
times 510-($-$$) db 0
将剩余的位置都填充为0
dw 0xaa55
结束标志
##制作操作系统镜像
- 编译源码
nasm hello.asm -o hello.bin
- 写入软盘镜像扇区
dd if=hello.bin of=helloworld.img bs=512 count=1 conv=notrunc
#运行 HelloWorld
##编写 bochs 配置文件 - bochsrc
1 |
|
##运行bochs
bochs -f bochsrc
运行结果如下图: