首先一张熟悉的图来说明GNU/linux的基本体系结构:

体系的上部分是用户(或应用程序)空间,这是用户应用程序执行的地方。用户空间之下是内核空间,Linux 内核正是位于这里。Linux 内核可以进一步划分成 3 层:最上面是系统调用接口,用户程序通过软件中断后,调用系统内核提供的功能,这个在用户空间和内核提供的服务之间的接口称为系统调用,它实现了一些基本的功能,例如 read 和 write;系统调用接口之下是内核代码,可以更精确地定义为独立于体系结构的内核代码,这些代码是 Linux 所支持的所有处理器体系结构所通用的;内核代码之下是依赖于体系结构的代码,构成了通常称为 BSP(Board Support Package)的部分,这些代码用作给定体系结构的处理器和特定于平台的代码。

然后介绍Linux内核的五个子系统:

Linux内核主要由进程调度(SCHED)、内存管理(MM)、虚拟文件系统(VFS)、网络接口(NET)和进程间通信(IPC)5个子系统组成,如图1所示。

图1 Linux内核的组成部分与关系


1.进程调度

进程调度控制系统中的多个进程对CPU的访问,使得多个进程能在CPU中“微观串行,宏观并行”地执行。进程调度处于系统的中心位置,内核中其他的子系统都依赖它,因为每个子系统都需要挂起或恢复进程。

图2 Linux进程状态转换

如上图2所示,Linux的进程在几个状态间进行切换。在设备驱动编程中,当请求的资源不能得到满足时,驱动一般会调度其他进程执行,并使本进程进入睡眠状态,直到它请求的资源被释放,才会被唤醒而进入就绪态。睡眠分成可被打断的睡眠和不可被打断的睡眠,两者的区别在于可被打断的睡眠在收到信号的时候会醒。

在设备驱动编程中,当请求的资源不能得到满足时,驱动一般会调度其他进程执行,其对应进程进入睡眠状态,直到它请求的资源被释放,才会被唤醒而进入就绪态。设备驱动中,如果需要几个并发执行的任务,可以启动内核线程,启动内核线程的函数为:

pid_t kernel_thread(int (*fn)(void *), void *arg, unsigned long flags);

当用户使用系统提供的库函数进行进程编程,用户可以动态地创建进程,进程之间还有等待,互斥等操作,这些操作都是由linux内核来实现的。linux内核通过进程管理子系统实现了进程有关的操作,在linux系统上,所有的计算工作都是通过进程表现的,进程可以是短期的(执行一个命令),也可以是长期的(一种网络服务)。linux系统是一种动态系统,通过进程管理能够适应不断变化的计算需求。
   在用户空间,进程是由进程标示符(PID)表示的。从用户角度看,一个PID是一个数字值,可以唯一标识一个进程,一个PID值在进程的整个生命周期中不会更改,但是PID可以在进程销毁后被重新使用。创建进程可以使用几种方式,可以创建一个新的进程,也可以创建当前进程的子进程。
在linux内核空间,每个进程都有一个独立的数据结构,用来保存该进程的ID、优先级、地址的空间等信息,这个结构也被称做进程控制块(Process Control Block)。所谓的进程管理就是对进程控制块的管理。
   linux的进程是通过fork()函数系统调用产生的。调用fork()的进程叫做父进程,生成的进程叫做子进程。子进程被创建的时候,除了进程ID外,其它数据结构与父进程完全一致。在fork()系统调用创建内存之后,子进程马上被加入内核的进程调试队列,然后使用exec()系统调用,把程序的代码加入到子进程的地址空间,之后子进程就开始执行自己的代码。
   在一个系统上可以有多个进程,但是一般情况下只有一个CPU,在同一个时刻只能有一个进程在工作,即使有多个CPU,也不可能和进程的数量一样多。如果让若干的进程都能在CPU上工作,这就是进程管理子系统的工作。linux内核设计了存放进程队列的结构,在一个系统上会有若干队列,分别存放不同状态的进程。一个进程可以有若干状态,具体是由操作系统来定义的,但是至少包含运行态、就绪态和等待3种状态,内核设计了对应的队列存放对应状态的进程控制块。
   当一个用户进程被加载后,会进入就绪态,被加入到就绪态队列,CPU时间被轮转到就绪态队列后,切换到进程的代码,进程被执行,当进程的时间片到了以后被换出。如果进程发生I/O操作也会被提前被换出,并且存放到等待队列,当I/O请求返回后,进程又被放入就绪队列。linux系统对进程队列的管理设计了若干不同的方法,主要的目的是提高进程调试的稳定性。


2.内存管理

内存管理的主要作用是控制多个进程安全地共享主内存区域。当CPU提供内存管理单元(MMU)时,Linux内存管理完成为每个进程进行虚拟内存到物理内存的转换。Linux 2.6引入了对无MMU CPU的支持。

如下图3所示,一般而言,Linux的每个进程享有4GB的内存空间,0~3GB属于用户空间,3~4GB属于内核空间,内核空间对常规内存、I/O设备内存以及高端内存存在不同的处理方式。

图3 Linux进程地址空间

使用虚拟内存技术的计算机,内存管理的硬件按照分页方式管理内存。分页方式是把计算机系统的物理内存按照相同大小等分,每个内存分片称作内存页,通常内存页大小是4KB。Linux内核的内存管理子系统管理虚拟内存与物理内存之间的映射关系,以及系统可用内存空间。内存管理要管理的不仅是4KB缓冲区。Linux提供了对4KB缓冲区的抽象,例如slab分配器。这种内存管理模式使用4KB缓冲区为基数,然后从中分配结构,并跟踪内存页使用情况,比如哪些内存页是满的,哪些页面没有完全使用,哪些页面为空。这样就允许该模式根据系统需要来动态调整内存使用。
   在支持多用户的系统上,由于内存占用的增大,容易出现物理内存被消耗尽的情况。为了解决物理内存被耗尽的问题,内存管理子系统规定页面可以移出内存并放入磁盘中,这个过程称为交换。内存管理的源代码可以在./linux/mm中找到。


3.虚拟文件系统

如下图4所示,Linux虚拟文件系统(VFS)隐藏各种了硬件的具体细节,为所有的设备提供了统一的接口。而且,它独立于各个具体的文件系统,是对各种文件系统的一个抽象,它使用超级块super block存放文件系统相关信息,使用索引节点inode存放文件的物理信息,使用目录项dentry存放文件的逻辑信息。

图4 Linux文件系统

在不同格式的文件分区上,程序都可以正确地读写文件,并且结果是一样的。有时在使用linux系统的时候发现,可以在不同类型的文件分区内直接复制文件,对应用程序来说,并不知道文件系统的类型,甚至不知道文件的类型,这就是虚拟文件系统在背后做的工作。虚拟文件系统屏蔽了不同文件系统间的差异,向用户提供了统一的接口。
    虚拟文件系统,即VFS(Virtual File System)是Linux内核中的一个软件抽象层。它通过一些数据结构及其方法向实际的文件系统如ext2,vfat等提供接口机制。通过使用同一套文件 I/O 系统调用即可对Linux中的任意文件进行操作而无需考虑其所在的具体文件系统格式;更进一步,文件操作可以在不同文件系统之间进行。在linux系统中,一切都可以被看做是文件。不仅普通的文本文件、目录可以当做文件进行处理,而且字符设备、块设备、套接字等都可以被当做文件进行处理。这些文件虽然类型不同,但是却使用同一种操作方法。这也是UNIX/Linux设计的基本哲学之一。
    虚拟文件系统(简称VFS)是实现“一切都是文件”特性的关键,是Linux内核的一个软件层,向用户空间的程序提供文件系统接口;同时提供了内核中的一个抽象功能,允许不同类型的文件系统存在。VFS可以被理解为一种抽象的接口标准,系统中所有的文件系统不仅依靠VFS共存,也依靠VFS协同工作。为了能够支持不同的文件系统,VFS定义了所有文件系统都支持的、最基本的一个概念上的接口和数据结构,在实现一个具体的文件系统的时候,需要向VFS提供符合VFS标准的接口和数据结构,不同的文件系统可能在实体概念上有差别,但是使用VFS接口时需要和VFS定义的概念保持一致,只有这样,才能实现对用户的文件系统无关性。VFS隐藏了具体文件系统的操作细节,所以,在VFS这一层以及内核其他部分看来,所有的文件系统都是相同的。对文件系统访问的系统调用通过VFS软件层处理,VFS根据访问的请求调用不同的文件系统驱动的函数处理用户的请求。文件系统的代码在访问物理设备的时候,需要使用物理设备驱动访问真正的硬件。


4.网络接口

网络接口提供了对各种网络标准的存取和各种网络硬件的支持。如下图5所示,在Linux中网络接口可分为网络协议和网络驱动程序,网络协议部分负责实现每一种可能的网络传输协议,网络设备驱动程序负责与硬件设备通信,每一种可能的硬件设备都有相应的设备驱动程序。

图5 Linux网络体系结构

写网络应用程序,使用socket通过TCP/IP协议与其他机器通信,和前面介绍的内核子系统相似,socket相关的函数也是通过内核的子系统完成的,担当这部分任务的是内核的网络子系统,有时也把这部分代码称为“网络堆栈”。Linux内核提供了优秀的网络处理能力和功能,这与网络堆栈代码的设计思想是分不开的,Linux的网络堆栈部分沿袭了传统的层次结构,网络数据从用户进程到达实际的网络设备需要四个层次:用户进程,套接字,网络协议,网络设备。

实际上,在每层里面还可以分为好多层次,数据传输的路径是按照层次来的,不能跨越某个层次。linux网络子系统对网络层次采用了类似面向对象的设计思路,把需要处理的层次抽象为不同的实体,并且定义了实体之间的关系和数据处理流程:

(1)网络协议:网络协议可以理解为一种语言,用于网络中不同设备之间的通信,是一种通信的规范。
   (2)套接字:套接字是内核与用户程序的接口,一个套接字对应一个数据连接,并且向用户提供了文件I/O,用户可以像操作文件一样在数据连接上收发数据,具体的协议处理由网络协议部分处理。套接字是用户使用网络的接口。
   (3)设备接口:设备接口是网络子系统中软件和硬件的接口,用户的数据最终是需要通过网络硬件设备发送和接收的,网络设备千差万别,设备驱动也不尽相同,通过设备接口屏蔽了具体设备驱动的差异。
   (4)网络缓冲区:网络缓冲区也称为套接字缓冲区(sk_buff),是网络子系统中的一个重要结构。网络传输数据存在许多不定因素,除了物理设备对传输数据的限制(例如MMU),网络受到干扰、丢包、重传等,都会造成数据的不稳定,网络缓冲区通过对网络数据的重新整理,使业务处理的数据包是完整的。网络缓冲区是内存中的一块缓冲区,是网络系统与内存管理的接口。


5.进程通信

进程通信支持提供进程之间的通信,Linux支持进程间的多种通信机制,包含信号量、共享内存、管道等,这些机制可协助多个进程、多资源的互斥访问、进程间的同步和消息传递。


子系统之间的依赖关系:

Linux内核的5个组成部分之间的依赖关系如下:

·进程调度与内存管理之间的关系:这两个子系统互相依赖。在多道程序环境下,程序要运行必须为之创建进程,而创建进程的第一件事情,就是将程序和数据装入内存。

·进程间通信与内存管理的关系:进程间通信子系统要依赖内存管理支持共享内存通信机制,这种机制允许两个进程除了拥有自己的私有空间,还可以存取共同的内存区域。

·虚拟文件系统与网络接口之间的关系:虚拟文件系统利用网络接口支持网络文件系统(NFS),也利用内存管理支持RAMDISK设备。

·内存管理与虚拟文件系统之间的关系:内存管理利用虚拟文件系统支持交换,交换进程(swapd)定期由调度程序调度,这也是内存管理依赖于进程调度的惟一原因。当一个进程存取的内存映射被换出时,内存管理向文件系统发出请求,同时,挂起当前正在运行的进程。

除了这些依赖关系外,内核中的所有子系统还要依赖于一些共同的资源。这些资源包括所有子系统都用到的例程,如分配和释放内存空间的函数、打印警告或错误信息的函数及系统提供的调试例程等。

转载:

http://infohacker.blog.51cto.com/6751239/1201601

参考:

https://www.ibm.com/developerworks/cn/linux/l-linux-kernel/

http://infohacker.blog.51cto.com/6751239/1203700

Linux内核的5个子系统相关推荐

  1. linux内核分成如下五个子系统,linux内核主要由5个子系统 Linux内核由哪几个子系统组成?...

    1, Linux内核由哪几个子系统组成? Linux内核主要由五个子系统组成:进程调度,内存管理,虚拟文件系统,网络接口,进程间通信.1.进程调度(SCHED):控制进程对CPU的访问.当需要选择下一 ...

  2. 【内核】嵌入式linux内核的五个子系统

    Perface Linux内核主要由进程调度(SCHED).内存管理(MM).虚拟文件系统(VFS).网络接口(NET)和进程间通信(IPC)5个子系统组成,如图1所示. 图1 Linux内核的组成部 ...

  3. linux内核分为四个子系统,linux操作系统的内核有哪几个子系统构成,简要说明各子系统的作用...

    Linux是一个一体化内核(monolithic kernel)系统."内核"指的是一个提供硬件抽象层.磁盘及文件系统控制.多任务等功能的系统软件.一个内核不是一套完整的操作系统. ...

  4. Linux内核中的GPIO系统之(3):pin controller driver代码分析

    一.前言 对于一个嵌入式软件工程师,我们的软件模块经常和硬件打交道,pin control subsystem也不例外,被它驱动的硬件叫做pin controller(一般ARM soc的datash ...

  5. Android研究-linux内核启动到android系统

    很多人阅读代码,总喜欢从头开始,这样觉得很安全,有依靠,无论如何总是能知道"头",有头就能找到任何需要的部分. Android生在linux内核基础上,linux内核启动的最后一步 ...

  6. 解决ubuntu更改Linux内核(或更新系统)后扩展屏(第二显示器)无法正常显示问题)

    解决ubuntu更改Linux内核(或更新系统)后扩展屏(第二显示器)无法正常显示问题 我的解决方案 一定先看这个(很重要) 直接看这个就可以 前几天更新了一下ubuntu系统,一切正常,但是当我把系 ...

  7. Linux内核错误(引导系统)Deepin用户手册在/etc/sysctl.conf文件中加入kernel.panic = 20,在/etc/sysctl.conf中kernel.sysrq=1内存

    Linux内核错误(引导系统)- 系统管理 -Deepin深度系统用户手册 Power By Baidu Ai 00:00 00:00 目录 1 简介 2 问题分析 3 案例分析 此文章约为4327字 ...

  8. 如何安装新linux内核,详解Debian系统中安装Linux新内核的流程

    一直对Linux内核很有兴趣,但苦于入门不易,认真看了ldd前5章突然就来感觉了,光看不练不顶用,首先就需要环境搭建. 使用的是Debian 5.0,内核2.6.26,欲安装的新内核为2.6.28,这 ...

  9. linux内核中的GPIO系统之(2):pin control subsystem

    一.前言 在linux2.6内核上工作的嵌入式软件工程师在pin control上都会遇到这样的状况: (1)启动一个新的项目后,需要根据硬件平台的设定进行pin control相关的编码.例如:在b ...

最新文章

  1. 【从零开始的ROS四轴机械臂控制】(一)- 实际模型制作、Solidworks文件转urdf与rviz仿真
  2. ASP .NET Core Web MVC系列教程一:创建一个Web应用程序
  3. xhr XMLHttpRequest 简介
  4. 列字段通用excel导入修改版
  5. 前端学习(2986):一文理解数据劫持4
  6. java学习(130):treemap类
  7. python教程答案十九章_Python 编程从入门到实践 第19章 注销一节问题
  8. 洛谷 P2689 东南西北【模拟/搜索】
  9. Android开发笔记(一百六十一)NFC近场通信
  10. linux中文件输出输入,linux中文件输入输出的管理
  11. 实验3.1 定义一个CPU类,观察构造函数和析构函数的调用顺序
  12. IBM 100年 科技引导未来
  13. idea 优化_编程小技巧之 IDEA 的 Live Template
  14. FastStone Capture屏幕长截图
  15. 北京二手房呈井喷态势 单日网签年内首超600套
  16. can是什么时候处于显性_CAN总线什么情况下为空闲状态? - 全文
  17. 文献阅读---多年生黑麦草种质中与耐热性相关的生理性状、分子标记和叶绿素分解代谢基因的自然变异
  18. lua脚本加密,lua代码加密使用说明
  19. visual studio怎么让button一直生效_异地投保怎么做?看完你就知道
  20. 怎么翻译PDF文件内容?教你一招轻松翻译整篇PDF文件

热门文章

  1. Linux TWI开发指南
  2. 去除Ninja的提醒
  3. 分布式自增ID雪花算法snowflake (Java版)
  4. 孩子发烧是细菌感染还是病毒感染?教你秒懂血常规!
  5. 在MySQL中 NULL的含义是_mysql null的含义是什么
  6. 神经网络四:Softmax以及与Sigmoid的关系
  7. 考研政治——马原相关哲理
  8. offer选择:创业公司 VS 大厂外包
  9. 【总结】大学生寒假社会实践-社区志愿服务模板
  10. python高级学习笔记Day04--01 上下文管理器,生成器,深拷贝,浅拷贝,正则表达式