Finding the start of the Root Directory BootLoader

回眸只為那壹抹淺笑 提交于 2019-12-13 02:48:33

问题


I am creating a BootLoader that boots from a CD and I am having trouble discovering how to find the start of the root Directory on the Disk here is my boot code:

BITS   16

ORG  0x00

Start: jmp main


;Colors for text
%DEFINE TEAL 0x03
%DEFINE RED 0x04
%DEFINE PURPLE 0x05
COL: db 0
ROW:  db 0

;macro for print
%macro Print 2
pusha
    xor ax, ax
    xor dx, dx
    mov dh, BYTE[ROW];puts the row into the dh register
    mov dl, BYTE[COL]
    xor bx, bx
    mov bl, %2
    mov si, %1
    call cPrint
    mov BYTE[COL], dl
 ;saves the rows for the next time we need to print
popa
%endmacro

Print_ln:

pusha   
    mov dh, BYTE[ROW]          
    mov ah, 0x02            ;set cursor pos
    mov bh, 0x00            ;page 00
    inc dh                  ;row 00
    mov dl, 0x00            ;col. 00    
    int 0x10
    mov BYTE[ROW], dh
    mov BYTE[COL], 0
    popa


ret

cPrint:                   ; Routine: output string in SI to screen


 .top:
    ;Paramaters for Input 
    mov ah, 09h             ; Must be 9 to print color
    mov cx, 0x01            ;x position
    lodsb                   ; Get character from string
    test al, al
    je .done                ; If char is zero, end of string
    int 0x10                 ; Otherwise, print it

    mov ah, 0x02            ;set cursor position
    mov bh, 0x00            ;page
    inc dl      ;column
    int 0x10                ;changes the cursor position so the next char can be written at the new location
    jmp .top

 .done:
    ret

;clears the screen and sets the cursor position to the top left 
 clear:
    mov ah, 0x0F            ;get current video mode
    mov al, 0x00            ;reset register
    int 0x10                ;get video mode
    mov ah, 0x00            ;set video mode
    int 0x10                ;reset screen
    mov ah, 0x02            ;set cursor pos
    mov bh, 0x00            ;page 00
    mov dh, 0x00            ;row 00
    mov dl, 0x00            ;col. 00
    int 0x10                ;set pos
ret



;CMPSB compares the byte at [DS:SI] or [DS:ESI] with the byte at [ES:DI] 
;or [ES:EDI], 
;and sets the flags accordingly. It then increments or decrements (depending 
;on the direction flag: increments
; if the flag is clear, decrements if it is set) SI and DI (or ESI and EDI).
Read_Sectors:  
        ;/* Read the sector into memory. */

        .ForLoop:
            mov     ah,042h
            xor     al,al
            mov     si, DiskAddressPacket
            mov     dl, [CDDriveNumber]
            int     013h
        jnc    .Success     ; /* read error? */

        Print Read_Sector_Error_MSG, RED

        cli
        hlt

.Success:
        Print Progress_MSG , PURPLE
        inc WORD[DiskAddressPacket.SectorsToRead]

        loop .ForLoop

ret


main:

    cli
    mov ax, 0x07c0  ;adjust the segment registers
    mov ds, ax
    mov gs, ax
    mov fs, ax


Create_Stack:
    xor ax, ax
    mov es, ax
    mov ss, ax
    mov sp ,0x0FFFE
    sti
    mov es, 0x200

    mov     [CDDriveNumber],dl
    call clear


    Print W_MSG, TEAL;prints the loading message in colour
    call Print_ln

    LOAD_ROOT:
    ;first calculate the start of the Root directory
     mov WORD[DiskAddressPacket.Offset], 0x01000
     mov cx, 0x01
     call Read_Sectors

     call Print_ln
     Print READ_SUCCESS, TEAL
     call Print_ln




    cli
    hlt



Sector_Size: dw 512                     
CDDriveNumber: db 80h
CD_bytes_per_sect:         dw    0
CD_root_dir_size:          dd    0
CD_root_dir_sectors:       dw    0
CD_root_dir_start:         dd    0
CD_file_size:              dd    0
CD_file_sectors:           dw    0
CD_file_start:             dd    0
CD_desc_sector:            dd    0
CD_Signature:              db "\2CD001"
CD_FILE_VER:               db 0x01

;Disk Address Packet


DiskAddressPacket:          db 16,0 
.SectorsToRead:             dw 1                              ; Number of sectors to read (read size of OS) 
.Offset:                    dw 0                              ; Offset :0000 
.Segment:                   dw 0200h                          ; Segment 0200
.End:                       dq 16                             ; Sector 16 or 10h on CD-ROM 

RETURN: DB 0

W_MSG: db "Loading Z-Boot", 0
Stage2: db "STAGE2 BIN"
Read_Sector_Error_MSG: db "Error, failed to read sector",0
READ_SUCCESS: db "Sectors read in correctly",0
Progress_MSG: db ".",0
FILE_NOT_FOUND: db "Error, file not found",0
FOUND: db "Found", 0
times 2046 - ($ - $$) db 0; padd out the rest of the file to 0
DW 0xAA55

I saw some code that did something like this to find the Volume descriptor I have a feeling you need that to find the root directory but I can't put my finger on it here is the code that does that:

get_next_desc: 
        ;/* Read the sector in memory at 0000:1000. */
        mov     [desc_sector],eax
        mov     bx,01000h
        mov     cx,1
        call    read_sectors

        ;/* Check for the signature "\2CD001" at the beginning of the descriptor. */
        mov     si, cd_signature
        mov     di,01000h
        mov     cx,6
        cmpsb
        je      found_desc

        ;/* Check if we have looked in all the descriptors of volume. */
        cmp     byte [es:0x1000],0FFh
        jne     next_desc

        ;/* We looked in all sessions of the disk, and the OS image wasn't found.
        ;   We display an error message on the screen and then prompts the user to
         ;  press a key to restart the computer. */
        mov     si, msg_file_not_found
        call    print_string
        jmp     reboot

next_desc: 

Here is what I use to assemble my code:

nasm ZerothStage.asm -o ZerothStage.bin

mkisofs -b ZerothStage.bin -no-emul-boot -o BootLoader.iso ./

回答1:


Nevermind I got it apparently I needed to load the segment offset address from the DAP into ES:DI and look for the Volume descriptor there here is what i used to solve it if anyone is interested.

Code:

    mov es, WORD[DiskAddressPacket.Segment] 
    mov di, WORD[DiskAddressPacket.Offset] 

    xor bx, bx 
    .top 
            mov al, BYTE[ES:DI+BX] 
            cmp al, ' ' 
            je .Done 
            mov ah, 0xE 
            int 0x010 
            inc bx 
    jmp .top 

    .Done:   

I read the fourth sector instead of the 16th sector apparently it is the last sector of the image that you must read in I am new to this so If anyone comes accross this could explain this a little better that would be great as I am still trying to get a grasp on these boot concepts



来源:https://stackoverflow.com/questions/24949598/finding-the-start-of-the-root-directory-bootloader

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!