Bran's Kernel Development Tutorial Known Bugs

来自osdev
跳到导航 跳到搜索

从好几个地方-包括这个Wiki-都指向 Bran的内核开发教程 作为起点。 但该教程存在一些问题,通常会让人们出现在论坛上,再次提出相同的问题。 这篇文章旨在先发制人地回答这些问题,就像是“Bran的常见问题”,希望对你有用。

注意: 包含Bran教程的网站osdever.net最近关闭了很长时间。 你可以在网上这里找到它的互联网档案

我一添加字符串,事情就出错了。

Bran教程中的链接器脚本不会将 rodata 节(Section)添加到二进制文件中,这是编译器放置静态字符串的地方。 用这个代替:

OUTPUT_FORMAT("binary")
ENTRY(start)
phys = 0x00100000;
SECTIONS
{
  .text phys : AT(phys) {
    code = .;
    *(.text)
    *(.rodata*)
    . = ALIGN(4096);
  }
  .data : AT(phys + (data - code))
  {
    data = .;
    *(.data)
    . = ALIGN(4096);
  }
  .bss : AT(phys + (bss - code))
  {
    bss = .;
    *(.bss)
    . = ALIGN(4096);
  }
  end = .;
}

如果仍然有问题,您可能需要在build.bat中更改NASM命令的输出格式,以生成ELF文件,而不是a.out

timer_wait永远不会返回

由于timer_ticks变量未定义为volatile,因此所提供的等待计时器tick的方法永远不会返回。 将其定义更改为volatile unsigned int timer_ticks = 0;将使timer_wait()函数工作。

此外,处理器可以进入睡眠状态,而不是忙于等待(busy waiting),以节省电量。 可以这样做:

void timer_wait(int ticks)
{
    unsigned int eticks;

    eticks = timer_ticks + ticks;
    while(timer_ticks < eticks) 
    {
        __asm__ __volatile__ ("sti//hlt//cli");
    }
}

未正确设置PIT

该教程说,提供的PIT设置代码片段是 “可选的”,而实际上不是。 别像我一样被这个BUG绊倒。

不使用交叉编译器

Bran的内核教程在windows上使用DJGPP和NASM (标准安装)。
要允许代码在交叉编译器上链接,必须首先从全局和外部ASM标签中删除所有前导下划线。

除零中断不会触发

在实现IDT和ISRs之后,本教程解释了除以零将引发异常 “divide by zero”,从而执行故障处理程序。 本教程提供了以下C代码:

int i = 10 / 0;

此异常的故障处理程序,并不会引发任何事情。 编译器通常会优化并插入一些额外的代码 (因此实际上没有除以零)。 保证引发此异常的唯一方法是编写一些内联程序集,如下所示:

__asm__  ("div %0" :: "r"(0));

编译器错误: unknown type name ‘size_t'

GCC生成以下错误:unknown type name 'X'。 教程源代码不包括“size_t”或“uint32_t”等类型的任何标准定义。 在每个源文件中包括以下头:

#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>

参考资料