hi,
ich versuch mich(angelehnt an das 3.tutorial) an einem kleinen bootloader und kernel. klappt prinzipiell auch alles, bis auf das manipulieren der interrupt-vector-table. meine installierte interrupt-routine wird scheinbar nicht aufgerufen. ich poste mal etwas code. der bootloader
org 0x7c00
main:
cli
mov ax, cs
mov ds, ax
mov es, ax
mov ax, 0x9000
mov ss, ax
xor ax, ax
mov sp, ax ; relative adressing to stack segment
sti
mov [bootdrv], dl
mov si, loadmsg
call puts
call load
;; jump to kernel
;; emulated function call
mov si, loadmsg2
call puts
call getkey
mov ax, kerneladr
push ax
;; only necessary for far jumps (retf)
xor ax, ax
push ax
retf ; pops kernel address 0x1000
load:
;;; loads the kernel
push ds
mov ax, 0 ; reset function
mov dl, [bootdrv] ; what drive?
int 13h ; interrupt
pop ds
jc load
load_impl:
mov ax, kerneladr
mov es, ax ; buffer address for reading
xor bx, bx ; offset = 0
;; read in sectors
mov ah, 2 ; read function
mov al, 1 ; 1 sectors
mov cx, 2 ; cylinder = 0, sector = 2
xor dx, dx ; head = 0, drive = 0
int 13h ; es:bx = 0x1000
jc load_impl
ret
getkey:
;;; wait for keypress
xor ah, ah ; function 0
int 16h
ret
puts:
;;; string output
;;; expects the data to be in si
lodsb
or al, al
jz short puts_end ; end?
mov ah, 0x0e ; function
mov bx, 0x0 ; attribute-byte, unecessary
int 10h ; writing
jmp puts
puts_end:
ret
;; variablen
kerneladr equ 0x1000
bootdrv db 0
loadmsg db "Loading kernel ...", 13, 10, 0
loadmsg2 db "Press key to initialize kernel code ...", 13, 10, 0
times 510 - ($ - $$) db 0
dw 0xaa55
und der kernel:
;;; kernel code now
mov ax, kerneladr
mov ds, ax
mov es, ax
main:
mov si, msg
call puts
;; interrupts
push es
mov ax, 0x7c00
mov es, ax
cli
;; interrupts
mov word [es:21h*4], int_21h
mov [es:21h*4+2], cs
sti
pop es
;; call interrupt
mov si, msg_int
xor al, al
int 21h ; printing (**)
mov al, 1
int 21h ; waiting for key .. (**)
mov si, msg_boot
xor al, al
int 21h ; printing (**)
mov al, 1
int 21h ; waiting for key .. (**)
jmp reboot
;; interrupt handler
int_21h:
;; al = 0 -> print
;; al = 1 -> wait for key press
cmp al, 0
je int_21h_puts
cmp al, 1
je int_21h_getkey
int_21h_end:
iret
int_21h_puts:
lodsb
or al, al
jz int_21h_end ; end?
mov ah, 0x0e ; function
mov bx, 0x0008
int 10h
jmp int_21h_puts
int_21h_getkey:
xor ah, ah
int 16h
jmp int_21h_end
;; variables
kerneladr equ 0x1000
msg db "welcome", 13, 10, 0
msg_boot db "press any key to reboot ...", 13, 10, 0
msg_int db "interrupt message", 13, 10, 0
reboot:
;; now rebooting
db 0xea
dw 0x0000
dw 0xffff
times 512 - ($ - $$) db 0
ich sitzt jetzt schon ziemlich lang davor, komm aber auf keinen grünen zweig.
es wird wie gesagt weder die ausgabe vollzogen, noch auf einen tastendruck gewartet ((**) im code). rebootet wird auch nicht, was mich auch etwas wundert.
das einzige, das für mich sinn ergeben würde ist, dass der bootloader ja nach 0x7c00 geladen wird und sich die ivt ebenfalls an diesem ort befindet und überschrieben würde. aber eigentlich bin ich mir ziemlich sicher, dass die 1024Byte vom bios automatisch für die ivt freigelassen werden. würd sonst keinen sinn ergeben.
woran scheiterts bei meinem code?
danke für die hilfe