Bran's Kernel Development Tutorial Known Bugs
从好几个地方-包括这个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>