操作系统实验笔记

主引导记录MBR:

MBR存在于整个硬盘最开始的那个扇区,这个扇区便称为 MBR 引导扇区,扇区大小是 512 字节。整个硬盘只有1 个 MBR。

在 MBR 引导扇区中存储引导程序,为的是从 BIOS 手中接过处理器的控制权,也就是处理器的使用权。

MBR 引导扇区中的内容是:

\1) 446 字节的引导程序及参数;

\2) 64 字节的分区表;

\3) 2 字节结束标记 0x55 和 0xaa。

实模式下内存分段访问策略是段基址左移4位+段内偏移地址

IO接口:主机和外设的交接界面

IO端口:接口电路中可被CPU直接访问的寄存器

特权级

当使用调用门转换特权级时,会调用新特权级栈来保存ss_old,esp_old, cs_old, eip_old来当作返回地址时的作用,并在新特级权的栈完成命令

寄存器

寄存器

EAX 是"累加器"(accumulator), 它是很多加法乘法指令的缺省寄存器。

EBX 是"基地址"(base)寄存器, 在内存寻址时存放基地址。

ECX 是计数器(counter), 是重复(REP)前缀指令和LOOP指令的内定计数器。

EDX 则总是被用来放整数除法产生的余数。

ESI/EDI分别叫做"源/目标索引寄存器"(source/destination index),因为在很多字符串操作指令中, DS:ESI指向源串,而ES:EDI指向目标串.

ESP:栈指针寄存器(extended stack pointer),其内存放着一个指针,该指针永远指向系统栈最上面一个栈帧的栈顶。

EBP:基址指针寄存器(extended base pointer),其内存放着一个指针,该指针永远指向系统栈最上面一个栈帧的底部。

EIP:寄存器存放下一个CPU指令存放的内存地址,当CPU执行完当前的指令后,从EIP寄存器中读取下一条指令的内存地址,然后继续执行。

四个32位的控制寄存器,它们是CR0,CR1,CR2和CR3。

CR0中包含了6个预定义标志,0位是保护允许位PE(Protedted Enable),用于启动保护模式,如果PE位置1,则保护模式启动,如果PE=0,则在实模式下运行。

段寄存器:

通常来说,代码段用cs寄存器来分段和引用;数据段用ds寄存器来分段和引用;栈段用ss寄存器来分段和引用。另外3个段寄存器es、fs和gs可以用来分段和引用额外的数据段。在程序执行代码段里的代码、或访问数据段中的数据之前,需要事先将合法的16位段选择符的值加载到适当的段寄存器中,否则无法执行代码或访问数据。因此,虽然一个程序可以有很多段,但是某一时刻最多可以同时使用的只有其中的6个。要引用其他段,就要先加载对应的段选择符到适当的段寄存器中。

每个段寄存器都包含两个部分:对开发者可见的部分和不可见的隐藏部分。每当向一个段寄存器中加载段选择符的时候,处理器会自动将段选择符指向的段描述符中的基地址、限长和一些属性信息加载到段寄存器中的隐藏部分。这样,每当程序使用相同的段寄存器来执行代码或访问数据时,处理器就无需再从位于内存中的GDT或LDT中加载段描述符了,而是直接使用段寄存器中的隐藏部分,这样可以加速逻辑地址到线性地址的转换效率,避免访问内存(即使命中了cache也不如直接访问隐藏寄存器文件来得快)。

mov ax, 0x1234; 0x1234视为内容操作数,赋值到ax mov ax, [0x1234];

0x1234被视为内存地址,寻址取得内容作为操作数,送入ax。

堆栈框架原理

c语言函数约定,参数从右往左压入栈中,然后压入函数的返回地址。然后将ebp压入栈中,movebp,esp;用来当访问栈中其他数据时的基址。

计算机基础知识

输入,运算,输出是计算机的基础

计算机硬件的三个基本要求:cpu,内存,IO

程序是数据和指令的集合

汇编语言和机器语言

机器语言为原生代码,即由0,1这两个数字组合而成。

cpu的时钟信号为电信号,每隔一段时间就变化一次电压

汇编语言用助记符来表示 mov ax bx 由操作码和操作数组成

操作数必须是存储在cpu寄存器中的数据

机器语言用数字符号表示 0101100 但他们所实现功能是一样的

PC指针存储着接下来要运行的程序地址

A类寄存器为计算,F类寄存器为标志(是否有溢出,进位,归零)等,SP寄存器也为“栈顶指针”

页表项

 每个页表项占多大的地址空间(多大字节能表示完所有的页表项(也可以说是内存块号),一般为4B, 计算过程如下 ,

4G(物理内存大小)/4K(页大小)=2^20,至少需要20位二进制位,即3B(24位)才能表示这么多的页表项号, 因为一个页面对应一个页表项,页表项里放的是内存块号。为什么算出来是3B,而一般我们用4B呢?一般是为了方便取整使用, 现在假设有2GB内存,页面大小为4KB,页表项大小为4B。那么它一共有2GB/4KB=512K个内存块(or页,内存块大小=页面大小), 也就是说页表项有512K项(一个页表项对应一个块号),而每个页表项的大小4B, 那么页表在内存中占用的大小是:512K*4B=2MB,意味着,只要2MB就可以表示512K个页(每个页是4KB,总内存大小是2G), 它页表本身占用了2MB/4KB=512个页。 一般来说一级页表的页表项和页面大小没什么区别

保护模式下的内存段保护

汇编语言

 IN指令的意思是从端口中读取数据,比如 IN AL,80H,将80H端口数据读入到AL中
 OUT指令的意思是往端口输出数据,比如 OUT 80H,AL,将AL输出到80H端口

保护模式下内存段的保护

段描述符中的选择子:

在保护模式下,选择子所代表的段描述符在全局/局部描述符表(GDT/LDT)中的位置需要通过选择子的索引值来计算得出。由于每个段描述符在GDT/LDT中的长度为8个字节(64位),因此选择子的索引值需要乘以8(即左移3位),才能获得对应的段描述符在内存中的起始地址。

同时,由于段描述符的第7个字节的最后3位是未使用的,因此在计算段描述符的起始地址时,需要将选择子的索引值乘以8后再加上7,以获取段描述符的第7个字节。这样做可以保证从内存中正确地提取出段描述符的所有信息。

实际界限值:

实际段界限大小=描述符中段界限*0x lOOO+0xFFF

代码段既然也是内存中的区域,所以对于代码段的访问也要用“段基址:段内偏移地址”的形式,

在32 位保护模式下,段基址存放在 cs 寄存器中,段内偏移地址,即有效地址,存放在 EIP 寄存器中。CS:EIP只是起始地址

举个例子,假设数据段描述符的段界限是 Oxl2345 ,段基址为 OxOOOOOOOO 如果 位为 ,那么实际段界限便是 Oxl2345 。如果 位为 ,那么实际段界限便是 Oxl2345* OxlOOO+OxFFF=Oxl2345FFF 。如果访问的数据地址是 Oxl2345FFF ,还要看访问的数据宽度。 若数据大小是 字节,如 mov ax, byte [Oxl2345 ,这种内存操作一点问题都没有,数据完全在实 际段界限之内 若该数据大小是 字节,如 mov ax, word [Ox 12345町,这种内存操作超过了实际的段界限,数据所 在地址分别是 Oxl2345FFF Oxl234600。这两个字节, CPU 会抛异常。其中G位为段界限的粒子度

向下扩展的栈段:

为了避免碰撞,将段界限地址+ 视为钱可以访问的下限。段界限+ ,才是战指针可达的下边界

CS:IP 寄存器

CS:IP 两个寄存器指示了 CPU 当前将要读取的指令的地址,其中 CS 为代码段寄存器,而 IP 为指令指针寄存器

Shell 将可执行文件加载到内存中以后,就会设置 CPU 中的两个寄存器,即设置 CS:IP 两个寄存器指向可执行文件的起始地址,此后 CPU 便从这个起始地址开始读取内存中的指令,并且执行。

也就是说,当一个可执行文件加载到内存中以后,CS:IP 两个寄存器便指向了这个可执行文件的起始地址

Q8925A芯片中断命令

icw 表示 初始化 initialization command words ocw 表示 操作命令 icw 1 表示连接方式(单片还是级联)和 中断信号触发方式 icw 2 来这是中断向量号 icw 3 来决定主片和从片用哪个irq口来相连

ocw 1 屏蔽连接在8259A上的外部设备信号中断

ocw 2 设置中断结束(手动,会发送EOI(end ofinterrupt),或自动模式)和优先级模式

ocw 3 用不上

一个节由.section 当关键词标识

section.data表示包含了已初始化的数据,可以用来存放程序中已初始化的全局变量的一块内存区域

section.text表示一个段的内容代码

中断向量号0-19为处理器内部固定的异常类型,20-31为X86的inter保留,我们要从32的信号量开始写

将主片Q8259A的IRQ0类型设置32信号量

中断内容实现

IDT中断描述符本质是一个中断描述符数组,初始化主片和从片的icw命令后,再向主片和从片继续写入命令时会变为ocw命令操作。

1.时钟中断信号从8259A芯片IR0引脚进入,pic_init函数设置起始中断向量号为0x20,IR0引脚接受信号。 2.cpu接收到0x20的中断向量号,查询IDTR寄存器获得的idt首地址,随即找到0x20对应的中断门描述符,从而获得中断程序入口地址。idt_desc_init函数里的make_idt_desc函数写好了idt的所有中断门描述符,idt_init赋值了idtr,kernel.s里的intr_entry_table数组记录了33个中断程序入口地址。 3.cpu保存现场后,执行中断处理程序,相当于执行kernel.s定义的宏VECTOR 0x20,ZERO,这个宏里的代码执行了call [idt_table + %14],调用了c程序。相当于中断处理程序核心功能是c写的。

  1. exception_init函数把general_intr_handler这个c函数地址赋值给了idt_table[i]数组,所以call [idt_table + %14]就是调用c函数general_intr_handler,上一句push %1 就是c函数general_intr_handler所需参数中断向量号。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值