重學保護模式,又做了一次重要的實驗,希望對大家有所幫助。

 雖然是僅僅顯示了幾個字符,卻是完成兩次全局描述符表的加載,因爲兩個表處於物理內存的不同地方,因此這個實驗還是有點意思的!

不知道大家發現沒有,很多標籤後都直接加上了0x10000的絕對地址,而loop和call指令轉移的標籤.1和_putc卻沒有,可見有的指令使用的是絕對地址,而有的是相對地址,這可非常地難搞了!!!

然而我們編譯後生成的文件格式爲bin,並且是分別編譯,不含有任何符號信息和鏈接地址的信息,這樣如果把多個文件集成在一起生成內核文件就會有問題了,不過好在現在還可以運行了,暫時也就這樣吧!

;kernel.asm
bits 32
kernel_start:
	mov ax, 2 * 8
	mov ds, ax
	lgdt [gdtr + 0x10000]
	
	mov ax, 2 * 8
	mov ds, ax
	mov es, ax
	mov ss, ax
	mov fs, ax
	mov esp, kernel_stack_top + 0x10000
	mov ax, 3 * 8
	mov gs, ax
	jmp dword 1 * 8:new_start + 0x10000
new_start:
	mov ecx, 80 * 25
	mov ax, 3 * 8
	mov es, ax
	mov edi, 0
	mov ax, 0
	rep stosw
	
	mov ax, 2 * 8
	mov es, ax
	
;	mov ebx, 0
;	mov al, 'L'
;	mov ah, 12
;	mov [gs:ebx], ax
	
	push 12
	push 'L'
	call _putc
	add esp, 2 * 4
	
	push 13
	push 'z'
	call _putc
	add esp, 2 * 4
	
	push 14
	push 'h'
	call _putc
	add esp, 2 * 4
	
	push 15
	push 'q'
	call _putc
	add esp, 2 * 4
	
	mov ecx, 10

.1:	
	push 15
	push '$'
	call _putc
	add esp, 2 * 4
	loop .1

	jmp $
	
_putc: ; void putc(char c, int colour);
	push ebp
	mov ebp, esp
	mov ebx, [_pos + 0x10000]
	mov al, [esp + 2 * 4]
	mov ah, [esp + 3 * 4]
	mov [gs:ebx], ax
	inc ebx
	inc ebx
	mov [_pos + 0x10000], ebx
	pop ebp
	ret

_pos: dd 0

align 8

gdt_start:
	dq 0x0000000000000000 ; 0 * 8
	dq 0x00c09a000000ffff ; 1 * 8
	dq 0x00c092000000ffff ; 2 * 8
	dq 0x00c0920b8000ffff ; 3 * 8
gdt_end:

gdtr:
	dw gdt_end - gdt_start - 1
	dd 0x10000 + gdt_start

	times 1024 dd 0
kernel_stack_top:
;boot.asm
bits 16

real_mode_start:
	mov ax, 0x7c0 ; == mov ax, cs
	mov ds, ax
	mov ss, ax
	mov sp, 0x0
	
load_sys_to_0x10000: ; form floppy boot sector to memory
	mov dx, 0x0000
	mov cx, 0x0002
	mov ax, 0x1000 ; real mode segment is 0x1000, so address is 0x10000
	mov es, ax
	xor bx, bx
	mov ax, 0x200 + 0x11
	int 0x13
	jnc ok_load
	
	jmp $
	
ok_load:
	cli

	mov ax,0x7c0
	mov ds,ax
	
	lgdt [gdtr]
	
	mov eax, cr0
	or eax, 0x1
	mov cr0, eax
	jmp dword 1 * 8 : 0x10000 ; change to protected mode
	
gdt_start:
	dq 0x0000000000000000 ; 0 * 8
	dq 0x00c09a000000ffff ; 1 * 8
	dq 0x00c092000000ffff ; 2 * 8
	dq 0x00c0920b8000ffff ; 3 * 8
gdt_end:

gdtr:
	dw gdt_end - gdt_start - 1
	dd 0x7c00 + gdt_start

times 510 -($ - $$) db 0
	
	dw 0xaa55
###############################################################
# bochsrc.txt file for DLX Linux disk image.
###############################################################

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

# filename of ROM images
romimage: file=../BIOS-bochs-latest
vgaromimage: file=../VGABIOS-lgpl-latest

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

# hard disk
ata0: enabled=1, ioaddr1=0x1f0, ioaddr2=0x3f0, irq=14
#ata0-master: type=disk, path="hd10meg.img", cylinders=306, heads=4, spt=17

# choose the boot disk.
boot: a

# default config interface is textconfig.
#config_interface: textconfig
#config_interface: wx

#display_library: x
# other choices: win32 sdl wx carbon amigaos beos macintosh nogui rfb term svga

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

# disable the mouse, since DLX is text only
mouse: enabled=0

# set up IPS value and clock sync
cpu: ips=15000000
clock: sync=both

# enable key mapping, using US layout as default.
#
# NOTE: In Bochs 1.4, keyboard mapping is only 100% implemented on X windows.
# However, the key mapping tables are used in the paste function, so 
# in the DLX Linux example I'm enabling keyboard_mapping so that paste 
# will work.  Cut&Paste is currently implemented on win32 and X windows only.

keyboard: keymap=../keymaps/x11-pc-us.map
#keyboard: keymap=../keymaps/x11-pc-fr.map
#keyboard: keymap=../keymaps/x11-pc-de.map
#keyboard: keymap=../keymaps/x11-pc-es.map
rem auto.cmd
@echo off

nasm -fbin -o boot.bin boot.asm
dd if=boot.bin of=a.img
nasm -fbin -o kernel.bin kernel.asm
dd if=kernel.bin of=a.img seek=1 count=17

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章