[第5天] 字体和鼠标

       今天比较轻松愉快,作者介绍了如何显示字体和做了一个鼠标模型。当然是用显示的点阵原理做的。我觉得这个显示字体的原理应该跟真正操作系统差不多。为了规范,我没有像以前那样把内核直接拼接到第二扇区,我把他当作文件一样放进去。从img文件可以看出,这个文件的起始位置在0x4400,所以要读很多扇区,干脆就读了10个柱面。相应的内存位置也改了,从0x1000改到0xc400了。

数据读取:

       这本来是好几天前的事情,但是我现在才真正理解这个读取。作者采用的方法是1个扇区1个扇区的读,而int 13h这个中断,明明可以连续读好几个扇区,效率高啊。但是因为这个原因,我debug好久,才发现不能这么做,这样做会引起DMA boundary error,这个太坑了ES:BX越了64K的界就会悲剧,怪不得我不能连续读4个扇区。我没有找解决方法,直接按作者的来。代码类似就不放了,关键教训就是 DMA Boundary Error。。

显示字符:

        字符就是点阵啊。比如A可以表示成8*16,如下图所示。用二进制表示就是下面的代码。有了这些二进制之后,就可以在对应的1位把颜色改成白色,0位改成背景色。代码见github

 A

制作字体:

       256个ascii,一个个做过来很蛋碎,还好作者提供了友人的制作的字体。但那字体都是.*表示,要经过转换。python就上了,直接脚本处理,然后tr命令去掉引号就万事ok了。然后当作头文件引入即可。作者使用链接的方式,我感觉没必要。总之所以字符都能显示了。还遇到一个事,就是sprintf不能用,因为我是64位系统,先不管这事,自己写个转换函数就能输出数字了。以后再想如何优雅的处理32位的事情。

制作鼠标:

      原理与制作字体一致,这鼠标还不能动。作者由此挖了个大坑,这次我没有跳进去。后面几天讲中断处理,感觉很麻烦。下面是目前系统的样子。总体代码见github

SlefMouse

GDT和IDT:

        GDTIDT这东西我还是没有完全搞懂。反正跟32位保护模式密切相关,什么代码段数据段的。一不小心代码就执行不了。本来我也把代码复制到0x280000去了,但是有可能入口地址啊,段寄存器啊什么的原因,导致不能运行代码。我就先放着不管了。

真机操作:

        做了操作系统不能在真机上跑,怎么行。但这事折腾了我1个晚上。刚开始我以为内存位置不对搞了半天。后来靠我天才的测试方法发现,原来disk read之前就跪了。对比时候发现是sp寄存器的问题。谁说sp寄存器一定要初始化为0x7c00啊,我参考的那个告诉我0x9000,太坑。。反正寄存器初始化正确后,我就能在同学的机子上跑了。我自己的笔记本是disk read error。我原本以为是显示用的LVDS而不是VGA的关系,然后我陷入了沉思,其他grub是怎么做到的? 后来我发现那个A20 没有打开。这个A20是允许使用超过1M的内存空间,一般都是打开的啊。我这么做之后,发现行了!!

        后来我突然就发现一个严重的问题,TMD,这个A20是读了磁盘之后才启用的啊,根本没有关系啊!!我无语了,我用特殊的调试技巧,发现真没关系。我把那段代码改掉,随便放点其他的代码,一样可以!!妹的,难道是跟引导长度有关,还是我BIOS的BUG? 还是更深层的原因,我还不知道。。反正成功了!上图!(事实证明是我电脑问题,BIOS Bug的可能性大,别的电脑都行)

Real Laptop

链接:

  1. Understanding the PC Boot Proces and Writing a Bootloader