带 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 你必须考虑字节顺序并放置 在 段 之前偏移。解决方法很简单——在结构中交换 segment 和 offset。它将显示:
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
这是我的引导扇区和内核代码 我正在使用 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 你必须考虑字节顺序并放置 在 段 之前偏移。解决方法很简单——在结构中交换 segment 和 offset。它将显示:
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