Bootloader 可以在模拟器中运行,但不能在真实硬件上运行
Bootloader works in emulators but not on real hardware
我正在用汇编编写一个引导加载程序,它似乎在 qemu、bochs 和 virtualbox 上运行良好。但是,它并没有在真正的硬件上加载内核(看起来)。
引导加载程序首先向视频内存写入一个字符(用于调试),然后从驱动器读取扇区 2 并远跳转到内核。然后内核将一些字符写入显存。
在真机上,我在屏幕上看到了来自引导加载程序的字符,它挂在那里(blink插入符号)。
我已经尝试将DS、ES、SI设置为零,我也在设置堆栈段。
我正在使用 bios int 13 函数 2 读取驱动器的扇区 2。我有点怀疑它与驱动器号有关。我都尝试使用启动时传递给引导加载程序的驱动器号(在 dl 中),并手动将其设置为 0x0、0x80 和 0x81。
我注意到一件奇怪的事情是我用来接近跳跃的标签神奇地得到了正确的地址。使用 objdump 我看到例如:jmp 0x2,而使用 gdb 和 qemu,它说:jmp 0x7c02。 CS 和所有其他段寄存器都为零。无论我在 linking 中使用 -Ttext 0x0 还是 -Ttext 0x7c00,引导加载程序在所有模拟器上都能正常工作。 objdump 说 jmp 0x7c02 当我 link 和 -Ttext 0x7c00.
编辑,引导加载程序如下所示:
.code16
.text
movw [=10=]xb800, %ax
movw %ax, %ds
movw [=10=]x0741, (0x0)
xorw %ax, %ax
movw %ax, %ds
movw %ax, %si
movw %ax, %es
movw [=10=]x8000, %ax
movw %ax, %ss
movw [=10=], %sp
movb , %ah
movb , %al
movw [=10=]x02, %cx
movb [=10=]x00, %dh
movw [=10=]x5000, %bx
movw %bx, %es
movw [=10=]x0, %bx
int [=10=]x13
ljmpw [=10=]x5000, [=10=]x0000
编辑,第二阶段:
.code16
.text
movw [=11=]xb800, %ax
movw %ax, %ds
movw [=11=]x0742, (0x2)
forever:
jmp forever
如果您的硬件正在为 USB 驱动器使用软盘仿真,则如果您的 MBR 中没有正确的 BIOS Parameter Block (BPB),它可能无法正常启动。许多 BIOS 将尝试在引导加载程序启动时检测 BPB,甚至可能在引导加载程序加载到内存后使用适当的驱动器几何形状更新值。可能您的引导加载程序未被检测为正确的可引导驱动器,或者它是但 BIOS 在执行之前用驱动器几何信息覆盖了您的一些代码。
下面添加了一个看起来像 2.88MB 软盘的 BPB。
.global _start
.code16
.text
_start:
jmp main
.space 3 - (.-_start)
/* Configuration for a 2.88MB floppy using FAT 12 */
OEMname: .ascii "MYBOOT "
bytesPerSector: .word 512
sectPerCluster: .byte 1
reservedSectors: .word 1
numFAT: .byte 2
numRootDirEntries: .word 240
numSectors: .word 5760
mediaType: .byte 0xf0
numFATsectors: .word 9
sectorsPerTrack: .word 36
numHeads: .word 2
numHiddenSectors: .long 0
numSectorsHuge: .long 0
driveNum: .byte 0
reserved: .byte 0x00
signature: .byte 0x29
volumeID: .long 0x54428E71
volumeLabel: .ascii "NO NAME "
fileSysType: .ascii "FAT12 "
main:
movw [=10=]xb800, %ax
movw %ax, %ds
movw [=10=]x0741, (0x0)
xorw %ax, %ax
movw %ax, %ds
movw %ax, %si
movw %ax, %es
movw [=10=]x8000, %ax
movw %ax, %ss
movw [=10=], %sp
movb , %ah
movb , %al
movw [=10=]x02, %cx
movb [=10=]x00, %dh
movw [=10=]x5000, %bx
movw %bx, %es
movw [=10=]x0, %bx
int [=10=]x13
ljmpw [=10=]x5000, [=10=]x0000
.space 510-(.-_start)
.word 0xaa55
我正在用汇编编写一个引导加载程序,它似乎在 qemu、bochs 和 virtualbox 上运行良好。但是,它并没有在真正的硬件上加载内核(看起来)。
引导加载程序首先向视频内存写入一个字符(用于调试),然后从驱动器读取扇区 2 并远跳转到内核。然后内核将一些字符写入显存。
在真机上,我在屏幕上看到了来自引导加载程序的字符,它挂在那里(blink插入符号)。
我已经尝试将DS、ES、SI设置为零,我也在设置堆栈段。
我正在使用 bios int 13 函数 2 读取驱动器的扇区 2。我有点怀疑它与驱动器号有关。我都尝试使用启动时传递给引导加载程序的驱动器号(在 dl 中),并手动将其设置为 0x0、0x80 和 0x81。
我注意到一件奇怪的事情是我用来接近跳跃的标签神奇地得到了正确的地址。使用 objdump 我看到例如:jmp 0x2,而使用 gdb 和 qemu,它说:jmp 0x7c02。 CS 和所有其他段寄存器都为零。无论我在 linking 中使用 -Ttext 0x0 还是 -Ttext 0x7c00,引导加载程序在所有模拟器上都能正常工作。 objdump 说 jmp 0x7c02 当我 link 和 -Ttext 0x7c00.
编辑,引导加载程序如下所示:
.code16
.text
movw [=10=]xb800, %ax
movw %ax, %ds
movw [=10=]x0741, (0x0)
xorw %ax, %ax
movw %ax, %ds
movw %ax, %si
movw %ax, %es
movw [=10=]x8000, %ax
movw %ax, %ss
movw [=10=], %sp
movb , %ah
movb , %al
movw [=10=]x02, %cx
movb [=10=]x00, %dh
movw [=10=]x5000, %bx
movw %bx, %es
movw [=10=]x0, %bx
int [=10=]x13
ljmpw [=10=]x5000, [=10=]x0000
编辑,第二阶段:
.code16
.text
movw [=11=]xb800, %ax
movw %ax, %ds
movw [=11=]x0742, (0x2)
forever:
jmp forever
如果您的硬件正在为 USB 驱动器使用软盘仿真,则如果您的 MBR 中没有正确的 BIOS Parameter Block (BPB),它可能无法正常启动。许多 BIOS 将尝试在引导加载程序启动时检测 BPB,甚至可能在引导加载程序加载到内存后使用适当的驱动器几何形状更新值。可能您的引导加载程序未被检测为正确的可引导驱动器,或者它是但 BIOS 在执行之前用驱动器几何信息覆盖了您的一些代码。
下面添加了一个看起来像 2.88MB 软盘的 BPB。
.global _start
.code16
.text
_start:
jmp main
.space 3 - (.-_start)
/* Configuration for a 2.88MB floppy using FAT 12 */
OEMname: .ascii "MYBOOT "
bytesPerSector: .word 512
sectPerCluster: .byte 1
reservedSectors: .word 1
numFAT: .byte 2
numRootDirEntries: .word 240
numSectors: .word 5760
mediaType: .byte 0xf0
numFATsectors: .word 9
sectorsPerTrack: .word 36
numHeads: .word 2
numHiddenSectors: .long 0
numSectorsHuge: .long 0
driveNum: .byte 0
reserved: .byte 0x00
signature: .byte 0x29
volumeID: .long 0x54428E71
volumeLabel: .ascii "NO NAME "
fileSysType: .ascii "FAT12 "
main:
movw [=10=]xb800, %ax
movw %ax, %ds
movw [=10=]x0741, (0x0)
xorw %ax, %ax
movw %ax, %ds
movw %ax, %si
movw %ax, %es
movw [=10=]x8000, %ax
movw %ax, %ss
movw [=10=], %sp
movb , %ah
movb , %al
movw [=10=]x02, %cx
movb [=10=]x00, %dh
movw [=10=]x5000, %bx
movw %bx, %es
movw [=10=]x0, %bx
int [=10=]x13
ljmpw [=10=]x5000, [=10=]x0000
.space 510-(.-_start)
.word 0xaa55