自制操作系統--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,就不會產生問題了。


發佈了13 篇原創文章 · 獲贊 0 · 訪問量 9925
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章