Linux内核的组成部分

1.进程、进程切换、调度

  • 系统中同时真正在运行的进程数目最多不超过CPU数目
  • 确定哪个进程运行多长时间的过程称之为调度

2.UNIX进程

  • init是进程树的根,所有进程都直接或间接起源该进程
##@##>pstree
  • UNIX创建新进程的机制:分别是fork和exec
    (1)fork技术:写时复制(copy on write),原理:将内存复制操作延迟到父进程或子进程向某内存页面写入数据之前,在只读访问的情况下父进程和子进程可以共用同一内存页
    (2)exec将一个新程序加载到当前进程的内存中并执行。
    旧程序的内存页将刷出,其内容将替换为新数据,然后开始执行新程序。

  • 线程
    进程可以看作一个正在执行的程序,线程则是与主程序并行运行的程序函数或例程

  • 命名空间
    每个命名空间可以包含一个特定的PID集合

3.地址空间与特权级别

  • Linux将虚拟地址空间划分为2个部分,内核空间和用户空间
    在这里插入图片描述

  • 地址空间的最大长度与实际可用的物理内存数量无关,因此被称之为虚拟地址空间

  • 各个系统进程的用户空间是完全彼此分离的,而虚拟地址空间顶部的内核空间总是同样的。

  • 特权级别
    在多处理器系统上,许多线程启动时指定了CPU。并限制只能在某个特定的CPU上运行。从内核线程名称之后的斜线和CPU编号可以看出这一点

[xxxx@xxxx ~]# ps fax
  PID TTY      STAT   TIME COMMAND
    2 ?        S      0:01 [kthreadd]
    3 ?        S      0:00  \_ [migration/0]
    4 ?        S      0:00  \_ [ksoftirqd/0]
    5 ?        S      0:00  \_ [migration/0]
    6 ?        S      0:00  \_ [watchdog/0]
    7 ?        S      0:00  \_ [migration/1]
    8 ?        S      0:00  \_ [migration/1]
  • 虚拟和物理地址空间,内核和CPU如何将实际可用的物理内存映射到虚拟地址空间的区域?
    (1)使用页表来为物理地址分配虚拟地址。
    虚拟地址关系到进程的用户空间和内核空间,而物理地址则用来寻址实际可用的内存。
    进程A的虚拟内存页1映射到物理内存页A,而进程B的虚拟内存页1映射到物理内存页5。
    (2)物理内存页经常称作页帧,页则专指虚拟地址空间中的页
    (3)由于内核负责将虚拟地址空间映射到物理地址空间,因此可以决定哪些内存区域在进程之间共享,哪些不共享。
    在这里插入图片描述

4.页表

  • 用来将虚拟地址空间映射到物理地址空间的数据结构称为页表
    为什么需要多级页表?
    (1)若使用数组,对虚拟地址空间中的每一页,都分配一个数组项,该数组项指向与之关联的页帧。若为32bit的机器,使用4KB页,在虚拟地址空间为4GB的前提下,则需要包含100万项的数组。因为虚拟地址空间的大部分区域都没有使用,因而也没有关联到页帧,那么就可以使用功能相同,但内存用量少的模型:多级页表
    (2)全局页目录PGB(Page Global Directory),索引进程中的一个数组,每个进程仅有一个。PGD指向另一些数组PMD的起始地址
    中间页目录PMD(Page Middle Directory):其数组项是指针,指向下一级数组,称之为页表或目录
    (3)页表数组PTE(Page Table Entry),用作页表的索引。虚拟内存页和页帧之间的映射就此完成,页表的数组项指向页帧。
    (4)多级页表节省了大量的内存。每次访问内存,通过多级页表(逐级访问多个数组)才能将虚拟地址转换为物理地址。为了加速该过程,CPU有2种方法:内存管理单元MMU(Memory Management Unit)优化内存访问,地址转换中最频繁的地址保存到TLB(地址转换后备缓冲器,Translation Lookaside Buffer)的CPU高速缓存中
    在这里插入图片描述
  • 内存映射:在内核中大量使用,也可应用于用户应用程序
    映射方法可以将任意来源的数据传输到进程的虚拟地址空间,但任何修改都会自动传输到原数据源。

5.物理内存的分配

  • 在内核分配内存时,必须记录页帧的已分配或空闲状态
    内核可以只分配完整的页帧,委托用户空间中的标准库将内存划分为更小的部分,标准库将来源于内核的页帧拆分为小的区域,并未进程分配内存
  • 伙伴系统:分配连续页
    (1)内核对所有大小相同的伙伴(1,2,4,8。。。。)都放置到同一个列表中管理。各有8页的一对伙伴也在相应的列表中.
    如果系统需要8个页帧,则将16个页帧组成的块拆分为2个伙伴,其中一块用于满足应用程序的请求,而剩余的8个页帧则放置到对应8页大小内存块的类表中。
    (2)如果下一个请求只需要2个连续页帧,则由8页组成的块会分裂成2个伙伴,每个包含4个页帧。
    其中一块放置回伙伴列表中,而另一个再次分裂成2个伙伴,每个包含2页。
    其中一个回到伙伴系统,另一个则传递给应用程序。
    在这里插入图片描述
  • slab缓存
    内核无法使用标准库函数,但是需要比完整页帧小得多的内存块,所以使用了slab缓存
    (1)对频繁使用的对象,内核定义了只包含了所需类型对象实例的缓存,slab缓存自动维护与伙伴系统的交互,在缓存用尽时会请求新的页帧
    (2)内核针对不同大小的对象定义了一组slab缓存。
    与用户空间编程不同的是,这些函数都增加了前缀k,eg:kmalloc,kfree
    (3)页帧的分配由伙伴系统进行,slab分配器则负责分配小内存以及提供一般性的内核缓存
    在这里插入图片描述
  • 页面交换和页面回收
    (1)页面交换:在内核需要更多内存时,不经常使用的页可以写入磁盘
    (2)页面回收:用于将内存映射被修改的内容与底层的块设备同步

6.系统调用

  • 对于所有的处理器来说,一个共同点是:用户进程从用户态切换到内核态,并将系统关键任务委派给内核执行,系统调用是必由之路

7.设备驱动程序、块设备和字符设备

  • 对外设的访问可利用/dev目录下的设备文件来完成,程序对设备的处理完全类似于常规的文件
  • 外设可分为以下2类:
    (1)字符设备
    提供连续的数据流,应用程序可以顺序读取,此类设备支持按字节/字符来读写数据
    (2)块设备
    应用程序可以随机访问设备数据,程序可自行确定读取数据的位置;
    硬盘是典型的块设备,应用程序可以寻址磁盘上的任何位置,数据的读写只能以块(通常是512B)的倍数进行。与字符设备不同,块设备并不支持基于字符的寻址。
    编写块设备的驱动程序较字符设备要复杂得多,为此内核广泛使用缓存机制

8.网络

  • 在发送数据时,内核必须首先根据各个协议层的要求打包数据,然后才能发送

9.文件系统

  • 虚拟文件系统层、文件系统实现和块设备层之间的互操作
    在这里插入图片描述

10.模块和热拔插

  • 模块用于在运行时,动态地向内核添加功能,如设备驱动程序、文件系统、网络协议等
  • 模块在本质上不过是普通的程序,只是在内核空间而不是用户空间执行而已
  • 某些总线(eg:USB和FireWire)允许在系统运行时连接设备,而无需系统重启。
    在系统检测到新设备时,通过加载对应的模块,可以将必须的驱动程序自动添加到内核

11.缓存

  • 由于内核是通过基于页的内存映射来实现访问块设备的,因此缓存也是按页组织的,也就是说整个页都缓存起来了,故称之为页缓存(page cache)
  • 块缓存已经被页缓存取代了

12.链表处理

  • 内核提供的标准链表可用于将任何类型的数据结构彼此链接起来。很明确,它不是类型安全的。

13.对象管理和引用计数

  • (1)一般性的内核对象
  • (2)对象集合
  • (3)引用计数
    引用计数用于检测内核中有多少地方使用了某个对象

14.数据类型

  • (1)类型定义
    内核使用typedef来定义各种数据类型,以避免依赖于体系结构相关的特性,比如,各个处理器上标准数据类型的位长可能都不见得相同。

  • (2)字节序
    为表示数字,现代计算机采用大端序( big endian)或小端序( little endian)格式

  • (3)per-cpu变量
    在有若干CPU的系统上,会为每个CPU分别创建变量的一个实例。用于某个特定CPU的实例可以通过get_cpu(name, cpu)获得,其中smp_processor_id()可以返回当前活动处理器的ID,用作前述的cpu参数。

  • (4)访问用户空间
    源代码中的多处指针都标记为__user,该标识符对用户空间程序设计是未知的。
    这是因为内存是通过页表映射到虚拟地址空间的用户空间部分的,而不是由物理内存直接映射的。因此内核需要确保指针所指向的页帧确实存在于物理内存中

  • 参考:<深入Linux内核架构>

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章