linux内核介绍
内核体系结构
Linux内核主要由五个子系统组成:进程调度,内存管理,虚拟文件系统,网络接口,进程间通信。
- 进程调度(SCHED):控制进程对CPU的访问。当需要选择下一个进程运行时,由调度程序选择最值得运行的进程。可运行进程实际上是仅等待CPU资源的进程,如果某个进程在等待其它资源,则该进程是不可运行进程。Linux使用了比较简单的基于优先级的进程调度算法选择新的进程。
- 内存管理(memory management,MM)允许多个进程安全的共享主内存区域。Linux 的内存管理支持虚拟内存,即在计算机中运行的程序,其代码,数据,堆栈的总量可以超过实际内存的大小,操作系统只是把当前使用的程序块保留在内存中,其余的程序块则保留在磁盘中。必要时,操作系统负责在磁盘和内存间交换程序块。内存管理从逻辑上分为硬件无关部分和硬件有关部分。硬件无关部分提供了进程的映射和逻辑内存的对换;硬件相关的部分为内存管理硬件提供了虚拟接口。
- 虚拟文件系统(Virtual File System,VFS)隐藏了各种硬件的具体细节,为所有的设备提供了统一的接口,VFS提供了多达数十种不同的文件系统。虚拟文件系统可以分为逻辑文件系统和设备驱动程序。逻辑文件系统指Linux所支持的文件系统,如ext2,fat等,设备驱动程序指为每一种硬件控制器所编写的设备驱动程序模块。
- 网络接口(NET)提供了对各种网络标准的存取和各种网络硬件的支持。网络接口可分为网络协议和网络驱动程序。网络协议部分负责实现每一种可能的网络传输协议。网络设备驱动程序负责与硬件设备通讯,每一种可能的硬件设备都有相应的设备驱动程序。
- 进程间通讯(inter-process communication,IPC) 支持进程间各种通信机制。
处于中心位置的进程调度,所有其它的子系统都依赖它,因为每个子系统都需要挂起或恢复进程。一般情况下,当一个进程等待硬件操作完成时,它被挂起;当操作真正完成时,进程被恢复执行。例如,当一个进程通过网络发送一条消息时,网络接口需要挂起发送进程,直到硬件成功成功地完成消息的发送,当消息被成功的发送出去以后,网络接口给进程返回一个代码,表示操作的成功或失败。其他子系统以相似的理由依赖于进程调度。
各个子系统之间的依赖关系如下:
进程调度与内存管理之间的关系:这两个子系统互相依赖。在多道程序环境下,程序要运行必须为之创建进程,而创建进程的第一件事情,就是将程序和数据装入内存。
进程间通信与内存管理的关系:进程间通信子系统要依赖内存管理支持共享内存通信机制,这种机制允许两个进程除了拥有自己的私有空间,还可以存取共同的内存区域。
虚拟文件系统与网络接口之间的关系:虚拟文件系统利用网络接口支持网络文件系统(NFS),也利用内存管理支持RAMDISK设备。
内存管理与虚拟文件系统之间的关系:内存管理利用虚拟文件系统支持交换,交换进程(swapd)定期由调度程序调度,这也是内存管理依赖于进程调度的唯一原因。当一个进程存取的内存映射被换出时,内存管理向文件系统发出请求,同时,挂起当前正在运行的进程。
除了这些依赖关系外,内核中的所有子系统还要依赖于一些共同的资源。这些资源包括所有子系统都用到的过程。例如:分配和释放内存空间的过程,打印警告或错误信息的过程,还有系统的调试例程等等。
linux中断机制
- 硬件的中断响应 ---> 内核驱动中的中断
- 系统调用的函数响应(sys_call) ---> 系统调用
- 自定义中断 ---> 软件的中断模式
- 信号中断 ---> 对了解信号的使用、创建等
- 系统的异常和错误 ---> 系统的异常获取,了解系统异常的作用
linux中断机制
硬中断
由与系统相连的外设(比如网卡、硬盘)自动产生的。主要是用来通知操作系统系统外设状态的变化。比如当网卡收到数据包 的时候,就会发出一个中断。我们通常所说的中断指的是硬中断(hardirq);硬中断的本质是接收到中断信号后,跳转到公共段代码执行do_IRQ,并切换到硬中断请求栈,执行中断回调函数。
软中断
为了满足实时系统的要求,中断处理应该是越快越好。linux为了实现这个特点,当中断发生的时候,硬中断处理那些短时间
- 软中断通过open_softirq注册一个软中断处理函数,即在软中断向量表softirq_vec数组中添加新的软中断处理action函数。
- 调用raised_softirq软中断触发函数,即把软中断标记为挂起状态。内核会在一些位置检查是否有挂起状态的软中断,如果有的话会调用do_softirq函数来执行软中断处理函数。
- do_softirq函数做的一个重要的工作是切换到软中断请求栈。切换到软中断请求栈就代表了此时已经处于了软中断上下文中了。
- 切换到软中断请求栈
- 调用__do_softirq函数
- __do_softirq函数
- 开始执行软中断处理函数
- 如果还有更多挂起的软中断没有处理,则调用wakeup_softirq函数唤醒内核线程来处理本地CPU的软中断。该线程会循环调用do_softirq函数而不是在内核那些检查软中断是否挂起的位置进行检查,节省了时间。
中断处理流程
- 将所有的寄存器入栈:SS EFLAGS ESP CS EIP (8086) <---> R0 - R15 (ARM)
- 将异常码(中断号)入栈
- 将当前的函数返回值入栈(为了在中断执行后能够找到在哪里中断的,能够返回原先函数执行的位置)
- 调用对应的中断服务函数
- 出栈函数返回值
- 出栈所有的入栈的寄存器 (中断号丢弃了)
中断前的处理过程和中断后的回复过程 | 中断的执行过程 | |
硬件中断的处理过程 | system_call.s | trap.c |
软件及系统调用的处理过程 | system_call.s | fork.c/signal.c/exit.c/sys.c |
中断的代码实现
内核源码结构
内核引导程序