CPU的寻址方式(Linux内核情景分析)
2016-05-17 14:10
274 查看
Intel在8086 CPU中设置了四个“段寄存器”:CS、DS、SS和ES,分别用于可执行代码即指令、数据、堆栈和其他。
每个段寄存器都是16位的,对应于地址总线中的高16位。
每条“访内”指令中的“内部地址”都是16位的,但是在送上地址总线之前都在CPU内部自动地与某个段寄存器中的内容相加,形成一个20位的实际地址。(映射)
段寄存器中的内容对应于20位地址总线中的高16位;
相加时拿内部地址中的高12位与段寄存器中的16位相加;
对于每一个由段寄存器的内容确定的“基地址”,一个进程总是能够访问从此开始的64K字节的连续地址空间,而无法加以限制。(没有地址空间的保护机制)
通过改变段寄存器的内容,一个进程可以随意访问内存中的任何一个单元。
8086的这种内存寻址方式缺乏对内存空间的保护,就称为“实地址模式”。
i386系列的保护模式
同一种系统结构中的改进与加强。
支持实地址模式,又要能支持保护模式。
Intel设计人员的基本思路是:在保护模式下改变段寄存器的功能,使其从一个单纯的基地址变成指向一个数据结构的指针。
(1)根据指令的性质来确定应该使用哪个段寄存器;
(2)根据段寄存器的内容,找到相应的“地址段描述结构”;
(3)从地址段描述结构中的到基地址;
(4)将指令中发出的地址作为位移,与段描述结构中规定的段长度相比,看看是否越界;
(5)根据指令的性质和段描述符中的访问权限来确定是否越权;
(6)将指令中发出的地址作为位移,与基地址相加得到实际的“物理地址”。
段描述结构在实际使用时将其装载入CPU中的一组“影子”结构。
80386CPU中增设了两个寄存器:全局性的段描述表寄存器GDTR(global descriptor table register)和局部性的LDTR(local descriptor table register)。
用来指向存储在内存中的段描述表。
访问这两个寄存器的专用指令设计为“特权指令”。
段寄存器的高13位用作访问段描述表中具体描述结构的下标(index);
TI = 0时使用GDTR, = 1时使用LDTR;
RPL == 00最高级, 11 = 最低级。
GDTR或LDTR中的段描述表指针和段寄存器中给出的下标结合在一起,才决定了具体的段描述表项在内存中的什么地方。
每个段描述表项的大小是8个字节,含有段的基地址和段的大小,再加上其它一些信息。
每当一个段寄存器的内容改变时(通过MOV、POP等指令或发生中断等事件),CPU就把由这段寄存器的新内容所决定的段描述项装入CPU内部的一个“影子”描述项。
CPU中有几个段寄存器就有几个影子描述项。
在80386的段式内存管理基础上,如果把每个段寄存器都指向同一个描述项,而在该描述项中将基地址设为0,并将段长度设成最大,这样便形成了一个从0开始覆盖整个32位地址空间的一个整段。
由于基地址为0,此时的物理地址与逻辑地址相同,CPU放到地址总线上的地址就是指令中给出的地址。
用来装入和存储GDTR和LDTR的指令LGDT/LLDT和SGDT/SLDT等都是特权指令。
用户程序不但不能改变GDTR和LDTR的内容,还无法确知其段描述表在内存中的位置,也无法访问其空间,从而无法通过修改段描述项来打破系统的保护机制。
80386如何分隔系统状态和用户状态
80386划分成四个特权级别,0级为最高,3级为最低,每一条指令都有其适用级别。
LGDT特权指令中有在0级下才能使用,一般的输入/输出指令(IN,OUT)则规定为0级或1级。用户的应用程序都是3级。
一般程序的当前运行级别由其代码段的局部描述项中的dpl字段(descriptor privilege level)决定。
每个描述项中的dpl字段都是在0级状态下由内核设定。
全局段描述的dpl字段表示所需的级别。
i386 CPU中还有中断向量表指针寄存器IDTR、与进程有关的寄存器TR以及描述任务状态的“任务状态段”TSS等。
每个段寄存器都是16位的,对应于地址总线中的高16位。
每条“访内”指令中的“内部地址”都是16位的,但是在送上地址总线之前都在CPU内部自动地与某个段寄存器中的内容相加,形成一个20位的实际地址。(映射)
段寄存器中的内容对应于20位地址总线中的高16位;
相加时拿内部地址中的高12位与段寄存器中的16位相加;
对于每一个由段寄存器的内容确定的“基地址”,一个进程总是能够访问从此开始的64K字节的连续地址空间,而无法加以限制。(没有地址空间的保护机制)
通过改变段寄存器的内容,一个进程可以随意访问内存中的任何一个单元。
8086的这种内存寻址方式缺乏对内存空间的保护,就称为“实地址模式”。
i386系列的保护模式
同一种系统结构中的改进与加强。
支持实地址模式,又要能支持保护模式。
Intel设计人员的基本思路是:在保护模式下改变段寄存器的功能,使其从一个单纯的基地址变成指向一个数据结构的指针。
(1)根据指令的性质来确定应该使用哪个段寄存器;
(2)根据段寄存器的内容,找到相应的“地址段描述结构”;
(3)从地址段描述结构中的到基地址;
(4)将指令中发出的地址作为位移,与段描述结构中规定的段长度相比,看看是否越界;
(5)根据指令的性质和段描述符中的访问权限来确定是否越权;
(6)将指令中发出的地址作为位移,与基地址相加得到实际的“物理地址”。
段描述结构在实际使用时将其装载入CPU中的一组“影子”结构。
80386CPU中增设了两个寄存器:全局性的段描述表寄存器GDTR(global descriptor table register)和局部性的LDTR(local descriptor table register)。
用来指向存储在内存中的段描述表。
访问这两个寄存器的专用指令设计为“特权指令”。
段寄存器的高13位用作访问段描述表中具体描述结构的下标(index);
TI = 0时使用GDTR, = 1时使用LDTR;
RPL == 00最高级, 11 = 最低级。
GDTR或LDTR中的段描述表指针和段寄存器中给出的下标结合在一起,才决定了具体的段描述表项在内存中的什么地方。
每个段描述表项的大小是8个字节,含有段的基地址和段的大小,再加上其它一些信息。
每当一个段寄存器的内容改变时(通过MOV、POP等指令或发生中断等事件),CPU就把由这段寄存器的新内容所决定的段描述项装入CPU内部的一个“影子”描述项。
CPU中有几个段寄存器就有几个影子描述项。
在80386的段式内存管理基础上,如果把每个段寄存器都指向同一个描述项,而在该描述项中将基地址设为0,并将段长度设成最大,这样便形成了一个从0开始覆盖整个32位地址空间的一个整段。
由于基地址为0,此时的物理地址与逻辑地址相同,CPU放到地址总线上的地址就是指令中给出的地址。
用来装入和存储GDTR和LDTR的指令LGDT/LLDT和SGDT/SLDT等都是特权指令。
用户程序不但不能改变GDTR和LDTR的内容,还无法确知其段描述表在内存中的位置,也无法访问其空间,从而无法通过修改段描述项来打破系统的保护机制。
80386如何分隔系统状态和用户状态
80386划分成四个特权级别,0级为最高,3级为最低,每一条指令都有其适用级别。
LGDT特权指令中有在0级下才能使用,一般的输入/输出指令(IN,OUT)则规定为0级或1级。用户的应用程序都是3级。
一般程序的当前运行级别由其代码段的局部描述项中的dpl字段(descriptor privilege level)决定。
每个描述项中的dpl字段都是在0级状态下由内核设定。
全局段描述的dpl字段表示所需的级别。
i386 CPU中还有中断向量表指针寄存器IDTR、与进程有关的寄存器TR以及描述任务状态的“任务状态段”TSS等。
相关文章推荐
- linux和windows的换行符问题
- linux后台开发必备技能
- Linux 下 Error: Could not find or load main class Hello world
- Solution of wireless link "PCI unknown" on Centos 7.1
- linux grep命令详解
- linux系统中的定时器
- CentOS6.5分区与文件系统
- Linux命令 - netstat
- part1:13-linux编译器GCC
- linux tar命令运维实践
- Linux的防火墙--IP Tables
- linux系统命令大全使用详解(大全)
- 调优HASHSIZE和CONNTRACK_MAX值
- 使用screen管理linux会话
- 解决LINUX 双网卡无法上网问题小记
- linux下搭建主从DNS服务器及传送和递归属性详解
- Qt程序移植到Firefly开发板(Arm linux)下运行--转载
- LB负载均衡集群
- Linux find查找命令的mtime,cime,atime迷雾
- CentOS(RHEL)内核版本与系统版本对应关系