带 MASM 的 2 阶段引导加载程序

2 stage boot loader with MASM

这是我的引导扇区和内核代码 我正在使用 int 13 func 42 从 usb 加载我的引导扇区到 1000:00(h) 我正在跳转到内核 但是加载内核后总是没有任何反应...

;------------------------------------------------------------
.286                               ; CPU type
;------------------------------------------------------------
.model TINY                        ; memory of model
;---------------------- EXTERNS -----------------------------
extrn               _BootMain:near     ; prototype of C func
;------------------------------------------------------------
;------------------------------------------------------------   
.code   
org             07c00h         ; for BootSector
main:
                jmp short start    ; go to main
                nop

;----------------------- Vairiables -----------------------
        BiosDriveID db  0       

;----------------------- CODE SEGMENT -----------------------
start:  
        cli
        mov     [BiosDriveID],dl
        mov     ax,cs               ; Setup segment registers
        mov     ds,ax               ; Make DS correct
        mov     es,ax               ; Make ES correct
        mov     ss,ax               ; Make SS correct        
        mov     bp,7c00h
        mov     sp,7c00h            ; Setup a stack
        sti

        ;call           _BootMain



        mov     si, OFFSET msgLoading
        call    DisplayMessage


     ;*************************************************************************
     ; Setup DISK ADDRESS PACKET
     ;*************************************************************************

        mov     si, OFFSET msgDAPACK
        call    DisplayMessage
        jmp     strtRead

        DAPACK:
                db      010h         ; Packet Size
                db      0            ; Always 0
        blkcnt: 
                dw      1            ; Sectors Count    
        db_add:
                dw      01000h       ; Transfer Segment
                dw      0h           ; Transfer Offset
        d_lba:
                dd      1            ; Starting LBA (0 - n)
                dd      0            ; Bios 48 bit LBA


     ;*************************************************************************
     ; Start Reading Sectors using INT13 Func 42     
     ;*************************************************************************
strtRead:
        mov     si, OFFSET msgSectors
        call    DisplayMessage

        mov     si, OFFSET DAPACK
        mov     ah,042h             
        mov     dl,[BiosDriveID]
        int     013h    
        jc      readError
        jmp     readOK

     ;*************************************************************************
     ; Sectors Reading Error
     ;*************************************************************************
readError:
        mov     si,OFFSET msgFailure
        call    DisplayMessage
        hlt


     ;*************************************************************************
     ; Sectors Reading OK
     ;*************************************************************************
readOK:
        mov     si, OFFSET msgReadOK
        call    DisplayMessage

        mov     ax,01000h
        mov     ds,ax               ; Make DS correct
        mov     es,ax               ; Make ES correct
        mov     ss,ax               ; Make SS correct 

        db      09Ah
        dw      0000h
        dw      1000h

        ;mov        si, OFFSET msgLoading
        ;call   DisplayMessage


        ;call   farKernel
        ;push   1000h
        ;push   0000h
        ;retf
        hlt



        ret




     ;*************************************************************************
     ; PROCEDURE DisplayMessage
     ; display ASCIIZ string at ds:si via BIOS
     ;*************************************************************************
     DisplayMessage     proc    near
          lodsb                                       ; load next character
          or      al, al                              ; test for NUL character
          jz      DONE
          mov     ah, 00Eh                            ; BIOS teletype
          mov     bh, 000h                            ; display page 0
          mov     bl, 007h                            ; text attribute
          int     010h                                ; invoke BIOS
          jmp     DisplayMessage
     DONE:
          ret
     DisplayMessage     endp
     ;*************************************************************************


;*******************************************************************************
;messages that needs to be shown

     msgLoading:
                db 00Dh, 00Ah, "******************************************"
                db 00Dh, 00Ah, "* AFME Operating System Version 1.00...  *"             
                db 00Dh, 00Ah, "******************************************", 00Dh, 00Ah,000h

     msgDAPACK   db 00Dh, 00Ah, "Setup Disk Addressing Packet...", 00Dh, 00Ah, 000h
     msgSectors  db 00Dh, 00Ah, "Start Loading Sectors...", 00Dh, 00Ah, 000h

     msgFailure  db 00Dh, 00Ah, "Kernel loading failed...", 00Dh, 00Ah, 000h

     msgReadOK   db 00Dh, 00Ah, "Kernel loading succeded...", 00Dh, 00Ah, 000h 

     msgCRLF     db 00Dh, 00Ah, 000h



     db 506-($-start) dup (0)
     dw 0AA55h
     ;************************************************************************* 

KERNEL:



     END main                ; End of program

和内核

;------------------------------------------------------------
.286                               ; CPU type
;------------------------------------------------------------
.model TINY                        ; memory of model
;---------------------- EXTERNS -----------------------------
;extrn              _BootMain:near     ; prototype of C func
;------------------------------------------------------------
;------------------------------------------------------------   
.code   
org             0h         ; for Kernel
main:
;----------------------- CODE SEGMENT -----------------------
start:  

        mov     ah,9
        mov     al,64
        mov     bh, 0                            ; display page 0
        mov     bl,4
        mov     cx,1
        int     010h
        hlt
        mov     si, OFFSET msgHello
        call    DisplayMessage

        hlt


     ;*************************************************************************
     ; PROCEDURE DisplayMessage
     ; display ASCIIZ string at ds:si via BIOS
     ;*************************************************************************
     DisplayMessage     proc    near
          lodsb                                       ; load next character
          or      al, al                              ; test for NUL character
          jz      DONE
          mov     ah, 00Eh                            ; BIOS teletype
          mov     bh, 000h                            ; display page 0
          mov     bl, 007h                            ; text attribute
          int     010h                                ; invoke BIOS
          jmp     DisplayMessage
     DONE:
          ret
     DisplayMessage     endp
     ;*************************************************************************


;*******************************************************************************
;messages that needs to be shown




     msgHello  db 00Dh, 00Ah, "Helloo From the kernel...", 00Dh, 00Ah, 000h

     END main                ; End of program

有人可以帮忙吗?

根据 Michael 的说法,我忘记了小尾数法,因此在替换 DAPACK 中的偏移量和段后它可以正常工作。 谢谢大家。

我注意到您的代码存在一些问题。第一个是小的。您的引导加载程序以:

开头
start:  
        cli
        mov     [BiosDriveID],dl
        mov     ax,cs               ; Setup segment registers
        mov     ds,ax               ; Make DS correct

mov将启动盘符BiosDriveID。然而,你在设置 DS 之前就这样做了。当您编写 mov [BiosDriveID],dl 时,假定 DS 段但您实际上并未设置它。在 DS 已经有效的情况下,您不能依赖 BIOS 跳转到您的引导扇区。您应该确保先设置 DS

start:  
        cli
        mov     ax,cs               ; Setup segment registers
        mov     ds,ax               ; Make DS correct
        .
        .
        mov     [BiosDriveID],dl    ; DS is properly set.

阻止启动内核的主要错误是您完成的磁盘读取使用此数据包:

    DAPACK:
            db      010h         ; Packet Size
            db      0            ; Always 0
    blkcnt: 
            dw      1            ; Sectors Count    
    db_add:
            dw      01000h       ; Transfer Segment
            dw      0h           ; Transfer Offset
    d_lba:
            dd      1            ; Starting LBA (0 - n)
            dd      0            ; Bios 48 bit LBA

特别是 db_add 假设持有 segment:offset 。您已经这样做了,但是您没有按正确的顺序放置它们。英特尔 x86 是小端,所以如果你将 segment:offset 分成两个单独的 WORDS 你必须考虑字节顺序并放置 之前偏移。解决方法很简单——在结构中交换 segmentoffset。它将显示:

    DAPACK:
            db      010h         ; Packet Size
            db      0            ; Always 0
    blkcnt: 
            dw      1            ; Sectors Count    
    db_add:
            dw      0h           ; Transfer Offset   \ Reversed to conform
            dw      01000h       ; Transfer Segment  / to little Endian
    d_lba:
            dd      1            ; Starting LBA (0 - n)
            dd      0            ; Bios 48 bit LBA