Hi,
ich bin seit ein paar Tagen dabei, mir ein betriebssystem zu schreiben. Aber ich schaffs nicht, in den PMode zu kommen.
org 0x7C00 ; right after some BIOS stuff
start:
cli ; no interrupts
xor ax, ax
mov ds, ax ; set ds
mov es, ax ; and es
mov ax, 0x9000 ; this is our stack address
mov ss, ax
mov sp, 0x400 ; its 512 bytes big
sti ; allow interrupts
; save out bootdrive
mov [bootdrv], dl
; load the kernel
mov ax,0x1000 ; ES:BX = 0x10000
mov es,ax
mov bx, 0
call read_it
call kill_motor
;enter pmode
cli
; enable a20
call kbc
mov al,0xD1 ; write
out 0x64,al
call kbc
mov al,0xDF ; enable s20
out 0x60,al
call kbc
sti
; ok, this should be enabled...let's hope so
;lgdt [gdtr] ; load gdtr pointer
;mov eax,cr0 ; finally enter pmode
;or al,1
;mov cr0,eax
;jmp codesel:Pmode
;[BITS 32]
;Pmode:
;mov eax,datasel
;mov ds,eax
;mov ds,eax
;mov es,eax
;mov fs,eax
;mov gs,eax
;mov ss,eax
;mov esp,0x90000
mov si,loadmsg
putstr: ; print a string
lodsb ; load character
or al,al
jz short putstre ; if 0 >> end of string
mov ah,0x0E ; 0x0E
mov bx,0x0007 ; attribute
int 0x10 ; call the function
jmp putstr ; next character
putstre:
; jump to the kernel
;jmp codesel:0x100000
mov ax, 0x1000 ; the address of our kernel
mov es, ax ; update registers
mov ds, ax
push ax
mov ax, 0
push ax
retf
;--------------------------------------------
;--------------------------------------------
bootdrv db 0 ; bootdrive
loadmsg db "Loading the kernel...",13,10,0
; load the kernel (second sector)
read_it:
reset: ; floppydrive reset (Interrupt 13h, 0)
push ds ; save ds
mov ax, 0 ; reset
mov dl, [bootdrv] ; our bootdrive
int 13h
pop ds ; recover ds
jc reset ; try again if it didn't work
; read sector
read_sec:
mov ah, 2 ; read
mov al, 5 ; read 5 sectors
mov ch, 0 ; cylinder = 0
mov cl, 2 ; sector = 2
mov dx, 0 ; head=0, drive=0
int 13h
jc read_sec ; try again if it didn't work
retn
kill_motor: ; turns off the floppy drive's motor
push dx
mov dx,0x3f2
mov al,0x0c
out dx, al
pop dx
ret
kbc:
xor al, al ; set al to 0
in al, 0x64 ; get kbd status through input port 0x64
test al, 2 ; check if second bit is clear
jnz kbc
ret
; the GDT table
gdtr: ; desctiptortable
dw gdt_end-gdt-1 ; Limit
dd gdt ; baseaddress
gdt:
dd 0,0 ; 0 descriptor
codesel equ $-gdt
dw 0xFFFF ; segmentgoesse
dw 0x0000 ; Segmentadresse 0..15
db 0x00 ; Segmentadresse 16..23
db 0x9A ; Zugriffsberechtigung und Typ
db 0xCF ; Zusatzinformationen und Segmentgröße 16...19
db 0x00 ; Segmentadresse 24..31
datasel equ $-gdt
dw 0xFFFF ; segmentgroesse
dw 0x0000 ; Segmentadresse 0..15
db 0x00 ; Segmentadresse 16..23
db 0x92 ; Zugriffsberechtigung und Typ
db 0xCF ; Zusatzinformationen und Segmentgröße 16...19
db 0x00 ; Segmentadresse 24..31
gdt_end
times 512-($-$$)-2 db 0 ; to make sure the first sector is full
dw 0AA55h ; Bootsignature
So siehts aus. Und so geht es auch, aber nur weil ich nicht in den pmode gehe.
Den Code hab ich fast 1:1 aus der Ausgabe 7 genommen. Aber irgendwie geht es nicht. Ich hab das Gefuehl, dass dann irgendwas mit den Adressen falsch ist, aber ich weiss nicht, was.
Kleine Anmerkung:
An einer Stelle geb ich einen String aus. Wenn ich in den Pmode gehe, dann wird der nur ausgegeben, wenn er nach dem code steht, wo ich das bootlaufwerk speichere. Sprich: bei ";load the kernel" muss er sich irgendwie aufhaengen. Aber wo denn? Und warum haengt er da nur, wenn ich spaeter ich den pmode wechsel? Das weiss er doch noch nicht an dieser Stelle.
Hm...ich hoffe mal, jemand kann mir helfen.
Edit: Also ich hab jetzt gemerkt, dass er nicht haengt sondern rebootet. Im qemu sah's halt anders aus. Hm....ich verstehs nicht.