雖然是僅僅顯示了幾個字符,卻是完成兩次全局描述符表的加載,因爲兩個表處於物理內存的不同地方,因此這個實驗還是有點意思的!
不知道大家發現沒有,很多標籤後都直接加上了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