linux内核体系结构

2023-05-16

本节介绍了linux内核的编制模式和体制结构,
然后详细描述linux内核代码目录中组织形式以及子目录各个代码文件的主要功能以及基本调用的层次关系

一个完整可用的操作系统主要由4部分组成: 硬件、操作系统内核、操作系统服务和用户应用程序,如下图

  1. 用户应用程序:指那些字处理程序、Internet浏览器程序或者用户自行开发的应用程序
  2. 操作系统服务程序:指那些向用户提供的服务被看作是操作系统部分功能的程序。在Linux操作系统上,这些程序包括 shell命令解析系统以及那些内核编程接口等系统程序
  3. 操作系统内核程序:后期会详细讲解,它主要用于对硬件资源的抽象和访问调度。
    操作系统组成部分

Linux内核模式

目前,操作系统内核的结构模式主要可分为整体式的单内核模式和层次式的微内核模式。而本章所用的是Linux 0.11 内核,则是采用了单内核模式。
单内核模式的主要优点是内核代码结构紧凑、执行速度快,不足之处主要是层次结构性步强。
在单内核模式中,系统提供服务流程为:应用主程序使用指定的参数值执行系统调用指令(int x80),使CPU从用户态(User Mode)切换到到核心态(Kernel Model),然后系统根据具体的参数值调用特定的系统调用服务程序。
这些服务程序根据底层的一些支持函数已完成特定的功能。在完成了应用程序所要求的服务后,操作系统又从内核态切换到用户态,返回到应用程序中继续执行后面的指令。
因此概要地讲,单内核模式的内核也可粗略分为三层:**调用服务的主程序层、执行系统调用的服务层和支持系统调用的底层函数**

单内核模式的简单结构模型

Linux内核系统体系结构

Linux 内核主要由5个模块构成,
分别是:进程调度模块、内存管理模块、文件系统模块、进程间通信模块和网络接口模块
  1. 进程调度模块:用来负责控制进程对CPU 资源的使用。所采取的调度策略是各进程能够公平合理地访问CPU,同时保证内核能及时执行硬件操作。
  2. 内存管理模块:用于确保所有进程能够安全地共享机器主内存区,同时内存管理模块还支持虚拟内存管理方式,使得Linux支持进程使用比实际内存空间更多的内存容量。并可以利用文件系统把暂时不用的内存数据块会被交换到外部存储设备上去,当需要时再交换回来。
  3. 文件系统模块:用于支持对外部设备的驱动和存储。虚拟文件系统模块通过所有的外部存储设备提供一个通用的文件接口,隐藏了各种硬件设备的不同细节。
  4. 进程间通信模块:用于支持多种进程间信息交换方式。
  5. 网络接口模块:用于对多种网络通信标准的访问并支持更多的网络设备。

模块的依赖关系如下,其中连线代表它们之间的依赖关系,虚线和虚框部分表示Linux 0.11版本中还没实现的部分
Linux内核系统模块结构及相互依赖关系
由上图可以看出,所有的模块都与进程调度模块存在依赖关系。因为它们都需要依靠进程调度程序来挂起或重新运行它们的进程。通常,一个模块会在等待硬件期间被挂起,而在操作完成后才可继续运行。如: 当一个进程试图将一数据块写到软盘上去时,软盘驱动程序就可以在启动软盘旋转期间将该进程置为挂起等待状态,而在软盘进入到正常转速后再使得该进程能继续运行。另外3个模块也就是由于类似的原因而与进程调度模块存在依赖关系。
内核结构

系统定时

在Linux 0.11内核中,PC机的可编程定时芯片 Intel 8253被设置成每隔10毫秒就发出一个时钟中断(IRQ0)信号。这个时间节拍就是系统运行的脉搏,称之为1个系统滴答。因此每经过1个滴答就会调用一次时钟中断处理程序timer_intrrupt。该处理程序主要用来通过jiffies变量来累计自系统启动以来经过的时钟滴答数。每当发生一次时钟中断该值就增1。然后从被中断程序的段选择符中取得当前特权级CPL作为参数调用do_timer()函数。
do_timer()函数则根据特权级对当前进程运行时间作为累计。如果CPL=0,则表示进程是运行在内核态时被中断,因此把进程的内核运行时间统计值stime蹭1,否则把进程用户态运行时间统计值增1。如果成行添加过定时器,则对定时器链表进行处理。若某个定时器时间到(递减后等于0),则调用该定时器的处理函数。然后对当前进程运行时间进行处理,把当前进程运行时间片减1.。如果此时当前进程时间片并还大于0,表示其时间片还没有用完,于是就退出do_timer()继续运行当前进程。如果此时进程时间片已经递减为0,表示该进程已经用完了次使用CPU的时间片,于是程序就会根据被中断程序的级别来确定进一步处理的方法。若被中断的当前进程是工作在用户态的(特权级别大于0),则do_timer()就会调用调度程序shedule()切换到其它进程去运行。如果被中断的当前进程工作在内核态,也即在内核程序中运行时被中断,则do_timer()会立刻退出。因此这样的处理方式决定了Linux系统在内核态运行时不会被调度程序切换。内核态程序是不可抢占的,但当处于用户态程序中运行时则是可以被抢占的。

Linux进程控制

**程序是一个可执行的文件,而进程(process)是一个执行中的程序实例。利用分时技术,在Linux 操作系统上同时可以运行多个进程。分时技术的基本原理是把CPU的运行时间划分成一个个规定长度的时间片,让每一个进程在一个时间片内运行。当进程的时间片用完时系统就利用调度程序切换到另一个进程去运行。**因此实际上对于具有单个CPU的机器来说某一时刻只能运行一个进程。但由于每个进程运行的时间片很段(例如15个系统滴答=150毫秒),所以表面看起来好像所有进程在同事运行着。

对于Linux0.11内核来讲,系统最多可有64个进程同时存在。除了第一个进程是“手工”建立以外,其余的都是进程使用系统调用fork创建的新进程,被创建的进程称为子进程(child process),创建者,则称为父进程(parent process)。内核程序使用程序标识号(process ID,pid)来标识每个进程。进程由可执行的指令代码、数据和堆栈区域组成。进程中的代码和数据部分分别对应一个执行文件中的代码段、数据段。每一个进程只能执行自己的代码和访问自己的数据及堆栈区。进程之间相互之间的通信需要通过系统调用来进行。对于只有一个CPU的系统,在某一时刻只能有一个进程正在运行。内核通过调度程序分时调度各个进程运行。

Linux 系统中,一个进程可以在内核态(kernel mode) 或用户态(user mode)下执行,因此,Linux 内核 堆栈和用户堆栈是分开的。用户堆栈用于进程在用户态下临时保存调用函数的参数、局部变量等数据。内核堆栈则含有内核程序执行函数调用时的信息。

任务数据结构

内核程序是通过进程表对进程进行管理,每个进程在进程表中占有一项。在Linux系统中,进程表项是一个task_struct 任务结构指针。任务数据结构定义在头文件include/linux/sched.h中。有些书上称其为进程控制块PCB或进程描述符PD。其中保存着用于控制和管理进程的所有信息。

struct task_struct {
	long state;	//任务的执行状态(-1不可执行,0可运行(就绪),>0已停止)
	long counter;	//任务运行时间计数(递减)(滴答数),运行时间片
	long priority; // 运行优先数。任务开始运行时 counter=priority,越大运行越长。
	long signal;	// 信号。是位图,每个比特位代表一种信号,信号值=位偏移值+1。
	struct sigaction sigaction[32]; // 信号执行属性结构,对应信号将要执行的操作和标志信息。
	long blocked; // 进程信号屏蔽码(对应信号位图)。
	int exit_code; // 任务执行停止的退出码,其父进程会取。
	unsigned long start_code; // 代码段地址。
	unsigned long end_code; // 代码长度(字节数)。
	unsigned long end_data; // 代码长度 + 数据长度(字节数)。
	unsigned long brk; // 总长度(字节数)。
	unsigned long start_stack; // 堆栈段地址。
	long pid;// 进程标识号(进程号)。
	long father;// 父进程号。
	long pgrp;// 父进程组号。
	long session;// 会话号。
	long leader;// 会话首领。
	unsigned short uid;// 用户标识号(用户 id)。
	unsigned short euid;// 有效用户 id。
	unsigned short suid;// 保存的用户 id。
	unsigned short gid;// 组标识号(组 id)。
	unsigned short egid;// 有效组 id。
	unsigned short sgid;// 保存的组 id。
	long alarm;// 报警定时值(滴答数)。
	long utime;// 用户态运行时间(滴答数)。
	long stime;// 系统态运行时间(滴答数)。
	long cutime;// 子进程用户态运行时间。
	long cstime;// 子进程系统态运行时间。
	long start_time;// 进程开始运行时刻。
	unsigned short used_math;// 标志:是否使用了协处理器。
	int tty;// 进程使用 tty 的子设备号。-1 表示没有使用。
	unsigned short umask;// 文件创建属性屏蔽位。
	struct m_inode * pwd;// 当前工作目录 i 节点结构。
	struct m_inode * root;// 根目录 i 节点结构。
	struct m_inode * executable; // 执行文件 i 节点结构。
	unsigned long close_on_exec; // 执行时关闭文件句柄位图标志。(参见 include/fcntl.h)
	struct file * filp[NR_OPEN]; // 文件结构指针表,最多 32 项。表项号即是文件描述符的值。
	struct desc_struct ldt[3]; // 任务局部描述符表。0-空,1-代码段 cs,2-数据和堆栈段 ds&ss。
	struct tss_struct tss;// 进程的任务状态段信息结构。
}

当一个进程在执行时,CPU的所有寄存器中的值、进程的状态以及堆栈中的内容呗称为该进程的上下文。当内核需要切换至另一个进程时,它就需要保存当前进程的所有状态,也即保存当前进程的上下文,以便在再次执行该进程时,能够回复到切换时的状态执行下去。当前进程上下文均保存在进程的任务数据结构中。在发生中断时,内核就在呗中断进程的上下文中,在内核态下执行中断服务例程。但同时会保留所有需要用到的资源,以便中断服务结束时能恢复被中断进程的执行。

进程运行状态

一个进程在其生存期内,可处于一组不同的状态,称为进程状态。进程状态保存在进程结构体中state字段中。当进程正在等待系统中的资源而处于等待状态时,则称其处于睡眠等待状态。睡眠等待状态被分为可中断的和不可中断的等待状态。
在这里插入图片描述

  • 运行状态(running):当进程正在被 CPU 执行,或已经准备就绪随时可由调度程序执行,进程可以在内核态运行,也可以在用户态运行。当系统资源已经可用时,进程就被唤
    醒而进入准备运行状态,该状态称为就绪态。这些状态(图中中间一列)在内核中表示方法相同,
    都被成为处于 TASK_RUNNING 状态。
  • 可中断睡眠状态(TASK_INTERRUPTIBLE):当进程处于可中断等待状态时,系统不会调度该进行执行。当系统产生一个中断或者释放了进程正
    在等待的资源,或者进程收到一个信号,都可以唤醒进程转换到就绪状态(运行状态)
  • 不可中断睡眠状态(TASK_UNINTERRUPTIBLE):与可中断睡眠状态类似。但处于该状态的进程只有被使用 wake_up()函数明确唤醒时才能转换到可
    运行的就绪状态。
  • 暂停状态(TASK_STOPPED):当进程收到信号 SIGSTOP、SIGTSTP、SIGTTIN 或 SIGTTOU 时就会进入暂停状态。可向其发送
    SIGCONT 信号让进程转换到可运行状态。在 Linux 0.11 中,还未实现对该状态的转换处理。处于该
    状态的进程将被作为进程终止来处理。
  • 僵死状态(TASK_ZOMBIE):当进程已停止运行,但其父进程还没有询问其状态时,则称该进程处于僵死状态。

当一个进程的运行时间片用完,系统就会使用调度程序强制切换到其它的进程去执行。另外,如果
进程在内核态执行时需要等待系统的某个资源,此时该进程就会调用 sleep_on()或 sleep_on_interruptible()
自 愿 地 放 弃 CPU 的 使 用 权 , 而 让 调 度 程 序 去 执 行 其 它 进 程 。 进 程 则 进 入 睡 眠 状 态
(TASK_UNINTERRUPTIBLE 或 TASK_INTERRUPTIBLE)


只有当进程从“内核运行态”转移到“睡眠状态”时,内核才会进行进程切换操作。在内核态下运行的进程不能被其它进程抢占,而且一个进程不能改变另一个进程的状态。为了避免进程切换时造成内
核数据错误,内核在执行临界区代码时会禁止一切中断。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

linux内核体系结构 的相关文章

随机推荐

  • Java与设备(PLC)通信

    通信名词 上位机 指可以直接发出操控命令的计算机 xff0c 一般是PC host computer master computer upper computer 控制者和提供服务者是上位机 xff1b 工控机 工作站 触摸屏可作为上位机
  • DAMA学习笔记

    第1章 数据管理 1 1 引言 1 数据管理 xff1a 为了实现数据价值 xff0c 制定计划 制度并执行 监督 2 数据管理专业人员 xff1a 技术人员 xff08 数据库管理员 网络管理员 程序员 xff09 和业务人员 xff08
  • 2023 学习日志

    2023 01 03 mybatis源码学习 学习视频 xff1a https www bilibili com video BV1Tp4y1X7FM p 61 1 amp vd source 61 cc82a52a9b9b8b31eca3
  • EL表达式两个foreach嵌套循环

    集合List中加List泛型的泛型 List lt RiskEvaSuitQuestion gt riskEvaSuitQuestionList 61 riskEvaSuitQuestionService getQueList 100003
  • JQuery通过radio,select改变隐藏显示div

    1 xff09 select下拉框控制div的隐藏与显示 lt script gt function checkYear var selectValue 61 34 select name 61 39 periodType 39 34 va
  • 开科唯识笔试

    对于这次的笔试 xff0c 我只想说BiShi 几道编程题加一道SQL题 1 找出所有三位数中的水仙花数 public void getNarcissusNums int g 61 0 s 61 0 b 61 0 sum 61 0 for
  • JDBC批量插入

    最近项目中有用到JDBC技术 xff0c 存在大量数据要进行插入 xff0c 通过研究采用批量插入速度快的不是一点点 下面简单比较了一下普通插入与批量插入5W条数据的时间效率 常规插入 xff1a 耗时12952ms public stat
  • 面试经历---YY欢聚时代(2015年11月21日上午初试、25日下午复试)

    YY欢聚时代一年多前去面试过一次 xff0c 当时鄙视了 xff0c 在现在的公司呆了1年半了 xff0c 感觉做得很不爽 xff0c 而且薪资又不满意 xff0c 所以想找个新工作 xff0c 就想去YY面试 下面将两次YY面试的经历写出
  • exe应用程序无法启动,因为应用程序的并行配置不正确

    问题 xff1a exe应用程序无法启动 xff0c 因为应用程序的并行配置不正确 有关详细信息 xff0c 请参阅应用程序事件日志 xff0c 或使用命令行 sxstrace exe 工具 原因查找 xff1a 1 xff09 开始 所有
  • TortoiseSVN is locked in another working copy

    TortoiseSVN提交报错 TortoiseSVN is locked in another working copy 原因 xff1a 可能是因为打开了多个commit会话 xff0c 然后又去修改了提交文件的内容 xff0c 导致文
  • Java对接企业微信

    最近需要对接企业微信 xff0c 例如将风险测评结果推送给企业微信中对应的用户 xff0c 然后用户对结果进行查看与确认操作 xff0c 所以这里就涉及到两方面 xff1a 1 xff09 将外部系统内容推送到企业微信 xff1b 2 xf
  • 微众银行面试

    机缘巧合 xff0c 其实并没有换工作的想法 xff0c 却收到了微众的面试邀请 xff0c 就想着去看看当是增长见识吧 xff0c 因为已经好久没准备面试的事情了 xff0c 而且微众毕竟作为腾讯系的看起来好像也不错 说实话那边离地铁站是
  • #TP4056#--3.7V锂电池充放电电路(实践日志篇)

    成就更好的自己 本篇为小型电源的实践日志 xff0c 内附各种充电应用电路 xff0c 并开源TP4056应用电路AD的原理图和PCB xff1b 先放一点锂电池常识性的知识 xff1a 锂电池是一类由锂金属或锂合金为负极材料 使用非水电解
  • ROS四旋翼无人机快速上手指南(1):无人机系统硬件概述与指南简介

    成就更好的自己 ROS无人机快速上手指南旨在于让使用此无人机开发平台的比赛参赛人员 xff0c 算法设计人员 xff0c 无人机爱好者更加快速的了解底层控制运作原理 xff0c 从而缩短开发周期 xff0c 减少掉坑次数 xff0c 快速验
  • ROS四旋翼无人机快速上手指南(2):Ubuntu18.04与ROS系统

    成就更好的自己 目录 Jetson版Ubuntu以及ROS的安装 xff1a ROS特性及Nano开发问题 PX4与Gazebo仿真环境 ROS与MATMAB仿真 Jetson版Ubuntu以及ROS的安装 xff1a ROS机器人系统运行
  • ROS四旋翼无人机快速上手指南(4):阿木实验室PX4功能包飞行控制分析与讲解(重点章节)

    成就更好的自己 这一章详细讲解一下阿木实验室 AMOV 的开源项目px4 command功能包 xff0c 此功能包通过mavlink协议直接控制烧录px4固件的自驾仪 xff0c 还融合了来自各个传感器的位姿 xff0c 距离等信息 xf
  • ROS四旋翼无人机快速上手指南(5):快速部署上层算法的操作与思路

    成就更好的自己 经过本系列上一篇文章关于PX4 command飞行控制功能包的分析 xff0c 相信大家对于飞整个流程有个大概的了解 xff0c 本章将在此基础上详细讲解一下应用级算法构建的思路与操作方法 关于PX4 command飞行控制
  • USB系列-LibUSB使用指南(1)-Windows下的报错与踩坑

    成就更好的自己 时隔一年再次开始撰写博客 xff0c 这一年的时间经历了很多 xff0c 现在终于稳定下来 以后很长一段时间都能够稳定的学习和更新 时间将会聚焦于USB和PCIe的开发进行 xff0c 能和大家共同进步真的很高兴 本篇为US
  • rosdep init和rosdep update出现问题解决,以及ros编程问题

    如果你在执行 rosdep init 过程中出现以下错误 ERROR cannot download default sources list from https raw githubusercontent com ros rosdist
  • linux内核体系结构

    本节介绍了linux内核的编制模式和体制结构 xff0c 然后详细描述linux内核代码目录中组织形式以及子目录各个代码文件的主要功能以及基本调用的层次关系 一个完整可用的操作系统主要由4部分组成 xff1a 硬件 操作系统内核 操作系统服