我正在尝试通过以下在线教程编写自己的操作系统。我已经成功实现并测试了GDT,IDT,ISR,IRQ和PIT。我无法实现键盘驱动程序将字符打印到屏幕上。我的操作系统将启动,成功打印欢迎消息,并使用注册到中断处理程序的回调函数等待键盘输入。当我按下一个键时,相应的字符将被放在屏幕上,屏幕将适当滚动,光标将移动,Qemu将崩溃。我从Qemu那里得到一个错误,说“Bad ram pointer 0xfff”。我希望系统在键入时在屏幕上按键。我试过用调试器来解决问题,但没有运气。当我调试我的键盘中断处理程序时,一切似乎工作正常(处理程序将正确执行),但后来有一些行为,我不太明白。处理完中断后,操作系统将开始循环一系列ISR。它将在看似无限的循环中循环通过ISR 13,14和15。当查看在DDD中执行的机器代码时,我注意到ISR13从ISR13 + 1(函数的第二行)开始跳过它的cli指令。这种行为在14或15中看不到。这让我感到困惑,因为我用GAS在GAS中定义了我的ISR,使用相同的宏创建了13和14,并且行为应该相同。我可以使用DDD永远地遍历这个无限循环(寄存器值以循环方式改变),但是一旦我继续执行内核,系统就会崩溃。有没有人对这种行为有解释?我该如何解决?我想我可能需要在键盘输入上实现某种缓冲。它是否正确?我是否有多个键盘中断进入太快,并导致我的系统崩溃?
This is the tutorial I'm basing most of the code off of.
我已经非常仔细地跟着它了,直到this point.我完成了这项工作,但是在处理分页之前决定在系统调试功能(以及终端的开头)中加入键盘驱动程序。记忆管理系统。
我正在关闭键盘驱动程序this similar tutorial.我相信第一个实际上基于第二个。
涵盖键盘驱动程序代码的部分是here.
Here is my keyboard driver.我确实替换了我在第三个教程中发现的扩展键映射,认为它会在未来的路上派上用场。
This is the text of a terminal session showing a make file being run, and the Qemu error.
Here is my source code, compiled objects, binary, and bootable iso. Wikisend表示该链接将持续一周。我正在使用带有Windows 7和VirtualBox的笔记本电脑为我的编码环境运行Debian来宾。我正在使用GCC交叉编译工具链described here.我正在使用Qemu(在Debian中)来测试我的操作系统,并使用GDB和DDD进行调试。
答案 0 :(得分:1)
请务必从James Molloy's Tutorial Known Bugs查看osdev.org。一些可能与您的问题相关的摘录:
问题:中断处理程序损坏中断状态
这篇文章之前告诉过你要了解ABI。如果你这样做,你会的 看到教程中建议的interrupt.s中的一个大问题:它 打破结构传递的ABI!它创建了一个实例 struct在堆栈上注册,然后按值传递给它 isr_handler函数然后假设结构完好无损 然后。但是,堆栈上的函数参数属于 该函数允许在它认为合适时删除这些值 (如果你需要知道编译器是否真的这样做了,你就是 以错误的方式思考,但事实上确实如此)。有两种方法 围绕这个。最实用的方法是将结构作为一个结构 而是指针,它允许您显式编辑寄存器 在需要时状态 - 对系统调用非常有用,没有 编译器随机为你做。编译器仍然可以编辑 当没有特别需要时,指针在堆栈上。第二 选项是另一个复制结构并传递它。
<小时/> 问题:struct registers :: esp无用
struct register结构有一个esp成员,它是其中之一 pusha推动的价值观。但是,popa会忽略此值 明显的原因。您应该将其重命名为useless_value并重命名 useresp改为esp。这个价值是无用的,因为它与之有关 当前的堆栈上下文,而不是被中断的内容。
<小时/> 问题:中断处理程序中的cli和sti
interrupt.s文件调用中断处理程序中的cli和sti来禁用和启用 中断,好像作者不知道是否中断 处理程序在打开或关闭中断时运行。你可以控制是否 它们通过简单地决定它来打开和关闭中断 特定中断的IDT条目。中断期间的sti 处理程序结束也没用,因为iret从中加载了eflags值 堆栈,包含一个告诉中断是打开还是关闭的位; 换句话说,中断处理程序自动恢复中断 是否在此中断之前启用了中断。
<小时/> 问题:multiboot.h
建议从GRUB源代码获取multiboot.h的副本 而不是从教程中复制。