本文用作交流分享的同时记录学习历程,如有不妥,还请纠正。

本文内容依据主要是《Linux内核源代码情景分析》及官方提供的Linux源码

知识储备

众所周知,Linux是开源的操作系统。

Linux采用C语言编写(在C中有嵌入汇编成分)。本文想要用Java这门语言在软件层面上模拟出Linux。

因为操作系统是和硬件最贴近的软件之一,所以本文需要读者有一定的硬件知识基础。比如,常见的寄存器以及他们的作用,外设和外设控制器与CPU的交互过程等。

当然,因为模拟是由Java完成的,所以需要Java语法基础。在Linux中,用到了不少数据结构,比如vm_area(虚存区域)用到了AVL树提升查询效率。在时钟中断一节中为了分摊定时器队列的长度,采取了散列表拆分法,凡此种种,读者需要有一定的数据结构基础。算法基础也是需要的,在查找异常表的过程中用到了二分查找,散列表中用到对位屏蔽的散列算法......对二进制的操作也要相当敏感,Linux源码中用到了大量类似 ( 状态 & 标志位 )的形式来判断状态的该标志位是否有效。

 

绪论

文章的主线是Linux的各个功能模块

其中比较重要的是:

1.内存管理

2.进程线程相关

3.中断,异常,系统调用

文章的意图是用简单的,便于理解的Java语言记录Linux的大体工作方式。

Linux本身就是一层软件。从单个CPU的视角去看,CPU只认识机器指令,完全没有线程和进程的概念,但也不能这么说,有的CPU还是想从硬件的角度为进程线程提供服务的,比如某些CPU(i386)提供了TR寄存器,用来保存TSS(进程存储栈指针等信息的数据结构)的地址。假如我们有一部小型的智能机器,他的处理器只执行一个固定的程序,比如循环检测当前温度是否到达某个阈值,如果到达了就发送报警信号。对于他的处理器来说,根本没有线程进程等复杂的概念,只是一味的处理机器指令而已。但是如果在处理器开启的时候先让他执行一层软件,这一层软件规定了哪些指令组成的程序是一个进程的内容,哪些又是另一些进程的内容,并且用数据结构把他们管理起来。这一层软件就可以规定什么时候要哪一个进程占有处理器,执行这个进程的机器指令。本质上是一种物理设备复用的思想。让我们的处理器在不同进程上切换,并且及时撤下暂时不能运行的进程,增加用途,提高利用率。

 

计算机中的实现分硬件实现和软件实现,有些时候某些功能没有硬件的支持,就只能在软件层次上实现,比如nanosleep,进程睡眠函数,会在指定时间后唤醒进程,其实就是让当前进程状态改变,并且进行一次调度,因为当前进程的状态不是可运行状态,故调度的时候不会调度当前进程,达到“睡眠”的效果,在指定时间后唤醒这个进程,其实就是在指定时间后执行函数改变这个进程的状态,如果计算机有提供硬件实现的延时机制,那么优先使用,否则用软件计数的方式实现。但是不是有硬件实现就一定要用硬件实现,比如之前提到的TSS,某些CPU本来是想操作系统通过改变TR寄存器实现进程切换,但是软件层次上,只改TSS中的某些变量会快得多。具体还是看效果如何。值得一提的是,作者以前认为页映射模式的虚地址映射到实地址是通过软件实现的,但实际上是通过MMU这一个有内存管理功能的硬件实现的。本文通过Java代码会结合硬件讲解,所以需要有一定硬件基础。

 

更新中...