模仿“一個操作系統的實現”,做保護模式的實驗,春節將至和大家分享!

 

 

; boot.asm
bits 16

start:
	mov ax, 0x7c0
	mov ds, ax
	
	mov dx, 0x1f2
	mov al, 10
	out dx, al
	
	mov dx, 0x1f3
	mov al, 1
	out dx, al
	mov dx, 0x1f4
	mov al, 0
	out dx, al
	mov dx, 0x1f5
	mov al, 0
	out dx, al
	mov dx, 0x1f6
	mov al, 0xe0
	out dx, al
	
	mov dx, 0x1f7
	mov al, 0x20
	out dx, al
	
	mov dx, 0x1f7
.1:
	in al, dx
	and al, 0x88
	cmp al, 0x8
	jnz .1
	
	mov dx, 0x1f0
	mov cx, 10 * 256
	mov bx, 0x200
.2:
	in ax, dx
	mov [bx], ax
	inc bx
	inc bx
	loop .2
	
	cli
	
	lgdt [gdtr]
	
	in al, 0x92
	or al, 0x2
	out 0x92, al
	
	mov eax, cr0
	or eax, 0x1
	mov cr0, eax
	
	jmp dword 1 * 8 : 0
	
gdt_start:
	dq 0x0000_0000_0000_0000 ; 0 * 8
	dq 0x00cf_9a00_7e00_ffff ; 1 * 8
	dq 0x00cf_9200_7e00_ffff ; 2 * 8
	dq 0x00c0_920b_8000_ffff ; 3 * 8
	dq 0x00cf_9a00_0000_ffff ; 4 * 8
	dq 0x00cf_9200_0000_ffff ; 5 * 8
gdt_end:

gdtr:
	dw gdt_end - gdt_start - 1
	dd gdt_start + 0x7c00
	
times 510 - ($ - $$) db 0
db 0x55, 0xaa
; loader.asm
bits 32

start:
	mov ax, 3 * 8
	mov gs, ax
	mov ax, 2 * 8
	mov ds, ax
	mov ss, ax
	mov esp, stack_top
	
	xor ebx, ebx
	mov byte [gs: ebx], 'P'
	inc ebx
	mov byte [gs: ebx], 0xc
	inc ebx

	mov dx, 0x1f2
	mov al, 220
	out dx, al
	
	mov dx, 0x1f3
	mov al, 11
	out dx, al
	mov dx, 0x1f4
	mov al, 0
	out dx, al
	mov dx, 0x1f5
	mov al, 0
	out dx, al
	mov dx, 0x1f6
	mov al, 0xe0
	out dx, al
	
	mov dx, 0x1f7
	mov al, 0x20
	out dx, al
	
	mov dx, 0x1f7
.1:
	in al, dx
	and al, 0x88
	cmp al, 0x8
	jnz .1
	
	mov dx, 0x1f0
	mov ecx, 220 * 256
	mov ebx, 0x100000 - 0x7e00
.2:
	in ax, dx
	mov [ebx], ax
	inc ebx
	inc ebx
	loop .2

	sub esp, 20 * 4
	
	mov dword [esp + 0 * 4], 0x7c00
	mov dword [esp + 1 * 4], 0
	mov dword [esp + 2 * 4], 0
	mov dword [esp + 3 * 4], 0
	mov dword [esp + 4 * 4], 0
	call create_descriptor	
	
	mov dword [esp + 0 * 4], 0x7c00
	mov dword [esp + 1 * 4], 1
	mov dword [esp + 2 * 4], 0x100000
	mov dword [esp + 3 * 4], 0x000fffff
	mov dword [esp + 4 * 4], 0x9a + 0xc000
	call create_descriptor

	mov dword [esp + 0 * 4], 0x7c00
	mov dword [esp + 1 * 4], 2
	mov dword [esp + 2 * 4], 0x100000
	mov dword [esp + 3 * 4], 0x000fffff
	mov dword [esp + 4 * 4], 0x92 + 0xc000
	call create_descriptor
	
	mov dword [esp + 0 * 4], 0x7c00
	mov dword [esp + 1 * 4], 3
	mov dword [esp + 2 * 4], 0xb8000
	mov dword [esp + 3 * 4], 0x00000fff
	mov dword [esp + 4 * 4], 0x92 + 0xc000
	call create_descriptor

	mov dword [esp + 0 * 4], 0x7c00
	mov dword [esp + 1 * 4], 4
	mov dword [esp + 2 * 4], 0
	mov dword [esp + 3 * 4], 0x000fffff
	mov dword [esp + 4 * 4], 0x9a + 0xc000
	call create_descriptor

	mov dword [esp + 0 * 4], 0x7c00
	mov dword [esp + 1 * 4], 5
	mov dword [esp + 2 * 4], 0
	mov dword [esp + 3 * 4], 0x000fffff
	mov dword [esp + 4 * 4], 0x92 + 0xc000
	call create_descriptor


	lgdt [gdtr]

	add esp, 20 * 4
	
	jmp dword 1 * 8 : 0

%include "syslib.asm"
	
stack_bottom:
	times 512 db 0
stack_top:

gdtr:
	dw 256 * 8 - 1
	dd 0x7c00
	
gdt_start:
	dq 0x0000_0000_0000_0000 ; 0 * 8
	dq 0x00cf_9a10_0000_ffff ; 1 * 8
	dq 0x00cf_9210_0000_ffff ; 2 * 8
	dq 0x00c0_920b_8000_ffff ; 3 * 8
	dq 0x00cf_9a00_0000_ffff ; 4 * 8
	dq 0x00cf_9200_0000_ffff ; 5 * 8
gdt_end:

gdtr1:
	dw gdt_end - gdt_start - 1
	dd gdt_start + 0x7e00
; kernel.asm
bits 32

start:
	mov ax, 3 * 8
	mov gs, ax
	mov ax, 2 * 8
	mov ds, ax
	mov es, ax
	mov fs, ax
	mov ss, ax
	mov esp, stack_top
	

	call cls

	mov ebx, 160 + 10
	mov byte [gs: ebx], 'P'
	inc ebx
	mov byte [gs: ebx], 0xe
	inc ebx
	
	mov dword [esp + 0 * 4], 0x7c00
	mov dword [esp + 1 * 4], 6
	mov dword [esp + 2 * 4], 0x100000 + ldt_start
	mov dword [esp + 3 * 4], ldt_end - ldt_start - 1
	mov dword [esp + 4 * 4], 0x82
	call create_descriptor
	
	mov dword [esp + 0 * 4], 0x100000 + ldt_start
	mov dword [esp + 1 * 4], 1
	mov dword [esp + 2 * 4], 0x100000 + local_task_start
	mov dword [esp + 3 * 4], local_task_end - local_task_start - 1
	mov dword [esp + 4 * 4], 0x9a + 0xc000
	call create_descriptor
	
	mov dword [esp + 0 * 4], 0x100000 + ldt_start
	mov dword [esp + 1 * 4], 0
	mov dword [esp + 2 * 4], 0xb8000
	mov dword [esp + 3 * 4], 0xfff
	mov dword [esp + 4 * 4], 0x92 + 0xc000
	call create_descriptor


	mov dword [esp + 0 * 4], 0x7c00
	mov dword [esp + 1 * 4], 7
	mov dword [esp + 2 * 4], 0x100000 + call_gate_start
	mov dword [esp + 3 * 4], call_gate_end - call_gate_start - 1
	mov dword [esp + 4 * 4], 0x9a + 0xc000
	call create_descriptor
	
	mov dword [esp + 0 * 4], 0x7c00 ; 
	mov dword [esp + 1 * 4], 8 ; 
	mov dword [esp + 2 * 4], 7 * 8; 
	mov dword [esp + 3 * 4], 0x8c00 + 0x6000
	mov dword [esp + 4 * 4], 0 ; 
	call create_gate

	mov dword [esp + 0 * 4], 0x7c00
	mov dword [esp + 1 * 4], 9
	mov dword [esp + 2 * 4], 0x100000 + func1_start
	mov dword [esp + 3 * 4], func1_end - func1_start - 1
	mov dword [esp + 4 * 4], 0x9a + 0xc000 + 0x60
	call create_descriptor

	mov dword [esp + 0 * 4], 0x7c00
	mov dword [esp + 1 * 4], 10
	mov dword [esp + 2 * 4], 0x100000 + func1_stack_top
	mov dword [esp + 3 * 4], func1_stack_bottom - func1_stack_top - 1
	mov dword [esp + 4 * 4], 0x92 + 0xc000 + 0x60
	call create_descriptor
	
	mov dword [esp + 0 * 4], 0x7c00
	mov dword [esp + 1 * 4], 11
	mov dword [esp + 2 * 4], 0xb8000
	mov dword [esp + 3 * 4], 0xfff
	mov dword [esp + 4 * 4], 0x92 + 0xc000 + 0x60
	call create_descriptor

	mov dword [esp + 0 * 4], 0x7c00
	mov dword [esp + 1 * 4], 12
	mov dword [esp + 2 * 4], 0x100000 + tss_start
	mov dword [esp + 3 * 4], tss_end - tss_start + 1
	mov dword [esp + 4 * 4], 0x89
	call create_descriptor
	
;	call 8 * 8 : 0
	
;	call 7 * 8 : 0

	mov ax, 6 * 8
	lldt ax

	call 1 * 8 + 4 : 0
	
	mov ebx, 640 + 10
	mov byte [gs: ebx], 'p'
	inc ebx
	mov byte [gs: ebx], 0xf
	inc ebx

	mov ax, 12 * 8
	ltr ax
	

	push 10 * 8 + 3
	push func1_stack_top
	push 9 * 8 + 3
	push 0
	retf
	

.loop:



	hlt
	jmp .loop

%include "syslib.asm"
	
stack_bottom:
	times 1024 db 0
stack_top:

cls: ; void cls(void)
	enter
	pusha
	
	xor ebx, ebx
	mov al, ' '
	mov ah, 0xf
	mov ecx, 2000
.1:
	mov [gs: ebx], ax
	inc ebx
	inc ebx
	loop .1
	
	popa
	leave
	ret


align 4096

ldt_start:
	dq 0, 0
ldt_end:

; align 4096

local_task_start:
	mov ax, 0 * 8 + 4
	mov gs, ax

	mov ebx, 320 + 10
	mov byte [gs: ebx], 'L'
	inc ebx
	mov byte [gs: ebx], 0x9
	inc ebx
	retf
local_task_end:


call_gate_start:
	mov ax, 3 * 8
	mov gs, ax
	
	mov ebx, 960 + 10
	mov byte [gs: ebx], 'c'
	inc ebx
	mov byte [gs: ebx], 0xf
	inc ebx
	retf
call_gate_end:



align 32
func1_stack_bottom:
	times 128 db 0
func1_stack_top:

align 32
func1_start:
	mov ax, 11 * 8 + 3
	mov gs, ax

	mov ebx, 800 + 10
	mov byte [gs: ebx], '3'
	inc ebx
	mov byte [gs: ebx], 0xb
	inc ebx
	
	call 8 * 8 + 3: 0

	jmp $
	
func1_end:


align 32

tss_start:
	dd 0
	dd stack_top
	dd 2 * 8
times 26 - 3 - 1 dd 0
	dw 0
	dw tss_end
tss_end:
	db 0xff

; sysmacro.asm
%macro enter 0
	push ebp
	mov ebp, esp
%endmacro

%macro push_some 0
	push ecx
	push edx
	push ebx
	push esi
	push edi
%endmacro

%macro pop_some 0
	pop edi
	pop esi
	pop ebx
	pop edx
	pop ecx
%endmacro
; syslib.asm
%include "sysmacro.asm"

; void create_descriptor(int table_start, int number, int base, int limit, int attrib)

; mov dword [esp + 0 * 4], 0x7c00
; mov dword [esp + 1 * 4], 1
; mov dword [esp + 2 * 4], 0x100000
; mov dword [esp + 3 * 4], 0x000fffff
; mov dword [esp + 4 * 4], 0x9a + 0xc000
; call create_descriptor

create_descriptor:
	enter
	pusha

	push ds
	mov ax, 5 * 8
	mov ds, ax

	mov word [ebx + 5], 0 	
	mov ebx, [ebp + 2 * 4]
	mov ecx, [ebp + 3 * 4]
	shl ecx, 3
	add ebx, ecx
	mov eax, [ebp + 5 * 4]
	mov [ebx], ax
	shr eax, 16
	and al, 0x0f
	mov [ebx + 6], al
	mov eax, [ebp + 4 * 4]
	mov ecx, eax
	and eax, 0x00ffffff
	mov [ebx + 2], eax
	shr ecx, 24
	mov [ebx + 7], cl
	mov ax, [ebp + 6 * 4]
	or [ebx + 5], ax

	pop ds
	popa
	leave
	ret
	

; void create_gate(int table_start, int irq, int select, int attrib, int offset)

; mov dword [esp + 0 * 4], 0x7c00 + 256 * 8 ; interrupt descriptor table start
; mov dword [esp + 1 * 4], 0x20 ; clock interrupt
; mov dword [esp + 2 * 4], 4 * 8 ; code segment select
; mov dword [esp + 3 * 4], 0x8e00 ; interrupt gate
; mov dword [esp + 4 * 4], clock_int ; interrupt process program enter address
; call create_gate

create_gate: 
	enter
	pusha

	push ds
	mov ax, 5 * 8
	mov ds, ax
	
	mov ebx, [ebp + 2 * 4]
	mov ecx, [ebp + 3 * 4]
	shl ecx, 3
	add ebx, ecx
	mov ax, [ebp + 4 * 4]
	mov [ebx + 2], ax
	mov ax, [ebp + 5 * 4]
	mov [ebx + 4], ax
	mov eax, [ebp + 6 * 4]
	mov [ebx + 0], ax
	shr eax, 16
	mov [ebx + 6], ax
	
	pop ds
	popa
	leave
	ret
	

 

 

###############################################################
# bochsrc.txt file for DLX Linux disk image.
###############################################################

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

# 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="c.img", cylinders=306, heads=4, spt=17

# choose the boot disk.
boot: c

# 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=c.img seek=0 count=1
echo.
nasm -fbin -o loader.bin loader.asm
dd if=loader.bin of=c.img seek=1 count=10
echo.
nasm -fbin -o kernel.bin kernel.asm
dd if=kernel.bin of=c.img seek=11 count=220
echo.

rem del *.bin
del c.img.lock

 

 

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