操作系统 —— “ 【操作系统真象还原】第0章 —— 提炼总结”

本文深入探讨了操作系统中的核心概念,包括软件如何访问硬件、应用程序与操作系统的协作、内存分段的原因以及不同类型的地址。解释了为什么称为“陷入”内核,并讨论了段寄存器、字节序、段与段重叠的概念。文章还触及了操作系统如何识别文件系统,帮助读者理解计算机系统的基础运作机制。
摘要由CSDN通过智能技术生成

 


第0章  一些你可能正感到迷惑的问题


软件如何访问硬件

● cpu通过 接口访问硬件。总体上大致分为串行和并行。

访问外部硬件有两个方式:

  • 将某个外设的内存映射到一定范围的内存空间中,cpu通过地址总线访问该内存区域会落到相应外设的的内存中。举例:显卡,汇编时候,显存被映射到主机物理内存上的低端1M 的0xB8000~0xBFFFF地址上。
  • 外设通过IO接口与CPU进行通信。CPU访问外设,就是访问IO接口。

访问IO接口本市上就是访问那些寄存器,这些寄存器就是人么常说的端口。

 

应用程序是什么,和操作系统是如何配合到一起的?

 

他们两都是软件,CPU知道去cs:ip寄存器中指向的内存取指令并执行。

总结,操作系统是人想出来的,为了让自己管理计算机方便而创造出来的一套管理方法。

  • 其实没有语言的存在,有的只是编译器。语言只是编译器和大家的约定。
  • 编译器提供了一套库函数,库函数中又有封装的系统调用。
  • 应用程序是通过系统调用来和操作系统配合完成某项功能的。
  • 应用程序加上操作系统才算是完整的程序。

 

用户态和内核态是对CPU来讲的:是指CPU运行在用户态(特权3级)还是内核态(特权0级)。

注意,用户进程永远不会因为进入内核态而变身为操作系统。
 

编译器下载的时候对应操作系统版本号,因为已经把宿主系统的系统调用号写死了。不同系统不一样。linux系统,直接嵌入汇编代码“int 0x80”便可以直接执行系统调用。


为什么称为“ 陷入 ” 内核

  当用户程序访问系统资源时,需要进行系统调用,CPU进入内核态,也称为管态。


内存访问为什么要分段?

 

首先,内存是随机读写设备,就是访问其内部任何一处,不需要从头开始找,只要直接给出其地址便可。

分段是内存访问机制,是给CPU用的访问内存的方式,只有CPU才关注段。

分段是从8086开始的,16位寄存器,那时没有虚拟地址一说,只有物理地址,访问任何存储单元都可以直接给出物理地址。

在直接以绝对物理地址访问内存的CPU上运行程序,该程序中指令的地址也必须得是绝对物理地址。

总结,要想在一个硬件上运行,就要遵循该硬件的规则,操作系统和编译器无一例外。

但是这样也就产生了一个重要问题——若加载程序运行,不论是内核程序,还是用户程序,程序中的地址若都是绝对物理地址,那该程序必须放在内存中固定的地方,于是,两个编译出来地址相同的用户程序无法同时运行,只能运行一个。

为了解决以上的问题,所以,采用分段的方式,让CPU采用“段基址+段内偏移地址”的方式来访问任意内存,这样的好处是程序可以重定位了,尽管程序指令中给的是绝对物理地址,但是可以同时运行多个程序了。

重定位:简单的说,就是将程序中的指令的地址改写成另外一个地址,但该地址处的内容还是原地址处的内容。

要想访问某个物理地址,只要凑出合适的段基地址和段内偏移地址,其和为该物理地址就行了。
 

关键点:只要程序分了段,把整个段平移到任何位置后,段内的地址相对于段基址是不变的,无论段基址是多少,只要给出段内偏移地址,CPU就能访问到正确的指令。于是加载用户程序时,只要将整个段的内容复制到新的位置,再将段基址寄存器中的地址改成该地址,程序便可准确无误地运行,因为程序中用的是段内偏移地址,相对于新的段基址,该偏移地址处的内存内容还是一样的。

说白了,就是段基址,变了,但是段偏移地址没变,也就是相对位置没变,因为段的内容是直接拷贝的,所以段的内容也没变,所以可以找到原来的内容的拷贝。

一个段最多访问64KB。改变段基址,有一个段变为另一个段,就像一个段在内存中滑动,采用这种在内存中来回挪位置的方式可以访问到任意内存位置。

所以,程序分段又是为了将大内存分成可以访问的小段,通过这样变通的方法就可以访问到所有的内存。
 


 

代码中为什么分为代码段、数据段?这和内存访问机制中的段是一回事吗

 

●  首先指令是连续紧凑的,只要给出 CPU 第一个指令的起始地址, CPU 在它执行本指令的同时,它会自动获取下一条的地址,
然后重复上述过程,继续执行,继续取址 。下一条指令的地址是按照前面指令的尺寸大小排下来的。其次是通过机器码能够判断当前指令长度,当前指令地址  + 当前指令长度 = 下一条指令地址。  

指令的连续是指执行逻辑上的连续性。

 

●  只有数据间有空隙,指令间不存在有空隙。
 

●   指令是由操作码和操作数组成的,操作数就是指程序中的数据。 把数据连续地并排在一起存储形成的段落,就称为数据段。

  • 编译器负责挑选出数据具备的属性,从而根据属性将程序片段分类,比如,划分出制度属性的代码段和可写属性的数据段。
  • 操作系统通过设置GDT全局描述符表来构建段描述符,在段描述符中指定段的位置、大小以及属性。
  • 这里,操作系统认为代码应该是只读的,所以给用来指向代码段的那个段描述符设置了只读的属性,这才是真正给段添加属性的地方。
  • CPU中的段寄存器提前被操作系统赋予相应的选择子,从而确定了指向的段,在执行指令时,会根据该段的属性来判断指令的行为,若有返回则发出异常。
     

 


物理地址、逻辑地址、有效地址、线性地址、虚拟地址的区别?


● 物理地址就是物理内存真正的地址,相当于内存中每个存储单元的门牌号,具有唯一性。不管在什么模式下,不管什么虚拟地址、线性地址, CPU 最终都要以物理地址去访问内存。

 

在实模式下,“段基址+段内偏移地址”经过段部件的处理,直接输出的就是物理地址,CPU可以直接通过此地址访问内存。

在保护模式下,“段基址 + 段内偏移地址”称为线性地址,不过,此时的段基址已经不是真正的地址了,而是选择子。若没有开启地址分页功能,此线性地址就被当作物理地址来用,可直接访问内存。 若开启了分页功能,此线性地址又多了一个名字,就是 虚拟地址虚拟地址、线性地址在分页机制下都是一回事) 。
 

无论在实模式或是保护模式下,段内偏移地址又称为有效地址,也称为逻辑地址,这是程序员可见的地址 。
 

线性地址或称为虚拟地址,都不是真实的内存地址。他们都用来描述程序或任务的地址空间。由于分页功能是需要在保护模式下开启的,32位系统保护模式下的寻址空间式4GB,所以虚拟地址或线性地址就是0~4GB的范围。

 


什么是段重叠

 

●   不管在实模式下还是保护模式下都会存在段重叠。


什么是平坦模型

 

● 平坦模型是相对于多段模型来说的,所以说平坦模型指的就是一个段 。


平坦模型不需要额外打开 A20 地址线。 多段模型需要额外打开 A20 地址线。

 


Cs Ds这类sreg段寄存器位宽是多少

 

●  32 位 CPU 有两种不同的工作模式:实模式和保护模式。

每种模式下,段寄存器中值的意义是不同的,但不管其为何值,在段寄存器中所表达的都是指向的段 在哪里

  • 在实模式下, cs 、 DS 、 ES 、 SS 中的值为段基址,是具体的物理地址,内存单元的逻辑地址仍为 “段基值:段内偏移量”的形式。
  • 在保护模式下,装入段寄存器的不再是段地址,而是“段选择子” C Selector), 当然,选择子也是数值,其依然为 16 位宽度。

sreg 都是 16 位宽。
 


什么是工程,什么是协议

 

●   软件中的工程是指开发一套软件所需要的全部文件,包括配置环境。它相当于一个大目录,以后写的代码都在这里面。全部文件包含实际代码和环境配置两部分。

● 协议是一种大家共同遵守的规约,主要用来实现通信、共享、协作。

 


局部变量和函数参数为什么要放在栈中


 

●  全局变量是放在数据段中的 (static 也属于全局性),意味着谁都可以随时随地访问。局部变量是放在栈中的, 因为是给自己用的, 放在数据段中纯属浪费空间。

堆是程序运行过程中用于动态内存分配的内存空间,是操作系统为每个用户进程 规划的,属于软件范畴。栈是为处理器运行必备的内存空间,是硬件必需的,但又是由软件(操作系统)提供的。
 

因为函数是在程序执行过程中调用的,在函数的编译阶段根本无法确定它会被调用几次,所以也不知道其会需要多少内存 。 所以局部变量和函数参数要放在栈中存储。

 


什么是大端字节序、小端字节序


● 内存是以字节为单位读写的,其最小的读写单位就是字节。
 

  • 小端字节序是数值的低宇节放在内存的低地址处,数值的高宇节放在内存的高地址。
  • 大端字节序是数值的低宇节放在内存的高地址处,数值的高宇节放在内存的低地址。

看看这两种字节序的优势:

  • 小端:因为低位在低字节,强制转换数据型时不需要再调整字节了。
  • 大端:有符号数,其字节最高位不仅表示数值本身,还起到了符号的作用。符号位固定为第 一字节,也就是最高位占据最低地址,符号直接可以取出来,容易判断正负。

 


Section 和 Segment的区别


C 程序大体上分为预处理、编译、汇编和链接 4 个阶段。

  • 预处理阶段是预处理器将高级语言中的宏展 开,去掉代码注释,为调试器添加行号等。
  • 编译阶段是将预处理后的高级语言进行词法分析、语法分析、 语义分析、优化,最后生成汇编代码。
  • 汇编阶段是将汇编代码编译成目标文件,也就是转换成了目标机器 平台上的机器指令。
  • 链接阶段是将目标文件连接成可执行文件。

总结:

  • section 称为节,是指在汇编源码中经由关键字 section 或 segment 修饰、逻辑划分的指令或数据 区域,汇编器会将这两个关键字修饰的区域在目标文件中编译成节,也就是说“节”最初诞生于目标文件中 。
  • segment 称为段,是链接器根据目标文件中属性相同的多个 section 合并后的 section 集合,这个集合称为 segment,也就是段,链接器把目标文件链接成可执行文件,因此段最终诞生于可执行文件中 。 我们平时所说的可执行程序内存空间中的代码段和数据段就是指的 segment。

在大多数情况下,这两者都被混为一谈。

 


什么是魔数


魔数: 不明就理地出现一个数字,不知道其是什么意思,感觉看不透,猜不出,就像魔法一样很神秘

 


操作系统是如何识别文件系统的


通过魔数来识别,一种文件系统对应一个魔数, 已对此值便知道文件系统类型 了。

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值