自制操作系统--1 环境搭建

网上有不少简单的加载器制作的文章,我也是初学,之前看过《Oranges‘s 一个操作系统的实现》,看到保护模式哪一点觉得非常头痛,有很多不清楚的地方,现在在看《30天自制操作系统》,虽然读起来简单多了,不过我使用的是Linux系统,做起来还是有些麻烦,此系列文章可以当作简单的学习笔记,不过会加上我个人的理解,将我当初迷茫的地方写出来,以及如何在Linux系统上搭建起操作系统的实验环境。最近一年准备主攻编译器和操作系统,希望能和大家一起学习,进步。

准备环境:

1.汇编器NASM,nasm是用的比较多的,采用intel汇编语法。有汇编基础的话很好学,文档见此处 NASM文档。
2.Bochs模拟器,要会使用简单的调试命令就行了。进入bochs后,输入help会有简单的帮助,差不多足够了。

Hello world

下面是一个简单的引导程序:
org 0x7c00        ; 告知nasm,代码会加载在0x7c00处,详细解释在后面
entry:
	mov ax,0
	mov ss,ax
	mov sp,0x7c00
	mov ds,ax
	mov es,ax

	mov si,msg
putloop:
	mov al,[si]
	add si,1
	cmp al,0
	je fin
	mov ah,0x0e
	mov bx,15
	int 0x10
	jmp putloop
fin:
	hlt
	jmp fin
msg:
	db 0x0a,0x0a	; 换行'\n'的ASCII码为10=0x0a
	db "Hello,world"
	db 0x0a
	db 0
	
	times 510-($-$$) db 0  ;重复到510字节处
	db 0x55,0xaa ;启动扇区标识
下面是Makefile,写得有点烂,见谅:
run : bochs a.img
	bochs -q  #启动
bin : 
	nasm -f bin hello.asm -o hello.bin  #编译生成bin格式文件
a.img : bin img
	dd if=./hello.bin of=./a.img bs=512 count=1 conv=notrunc  #将生成的文件写入软盘镜像
img : 
	bximage -q -fd -size=1.44 a.img  > /dev/null #创建软盘镜像
bochs:
	cp ~/bochsrc ./  #复制bochsrc到当前目录,这点实验的时候看情况更改
clean:
	-rm -f hello.bin bochsrc a.img
下面是复制过来的bochsrc
###############################################################
# Configuration file for Bochs
###############################################################

# how much memory the emulated machine will have
megs: 32
cpu: ips=10000000
# filename of ROM images
romimage: file=/usr/local/share/bochs/BIOS-bochs-latest
vgaromimage: file=/usr/local/share/bochs/VGABIOS-lgpl-latest
# what disk images will be used
floppya: 1_44=a.img, status=inserted

# choose the boot disk.
boot: floppy

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

# disable the mouse
mouse: enabled=1

# enable key mapping, using US layout as default.
keyboard_mapping: enabled=1, map=/usr/local/share/bochs/keymaps/x11-pc-us.map

现在,make以下,bochs运行,输入c(表示继续,debug版本的bochs),可以看到模拟器上显示了Hello,world。

下面来说以下以上代码依赖的一些约定:
1.引导扇区,磁盘的0柱面,0磁头,1扇区被称为磁盘的主引导区,在这512个字节中,有446个字节可以提供给引导程序使用,其后的64个字节为分区表,再之后的2个字节为FLAG字段,值为0x55,0xAA才会被BIOS加载时识别。

2.BIOS加电自检之后,会将引导扇区加载到内存0x7c00开始的地方,至于为什么是0x7c00, 请点这里。

3.在上面的汇编程序中,我们使用了org 0x7c00这条命令,告诉nasm程序将被加载到0x7c00这个位置。当执行流刚到达0x7c00这里的时候,现在的段寄存器CS,SS,DS,ES都等于0。我们可以看以下hello.bin的反汇编代码,运行ndisasm hello.bin | more.
00000000  8CC8              mov ax,cs
00000002  8ED0              mov ss,ax
00000004  8ED8              mov ds,ax
00000006  8EC0              mov es,ax
00000008  BE237C            mov si,0x7c23
0000000B  8A04              mov al,[si]
0000000D  81C60100          add si,0x1
00000011  3C00              cmp al,0x0
可以看到,mov si,0x7c23 这一条指令,在代码里,写的是 mov si,msg.如果我们去掉前面的org 0x7c00的话,这里的指令就成了mov si,0x23.显然,如果其他寄存器都为0的话,此时下面显示字符串的指令肯定会出错,因为地址有问题。讲到这就可以知道,org 0x7c00并不是必须的,我们完全可以使用其他的方式到达同样的目的,比如像下面这样修改:
jmp 0x7c0:entry
entry:
	mov ax,cs
	mov ss,ax
	mov ds,ax
	mov es,ax

	mov si,msg
这样的话,执行跳转时CS会被设置为0x7c0,其他寄存器也被下面的指令初始化为0x7c0,就不会产生问题了。


你可能感兴趣的:(操作系统)