2-х ступенчатый загрузчик с MASM

Вот мой код для загрузочного сектора и ядра. Я загружаю свой загрузочный сектор из usb, используя int 13 func 42 в 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

кто-нибудь может помочь?

2 ответа

Решение

Я заметил пару проблем с вашим кодом. Первый - второстепенный. Ваш загрузчик начинается с:

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

Вы mov буква загрузочного диска BiosDriveID, однако вы делаете это перед настройкой DS, Когда ты пишешь mov [BiosDriveID],dl, DS сегмент предполагается, но вы его не установили. Вы не можете полагаться на то, что BIOS перепрыгнет в ваш загрузочный сектор с уже действующим DS. Вы должны убедиться, что вы настроили 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 предположим, что сегмент удержания : смещение. Вы сделали это, однако вы не разместили их в правильном порядке. Intel x86 имеет младший порядок байтов, поэтому если вы разбиваете сегмент: смещение на два отдельных слова, вы должны учитывать порядок байтов и смещение перед сегментом. Исправить это просто - поменять сегмент и смещение в вашей структуре. Было бы читать:

    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

По словам Майкла, я забыл младший порядок байтов, поэтому после замены смещения и сегмента в DAPACK все работает правильно. Спасибо за все.

Другие вопросы по тегам