操作系统真相还原第0章笔记

2023-11-04

什么是陷入内核
应用程序处于特权级别3,操作系统内核处于特权级0,当用户程序访问系统资源时,(无论是硬件,还是内核数据结构),
它都需要进行系统调用,这样CPU便进入了内核态,也称为管态。
内存访问为什么要分段
编译器在编译程序时,肯定要根据CPU访问内存的规则将代码编译成机器指令,这样编译出来的程序才能在该CPU上运行,
所以说,在直接以绝对物理地址访问内存的CPU上运行程序,该程序中指令地址也必须是绝对的物理地址。
总之要想在该硬件上运行,就要遵从该硬件的规则。
若加载程序运行,不管其是内核程序,还是用户程序,程序中的地址若都是绝对的物理地址,那该程序必须在内存中的固定
地方,于是,两个编译的程序地址相同没有办法做到同时运行,只能运行一个,于是让CPU采用了“段基址+段内偏移地址”
的方式来访问任意程序了,这样的好处是程序可以重定位,尽管程序指令中给的是绝对的物理地址,但终究可以同时运行多个
程序了。
总结:编译器是根据CPU特性进行的指令机器码生成,如果使用的都是绝对的物理地址那么就没有办法同时运行两个编译的程序,
因此给出了“段基址+段内偏移”的方式实现了程序重定位进而为同时运行多个程序做好准备。
段基址+段内偏移地址
CPU设计者在地址处理单元中动了手脚,自动将段基址乘以16及左移4位,然后在和16位的段内偏移相加,这下地址就变成了20位。
代码中为什么存在代码段,数据段?
在X86平台的处理器中必须用到分段访问内存,正因如此处理器才提供了段寄存器,用来指定待访问内存段起始地址,
在硬件的内存访问机制中,处理器要用硬件-段寄存器指向软件中的内存段。
平坦模式:硬件段寄存器中指向的内存段最大为4GB。
多段模式:硬件段寄存器中指向内存段大小不一,像是汇编语言允许程序员自己分段,能够灵活安排布局,属于人为分段,
也就是采用了多段模型编程。
分页模型:由于处理器支持具有分页机制的虚拟内存,操作系统也采用分页模型因此编译器将程序的内容分为代码段,
数据段,比如gcc编译C语言程序就划分了代码段,数据段,栈段,.bss段,堆等内容,操作系统会将编译器编译的
用户程序段的内容分配到不同的物理地址上。
段的不同属性
数据段本身是需要被修改的,所以数据段就需要要可写属性,程序中的代码是不能被更改的,这样就要去代码段具备只读属性。
实现段不同的属性:
1.编译器负责挑选出数据具备的属性,从而根据属性将程序分段(代码段/数据段)分类,比如划分出只读属性的代码段和写属性的数据段,
编译器并没有让段具备某种属性而是归类到一起而已,也就是将程序多个section合并成一个大的segment。
2.操作系统通过设置GDT全局描述符表来构造段描述符,在段描述符中指定段的位置,大小及属性(包括S字段和TYPE字段),也就是说
操作系统认为代码段是只读的,所以给用来指向代码段的那个段描述符设置了只读属性,这才是真正的段添加属性的地方。
3.CPU中的段寄存器提前被操作系统赋予相应的的选择子,从而确定了指向的段,在执行指令时,会根据该段的属性来判断指令的行为,
若有返回则发出异常。
总结:编译器/操作系统/CPU这个三个的配合在一起才能对程序保护。
物理地址,逻辑地址,有效地址,线性地址,虚拟地址的区别
物理地址:在实模式下段基址+段偏移地址经过段部件的处理,直接输出的就是物理地址,CPU可以直接访问。	
线性地址:在保护模式下段基址+段偏移称为线性地址,不过段基址并不是真正的地址了,而是被称为段选择子,本质上是一个
索引,类似于数组下标,这个索引能在GDT(全局描述符表)中找到相应的段描述符,该描述符记录了段的起始地址,大小等信息,
这样便获得了段基址,没有开启分页功能,线性地址就是物理地址可以直接访问内存。
虚拟地址:虚拟地址是保护模型下的一种模式,是在开启分页功能后将线性地址转变为虚拟地址而非是物理地址,虚拟地址需要经过CPU的
页部件转换成具体物理地址。
有效地址:无论是保护模式还是实模式,段内偏移地址又被称为有效地址,也被称为逻辑地址。
段重叠
段重叠是指两个段基址+偏移后得到的地址范围相重合,比如C00+05和C02+2,C00和C02就重叠。
平坦模型
平台模式是相对于多端模式而言的,在实模式下访问超过64KB的内存需要重新指定不同的段,需要迂回的方式才能达成目标,
在保护模式下其是32位的,寻址能够达到4GB,段内偏移地址也是地址,所以32位环境下一个段就能够访问所有内存了,所以称为
平坦模式,相较于多段模式需要A20地址线延申访问1MB空间,平坦模式则不需要。
cs,ds这类sreg寄存器,位宽是多少
CS	代码段寄存器(Code Segment Register),其值是代码段的段基址。
DS	数据段寄存器(Data Segment Register),其是数据段的段基址。
ES	附加段寄存器(Extra Segment Register),其值是附加段的段基址,称为附加是因为此段寄存器用途不想其他sreg固定。
FS	附加段寄存器(Extra Segment Register),其值是附加段的段基址,用途不固定。
GS	附加段寄存器(Extra Segment Register),其值为附加数据段的段基址,用途不固定。
SS	堆栈段寄存器(Stack Segment Register),其值为堆栈的段值。
每种模式下段寄存器的意义不同:
实模式:CS/DS/ES/SS的值为段基址,是具体的物理地址,内存单元的逻辑仍然是段基址+段内偏移
保护模式:段寄存器不在是段地址,而是段选择子(Selector),选择子也是数值,长度仍然是16位。
结论:32位的CPU,sreg无论是工作在16位的实模式中,还是32位保护模式中用的段寄存器都是同一组,
32位下的段选择子是16位宽度,排除了寄存器32位环境下是32位宽的可能,sreg都是16位宽。
编译器程序和解析型程序的区别
解析型语言:JavaScript/Python/Perl/PHP/等,它们本身是文本文件,是某个应用程序的输入这个应用程序就是脚本解析器,
脚本中的代码没有真正上过CPU去执行,cs:ip从来没指向过它们,CPU眼里只有脚本解析器,本质上脚本解析器实时分析脚本运行。
编写型语言:运行时本身就是一个进程,由操作系统直接调用将CS:IP直接指向这个程序入口,使它在CPU上运行。
大端字节序/小端字节序
内存是以字节为单位进行读写的,其最小的读写单位就是字节。
小端字节序:
	数值的低位放在内存的低位,数据的高字节放在内存的高字节。
大端字节序:
	数值的低位放在内存的高位,数据高位放在内存的低位。
两种字节序的优势
小端:
	因为低位在低字节,强制数据转换数据型时不需要再调整字节了。
大端:
	有符号数,其字节最高位不仅表示数据本身,还起到了符号的作用,符号位固定为第一个字节,
	也就是最高位占据最低地址,符号直接可以取出来,容易判断正负。
	最高位在最低地址,也就是说可以直接取到,不用在跨越几个字节,减少了时钟周期。
强制数据转换方式:
	在强制数据转换时,如果转换是由低精度转向高精度,这数值本身是没有变化的,如short是2字节,将其
	转换为4字节的int类型,无非是0x1234变成0x00001234,数值上是不变的,只是存储形式发生了变化,
	如果高精度转向低精度,这必然要丢失一些字节,编译器的转换原则是强制转换低精度类型,丢弃数值的高字节,
	只保留低字节,比如:0x12345678强制转换后0x5678。
	总结:
		低精度转高精度数值不变。
		高精度转低精度丢弃高字节保留低字节。
常见CPU字节序
大端字节序:IBM Sun PowerPC
小端字节序:x86 DEC
ARM体系则大小端字节序通吃,具体用那类字节序由硬件决定。
字节序不仅是CPU中内存的概念,也存在于文件存储和网络传输中,bmp格式文件是小端字节序,jpg则是大端字节序,
这些完全是按照设计者设计的。
网络字节序:网络字节序就是大端字节序。
BIOS中断/DOS中断/Linux中断的区别
事件:
	无论是保护模式还是实模式,在任何情况下都会有来自内部或者外部的事件发生,
	如果事件来自于CPU内部就被称为异常(Exception),比如CPU在计算时发现分母为0,就会抛出0异常。
	如果事件源于外部,也就是该事件由外部设备触发并通知CPU,这个事件就被称为中断。
中断向量表(Interrupt Vector Table IVT):
	BIOS和DOS都存在于实模式下的程序,它们建立的中断调用就是建立在中断向量表中的,它们通过软中断
	int中断号调用的。
	中断向量表中的中断向量大小为4个字节,这个4个字节描述了中断处理例程(程序)的段基址和段内偏移地址,
	因为中断向量表长度1024字节,最多只能容纳256个中断向量处理程序。
	计算机的启动之初中断向量表的中断例程是由BIOS建立的,它从物理内存的0x0000处初始化,并在中断向量表中添加
	各种处理例程。
BIOS为什么需要中断向量表:
	BIOS的中断向量表的主要功能是提供了硬件访问的方法,该方法是的对硬件的操作变得简单易行。
	BIOS是通过in/out指令来操作硬件写外设端口,BIOS中断向量表是处理硬件的。
	BIOS为什么添加中断向量表例程:
		1.给直接用避免重复性的某些代码,直接写成中断函数。
		2.给后来的程序用,如加载器boot loader,它们在调用硬件资源时就不需要自己写重复代码。
	BIOS如何填写中断向量表例程:
		BIOS在运行期间会扫描0xC0000到0xE0000之间的内存,若是在某个区域发现前两个字节都是
		0x55,0xAA时,意味着这片区域存在ROM代码的存在,在做该区域的累加和检查若结果与第3个字节
		的值相符,说明代码无误,从第4个字节进入,这个时候就开始执行硬件的自带的例程以及初始化硬件,
		最后BIOS填写中断向量表相关项。
	BIOS中断:
		中断向量表中的0H~1FH项是BIOS中断。
硬件操作
每个外设包括如显卡/硬盘等都有自己的内存,但是这种内存是只读存储器ROM,硬件的自己功能调用例程以及
初始化代码就存放在ROM中,根据规范第一个内存单元是0x55,第二个存储单元是0xAA,第三个存储单元应该就是rom中以
512字节为单位的代码长度,第四个存储单元就是实际代码了,直到第三个存储单元所示的长度为止。
CPU访问外设ROM的方式:
	1.内存映射:
		通过地址总线的方式将外设自己的内存映射到某个内存区域,并不是映射到主板上插的内存条中。
		物理内存中0xA0000开始到0xFFFFF这部分内存中一部分是专门用来做映射的,如果硬件存在,
		硬件自己的ROM会被映射到这片内存中的某处。
	2.端口操作:
		外设都有自己的控制器,控制器上有寄存器,这些就寄存器就是所谓的端口,通过in/out指令读写端口来访问硬件的内存。
DOS中断调用与BIOS中断调用与Linux中断
DOS运行在实模式下,建立的中断调用也是在中断向量表中,不过中断向量号不能跟BIOS的冲突。
0x20~0x27是DOS中断,因为DOS在实模式下运行因此可以调用BIOS中断。
DOS中断只占用0x21中断号,也就是DOS只有一个中断例程。
DOS中断调用实现:
	先向ah寄存器写好子功能号,再执行int 0x21,这时中断向量表中0x21表项即物理地址的0x21*4处的中断处理程序开始
	根据寄存器ah中的值来调用相应的子功能。
DOS中断总结:	
	1.DOS中断例程跟BIOS中断一样都存在于中断向量表IVT中
	2.0x20~0x27是DOS中断
	3.DOS中断只占用了0x21中断号,DOS只有一个中断例程
	4.寄存器ah值子功能号,执行int 0x21来调用相应的子功能

Linux中断:
	Linux是在进入内核之后才建立的中断例程,在保护模式下中断向量表已经不存在了,取而代之的是中断描述符(Interrupt Descriptor Table,IDT),
	在Linux下执行的中断例程是在中断描述符表中,已经不在中断向量表中了。
	Linux中断与DOS中断类似,Linux是通过int 0x80指令进入一个中断程序后再根据eax寄存器的值来调用不同的子功能函数,如果在实模式下执行
	int指令会自动访问中断向量表,如果在保护模式下运行执行int指令则会自动访问中断描述符。
	Linux中断总结:
		1.Linux中断与DOS中断类似
		2.Linux中断例程是在中断描述符中而非中断向量表
		3.Linux是通过int 0x80根据eax中的值来调用子功能函数
		4.在保护模式下int处理的是中断描述符IDT,实模式下是中断向量表IVT		
Section和Segment的区别
在汇编语言中语法关键字section或segment来表示一段区域,操作系统加载程序时并不关心节的数量和大小,
操作系统只关心节的属性,因为程序必然需要加载到内存中才能够运行,而内存的访问会涉及全局描述符表,
中断描述符的访问权限等属性,保护模式下任何任何对内存的操作都必须经过段描述符表。
section成为节是汇编语言中关键字section和segment修饰,逻辑划分的指令或数据区域汇编器会将这两个关键字
修饰的区域在目标文件编译成节,节最初诞生于目标文件中。
segment成为段,是链接器根据目标文件中属性相同的多个section合并后的section集合,这个集合被成为segment,也就是段。	
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

操作系统真相还原第0章笔记 的相关文章

  • logback源码解析及自定义Appender、自定义logback.xml标签

    本文基于slf4j 1 7 25 目录 0 基本概念介绍 1 简单实用示例 2 加载解析配置logback配置文件源码解析 3 加载解析配置文件拓展点 3 1 标签对应复杂对象 默认用NestedComplexPropertyIA解析执行
  • VCS基本选项命令介绍

    一 如何执行 编译执行 1 编译链接生成二进制可执行文件 vcs source file compile time options 例如 vcs v2k filename v debug all 2k指2001版本 compile time

随机推荐

  • 怎么这么慢!:flask 和 node express 性能测试

    问题 我写完项目之后 顺手测了测性能 发现是真的低 测试环境配置 操作系统 win10 CPU Ryzen7 3700X 主板 微星8450M MORTAR MAX 显卡 技嘉RTX2060Super Windforce OC 内存 金士顿
  • 高级选择器

    div class test background ffff00 div class card container position relative margin 40px auto width 200px height 200px we
  • VirtIO实现原理——数据传输演示

    文章目录 初始化 示意图 代码分析 Guest第一次添加buffer 示意图 代码分析 Notify Host Host第一次处理buffer 示意图 代码分析 Guest第二次添加buffer Host第二次处理buffer 初始化 示意
  • PLY格式文件

    PLY是一种电脑档案格式 全名为多边形档案 Polygon File Format 或 斯坦福三角形档案 Stanford Triangle Format 该格式主要用以储存立体扫描结果的三维数值 透过多边形片面的集合描述三维物体 与其他格
  • OpenTiny 前端组件库正式开源啦!面向未来,为开发者而生

    华为开发者大会2023 HDC Cloud 2023 于7月7日 9日在东莞拉开帷幕 本届大会以 每一个开发者都了不起 为主题 OpenTiny作为前端企业级组件库解决方案 在本次大会上正式进行发布 项目发展历程 从自研走向开源的 Tiny
  • 黑圈数字符号0到50复制_[LaTeX 中文使用] 使用「数字形式」的罗马数字

    本文已加入专栏文章目录 归入 进阶使用 文章系列 背景信息 阿拉伯数字 1 2 3 4 5 6 7 8 9 10 11 12 由数字符号 0 1 2 3 4 5 6 7 8 9 构成 小写罗马数字 i ii iii iv v vi vii
  • TensorFlow制作自己的数据集,并用神经网络来训练自己制作的数据集【下】

    参考文章 VGGnet 从TFrecords制作到网络训练 Tensorflow制作并用CNN训练自己的数据集 TensorFlow中的协调器tf train Coordinator和入队线程启动器tf train start queue
  • Untiy shader 初学 淡入淡出效果

    Properties MainTex Texture 2D white Range Range Range 0 1 0 FadeRange FadeRange Range 3 100 3 SubShader Tags RenderType
  • 《Linux0.11源码解读》理解(五) head之开启分页

    先回顾一下地址长度以及组合的演变 16位cpu意味着其数据总线 寄存器也是16位 但是地址总线 寻址能力 与此无关 可能是20位 可以参考 cpu的位宽 操作系统的位宽和寻址能力的关系 cpu位宽 brahmsjiang的博客 CSDN博客
  • 海外APP推送(上篇):厂商通道与谷歌FCM通道的差异

    作者 极光高级工程师 史坤坤 企业出海图景 在疫情持续 叠加复杂多变的国际贸易环境下 中国对外直接投资流量和存量连续四年稳居全球前三 近八成中国企业将维持和扩大对外投资意向 看好对外投资前景 企业出海 第一要务就是要建立与用户的触达通道 在
  • 好文推荐——无需公网IP,远程连接SQL Server数据库【内网穿透】

    文章目录 0 声明 1 前言 2 本地安装和设置SQL Server 2 1 SQL Server下载 2 2 SQL Server本地连接测试 2 3 Cpolar内网穿透的下载和安装 2 4 Cpolar内网穿透的注册 3 本地网页发布
  • python中常用的工具包

    一 Python中常用的科学计算工具包 我们最了解的科学计算工具可能是Matlab 它能进行集数值计算 可视化工具及交互于一身 可惜的是它是一个商业产品 开源方面除了GNU Octave在尝试做一个类似Matlab的工具包外 Python的
  • 【Verilog 基础】阻塞赋值和非阻塞赋值的区别

    目录 阻塞赋值 非阻塞赋值 实际工程仿真 阻塞赋值仿真 编写Verilog代码 编写测试文件代码 综合看RTL图 进行实际仿真 非阻塞赋值仿真 编写Verilog代码 编写测试文件代码 综合看RTL图 实际仿真图 总结 阻塞赋值 阻塞赋值的
  • 统计封闭岛屿的数目

    1254 统计封闭岛屿的数目 关于岛屿的相似题目 岛屿数量 二维矩阵的dfs算法 封闭岛屿数量 二维矩阵的dfs算法 统计封闭岛屿的数目 统计子岛屿 不同岛屿的数量 class MaxAreaOfIsland floodFill 算法 12
  • BaseModel(数据模型映射关系)

    import BaseModel h implementation BaseModel id initContentWithDic NSDictionary dic self super init if self self dicToObj
  • 矿场无盘服务器,七号矿场引领传输新时代

    随着时代的高速发展 Web3 0时代也即将到来 海量数据的产生是必然的 如何确保数据有足够的存储空间 保证数据的安全 这就是未来需要攻克的难点 那么 IPFS网络去中心化存储 信息加密保护 信息不能篡改等技术是现阶段发展所需的技术 With
  • javascript 的筛选方法(多种方法细解)

    filter 是一个数组方法 于创建一个新的数组 其中包含原始数组中满足指定条件的所有元素 返回满足条件的所有内容 放在新的数组里 const numbers 1 2 3 4 5 6 const evenNumbers numbers fi
  • FreeBSD下开启SSH

    ee etc inetd conf 将sshd前边的注释去掉 ee etc ssh sshd config 将PermitRootLogin yes的注释去掉 允许root登陆
  • Stm32学习(七)外部中断

    1 外部中断 1 stm32的每一个IO都可以作为外部中断输入 2 stm32的中断控制器支持19个外部中断 事件请求 线0 15 对应外部IO口的输入中断 线16 连接到PVD输出 线17 连接到RTC闹钟事件 线18 连接到USB唤醒事
  • 操作系统真相还原第0章笔记

    什么是陷入内核 应用程序处于特权级别3 操作系统内核处于特权级0 当用户程序访问系统资源时 无论是硬件 还是内核数据结构 它都需要进行系统调用 这样CPU便进入了内核态 也称为管态 内存访问为什么要分段 编译器在编译程序时 肯定要根据CPU