本系列是对 陈莉君 老师 Linux 内核分析与应用[1] 的学习与记录。讲的非常之好,推荐观看
---- 保护模式 什么实模式和保护模式 这是CPU的两种工作模式,解析指令的方式不同。 在实模式下,16位寄存器需要通过段:偏移的方法才能达到1MB的寻址能力。 物理地址 = 段值 x 16 + 偏移 此时段值还可以看成地址的一部分,段值为XXXXh表示以XXXX0h开始的一段内存。 在保护模式下,CPU有着巨大的寻址能力,并为操作系统提供了虚拟内存和内存保护。 虽然物理地址的仍然用上面的公式表示,但此时“段”的概念发生了变化,它变成了一个索引,指向一个数据结构的一个表项,表项中详细定义了段的
经过多篇文章的介绍,我们实现了从实地址模式跳转到保护模式,并在 IA-32 硬件系统中实现了代码的编写与执行。 进军保护模式 保护模式进阶 — 再回实模式
经过一系列的文章,我们通过汇编语言,体验了保护模式下分段、分页、特权级跳转、中断、异常等机制。 那么,事到如今,你是否已经深谙保护模式的设计之道了呢?究竟什么是保护模式,保护模式又在“保护”什么呢?他为了什么诞生,又和实模式有什么区别呢? 本文我们就来详细总结一下。
此前我们对操作系统中的分段、分页机制以及虚拟地址、逻辑地址、线性地址、物理地址进行了较为详细的介绍。 操作系统的内存管理 — 分段与分页、虚拟地址、逻辑地址、线性地址、物理地址
知乎上搜到一个比较有意思的话题:如何理解「进入内核态」,要回答好这个问题需要对内存管理及程序的运行机制有比较深刻的了解,比如你需要了解内存的分段,分页,中断,特权级等机制,信息量比较大,本文将会从 Intel CPU 的发展历史讲起,循序渐近地帮助大家彻底掌握这一概念,相信大家看了肯定有帮助,本文目录如下
PS:原先实模式下的各个段寄存器作为保护模式下的段选择器,80486中有6个(即CS,SS,DS,ES,FS,GS)80位的段寄存器。由选择器CS对应表示的段仍为代码段,选择器SS对应表示的段仍为堆栈段。
进入保护模式以后,数据段、代码段等内存段不再是通过段寄存器获得段基址就可以使用,我们需要把段定义好,并且登记好,全局描述符表便是用来记录这些段信息的数据结构。
在上期,德国哲学家马克斯韦伯指出,通过在大型分布式计算系统中,引入中间管理层Hypervisor,并将CPU的内核视为计算资源,进行资源池化,建设科层制的分布式计算,是解决海量处理器并发计算问题的唯一可行的方法。在Hypervisor之下,每台虚拟机内部也有一个中间管理层Guest OS,管理虚拟机内部的计算、存储和网络资源,调度虚拟机内的计算任务,如下图所示:
此前的文章中,我们通过向地址 B8000h 写入数据来实现在显示器上输出彩色的文本,我们介绍说这是“彩色字符模式”,并且介绍了它的用法:
本文涉及的硬件平台是X86,如果是其他平台的话,如ARM,是会使用到MMU,但是没有使用到分段机制; 最近在学习Linux内核,读到《深入理解Linux内核》的内存寻址一章。原本以为自己对分段分页机制已经理解了,结果发现其实是一知半解。于是,查找了很多资料,最终理顺了内存寻址的知识。现在把我的理解记录下来,希望对内核学习者有一定帮助,也希望大家指出错误之处。
Intel 微处理器的段机制是从8086 开始提出的, 那时引入的段机制解决了从CPU 内部 16 位地址到20 位实地址的转换。为了保持这种兼容性,386 仍然使用段机制,但比以前复杂。 因此,Linux 内核的设计并没有全部采用Intel 所提供的段方案,仅仅有限度地使用 了一下分段机制。这不仅简化了Linux 内核的设计,而且为把Linux 移植到其他平台创造了 条件,因为很多RISC 处理器并不支持段机制。但是,对段机制相关知识的了解是进入Linux 内核的必经之路。
注:本分类下文章大多整理自《深入分析linux内核源代码》一书,另有参考其他一些资料如《linux内核完全剖析》、《linux c 编程一站式学习》等,只是为了更好地理清系统编程和网络编程中的一些概念性问题,并没有深入地阅读分析源码,我也是草草翻过这本书,请有兴趣的朋友自己参考相关资料。此书出版较早,分析的版本为2.4.16,故出现的一些概念可能跟最新版本内核不同。
当一个任务(进程)执行系统调用而陷入内核代码中执行时,我们就称进程处于内核运行态(或简称为内核态)。此时处理器处于特权级最高的(0级)内核代码中执行。当进程处于内核态时,执行的内核代码会使用当前进程的内核栈。每个进程都有自己的内核栈。当进程在执行用户自己的代码时,则称其处于用户运行态(用户态)。即此时处理器在特权级最低的(3级)用户代码中运行。当正在执行用户程序而突然被中断程序中断时,此时用户程序也可以象征性地称为处于进程的内核态。因为中断处理程序将使用当前进程的内核栈。这与处于内核态的进程的状态有些类似。
x86 系统中的保护模式,给系统的安全性提供了很大的保障,但是在我们之前的文章中,一直都淡化了特权级别这个概念。
—>内核态: CPU可以访问内存所有数据, 包括外围设备, 例如硬盘, 网卡. CPU也可以将自己从一个程序切换到另一个程序 —>用户态: 只能受限的访问内存, 且不允许访问外围设备. 占用CPU的能力被剥夺, CPU资源可以被其他程序获取
内核态:cpu可以访问内存的所有数据,包括外围设备,例如硬盘,网卡,cpu也可以将自己从一个程序切换到另一个程序。
本节来说说捋清启动需要知道的一些东西,因知识点的确很多,涉及了各个方面,我就不像其他章节一样各个部分前后有比较紧密的联系,而是直接以干货的形式罗列出来,这样或许更清晰些,不多说了来看
该文介绍了中断和异常的基本概念、分类,以及Linux 中中断和异常的处理方式,包括硬件中断、软件中断和异常的分类和处理。
3G-4G大部分是共享的,是内核态的地址空间。这里存放整个内核的代码和所有的内核模块以及内核所维护的数据。
这一点主要是了解下. 我们很多时候都听别人说 ring3 ring0 其实就是 CPU的等级划分.
准备工作:下载ucorelab在的master分支(注意不是main分支),需要用到的资料以及答案都在里面。
CS部分后面又4个0,相当于是左移了4位。总之就是要让CS左移4位之后加上EIP来得到要跳转的地址。
1、高位地址:栈(存放着局部变量和函数参数等数据),向下生长 (可读可写可执行)
中断描述符表是保护模式下用于存储中断处理程序的数据结构。CPU在接收到中断时,会根据中断向量在中断描述符表中检索对应的描述符。
作者简介: 王建峰,对于技术方向(主要是嵌入式领域的OS方向的系统应用)感兴趣,最近在学习操作系统基础。同时也是某芯原厂的驱动工程师,主要是gpu领域的驱动软件。https://gitee.com/hinzer/blog 1 概念介绍 1.1 什么是操作系统? 1.2 如何理解中断机制? 1.3 如何理解系统定时? 1.4 如何理解进程控制? 1.5 如何理解内存管理? 1.6 如何理解堆栈概念? 1.7 内核在源码中的体现? 1.8 如何理解系统调用? 1.9 如何理解特权级? 2 流程分析 2.1 引导
理论上来讲,可以把那些可靠性介于操作系统和应用程序之间的程序安排在这两个特权级上。
操作系统是用来管理与协调硬件工作的,开发一款操作系统有利于理解底层的运转逻辑,本篇内容主要用来理解操作系统是如何启动的,又是如何加载磁盘中的内核的,该系列文章参考各类底层书籍,通过自己的理解并加以叙述,让内容变得更加简单,一目了然,即可学到知识又能提高自己的表述能力。
bootloader主要做四件事,1.开启A20地址线;2.探测内存,把内存相关信息告诉内核;3.初始化全局描述符表,开启分段机制,进入保护模式;4.把操作系统内核从磁盘加载到内存指定位置,跳转到内核,执行内核代码。
我们的计算机启动时,首先BIOS会进行自检操作,在自检通过以后就需要将控制权交给MBR程序,在MBR程序中我们跳转到我们的OBR(内核加载器)中。
从应用程序或者应用开发者的角度来看,操作系统是计算机系统的核心软件,它为应用程序提供运行环境和基础服务。
arch:包含和硬件体系结构相关的代码,每种平台占一个相应的目录,如i386、arm、arm64、powerpc、mips等。Linux内核目前已经支持30种左右的体系结构。在arch目录下,存放的是各个平台以及各个平台的芯片对Linux内核进程调度、内存管理、中断等的支持,以及每个具体的SoC和电路板的板级支持代码。
上一篇文章中,我们详细介绍了操作系统特权级,以及利用调用门、TSS 实现不同特权级之间的跳转。 利用调用门实现特权级间跳转 — 原理篇
进程,这个词大家应该耳熟能详了,那进程是什么呢?我们说程序一般是外存上的一个可执行文件,而进程就是这个可执行文件在内存中的一个执行实例。概念始终只会是一个抽象的概念,进程系列文章通过 $xv6$ 的实例来将进程这个概念具象化。本篇主要介绍进程涉及到的一些数据结构,废话不多说,直接来看
与硬件相关的代码全部放在 arch(architecture 一词的缩写,即体系结构相关)目录下。
虽然我们程序员不是修电脑的,虽然计算机启动到操作系统启动这个部分其实对工作的意义可能不大,但就是上面说的那句话,不知道启动,总是说不过去的,所以我还是单独把它拿出来,作为我们万里长征的第一步。
分段让操作系统具备了对内存的保护能力,通过描述符表、选择子的多级跳转,让每一段内存都增加了一系列属性,从而可以实现读、写、执行等权限以及为不同程序赋予不同特权的保护功能。 在此前的文章中,我们已经提到,通过 LDT 来解决进程间内存独立的问题,其代价是寄存器的反复加载,这对于 CPU 来说是一件较为耗时的操作,于是,80386 开始,Intel 引入了内存分页功能,相比于 LDT,更为灵活高效,因此 LDT 已经基本不会被使用了。 那么,分页究竟是一种什么样的机制,又是如何实现的呢?本文我们就来一探究竟。
很多小伙伴在学操作系统的时候,学习到内存管理的部分时,都会接触到分段内存管理、分页内存管理。
版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u014688145/article/details/50608829
java的线程是映射到操作系统原生线程之上的,如果要阻塞或唤醒一个线程就需要操作系统介入,需要在户态与核心态之间切换,这种切换会消耗大量的系统资源,因为用户态与内核态都有各自专用的内存空间,专用的寄存器等,用户态切换至内核态需要传递给许多变量、参数给内核,内核也需要保护好用户态在切换时的一些寄存器值、变量等,以便内核态调用结束后切换回用户态继续工作。
在之前的文章中Linux从头学10:三级跳过程详解-从 bootloader 到 操作系统,再到应用程序,由于当时没有引入特权级的概念,用户程序和操作系统都工作在相同的特权级,因此可以直接通过[段选择子:偏移量] 的方式,来调用属于操作系统代码段中的函数,如下所示:
目前我们已进入保护模式,但依然会受到限制,虽然地址空间达到了4GB,但此空间是包括操作系统共享的4GB空间,我们把段基址+段内偏移地址称为线性地址,线性地址是唯一的,只属于某一个进程。在我们机器上即使只有512MB的内存,每个进程自己的内存空间也是4GB,这是指的虚拟内存空间。一直以来我们都是在内存分段机制下工作的,该模式下如果系统里面的应用程序过多,或者内存碎片过多无法容纳新的进程,则可能会出现进程需要等待,或无法直接运行的局面,而内存分页机制,理论上只要4KB内存就可以让程序运行下去。
4. 寄存器位。通常是表示一个位段的数值,例如 bit[15:12] 表示位序号从15往下数到12,这一段的数值。
论坛原始地址(持续更新):http://www.armbbs.cn/forum.php?mod=viewthread&tid=93149 第9章 RTX5任务运行在特权级或非特权级模式 本章教程为
领取专属 10元无门槛券
手把手带您无忧上云