我正在为自定义内核编写bootloader,它(bootloader)基于Linux内核v0.1 boot.s
。这是代码:
.set BOOTSEG, 0x7c0
.set LOADSEG, 0x9000
.set SYSSEG, 0x1000
start:
//copy the WHOLE bootloader to new location
movw BOOTSEG, %ax
movw %ax, %ds
xor %si, %si
movw LOADSEG, %ax
movw %ax, %es
xor %di, %di
movw 256, %cx
rep movsw
//jump to new location
cli
movw LOADSEG, %ax
movw %ax, %es
ljmp $LOADSEG, $loaded
loaded:
// ...
movw $0x3, %ax
int $0x10
// ...
当我尝试跳转到新位置时,Bochs写道:WARNING: HLT instrucion with IF=0
,但我的代码中根本没有hlt
条指令。跳转后Bochs继续运行,但无法正常工作,例如:int $0x10
无法清除屏幕。
可能是我复制了bootloader错误,但它与Linux类似。
那么,有人可以帮我解决这个问题吗?
答案 0 :(得分:3)
Bochs说你的IF(中断标志,允许的中断)是0,所以问题必须在你的远程跳跃中。你必须确保
loaded
标签后的代码不包含任何hlt
说明loaded
标签有正确的偏移量(检查您使用的编译器或链接器设置)根据您的osdev post,您尝试将GDT的段选择器与段寄存器相关联。如果在实模式下执行,则段寄存器的值将不会用于获取GDT条目,但它们将被移位并添加到偏移作为标准实模式段。我敢打赌,如果你注释掉(或删除)将段设置为GDT条目的代码,一切都会有效。试试吧。
它应该工作的原因很简单:你将CS片段从LOADSEG
更改为0x8
,实际上将你移动到IVT空间的实际模式。
如果要使用GDT,必须先跳转到保护模式。 您可以在Brokenthorn.com上的well written tutorials找到有关此主题的更多信息。