从昨晚开始开始断断续续读这本书了。在刚毕业的那时候读过windows核心编程,里面也有不少内核的知识,但是那本书偏重windows以及编码,对操作系统的实现涉及不多,今年反正是充电的一年,leetcode刷刷题也刷了不少了,算法应该是进步不少。操作系统内核本身就比较感兴趣,加之自己写过不少年的c++,内核代码应该阅读难度不太大,但是理解肯定还是很困难的。
昨晚大致阅读了一点儿,主要是讲到了linux内核的一些基本知识,比如进程、线程、调度之类的。其实这些简介广度还是很广的,比如内核的隔离,用了namespace,这里虽然没有往深处讲,但是现在用的很多的各种容器技术基本就是基于这套东西做的。
目前读到的是介绍虚拟内存这块。其实这块以前就有所了解,为了减小页表所占的控件,基本都使用多级页表,通过虚拟地址的不同位域来索引不同的多级页表,直到索引到真正的页表。取到页表的内容后,该值就指向了物理内存空间内某个页,页一般为4k,剩下的位数则索引页来定位到特定的字节。
比较有意思的是里面提到的伙伴系统(buddy system)。伙伴系统可以优化操作系统的内存分配。内核中有1,2,4,8,16,32,64,128,256,512,1024总共11个页框链表。每个链表都保存着有对应的连续页的首页的起始地址,也就是第一个链表中保存着1个空闲页的首地址,第二个则保存着有连续2个页空闲的首地址,所以每次从页框分配内存,最大的内存大小是4MiB。内核每次分配给用户空间的最小单位就是页,然后由用户空间的各种库函数来管理该页来分割为更小的单位。
伙伴系统主要因为在分配的时候,能将页框中的页分割为两个相同数量的页框。比如我需要分配64个页给用户空间,而64对应的链表为空,那么我们可以直接从128的链表中分配128的页框,然后分割为2个64的页框,1个页框全部分配给用户,1个页框则放入64的链表中。既然能分拆,那么也能合并。假如用户归还了某个页,那么会进入链表中,与物理内存中相邻的页进行合并,不断的提升为更大的页框。
暂时看到这里,等有空了继续。