没有hlt的HLT指令

时间:2013-08-16 11:48:15

标签: assembly x86 bootloader

我正在为自定义内核编写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类似。

那么,有人可以帮我解决这个问题吗?

1 个答案:

答案 0 :(得分:3)

Bochs说你的IF(中断标志,允许的中断)是0,所以问题必须在你的远程跳跃中。你必须确保

  1. loaded标签后的代码不包含任何hlt说明
  2. 您的loaded标签有正确的偏移量(检查您使用的编译器或链接器设置)
  3. 根据您的osdev post,您尝试将GDT的段选择器与段寄存器相关联。如果在实模式下执行,则段寄存器的值将不会用于获取GDT条目,但它们将被移位并添加到偏移作为标准实模式段。我敢打赌,如果你注释掉(或删除)将段设置为GDT条目的代码,一切都会有效。试试吧。

    它应该工作的原因很简单:你将CS片段从LOADSEG更改为0x8,实际上将你移动到IVT空间的实际模式。

    如果要使用GDT,必须先跳转到保护模式。 您可以在Brokenthorn.com上的well written tutorials找到有关此主题的更多信息。