一直以来,对linux充满了满满的憧憬。从今天开始,在未来的一段日子里,每天研究一个linux内核的小主题。坚持!!!!


linux的介绍在这里就不阐述了,几乎每本书籍中都有或多或少的介绍。


(一)内核的作用

内核就是硬件和软件之间的一个中间件。其作用是将应用程序的请求发送给硬件,并充当底层驱动程序,对系统中的组件和各种设备进行寻址。尽管如此,仍然可以从其它一些有趣的视角进行研究。

(1)从应用程序的视角来看,内核可以被认为是一台增强的计算机,将计算机抽象到一个高层次上。

(2)当若干程序在同一系统中并发运行时,也可以将内核视为资源管理程序。

(3)另一种研究内核的视角是将内核视为库,其提供了一组面向系统的命令。通常,系统调用用于向计算机发送请求。


(二)实现策略

当前,在操作系统实现方面,主要有两种主要的范式:

(1)微内核:这种范式中,只有最基本的功能直接有中央内核(即微内核)实现。所有其它的功能都委托给一些其它的进程,这些进程通过明确定义的通信接口与微内核进行通信。

(2)宏内核:与微内核相反,宏内核是构建系统内核的传统方法。在这种方法中,内核的全部代码,包括所有的子系统(如内存管理,文件系统,设备驱动程序)都打包到一个文件中。内核中的每一个函数都可以访问内核中所有其它部分。如果编程时不小心,很可能导致源代码中包括复杂的嵌套。

在目前,宏内核的性能仍然要强于微内核,Linux仍然是根据宏内核的范式实现的。


(三)内核的组成部分

1 进程,进程切换,调度

linux是多任务系统,它支持(看上去)并发执行的若干进程。但是,事实上,系统中同时运行的程序不会超过CPU的数目。

(1)内核借助于CPU的帮助,负责进程切换的技术细节。

(2)内核还必须确定如何在现存进程之间共享CPU时间。重要进程得到的CPU时间多一点,次要进程得到的少一点。确定哪个进程运行多长时间的过程成为调度。

2 UNIX进程

linux对进程采用了一种层次系统,每个进程都依赖于一个父进程。这种树形结构的扩展方式与新进程的创建方式是密切相关的。UNIX操作系统中有两种创建新进程的机制,分别是fork和exec。

(1)fork:

可以创建当前进程的一个副本,父进程和子进程只有PID不同。在该系统调用执行后,系统中有两个进程,都执行同样的操作。父进程内存的内容将被复制,至少从程序的角度来看是这样的。Linux使用了一种众所周知的技术来使fork操作更为高效,该技术称为写时复制(copy on write),主要原理是将内存复制操作延迟到父进程或子进程向某内存页面写入数据之前,在只读访问的情况下父进程和子进程可以共用同一内存页。

例如,使用fork的一种可能情况是,用户打开另一个浏览器窗口。如果选中了对应的选项,浏览器将执行fork,复制其代码,接下来子进程中将启动适当的操作建立新窗口。

(2)exec:

将一个新程序加载到当前进程的内存中并执行。旧程序的内存页将刷出,其内容将替换为新的数据。然后开始执行新程序。

2.1 线程

进程并不是内核支持的唯一一种程序执行形式。除了重量级进程,还有一种是线程(有时也称为轻量级进程),线程也已经出现相当长的一段时间,本质上一个线程也有可以由若干个线程组成,这些线程共享同样的数据和资源,但可能执行程序中不同的代码路径。线程概念已经完全集成到许多现代编程语言中,例如JAVA。简而言之,进城可以看做一个正在执行的程序,而线程则是与主程序并行运行的程序函数或例程。

linux使用clone方法创建线程,其工作方式类似于fork,但启用了精确的检查,以确认哪些资源与父进程共享,哪些资源为线程独立创建。

2.2命名空间

2.3 地址空间和特权级别

2.4页表

2.5物理内存的分配

2.6计时

2.7系统调用

系统调用按照不同类别进行分组:

(1)进程管理:创建新进程,查询信息,调试;

(2)信号:发送信号,定时器以及相关处理机制;

(3)文件:创建,打开和关闭文件,从文件读取和向文件写入,查询信息和状态;

(4)目录和文件系统:创建,删除和重命名目录,查询信息,链接,变更目录;

(5)保护机制:读取和变更UID/GID,命名空间的处理;

(6)定时器函数:定时器函数和统计信息;


2.8设备驱动程序,块设备和字符设备

设备驱动程序用于与系统连接的输入/输出设备通信,如硬盘,软驱,各种接口,声卡等。外设可以分为如下两种类型:

(1)字符设备:提供连续的数据流,应用程序可以顺序读取,通畅不支持随机存取。相反,此类设备支持按字节/字符来读写数据。举例来说,调制解调器是典型的字符设备。

(2)块设备:应用程序可以随机访问设备数据,程序可以确定读取数据的位置。硬盘是典型的块设备,应用程序可以寻址硬盘上的任何位置,并由此读取数据。此外,数据的读写只能以块(通常是512B)的倍数进行。与字符设备不同,块设备并不支持基于字符的寻址。

2.9网络

网卡也可以通过设备驱动程序进行控制,但在内核中属于特殊情况,因为网卡不能利用设备文件访问。原因在于在网络通信期间,数据打包到了各个协议层。再接收到数据后,内核必须针对各个协议层对数据进行拆包和处理,然后才能将数据传递给应用程序。发送数据时,也是如此。

Linux用套接字进行抽象。套接字可以看作应用程序,文件接口,内核的网络实现之间的代理。

2.10文件系统

2.11模块和热插播

模块在本质上不过是普通的程序,只是在内核空间而不是用户空间执行而已。模块必需提供某些代码段在模块初始化时执行,以便向内核注册和注销模块。另外,模块代码与普通代码的权利(和义务)都是相同的,可以向编译到内核中的代码一样,访问内核中所有的函数和数据。

对于支持热插拔而言,模块在本质上是必须的。某些总线(例如,USB和FireWire)允许在系统运行时连接设备,而无需系统重启。在系统检测到新设备时,通过加载对应的模块,可以将必要的驱动程序自动添加到内核中。

2.12缓存

2.13链表处理

2.14对象管理和引用计数

2.15数据类型

(1)类型定义:

使用typedef定义各种数据类型

(2)字节序

(3)per-cpu变量

(4)访问用户空间


(待续。。。。。。)