2

我正在为我的自定义内核编写引导加载程序,它(引导加载程序)基于 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不清除屏幕。

可能是我复制了引导加载程序错误,但它类似于Linux。

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

4

1 回答 1

3

Bochs 说你的 IF(中断标志,允许中断)为 0,所以问题一定出在你的跳远上。您必须确保

  1. 标签后的代码loaded不包含任何hlt说明
  2. 您的loaded标签有正确的偏移量(检查您使用的编译器或链接器设置)

根据您的osdev post,您正在尝试将 GDT 的段选择器与段寄存器相关联。如果您在实模式下执行此操作,段寄存器的值将不会用于获取 GDT 条目,但它们将作为标准实模式段移动并添加到偏移量。我敢打赌,如果您注释掉(或删除)将段设置为 GDT 条目的代码,一切都会正常工作。试试看。

它应该工作的原因很简单:您将 CS 段从 更改LOADSEG0x8,实际上将您移动到 ​​IVT 空间以进行实模式。

如果要使用 GDT,必须先跳转到保护模式。您可以在 Brokenthorn.com 上编写良好的教程中找到有关此主题的更多信息。

于 2013-08-16T12:36:51.057 回答