[第11天]制作新窗口

      博客记录到11天,进度已经15天(多任务)了。因为一个不小心就往前冲,停不下来。进度到一半,感觉接下去才是操作系统的核心。前面都是关于硬件的,没有涉及理论。先把11天记录下来再说。

      今天是昨天的延续。在完成叠加处理后可以制作新的窗口。而叠加处理不用修改,只需加个图层就行。主要代码其实跟显示鼠标差不多,如下。

      效果如下:居然有一点win98的味道了。

window

      然后作者不满意鼠标移动到图层的闪烁。因此加以优化。闪烁的主要原因是刷新整个上部图层效率不高。作者是用“MAP”的方式,记下屏幕每块区域的所属。这样之后,比如鼠标所在map就不需要刷新了。代码修改比较多,可以看github

      今天内容较少。。。。。

[第10天]叠加处理

      终于到1/3了。今天作者介绍如何处理上次出现的鼠标覆盖的问题。主要原理是把窗口分层。确定图层的相对位置。然后根据位置,从底至上刷新像素。

图层控制:

      以下是图层的主要控制部分。SHEET代表了每个图层的信息,含义如注释。SHTCTL保存控制所有图层的信息。一共支持256个图层。这里的col_inv还不是很理解。大致的作用就是看是否要进行刷新。起到的作用就是透明色效果。比如指定透明色为99,鼠标设定的背景色为99,那么在刷新是遇到99就不刷新。

控制函数:

      不仅为了解决这个问题,还为后面的窗口做准备。作者一下子把窗口相对高度(sheet_updown())也搞定了。最简单的方法是刷新所有的区域。但这样效率不高,画面还闪。因此作者的做法是只刷新窗口移动前后位置的像素。如sheet_refreshsub()的功能。这些函数的实现还是需要进行思考的。

初始化显示:

      因为不是在一个vram上显示,我们要做的是把一个个图层添加到屏幕。同时要分配内存,内存是额外增加的,所以之前的内存管理就在这里起到了很好的作用。但貌似作者没有很好的处理这里的内存释放。

后续:

      这个版本的刷新还不是最完善的。比如没有必要从底到上全部刷新。这些问题在下一天解决。今天成果和代码:

mouse

[第9天]内存管理

      今天作者先放下鼠标的问题,因为觉得会让读者感到无聊。确实。。今天作者初步讲了一下怎么测试内存容量以及测试的原理。

测试原理:

      往特定位置写入一个特定的数据如0xaa55aa55,进行反转,然后与0x55aa55aa比较是否相等。然后作者还说继续反转再与0xaa55aa55比较。我不是很清楚为什么要比较两次。。先照做。只要两次对比中有一次不一样就认为这个内存位置不是完整的,即到内存结尾了。

禁用缓存:

      cache的存在让上面的方法失效。因为CPU可以不访问内存直接在cache里操作。自然结果都是正确的,就无法判断内存大小。作者是先禁用了cache。原理有点蛋疼,主要是对CR0寄存器的某一标志位操作,需要设置第30位和29位为1,又因为x86小端记法,所以设置 #define CR0_CACHE_DISABLE 0x60000000 。代码见github

加速处理:

      作者原来的做法是每次检测4B。速度自然慢,可以0x1000位(4KB)一起检测,然后看最后一位就行,虽然会损失精度,但相对很小。代码如下:

 GCC优化:

      作者说他在编译后内存检测完全没有用,看汇编代码后发现判断被去掉了。原因是gcc自动优化了。还能不能好好玩耍了。还好我没有。但我使用-O1选项后也悲剧了。具体原因见书中解释。作者一怒就用了汇编。我不使用-O1没事就算了,直接用C。

内存管理:

      内存管理就是指内存的分配和释放。这是所有操作系统的基本职责。否则不知道内存用到哪了,不仅容量是个问题而且可能引起重叠。内存管理的方式大致有Single allocation,Partitioned allocation,Paged memory management,Segmented memory management。作者提供的内存管理我分不清是属于那一类。比较像Partitioned allocation。基本原理是从现有的空闲内存项中找到合适大小的分配。回收的时候看看能不能合并。不能合并的话新建表项。代码有点多。见github

注意事项:

      系统使用区域不能分配。我的系统内存与作者的有点不一样。然后后来被分配出去就死机了。所以要注意。今天没有分配内存,明天就有了。

mem

 

 

链接:

  1. Memory Management
  2. OSDev