assembly: indlæs sektor og eksekver
Jeg har en bootloader (xboot.asm) som skal boote min kerne (xkernel.asm).Først laver jeg et reset på floppy, læser 2. sektor på floppy (sektoren umiddelbart efter bootsektoren), placer den i hukommelsen, og til sidst eksekvere det indlæste (køre kernen).
Min kode virker ikke efter hensigten - er der nogen der kan fortælle mig hvorfor?
(4 filer: xboot.asm, disk.inc, common.inc, xkernel.asm)
----xboot.asm----
[BITS 16] ; not protected mode yet
[ORG 0h] ; the offset (the boot sector is loaded into memory at 7C00h:0000h - (segment:offset))
jmp start ; jumps to label "start"
nop ; nop (no operation)
; include will insert the code in disk.inc and common.inc here
%include "disk.inc"
%include "common.inc"
boot loader_info db "XBoot, ver 0.06, by XexxeX @ 12/05-2005",13,10,"Created for the XOS",13,10,0
pressanykey db "Press any key to boot XOS",13,10,0
kernel_read db "Reading kernel ...",13,10,0
boot_msg db "Booting kernel ...",13,10,0
; code
start: ; the actual bootstrap begins here
cli ; disable interrupts
mov ax, 0x07C0 ; point to where the boot sector starts
mov ds, ax ; setup ds register
mov ax, 0x9000 ; DUNNO???
mov es, ax ; setup a stack
mov sp, 0x1FFF ; DUNNO???
; insert protected mode here!
sti ; enable interrupts
call set_video_mode ; inits the videomode
call set_background_color ; changes the background color
mov si,boot loader_info
call print_string
mov si,pressanykey
call print_string
call read_char
mov si,kernel_read
call print_string
;!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! hertil ser det fint nok ud når der bootes
; men jeg ved ikke om problemet er at sektoren ikke indlæses, eller om den bare ikke eksekveres
call reset_floppy ; resets the floppy drive
call read_kernel ; reads the next sector on the disk = the kernel
mov si,boot_msg
call print_string
mov ax, 0100h ; cant load directly into segments - so a temp register is used (ax)
mov ds, ax ; Set the data segment register (ds) to point to the kernel location in memory
jmp 0100h:0000h ; goto what was just read into memory (the kernel)
; functions
set_video_mode:
mov al,03h ; select video mode 3 - color text
mov ah,00h ; set video mode function
int 10h ; call bios video services
ret
set_background_color:
mov ah,0Bh ; sets up the register, so the pc will know that it should change the backgroundcolor
mov bh,00h ; -"-
mov bl,01h ; 00=black,01=blue,02=green (see "testscreencolor.asm" for more colors)
int 10h
ret
; signature
times 510-($-$$) db 0 ; padding
dw 0xAA55 ; boot signature
----common.inc----
print_string: ; input : ds:si points to zero terminated string
cld ; direction forward
lodsb ; get next character
cmp al,0h
jz print_is_done ; too bad there isn't an instruction called "call if not zero"
call print_char
jmp print_string
print_is_done:
ret
print_char:
mov ah,0Eh
; mov cx,ABCDh ; cx and bp may work if i make the bootstrap 32bits instead of 16bits
; mov bp,ABCDh
; al contains the char to write
mov bh,00h ; the "window" to write to (like multiple screens in linux)
mov bl,07h ; sets font color to grey
int 10h
ret
read_char:
mov ah,00h ; set ah up to read a keypress
int 16h ; wait for a key to be pressed
ret
----disk.inc----
reset_floppy:
mov ah,00h ; function to perform (reset drive)
mov dl,00h ; drive (00h=a:)
int 13h ; perform the action
or ah, ah ; Check for error code
jnz reset_floppy ; Try again if ah != 0
ret
read_kernel:
; Code to load the second sector on the disk into memory location 0x0100:0x0000 (es:bx)
mov ax, 0100h ; Segment location to read into (remember can't load direct to segment register)
mov es, ax ; es = extended segment
mov bx, 0000h ; Offset to read into
mov ah, 02h ; BIOS read sector function
mov al, 01h ; read one sector
mov ch, 00h ; Track to read
mov cl, 02h ; Sector to read
mov dh, 01h ; Head to read
mov dl, 00h ; Drive to read
int 13h ; Make the BIOS call (int 13h contains mainly BIOS drive functions)
ret
----xkernel.asm----
[BITS 16] ; try with bits 32
jmp short start
; Variables
%include "common.inc"
os_info db 'XOS, ver 0.06, by XezzeX @ 12/05-2005',13,10,0
os_bootmsg db 'Booting XezzeXOS ...',13,10,0
os_rebootmsg db 'You have chosen to reboot!',13,10,'Press any key to reboot!',13,10,0
; Code
start:
; enter protected mode
; init external devices -> fdd,hdd,cdrom,audio,graphics,
; load "bash"-like prompt
mov si, os_info ; write OS info to screen
call print_string
mov si, os_bootmsg
call print_string
wait_for_key:
call read_char
call print_char
cmp al,0Dh ; 0Dh=<Enter>
jz reboot ; if true jumpto reboot
jmp wait_for_key ; loops forever (simulates something "bash"-like *GG*)
; the mission is to make this bootstrap load a kernel, which loads "bash"-like prompt
reboot:
mov si,os_rebootmsg
call print_string
call read_char
jmp 0xFFFF:0x0000 ; reboots the machine