理解Linux内核最好预备的知识点
Linux内核的特点
Linux内核的任务
内核的组成部分
哪些地方用到了内核机制?
Linux进程
Linux创建新进程的机制
Linux线程
内核线程
地址空间与特权级别
虚拟地址与物理地址
特权级别(Linux的两种状态)
系统调用
设备驱动程序、块设备和字符设备
网络
文件系统
模块和热插拔
注:本文为《深入Linux内核架构》 的学习笔记
理解Linux内核最好预备的知识点:
Linux内核的特点:
结合了unix操作系统的一些基础概念
Linux内核的任务:
1.从技术层面讲,内核是硬件与软件之间的一个中间层。作用是将应用层序的请求传递给硬件,并充当底层驱动程序,对系统中的各种设备和组件进行寻址。
2.从应用程序的层面讲,应用程序与硬件没有联系,只与内核有联系,内核是应用程序知道的层次中的最底层。在实际工作中内核抽象了相关细节。
3.内核是一个资源管理程序。负责将可用的共享资源(CPU时间、磁盘空间、网络连接等)分配得到各个系统进程。
4.内核就像一个库,提供了一组面向系统的命令。系统调用对于应用程序来说,就像调用普通函数一样。
内核实现策略:
1.微内核。最基本的功能由中央内核(微内核)实现。所有其他的功能都委托给一些独立进程,这些进程通过明确定义的通信接口与中心内核通信。
2.宏内核。内核的所有代码linux命令,包括子系统(如内存管理、文件管理、设备驱动程序)都打包到一个文件中。内核中的每一个函数都可以访问到内核中所有其他部分。目前支持模块的动态装卸(裁剪)。Linux内核就是基于这个策略实现的。
内核的组成部分:
1.用户空间(在“地址空间与特权级别”小节会详细介绍):
应用程序:
C库
2.内核空间(在“地址空间与特权级别”小节会详细介绍):
核心内核
设备驱动程序
硬件
详细可参考图1
特点:
1.不与任何特定的用户空间进程相关联。
2.与中断上下文运转的内核相比,内核线程可以进入睡眠状态,也可以像系统中的普通进程一样被调度器跟踪。
用途:
1.从内存和块设备之间的数据同步。
2.帮助调度器在CPU上分配进程。
如何查看内核线程:
命令:ps fax 方括号内的就是内核线程。
地址空间与特权级别
在正式介绍之前先介绍几个单位:
KiB 2^10字节
MiB 2^20
GiB 2^30
虚拟地址与物理地址:
虚拟地址:在计算机的专用术语中是指标识一个虚拟(非物理地址)的实体地址。
物理地址:切切实实存在的地址。在存储器里以字节为单位存储信息,为正确地存放或取得信息,每一个字节单元给以一个唯一的存储器地址,称为物理地址。
映射关系:
用页表为物理地址分配虚拟地址
注意:未必虚拟地址的所有页都映射到某个页帧。
原因:
1.页没有内存可以使用
2.数据尚不需要使用而没有载入内存。
3.页已经换出硬盘,需要时再换回内存。
页帧:物理内存页
页:专指虚拟地址空间中的页。
页表:将虚拟地址空间映射到物理地址空间的数据结构。
多级分页:建立虚拟地址到物理地址映射的一种方法,能有效减少内存用量。
CPU加速内存的访问过程,方法:
1.MMU(Memory Management Unit)内存管理单元
2.TLB(Translation Lookaside Buffer)地址转换后备缓冲器
IA-32位结构的CPU只需要使用二级页表,Linux内核总是使用四级页表,剩余部分由内核通过控页表对缺少的页表进行仿真。
概念注意:
1.CPU的字长决定了所能管理的地址空间的最大长度。对于32位系统是2^32 B = 4GiB
2.虚拟地址空间:地址空间的最大长度与实际可用的物理内存的数量无关。
虚拟地址空间划分为两个部分:
内核空间
用户空间
如图2所示:
图2%20虚拟内存的划分
有个等价名称值得一提:
用户层:指应用程序本身。指不属于内核的东西。
用户空间:不仅可以表示应用程序,还指代应用程序所运行的虚拟地址空间的一部分。与内核空间相对。
注意:每一个进程都有上述独立的虚拟地址空间。对于图2所示,每个进程有4GiB的内存空间。
Linux有两种状态,两种状态代表两种特权级别:
核心态:在虚拟地址的内核空间运行的状态。
用户状态:在虚拟地址的用户空间运行的状态。
注意:在用户状态禁止访问内核空间
这两种状态的差别在于:对高于TASK_SIZE的内存区域的访问。
定义:从用户状态到核心态的切换通过系统调用的特定手段完成。
方法:
1.内核代表用户程序执行代码
2.异步硬件中断激活,然后在中断上下文中进行。注意:在中断上下文运行时,内核不能进入睡眠状态。
注意:
内核空间中的代码可以对硬件执行一些底层操作并访问所有的虚拟和物理内存,而用户空间中的代码则由于cpu的安全边界控制,无法访问所有内存。平时我们调用recv函数会将网络i/o数据拷贝到定义的用户缓冲区内linux命令,这样就会在内核空间和用户空间之间进行数据拷贝,这样就会导致进程再内核态和用户态之间进行频繁转换,降低效率。假设用户代码调用write()这个系统调用,此时控制流转到了内核空间即cpu开始执行内核空间的代码,同时cpu运行状态也进入了内核态。