【发布时间】:2017-06-14 04:13:18
【问题描述】:
我正在用汇编语言编写一个引导加载程序,它似乎在 qemu、bochs 和 virtualbox 上运行良好。但是,它并没有在真实硬件上加载内核(似乎)。
引导加载程序首先将一个字符写入视频内存(用于调试),然后从驱动器读取扇区 2 并远跳转到内核。然后内核将一些字符写入显存。
在真机上,我在屏幕上看到引导加载程序中的字符,然后它挂起(闪烁的插入符号)。
我已尝试将 DS、ES、SI 设置为零,并且我也在设置堆栈段。
我正在使用 bios int 13 函数 2 从驱动器中读取扇区 2。我有点怀疑它与驱动器号有关。我都尝试使用在启动时(在 dl 中)传递给引导加载程序的驱动器号,并将其手动设置为 0x0、0x80 和 0x81。
我注意到的一件奇怪的事情是,我用来接近跳跃的标签神奇地获得了正确的地址。使用 objdump 我看到例如:jmp 0x2,而使用 gdb 和 qemu,它说:jmp 0x7c02。 CS 和所有其他段寄存器都为零。无论我在链接中使用 -Ttext 0x0 还是 -Ttext 0x7c00,引导加载程序在所有模拟器上都可以正常工作。当我与 -Ttext 0x7c00 链接时,objdump 说 jmp 0x7c02。
编辑,引导加载程序如下所示:
.code16
.text
movw $0xb800, %ax
movw %ax, %ds
movw $0x0741, (0x0)
xorw %ax, %ax
movw %ax, %ds
movw %ax, %si
movw %ax, %es
movw $0x8000, %ax
movw %ax, %ss
movw $0, %sp
movb $2, %ah
movb $1, %al
movw $0x02, %cx
movb $0x00, %dh
movw $0x5000, %bx
movw %bx, %es
movw $0x0, %bx
int $0x13
ljmpw $0x5000, $0x0000
编辑,第二阶段:
.code16
.text
movw $0xb800, %ax
movw %ax, %ds
movw $0x0742, (0x2)
forever:
jmp forever
【问题讨论】:
-
如果使用了相对跳跃,则近距离跳跃将起作用。
-
很抱歉,我们无法为您提供这么少的信息。您能否使用足够的代码制作第二个引导加载程序来演示手头的问题并向我们展示?
-
尝试通过拆分成更小的部分来解决它。如果您在加载第 2 扇区之前打印一个字符,则在加载后打印另一个字符(并且读取调用是否返回错误会有所不同)。将您的代码与可用的开源引导加载程序进行比较;也许他们做了一些你错过的设置。您是否按照 Ralf Brown 中断列表在通话前进行了适当的设置?
-
您应该检查错误代码并在错误时打印另一个字符。还显示加载的第二个扇区的开始。显然,还要确保所说的第二个扇区实际上已写入您的物理设备,也许在跳转到它之前从其中打印一个字符。
-
movw $0x074b, (0x1)似乎是错误的。每个单元格为 2 个字节。你的意思是movw $0x074b, (0x2)?
标签: assembly x86 x86-16 bootloader gnu-assembler