A problem in my self-made boot loader
Posted: Wed Jun 04, 2014 8:18 am
I wrote a small piece of code to fill the MBR in order to boot different OS, but sadly my code just don't work.
The code I wrote is listed below, and I made some comment on my code to make it clarified.
Fortunately, I minimize my problem to a small scale. The error occurs seemingly every time while checking the magic number in
0000:7dbeh, but I just can not figure out why. The problem haunted me for a long time, any help will be appreciated.
Hum, by the way, English is not my mother tongue, so I may made some mistake in my sentences. If I did, I am sorry for it.
The code I wrote is listed below, and I made some comment on my code to make it clarified.
Code: Select all
.386
.model tiny
code segment byte public 'CODE' use16
assume cs:code
assume ds:code,es:code
start:
xor ax,ax
mov ss,ax
mov sp,7c00h
mov ds,ax
mov es,ax
mov si,7c00h
mov di,0600h
mov cx,200h
cld
rep movsb ;Copy itself to 0000:0600.
push ax
push 061ch
retf ;Return to 0000:061c where the next insturction starts.
;--------------------------------------------------------------------------------------------
sti
push dx ;Save dx.
mov cx,04h
mov bp,07beh
CHECKPARTITIONTABLE:
cmp byte ptr [bp+00h],00h
jns NEXTPARTITION
inc [BOOTABLEPARTITIONCOUNT+600h]
NEXTPARTITION:
add bp,10h
loop CHECKPARTITIONTABLE ;Loop 4 times to find possible bootable partition.
;--------------------------------------------------------------------------------------------
cmp [BOOTABLEPARTITIONCOUNT+600h],'0'
jz NOBOOTABLEPARTITIONFOUND ;If ZF=1, no bootable partition found.
jmp BOOTABLEPARTITIONFOUND
;--------------------------------------------------------------------------------------------
GETINPUT:
xor ah,ah
int 16h
cmp al,[BOOTABLEPARTITIONCOUNT+600h]
ja ERRORLOADING
cmp al,'1'
jb ERRORLOADING ;Check user's input.
;--------------------------------------------------------------------------------------------
sub al,30h
mov cl,al
xor ch,ch
mov bp,07aeh ;For later addition.
ADDBPFORNEXTENTRY:
add bp,10h
loop ADDBPFORNEXTENTRY ;Points to the partition table user chose.
pop dx
LOADVBR:
mov [bp+00],dl
mov byte ptr [bp+11],05h ;5 times to try to load VBR sector.
mov ah,41h
mov bx,55aah
int 13h ;Check for int 13h extensions in BIOS.
jb ERRORLOADING ;Jump if CF=1, there is no int 13h extensions.
cmp bx,0aa55h
jnz ERRORLOADING
test cx,0001h
jz ERRORLOADING ;If no int 13h extensions, fail.
EXTENDEDREAD:
;--------------------------------------------------------------------------------------------
push dword ptr 00000000h
push dword ptr [bp+8]
push word ptr 0000h
push word ptr 7c00h
push word ptr 0001h
push word ptr 0010h
; Offset Size Description of DISK ADDRESS PACKET's Contents
; ------ ----- ------------------------------------------------------------
; 00h BYTE Size of packet (10h or 18h; 16 or 24 bytes).
; 01h BYTE Reserved (00).
; 02h WORD Number of blocks to transfer (Only 1 sector for this code).
; 04h DWORD Points to -> Transfer Buffer (0000 7C00 for this code).
; 08h QWORD Starting Absolute Sector (get from Partition Table entry:
; (00000000 + DWORD PTR [BP+08]). Remember, the Partition
; Table Preceding Sectors entry can only be a max. of 32 bits!
; 10h QWORD NOT USED HERE. (EDD-3.0; optional) 64-bit flat address
; of transfer buffer; only used if DWORD at 04h is FFFF:FFFF.
mov ah,42h
mov dl,[bp+00h]
mov si,sp
int 13h ;Try int 13h extended read.
jc ERRORLOADING
;--------------------------------------------------------------------------------------------
lahf
add sp,10h ;Remove DAP bytes from stack.
sahf ;Discard any possible change to PSW.
jnb CHECKMAGICNUMBER ;Jump when CF=0, indicating that extended read succeeded.
dec byte ptr [bp+11h]
jnz RESETDISK
cmp byte ptr [bp+00h],80h
jz ERRORLOADING
mov dl,80h
jmp LOADVBR
RESETDISK:
xor ah,ah
mov dl,[bp+00h]
int 13h ;Reset disk system.
jmp EXTENDEDREAD
CHECKMAGICNUMBER:
mov si,7dfeh
cmp word ptr [si],0aa55h ;Check the magic number where the VBR resides.
jnz ERRORLOADING ;If we do not see it, fail.
mov dl,[bp+00h]
xor dh,dh
jmp word ptr ds:[7c00h] ;Jump to Volume Boot Record(VBR) code loaded into Memory by this MBR.
;--------------------------------------------------------------------------------------------
NOBOOTABLEPARTITIONFOUND:
mov ax,offset NOBOOTABLEPARTITIONMSG
jmp DISPLAYMESSAGE
BOOTABLEPARTITIONFOUND:
mov ax,offset PROMPTMSG
jmp DISPLAYMESSAGE
SHOWBOOTABLEPARTITION:
mov ax,offset BOOTABLEPARTITION
inc [BOOTABLEPARTITION+601h]
mov bl,[BOOTABLEPARTITIONCOUNT+600h]
cmp [BOOTABLEPARTITION+601h],bl
jbe DISPLAYMESSAGE
jmp GETINPUT
ERRORLOADING:
mov ax,offset ERRORLOADINGMSG
mov [BOOTABLEPARTITIONCOUNT+600h],'0'
DISPLAYMESSAGE:
add ax,0600h ;Add base address to ax.
mov si,ax
LOADNEXTBYTE:
lodsb
cmp al,00h
jz THENEXTTODO
mov bx,0007h
mov ah,0eh
int 10h
jmp LOADNEXTBYTE
THENEXTTODO:
cmp [BOOTABLEPARTITIONCOUNT+600h],'0'
jnz SHOWBOOTABLEPARTITION
HALTCOMPUTER:
hlt
jmp HALTCOMPUTER
NOBOOTABLEPARTITIONMSG db 'No bootable partition found.',00 ;No bootable partition.
ERRORLOADINGMSG db 0ah,0dh,'Error loading operating system.',00 ;Error message.
PROMPTMSG db 'Input corresponding number to load OS boot record',0ah,0dh,00 ;Prompt the user.
BOOTABLEPARTITION db '(0)partition ',00
BOOTABLEPARTITIONCOUNT db '0'
code ends
end start
0000:7dbeh, but I just can not figure out why. The problem haunted me for a long time, any help will be appreciated.
Hum, by the way, English is not my mother tongue, so I may made some mistake in my sentences. If I did, I am sorry for it.