为了解决无穷大内存。linux 引入了虚拟存储系统,为了解决快速,linux 引入了cache ,交换机制等等,以使的存储系统,在容量上接近硬盘,速度上接近cache。(当然,我认为这是存储系统的实际目的)。
linux 的内存管理采取的是分页机制。它的设计目的是分时多任务。linux 可同时处理256个任务(这应该与某个变量来定义,一时想不起来)。同时它采用了两级饱和机制来分别内核进程与用户进程。
在386 保护模式的0-4g 的线性虚拟地址中,3-4g 是留给内核进程的。而0-3g分给用户进程。内核在内核空间的寻址不同于用户进程在用户空间的寻址。因为内核是在启动时装入内存的。所以它可以直接把地址映射到3g 以上。用户若想访问内核就不许通过swapper_pg_div 中的指针来得到页表。
相反,用户进程,在用户空间的寻址是通过所用户页目录中的指针得到用户的页表。并通过页表的指针直接指向相应的物理内存。
linux虚拟内存的实现,需要几种不同的机制来实现:
地址映射机制;
内存的分配与回收;
请页机制;
交换机制;
内存共享机制。
在具体的读源码之前。我们先根据我们以前学过的操作系统知识。和c语言等知识。来考虑一下,这几个机制如何实现。现自己设计一下。在看别人是怎样实现的。找到自己想不到。或者对效率空间有损的地方。这样才有进步。我不止一次的说。操作系统的某一部分,就起实现来说,非常简单。它的难点是如何将大量的功能集成出一个kernerl。
地址映射机制,说白了,就是在虚拟内存与物理内存上的一个桥梁。它要做的事情可能就是通过几个不同的表。把虚拟地址转换成物理地址,把物理地址转化虚拟地址。
我们以前说过。因为有系统与用户之分,它必须也要有不同的数据结构。为了解决速度等问题。它会有一个硬件的缓冲区
至于请页机制,更好理解。因为linux是页式存储的。因此必然会存在空白页和使用页。既然是页。就必然会存在页溢出。页无效。因此。在每一个页出错。或者该页存不下多余的数据时。就要 要求内核分配新的页面。
同时。当时用fork() 产生一个新的进程时,也需要分配新的页面。这一部分大概讲的就是进程如何向内存描述自己需要怎么样的和多少页 。
至于交换机制。我们也可以现想一想。内存中总与很多使用者的页。如果这些也已经把所有的页都用完了。再分配时必须把其中的某些页释放。释放那些页,需要考虑。如最近不用页。近期少用页,等等都可以在考虑之中。
这个算法,大概就是计算内存中使用的页,什么时候可以换出。说白了就是为所有的使用页计算一个”权”,而这个”权”就决定了他什么时候被释放以换如它的内容。需要想的是对于经常使用的页。可以把它放入cahe。(尽管这一部分对程序员是透明的,但我们应该理解他的原理)。