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 все работает правильно. Спасибо за все.