感觉bochs平台学习操作系统也是很好
感觉bochs平台学习操作系统也是很好
所需要的软件:
bochs: https://jaist.dl.sourceforge.net/project/bochs/bochs/2.6.8/Bochs-2.6.8.exe
nasm: https://www.nasm.us/pub/nasm/releasebuilds/2.14rc15/win64/nasm-2.14rc15-installer-x64.exe
dd(win): http://www.chrysocome.net/downloads/ee48819f687ea45e1b76fef8a83adce7/dd-0.6beta3.zip
安装方法:(不好意思,这个省略了,不要告诉我不会呀!)
dd不用安装解压后复制到nasm目录就行了。
安装好后设置环境变量:
###############################################################
# 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=floppyb.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: floppy
# 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
boot.s
bootseg equ 0x07c0
sysseg equ 0x1000
syslen equ 17
start:
jmp bootseg:go
go:
mov ax,cs
mov ds,ax
mov ss,ax
mov sp,0x0400
load_syetem:
mov dx,0x0000
mov cx,0x0002
mov ax,sysseg
mov es,ax
xor bx,bx
mov ax,0x200+syslen
int 0x13
jnc ok_load
die:
jmp die
ok_load:
cli
mov ax,bootseg
mov ds,ax
lidt [idt_48]
lgdt [gdt_48]
mov al, 0x11
out 0x20, al
out 0xa0, al
mov al, 0x20
out 0x21, al
mov al, 0x28
out 0xa1, al
mov al, 0x4
out 0x21, al
mov al, 0x2
out 0xa1, al
mov al, 0x1
out 0x21, al
out 0xa1, al
mov al, 0xff
out 0x21, al
out 0xa1, al
mov ax,0x0001
lmsw ax
jmp 8:0
gdt:
dw 0,0,0,0
dw 0x07ff
dw 0x0000
dw 0x9a01
dw 0x00c0
dw 0x07ff
dw 0x0000
dw 0x9201
dw 0x00c0
idt_48:
dw 0,0,0
gdt_48:
dw 0x7ff
dw 0x7c00+gdt,0
times 510-($-$$) db 0
dw 0xaa55
head.s
LATCH equ 11930
SCRN_SEL equ 0x18
TSS0_SEL equ 0x20
LDT0_SEL equ 0x28
TSS1_SEL equ 0x30
LDT1_SEL equ 0x38
bits 32
startup_32:
mov eax,0x10
mov ds,ax
lss esp,[init_stack]
;setup base fields of descriptors.
mov ebx, 0x10000
mov ecx, gdt
lea eax, [tss0]
mov edi, 0x20
call set_base
lea eax, [ldt0]
mov edi, 0x28
call set_base
lea eax, [tss1]
mov edi, 0x30
call set_base
lea eax, [ldt1]
mov edi, 0x38
call set_base
lea eax, [tss2]
mov edi, 0x40
call set_base
lea eax, [ldt2]
mov edi, 0x48
call set_base
call setup_idt
call setup_gdt
mov eax,dword 0x10
mov ds,ax
mov es,ax
mov fs,ax
mov gs,ax
lss esp,[init_stack]
; setup timer 8253 chip.
mov al,0x36
mov edx,0x43
out dx,al
mov eax,LATCH
mov edx,0x40
out dx,al
mov al,ah
out dx,al
;setup timer and system interrupt descriptors.
mov eax,0x00080000
mov ax,timer_interrupt
mov dx,0x8e00
mov ecx,0x20
lea esi,[idt+ecx*8]
mov [esi],eax
mov [esi+4],edx
mov ax,system_interrupt
mov dx,0xef00
mov ecx,0x80
lea esi,[idt+ecx*8]
mov [esi],eax
mov [esi+4],edx
;unmask the timer interrupt.
mov edx, 0x21
in al, dx
and al, 0xfe
out dx, al
; move to user mode (task0)
pushf
and dword[esp],0xffffbfff
popf
mov eax,0x40
ltr ax
mov eax,0x48
lldt ax
mov dword[current],2
sti
push long 0x17
push long usr_stk2
pushf
push long 0x0f
push long task2
iret
setup_gdt:
lgdt [lgdt_opcode]
ret
setup_idt:
lea edx,[ignore_int]
mov eax,0x80000
mov ax,dx
mov dx,0x8e00
lea edi,[idt]
mov ecx,256
rp_idt:
mov [edi],eax
mov [edi+4],edx
add edi,8
dec ecx
jne rp_idt
lidt [lidt_opcode]
ret
set_base:
add eax, ebx
add edi, ecx
mov [edi + 2], ax
ror eax, 16
mov [edi + 4], al
mov [edi + 7], ah
ror eax, 16
ret
write_char:
push gs
push ebx
push eax
mov ebx,SCRN_SEL
mov gs,bx
mov bx,[scr_loc]
shl ebx,1
mov [gs:ebx],ax
shr ebx,1
inc ebx
cmp ebx,2000
jb .l1
mov ebx,0
.l1:
mov [scr_loc],ebx
pop eax
pop ebx
pop gs
ret
align 4
ignore_int:
push ds
push eax
mov eax,0x10
mov ds,ax
mov eax,'H'
mov ah, 0xC
call write_char
pop eax
pop ds
iret
align 4
timer_interrupt:
push ds
push eax
push ebx
push ecx
push edx
mov eax,0x10
mov ds,ax
mov al,0x20
out 0x20,al
mov eax,1
cmp [current],eax
je here0
mov [current],eax
jmp TSS1_SEL:0
jmp here1
here0:
mov dword[current],0
jmp TSS0_SEL:0
here1:
pop edx
pop ecx
pop ebx
pop eax
pop ds
iret
align 4
system_interrupt:
push ds
push edx
push ecx
push ebx
push eax
mov edx,0x10
mov ds,dx
call write_char
pop eax
pop ebx
pop ecx
pop edx
pop ds
iret
current: dd 0
scr_loc: dd 0
align 4
lidt_opcode:
dw 256*8-1
dd idt + 0x10000
align 4
lgdt_opcode:
dw (end_gdt-gdt)-1
dd gdt + 0x10000
align 8
idt:
times 256*8 db 0
gdt:
dq 0x0000000000000000
dq 0x00c09a01000007ff
dq 0x00c09201000007ff
dq 0x00c0920b80000002
dw 0x68,tss0,0xe900,0x0
dw 0x40,ldt0,0xe200,0x0
dw 0x68,tss1,0xe900,0x0
dw 0x40,ldt1,0xe200,0x0
dw 0x68,tss2,0xe900,0x0 ;0x40
dw 0x40,ldt2,0xe200,0x0 ;0x48
end_gdt:
times 128*4 db 0
init_stack:
dd init_stack
dw 0x10
align 8
ldt0:
dq 0x0000000000000000
dq 0x00c0fa01000003ff
dq 0x00c0f201000003ff
tss0:
dd 0
dd krn_stk0,0x10
dd 0,0,0,0,0
dd task0,0x200
dd 0,0,0,0
dd usr_stk0,0,0,0
dd 0x17,0x0f,0x17,0x17,0x17,0x17
dd LDT0_SEL,0x8000000
times 128*4 db 0
krn_stk0:
align 8
ldt1:
dq 0x0000000000000000
dq 0x00c0fa01000003ff
dq 0x00c0f201000003ff
tss1:
dd 0
dd krn_stk1,0x10
dd 0,0,0,0,0
dd task1,0x200
dd 0,0,0,0
dd usr_stk1,0,0,0
dd 0x17,0x0f,0x17,0x17,0x17,0x17
dd LDT1_SEL,0x8000000
times 128*4 db 0
krn_stk1:
align 8
ldt2:
dq 0x0000000000000000
dq 0x00c0fa01000003ff
dq 0x00c0f201000003ff
tss2:
dd 0
dd krn_stk2,0x10
dd 0,0,0,0,0
dd task2,0x200
dd 0,0,0,0
dd usr_stk2,0,0,0
dd 0x17,0x0f,0x17,0x17,0x17,0x17
dd 0x48,0x8000000
times 128*4 db 0
krn_stk2:
task0:
mov eax,0x17
mov ds,ax
mov al,'H'
mov ah, 0xe
int 0x80
mov al,'e'
int 0x80
mov al, 39 ; '
int 0x80
mov al,'s'
int 0x80
mov al,' '
int 0x80
mov al,'c'
int 0x80
mov al,'r'
int 0x80
mov al,'a'
int 0x80
mov al,'z'
int 0x80
mov al,'y'
int 0x80
mov al,' '
int 0x80
mov ecx,0x1fffff
.l1:
loop .l1
jmp task0
times 128*4 db 0
usr_stk0:
task1:
mov al,' '
mov ah, 0xb
int 0x80
mov al,'i'
int 0x80
mov al,'s'
int 0x80
mov al,'n'
int 0x80
mov al,39
int 0x80
mov al,'t'
int 0x80
mov al,' '
int 0x80
mov al,'h'
int 0x80
mov al,'e'
int 0x80
mov al,'?'
int 0x80
mov ecx,0xfffff
.l2:
loop .l2
jmp task1
times 128*4 db 0
usr_stk1:
task2:
mov eax,0x17
mov ds,ax
mov al,'M'
mov ah, 0xd
int 0x80
mov ecx,0xffffff
here:
loop here
jmp task2
times 128*4 db 0
usr_stk2:
自己写的批处理文件,auto.cmd
@echo off
nasm -fbin -o boot.bin boot.s
dd if=boot.bin of=a.img
nasm -fbin -o head.bin head.s
dd if=head.bin of=a.img seek=1 count=17
copy a.img "C:\Program Files (x86)\Bochs-2.6.9\dlxlinux\a.img"
运行效果