S02. 内核的实现(未完)

news2024/9/24 11:33:19

一、虚拟内存管理

1、内存分页 

二级页表线性地址转换物理地址过程如下:

  1. 用虚拟地址的高10位乘以4,作为页目录表内的偏移地址,加上页目录表的物理地址,所得的和便是页目录项的物理地址。读取该页目录项,从中获取到页表的物理地址。
  2. 用虚拟地址的中间10位乘以4,作为页表内的偏移地址,加上在第1步中得到的页表物理地址,所得的和,便是页表项的物理地址。读取该页表项,从中获取到分配的物理页地址。
  3. 虚拟地址的高10位和中间10位分别是PDE(页目录项)和PTE(页表项)的索引值,所以它们需要乘以4。但低12位就不是索引值啦,其表示的范围是0-0xFFF,作为页内偏移最合适,所以虚拟地址的低12位加上第2步中得到的物理页地址,所得的和便是最终转换的物理地址。

2、零碎知识点 

  • 对于段寄存器的入栈,即 cs、ds、es、fs、gs、ss,无论在哪种模式下,都是按当前模式的默认操作数大小压入的。例如,在16位模式下,CPU直接压入2字节,栈指针sp减2。在32位模式下,CPU直接压入4字节,栈指针esp减4。
  • 对于通用寄存器和内存,无论是在实模式或保护模式:如果压入的是16位数据,栈指针减2。如果压入的是32位数据,栈指针减4。
  • 一个段描述符,在CPU眼里分为两大类,要么描述的是系统段,要么描述的是数据段,这是由段描述符中的S位决定的,用它指示是否是系统段。无论是代码,还是数据,甚至包括栈,它们都作为硬件的输入,都是给硬件的数据而已,所以代码段在段描述符中也属于数据段(非系统段)。各种称为 的结构便是系统段,也就是硬件系统需要的结构,非软件使用的,如调用门任多门。
  • 段寄存器CS、DS、ES、FS、GS、SS,在实模式下时,段中存储的是段基地址,即内存段的起始地址。而在保护模式下时,由于段基址已经存入了段描述符中所以段寄存器中再存放段基址是没有意义的,在段寄存器中存入的是一个叫作选择子的东西--Selector。
  • GDT中的第0个段描述符是不可用的,原因是定义在GDT中的段描述符是要用选择子来访问的,如果使用的选择子忘记初始化,选择子的值便会是0这便会访问到第0个段描述符。为了避免出现这种因忘记初始化选择子而选择到第0个段描述符的情况,GDT中的第0个段描述符不可用。
  • 在保护模式中,我们采用Linux等主流操作系统的内存段----平坦模型平坦模型就是整个内存都在一个段里,不用再像实模式那样用切换段基址的式访问整个地址空间。在32位保护模式中,寻址空间是4G,所以,平坦模型在我们定义的描述符中,段基址是0,段界限*粒度等于4G。粒度我们选的是4k,故段界限是0xFFFF。

 二、中断与异常

 1、中断分类

把中断按事件来源分类,来自CPU外部的中断就称为外部中断,来自CPU内部的中断称为内部中断。外部中断按是否导致宕机来划分,可分为可屏蔽中断和不可屏蔽中断两种,而内部中断按中断是否正常来划分,可分为软中断(int 8位立即数)和异常(故障、陷入和终止)。 

CPU为大家提供了两条信号线。外部硬件的中断是通过两根信号线通知CPU的,这两根信号线就是INTR(INTeRrupt)和NMI(Non Maskable Interrupt)。可屏蔽中断是通过INTR引脚进入CPU的,外部设备如硬盘、网卡等发出的中断都是可屏蔽中断。可屏蔽的意思是此外部设备发出的中断,CPU可以不理会,因为它不会让系统宕机,所以可以通过eflags寄存器的IF位将所有这些外部设备的中断屏蔽。不可屏蔽中断是通过NMI引脚进入CPU的,它表示系统中发生了致命的错误,它等同于宣布:计算机的运行到此结束了。可屏蔽中断并不会导致致命问题,它的数量是有限的,所以每一种中断源都可以获得一个中断向量号。而不可屏蔽中断引起的致命错误原因有很多,每一种都是硬伤,出现了基本上可以认为用软件解决不了,所以不可屏蔽中断的中断向量号统一为2。

对于中断是否无视eflags中的IF位,可以这么理解:首先,只要是导致运行错误的中断类型都不受IF位的管束,如INM、异常。其次,由于int n型的软中断用于实现系统调用功能,不能因为IF位为0就不顾用户请求,所以为了用户功能正常,软中断必须无视IF位。

2、中断处理过程 

2.1 中断向量和中断门描述符表

为了统一中断管理,把来自外部设备、内部指令的各种中断类型统统归结为一种管理方式,即为每个中断信号分配一个整数,用此整数作ID,而这个整数就是所谓的中断向量,ID作为中断描述符表的索引,这样就能找到对应的表项,进而从中找到对应的中断处理程序。中断向量的作用和选择子类似,它们都用来在描述符表中索引一个描述符,只不过选择子用于在GDT或LDT中检索段描述符,而中断向量专用于中断描述符表,其中没有RPL字段。异常和不可屏蔽中断的中断向量号是由CPU自动提供的,而来自外部设备的可屏蔽中断号是由中断代理提供的(咱们这里的中断代理是8259A),软中断是由软件提供的。

中断门:包含了中断处理程序所在段的段选择和段内偏移地址。当通过此方式进入中断后,标志寄存器eflags中的IF位自动置0,也就是在进入中断后,自动把中断关闭,避免中断嵌套。Linux就是利用中断门实现的系统调用,就是那个著名的int 0x80。中断门允许存在于IDT中,描述符中中断门的ype值为二进制1110。

同加载GDTR一样,加载DTR也有个专门的指令--lidt,其用法是:lidt 48位内存数据,在这48位内在数据中,前16位是IDT表的界限,后32位是IDT线性基地址。 

2.2 中断处理过程 

完整的中断过程分为CPU外和CPU内两部分。CPU外:外部设备的中断由中断代理芯片接收,处理后将该中断的中断向量号发送到CPU。CPU内:CPU执行该中断向量号对应的中断处理程序,处理器内的过程如下:

进入中断时要把NT位和TF位置为0。TF表示Trap Flag,也就是陷阱标志位,这用在调试环境中,当TF为0时表示禁止单步执行。

3、中断发生时的压栈

 3.2 中断进入

下面看看以上寄存器入栈情况及顺序,这里不再讨论有关特权检查的内容: 

  1. 处理器根据中断向量号找到对应的中断描述符后,拿CPL和中断门描述符中选择子对应的目标代码段的DPL比对,若CPL权限比DPL低,即数值上CPL>DPL,这表示要向高特权级转移,需要切换到高特叔级的栈。这也意味着当执行完中断处理程序后,若要正确返回到当前被中断的进程,同样需要将栈恢复为此时的旧栈。于是处理器先临时保存当前旧栈SS和ESP的值,记作SS_old和ESP_old,然后在TSS中找到同目标代码段DPL级别相同的栈加载到寄存器SS和ESP中,记作SS_new和ESP_new,再将之前临时保存的SS_old和ESP_old压入新栈备份。
  2. 在新栈中压入EFLAGS寄存器。
  3. 由于要切换到目标代码段,对于这种段间转移,要将CS和EIP保存到当前栈中备份,记作CS old和EIP_old,以便中断程序执行结束后能恢复到被中断的进程。当前栈是新栈,还是旧栈,取决于是否涉及到特权级转移。
  4. 某些异常会有错误码,此错误码用于报告异常是在哪个段上发生的,也就是异常发生的位置,所以错误码中包含选择子等信息。错误码会紧跟在EP之后入栈,记作ERROR_CODE。

如果未涉及到特权级转移,便不会到TSS中寻找新栈,而是继续使用当前旧栈,因此也谈不上恢复旧栈,此时中断发生时栈中数据不包括SS_old和ESP_old。比如中断发生时当前正在运行的是内核程序,这是0特权级到0特权级,无特权级变化。

 3.2 中断返回

中断处理程序返回时,假设在32位模式下,它从当前栈顶处依次弹出32位数据分别到寄存器EIP、CS、EFLAGS。iret指令并不清楚栈中数据的正确性,它只负责把栈顶处往上的数据,每次4字节,对号入座弹出到相关寄存器,所以在使用iret之前,一定要保证栈顶往上的数据是正确的。注意,如果中断有错误码,处理器并不会主动跳过它的位置,咱们必须手动将其跳过 

3.3 可编程中断控制器8259A 

 8259A是可屏蔽中断的代理,其作用是负责所有来自外设的中断,其中就包括来自时钟的中断,以后要通过它完成进程调度。Intel处理器共支持256个中断,但8259A只可以管理8个中断,所以为了多支持一些中断设备,提供了另一个解决方案,将多个8259A级联。有了级联这种组合后,每一个8259A就被称为1片。若采用级联方式,即多片8259A芯片串连在一起,最多可级联9个,也就是最多支持64个中断。n片8259A通过级联可支持7n+1个中断源,级联时只能有一片8259A为主片master,其余的均为从片slave。来自从片的中断只能传递给主片,再由主片向上传递给CPU,也就是说只有主片才会向CPU发送INT中断信号,如图7-11所示。

 可屏蔽中断响应流程:

  1. 当某个外设发出一个中断信号时,由于主板上已经将信号通路指向了8259A芯片的某个IRQ接口,所以该中断信号最终被送入了8259A。8259A首先检查IMR寄存器中是否已经屏蔽了来自该IRQ接口的中断信号。IMR寄存器中的位,为1,则表示中断屏蔽,为0,则表示中断放行。
  2. 如果该IRQ对应的相应位已经被置1,即表示来自该IRQ接口上的中断已经被屏蔽了,则将该中断信号丢弃,否则,将其送入IRR寄存器,将该IRQ接口所在IRR寄存器中对应的BIT置1。IRR寄存器的作用相当于待处理中断队列。在某个恰当时机,优先级仲裁器PR会从IRR寄存器中挑选一个优先级最大的中断,此处的优先级决判很简单,就是IRQ接口号越低,优先级越大,所以IRQ0优先级最大。
  3. 之后,8259A会在控制电路中,通过INT接口向CPU发送INTR信号。信号被送入了CPU的INTR接口后,这样CPU便知道有新的中断到来了,于是CPU将手里的指令执行完后,马上通过自己的INTA接口向8259A的INTA接口回复一个中断响应信号,表示已准备好。
  4. 8259A在收到这个信号后,立即将刚才选出来的优先级最大的中断在ISR寄存器中对应的BIT置1,此寄存器表示当前正在处理的中断,同时要将该中断从“待处理中断队列”寄存器IRR中去掉,也就是在IRR中将该中断对应的BIT置0。
  5. 接下来,CPU将再次发送INTA信号给8259A,这一次是想获取中断对应的中断向量号,就是我们前面所说的0~255的“整数”。由于大部分情况下8259A的起始中断向量号并不是0,所以用起始中断向量号+IRQ接口号便是该设备的中断向量号随后,8259A将此中断向量号通过系统数据总线发送给CPU。CPU从数据总线上拿到该中断向量号后,用它做中断向量表或中断描述符表中的索引,找到相应的中断处理程序并去执行。

8259A 中断控制器寄存器汇总表:

寄存器名称宽度描述
中断屏蔽寄存器 (IMR)8 位屏蔽或允许中断请求。每一位对应一个中断线。
中断请求寄存器 (IRR)8 位记录当前等待服务的中断请求。每一位对应一个中断线。
中断服务寄存器 (ISR)8 位记录当前正在服务的中断请求。每一位对应一个中断线。
初始化命令寄存器 1 (ICW1)8 位边沿触发,级联模式,需要 ICW4。
初始化命令寄存器 2 (ICW2)8 位设置中断向量偏移,即起始中断向量号。
初始化命令寄存器 3 (ICW3)8 位配置主从 8259A 连接关系,仅在级联的方式下才需要。
初始化命令寄存器 4 (ICW4)8 位用于设置8259A的工作模式,当ICW1中的IC4为1时才需要ICW4。
操作命令寄存器 1 (OCW1)8 位设置中断屏蔽寄存器(IMR)。
操作命令寄存器 2 (OCW2)8 位设置中断结束方式和优先级模式。
操作命令寄存器 3 (OCW3)8 位用于读取 IRR 或 ISR 的状态。

8259A的编程步骤:

既然8259A称为可编程中断控制器,就说明它的工作方式很多,咱们就要通过编程把它设置成需要的样子。对它的编程也很简单,就是对它进行初始化,设置主片与从片的级联方式,指定起始中断向量号以及设置各种工作模式。8259A的编程就是写入ICW和OCW,下面总结下写入的步骤 :

3.4 可编程定时器8253

Intel 8253 可编程定时器 (Programmable Interval Timer, PIT) 是一种广泛用于计算机系统中的计时和定时设备。它具有三个独立的计时器,每个计时器可以独立编程来执行各种计时任务。PIT芯片使用的振荡器运行频率(大约)为1.193182 MHz。

I/O port     Usage
0x40         Channel 0 data port (read/write)
0x41         Channel 1 data port (read/write)
0x42         Channel 2 data port (read/write)
0x43         Mode/Command register (write only, a read is ignored)

8253控制字寄存器

名称位数范围描述
BCD0BCD 模式选择。0:二进制计数,1:  BCD 计数。
M0, M1, M21-3定时器工作方式选择。
RW1, RW24-5设置待操作计数器的读写及锁存方式。
SC0, SC16-7选择计数器(0, 1, 2)。

 IRQ0引脚上的时钟中断信号频率是由8253的计数器0设置的,我们要使用计数器0。时钟发出的中断信号必须是周期性发出的,也就是我们要采取循环计数的工作方式,可选的工作方式为方式2和方式3,这里咱选择方式3。初始化8253的步骤如下:

三、进程间的同步与互斥

四、特权级 & 系统调用

1、特权级简介

CPL:在CPU中运行的是指令,故而代码段猫述符中的DPL,便是当前CPU所处的特权级,这个特权级称为当前特权级,即CPL(Current Privilege Level),它表示处理器正在执行的代码的特权级别。当处理器特权级检查的条件通过后,新代码段的DPL就变成了处理器的CPL,并且且标代码段描述符的DPL将保存在代码段寄存器CS中的RPL位。注意,只是代码段寄存器CS中的RPL是CPL,其他段寄存器中选择子的RPL与CPL无关。在任意时刻,当前特权级CPL保存在CS选择子中的RPL部分。

RPL:由于指令存放在代码段中,所以,就用代码段寄存器CS中选择的RPL位表示代码请求别人资源能力的等级。代码段寄存器CS和指令指针寄存器EP中指向的指令便是当前在处理器中正在运行的代码。CPL是对当前正在运行的程序而言的,而RPL有可能是正在运行的程序,也可能不是。在一般情况下,如果低特权级不向高特权级程序提供自己特权级下的选择子,也就是不涉及向高特权级程序委托办事的话,CPL和RPL都来自同一程序。但凡涉及委托,进入0特权级后,CPL是指代理人(即内核),RPL则是委托者。

特权级转移分为两类,一类是由中断门、调用门等手段实现低特权级转向高特权级,另一类则相反,是由调用返回指令从高特权级返回到低特叔级,这是唯一能让处理器降低特权级的情况。  

访问者任何时候都不允许访问比自己特权更高的资源,无论受访资源是数据,还是代码。对于受访者为数据段来说,只有访问者的权限大于等于该DPL表示的最低权限才能够继续访问,否则连这个门槛都迈不过去。对于受访者为代码段来说,只有访问者的权限等于该DPL表示的最低权限才能够继续访问,即只能平级访问。处理器能够通过以下两方式转向执行高特权级的代码段:

  1. 基于一致性代码段实现。一致性代码段也称为依从代码段,用来实现从低特权级的代码向高特权级的代码转移。一致性代码段是指如果自己是转移后的目标段,自己的特权级(DPL)一定要大于等于转移前的CPL,即数值上CPL≥DPL。一致性代码段的一大特点是转移后的特权级不与自己的特权级(DPL)为主,而是与转移前的低特权级一致,也就是说处理器遇到目标段为一致性代码段时,并不会将CPL用该目标段的DPL替换。代码段可以有一致性和非一致性之分,但所有的数据段总是非一致的,即数据段不允许被比本数据段特权级更低的代码段访问。(本实现全程不采用一致性代码段)
  2. 通过门结构(中断门或者调用门)实现由低特权级转移到高特权级。
不通过门结构,直接访问一般数据和代码时的特权检查规则:

2、调用门

calljmp指令后接调用门选择子为参数以调用函数例程的形式实现从低特权向高特权转移,可用来实现系统调用。call指令使用调用门可以实现向高特权代码转移,jmp指令使用调用门只能实现向平级代码转移。门的门槛是访问者特权级的下限,访问者的特权级再低也不能比门描述符的特权级DPL低,即数值上CPL≤门的DPL。门的门框是访问者特权级的上限,访问者的特权级再高也不能比门描述符中且标程序所在代码段的DPL高,即数值上CPL≥目标代码段DPL

假设用户进程要调用某个调用门,该门描述符中参数的个数是2,调用前的当前特权级为3,调田后的新特权级为0。用户进程通过cal指令调用调用门的完整过程:

  1. 现为此调用门提供2个参数,这是在使用调用门前完成的,目前是在3特权级,所以要3特权级栈中压入参数,分别是参数1和参数2。
  2. 在这一步骤中要确定新特权级使用的栈,根据门描述符中选择子对应的目标代码段的DPL(等于0),处理器自动在TSS中找到合适的栈段选择子SS和栈指针ESP,它们作为转移后新的栈。为方便叙述,将它们记作SS_new、ESP_new。
  3. 检查新栈段选择子对应的描述符的DPL和TYPE,如果未通过检查则处理器引发异常。
  4. 如果转移后的目标代码段DPL比CPL要高,说明栈段选择子SS_new是特权级更高的栈,这说明需要特权级转换,需要切换到新栈,由于转移前的旧栈段选择子SS_old及指针ESP_old得保存到新栈中,这样在高特权级的目标程序执行完成后才能通过retf指令恢复旧栈。处理器先找个地方临时保存SS_old和ESP_old,之后将SS_new加载到栈段寄存器SS,esp_new加载到栈指针寄存器esp,这样便启用了新栈。
  5. 在使用新栈后,将上一步中临时保存的SS_old和ESP_old压入到当前新栈中,也就是0特权级栈。由于讨论的是32位模式,故栈操作数也是32位,SS_old只是16位数据,将其高16位用0填充后入栈保存。
  6. 在这一步中要将用户栈中的参数复制到转移后的新栈中,根据调用门描述符中的参数个数决定复制几个参数。
  7. 由于调用门描述符中记录的是目标程序所在代码段的选择子及偏移地址,这意味着代码段寄存器CS要用该选择子重新加载,只要段寄存器被加载,段描述符缓冲寄存器就会被刷新,从而相当于切换到了新段上运行,这是段间远转移。所以需要将当前代码段CS和EIP都备份在栈中,这两个值分别记作CS_old和EIP_old,这两个值是将来恢复用户进程的关键。
  8. 把门描述符中的代码段选择子装载到代码段寄存器CS,把偏移量装载到指令指针寄存器EP。至此,处理器终于从用户程序转移到了内核程序上,实现了特权级由3到0的转移,开始执行门描述符中对应的内核服务程序。

下面是利用retf指令丛调用门返回的过程: 

  1. 当处理器执行到retf指令时,它知道这是远返回,所以需要从栈中返回旧栈的地址及返回到低特权级的程序中。这时候它要进行特权级检查。先检查栈中CS选择子,根据其RPL位,即未来的CPL,判断在返回过程中是否要改变特权级。
  2. 此时栈顶应该指向栈中的EIP_old,在此步骤中获取栈中CS_old和EIP_old,根据该CS_old选择子对应的代码段的DPL及选择子中的RPL做特权级检查,如果检查通过,先从栈中弹出32位数据,即EIP_old到寄存器EP,然后再弹出32位数据CS_old,此时要临时处理一下,由于所有的段寄存器都是16位的,当然包括CS,所以丢弃CS old的高16位,将低16位加载到CS寄存器。此时栈指针ESP_new指向最后一个参数。
  3. 如果返回指令retf后面有参数,则增加栈指针ESP_new的值,以跳过栈中参数,如参数1和参数2,所以retf后面的参数应该等于参数个数*参数大小。此时,栈指针ESP_new便指向ESP_old。
  4. 如果在第1步中判断出需要改变特权级,从栈中弹出32位数据ESP_old到寄存器ESP。同样寄存器SS也是16位的,故再弹出32位的SS_old,只将其低16位加载到寄存器SS,此时恢复了旧栈。

五、进程管理

 1、TSS简介

TSS,即 Task State Segment,意为任务状态段。TSS是每个任务都有的结构,它用于一个任务的标识,相当于任务的身份证,程序拥有此结构才能运行,这是处理器硬件上用于任务管理的系统结构,处理器能够识别其中每一个字段。

TSS是硬件支持的系统数据结构,它和GDT等一样,由软件填写其内容,由硬件使用。GDT要加载到寄存器GDTR中才能被处理器找到,TSS也是一样,它是由TR(Task Register)寄存器加载的,每次处理器执行不同任务时,将TR寄存器加载成不同任务的TSS就成了。 

TSS同其他普通段一样,是位于内存中的区域,因此可以把TSS理解为TSS段,只不过TSS中的数据并不像其他普通段那样散乱,TSS中的数据是按照固定格式来存储的。TSS中的字段基本上全是寄存器名称,这些寄存器就是任务运行中的最新状态可见TSS的主要作用就是保存任务的快照,也就是CPU执行该任务时,寄存器当时的瞬时值。除了一般的寄存器外,TSS中还有I/O位图上一个任务的TSS指针。I/O位图在单个端口的粒度上进行IO特权控制。另外,CPU在不同特权级下用不同的栈,这三组栈是用来由低特权级往高特权级跳转时用的,最低的特权级是3,没有更低的特权级会跳入3特权级,因此TSS中没有SS3和esp3。 

TSS和LDT一样,必须要在GDT中注册才行,这也是为了在用描述符的阶段做安全检查,因此TSS是通过选择子来访问的,将tss加载到TR的指今是ltr,其指令格式为:

有了TSS后,任务在被换下CPU时,由CPU自动地把当前任务的资源状态(所有寄存器、必要的内存结构,如栈等)保存到该任务对应的TSS中(由寄存器TR指定)。CPU通过新任务的TSS选择子加载新任务时,会把该TSS中的数据载入到CPU的寄存器中,同时用此TSS描述符更新寄存器TR。以上动作是CPU自动完成的,不需要人工千预,这就是前面所说的硬件一级的原生支持。不过,第一个任务的TSS是需要手工加载的,否则第一个任务的状态该没有地方保存了。 在系统初始化时,必须向Task Register写入一个有效的TSS描述符对应的选择子。在本课程中,写入的则是init_main()对应的描述选选择子,即其为最开始运行的任务。

为了支持多任务,CPU厂商提供了LDT及TSS这两种原生支持,他们要求为每一个任多分别配一个LDT及TSS,LDT中保存的是任务自己的实体资源,也就是数据和代码TSS中保存的是任务的上下文状态及三种特权级的栈指针、I/O位图等信息。既然LDT和TSS用来表示一个任务,那么任务切换就是换这两个结构:将新任务对应的LDT信息加载到LDTR寄存器,对应的TSS信息加载到TR寄存器。任务的段放在GDT,还是LDT中,无非就是在用选择子选择它们时有区别,任务私有的实体资源不是必须放在它白已的LDT中。综上所述,LDT是可有可无的,真正用于区分一个任务的标志是TSS。

2、任务切换 

在CPU眼里,一个TSS就代表一个任务,TSS才是任务的标志,CPU区分任多就是靠TSS。因此,只要TR寄存器中的TSS信息不换,无论执行的是哪里的指令,也无论指令是否跨越特权级(从用户态到内核态),CPU都认为还是在同一个任务中。 进行任务切换的方式有中断+任务门call或jmp+任务门iretd。

2.1 call、jmp切换任务

2.2 现代操作系统采用的任务切换方式 

Linux为每个CPU创建一个TSS,在各个CPU上的所有任务共享同个TSS,各CPU的TR寄存器保存各CPU上的TSS,在用ltr指令加载TSS后,该TR寄存器永远指向同一个TSS,之后再也不会重新加载TSS。在进程切换时,只需要把TSS中的SS0及esp0更新为新任务的内核栈的段地址及栈指针。 当CPU由低特权级进入高特权级时,CPU会自动从TSS中获取对应高特权级的栈指针(TSS是CPU内部框架原生支持的,当然是直动从中获取新的栈指针)。具体地,Linux只用到了特权3级和特权0级,因此CPU从3特权级的用户态进入0特权级的内核态时(比如从用户进程进入中断),CPU自动从当前任务的TSS中获取SS0和esp0字段的值作为0特权级的栈,然后Linux手动执行一系列的push指令将任务的状态的保存在0特权级栈中,也就是TSS中esp0所指向的栈。

 六、文件系统

1、MBR & DBR

在磁盘存储中,MBR(Master Boot Record,主引导记录)和 DBR(DOS Boot Record,DOS 引导记录)是两个重要的引导区结构,它们在磁盘启动和文件系统管理中发挥关键作用。

MBR(主引导记录)

位置和作用
  • 位置:MBR 位于硬盘的第一个扇区,即逻辑块地址(LBA)0。
  • 作用:MBR 包含启动引导代码、分区表和引导签名,是 BIOS 加载操作系统的第一步。它负责将控制权交给分区中的操作系统引导程序。
MBR 结构
偏移量大小描述
0x000446 字节引导代码
0x1BE64 字节分区表(4 个分区,每个 16 字节)
0x1FE2 字节引导签名(0x55AA)

DBR(DOS 引导记录)

位置和作用
  • 位置:DBR 位于每个分区的第一个扇区,即每个分区的逻辑块地址 0。
  • 作用:DBR 包含文件系统的引导代码和基本信息。它负责加载操作系统引导程序并启动操作系统。
DBR 结构(以 FAT 文件系统为例)
偏移量大小描述
0x0003 字节跳转指令
0x0038 字节OEM 标识符
0x00B25 字节BPB(BIOS 参数块)
0x02426 字节扩展 BPB
0x03E448 字节引导代码
0x1FE2 字节引导签名(0x55AA)

MBR 与 DBR 的关系

  1. 引导过程

    • 计算机启动时,BIOS 加载 MBR 并执行其中的引导代码。
    • MBR 引导代码根据分区表信息找到活动分区,并将控制权交给该分区的 DBR。
    • DBR 执行文件系统的引导代码,进一步加载操作系统引导程序。
  2. 分区管理

    • MBR 负责管理整个硬盘的分区信息,每个分区都有一个对应的 DBR。
    • DBR 负责管理分区内的文件系统信息和引导操作系统。


 

七、相关图例

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1976241.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

隐藏采购订单类型

文章目录 1 Introduction2 code 1 Introduction The passage is that how to hiden purchase type . 2 code DATA: ls_shlp_selopt TYPE ddshselopt. IF ( sy-tcode ME21N OR sy-tcode ME22N OR sy-tcode ME23N or sy-tcode ME51N OR sy-tcode ME52N OR sy-tcode ME5…

CTFSHOW 萌新 web10 解题思路和方法(passthru执行命令)

点击题目链接,分析页面代码。发现代码中过滤了system、exec 函数,这意味着我们不能通过system(cmd命令)、exec(cmd命令)的方式运行命令。 在命令执行中,常用的命令执行函数有: system(cmd_code);exec(cmd_…

Xilinx管脚验证流程及常见问题

1 流程 1.1 新建I/O Planning Project I/O Planning Project中可以不需要RTL的top层.v代码,仅图形化界面即可配置管脚约束XDC文件的生成: Create I/O Ports: 导出XDC文件和自动生成的top_interface.v文件: 1.2 新建test Project …

HarmonyOS开发:生命周期详解

目录 前言 生命周期的概念HarmonyOS生命周期最后 前言 随着移动端操作系统的多样化发展,HarmonyOS作为华为推出的一款面向全场景的分布式操作系统,受到了业内外的广泛关注。其实HarmonyOS的设计和开发模式,与传统的移动端操作系统有着显著…

【TwinCAT3教程】IEC61131-3编程基础

在开发可编程序控制器(PLC)的早期阶段没有统一的标准,这种编程语言不统一的情况,给用户带来极大的不方便,近几年由于自动化系统的发展,IEC的第七个工作组制定了IEC(International Electro techn…

三十七、MyBatis-Plus(3)

🌻🌻 目录 一、CRUD 扩展 (2)1.1 Select1.2 分页查询1.3 Delete1.3.1 物理删除1.3.2 逻辑删除 二、性能分析插件三、条件构造器四、代码自动生成器 一、CRUD 扩展 (2) 1.1 Select 查询所有: /* * 查询 * */Test //查询全部 public void sele…

PCB设计经验——布线原则

1.连线精简——避免直角布线 导线也应看作一种元器件,有自己的电阻,电感,电容 PCB走线在直角转弯的地方,信号前后部分相互影响,导致分布电容增加,对信号上升沿和下降沿有延缓影响。从阻抗的角度来说&#…

鸿蒙媒体开发【相机数据采集保存】拍照和图片

相机数据采集保存 介绍 本示例主要展示了相机的相关功能 接口实现相机的预览拍照功能。 效果预览 使用说明 弹出是否允许“CameraSample”使用相机?点击“允许”弹出是否允许“CameraSample”使用麦克风?点击“允许”进入预览界面,预览正…

快递点“内鬼”才是倒卖我们个人信息的源头

下面是一个真实的案例来分析一下我们的信息是怎么被倒卖出去的。以次来给大家敲响警钟,不要相信所谓的退货退款类的诈骗。【所有涉及到金钱的都是诈骗,获取你信息也很容易,所以不要轻信诈骗谎言】 01-盗取快递信息过程 内鬼与骗子勾结&…

深度学习(1)--机器学习、人工智能、深度学习的关系

1956 年提出 AI 概念,短短3年后(1959) Arthur Samuel 就提出了机器学习的概念: Field of study that gives computers the ability to learn without being explicitly programmed. 机器学习研究和构建的是一种特殊算法&#xff0…

Mindspore框架DCGAN模型实现漫画头像生成|(二)DCGAN模型构建

Mindspore框架DCGAN模型实现漫画头像生成 Mindspore框架DCGAN模型实现漫画头像生成|(一)漫画头像数据集准备Mindspore框架DCGAN模型实现漫画头像生成|(二)DCGAN模型构建Mindspore框架DCGAN模型实现漫画头像生成|(三&a…

广州市广州城市信息模型(CIM)白皮书学习

一级标题 二级标题 框架 四级标题 五级标题 六级标题 CIM平台定义 以建筑信息模型(BIM)、地理信息系统(GIS)、物联网(IoT)等技术为基础,整合城市地上地下、室内室外、历史现状未来多维多尺度信息模型数据和城市感知数据,构建起三维数字空间的城市…

主持人大赛活动流程和规则

比赛内容: ①命题主持三分钟 选手抽签获得一命题主持内容,思考三十秒后开始主持 ②模拟主持两分钟 选手提前自己准备好,模拟主持一段电视或广播节目。 要求创意新颖、声情并茂。 ③即兴演讲两分钟 选手现场抽题。抽到一个话题,思…

算法021:山脉数组的峰顶索引

山脉数组的峰顶索引. - 备战技术面试?力扣提供海量技术面试资源,帮助你高效提升编程技能,轻松拿下世界 IT 名企 Dream Offer。https://leetcode.cn/problems/peak-index-in-a-mountain-array/ 这个题,看似好像不是递增或者递减数组&#xff…

【网络安全入门】学习网络安全必须知道的77个网络基础知识

1、TCP/IP 协议的四层模型(网络接口层、网络层、传输层、应用层) TCP/IP 协议是互联网通信的基础,四层模型中,网络接口层负责与物理网络的连接;网络层主要处理 IP 数据包的路由和转发;传输层提供端到端的可…

电路原理分析

文章目录 0 基础符号说明电容电感电阻U/IC二极管三极管变压器杂合元件IGBT电机运放开关TPJ高组态电阻上拉电阻可靠高电平提高驱动能力阻值选择下拉电阻可靠低电平晶振压电效应晶振原理实物电荷泵电路防倒灌电路0 基础符号说明 电容 电容 C Electrolytic capacitor 电解电容 E…

内网穿透--LCX端口转发实验

实验背景 通过公司带有防火墙功能的路由器接入互联网,然后由于私网IP的缘故,公网无法直接访问内部主机,通过端口转发,穿透访问内网主机服务。 实验设备 1.路由器一台,实现内部 DHCP 分配和边界 NAT 2.外网 window20…

Java语言程序设计——篇十一(3)

🌿🌿🌿跟随博主脚步,从这里开始→博主主页🌿🌿🌿 欢迎大家:这里是我的学习笔记、总结知识的地方,喜欢的话请三连,有问题可以私信🌳🌳&…

JavaFX布局-ButtonBar

JavaFX布局-ButtonBar 常用属性buttonOrderpaddingbuttonMinWidth 实现方式Java实现fxml实现 一个特殊的容器,用于创建一组按钮,水平排列按钮太多,会被遮住,不会自动产生滚动条 常用属性 buttonOrder 预制顺序 buttonBar.setBut…

别再盲目推广了!Xinstall助你开启App线下推广新篇章

在这个数字化飞速发展的时代,App已经成为我们生活中不可或缺的一部分。然而,App市场的竞争也日益激烈,如何让你的App在众多竞争者中脱颖而出,成为每个推广者必须面对的问题。今天,就让我们一起探讨一下App线下推广的痛…