您的位置:首页 > 其它

操作系统实验报告-地址映射

2017-03-06 12:01 281 查看


地址映射


实验步骤

用汇编级调试启动linux-0.11:

cd ~/workspace/oslab
./dbg-asm


ubuntu终端进入bochs的调试模式,先让linux-0.11正常运行:



在linux-0.11中添加文件/usr/root/test.c,内容如下:

#include <stdio.h>

int i = 0x12345678;

int main(void)
{
printf("The logical/virtual address of i is 0x%08x", &i);
fflush(stdout);

while (i)
;

return 0;
}


在linux-0.11中编译test.c,运行目标文件:

gcc -o test test.c
./test


程序进入死循环,切换到ubuntu的终端,按下Ctrl+C暂停linux-0.11:



为了让linux-0.11中运行的test跳出循环,需要找到逻辑地址ds:0x3004对应的物理地址,将其内容(变量i)改为0。

首先要得到段表LDT,取得ds对应的段描述符,才能得到ds的基址,从而得到ds:0x3004对应的线性地址,进而从线性地址计算出物理地址。


LDT的段描述符

段描述符放在LDT中,ldt的描述符放在GDT中,GDT的地址与LDT在GDT中的项的索引分别保存在gdtr和ldtr中:



s部分是一个段选择子,dl和dh是bochs自动算得的段描述符。

ldtr为0x0068 => 0000 0000 0110 1000 b,可知索引为1101b即13,TI位为0,即GDT中的第13项为LDT的段描述符,每个段描述符64bit => 8byte:



得到的LDT段描述符(与sreg指令得到的ldtr中的dl、dh相同),从而我们可以得到LDT的基址为0x00f9a2d0。


ds的段描述符

ds段选择子为0x0017 => 0000 0000 0001 0111 b,可知索引为10b即2,TI位为1,即LDT中的第2项为ds的段描述符,每个段描述符64bit => 8byte:



得到的ds段描述符,从而我们可以得到ds的基址为0x10000000。


线性地址

故ds:0x3004对应的线性地址为0x10000000+0x3004=0x10003004。


由线性地址计算出物理地址 

线性地址0x10003004 => 0001 0000 0000 0000 0011 0000 0000 0100 b,可知页目录号为1000000b即64,页表为11b即3,页内偏移为100b即4 。

页目录表的基址存放于CR3中:



获取页目录项:



可知页表基地址为0x00fa9000 。

获取页表项:



可知物理页基地址为0x00fa7000 。



可以看到内容是test.c中的变量i的值,将它设置为0:



让linux-0.11继续运行:



成功跳出循环,程序结束:




注解


段选择子



RPL:特权级,0~3权限递减;

TI:1表示INDEX为LDT表中的索引,0表示为GDT的;

INDEX:段描述符在表(LDT/GDT)中的项的索引。


段描述符中的段基址



段基址在段描述符中被分成3个部分,重新组合即可得到段基址。


由线性地址计算出物理地址




directory:页目录号

table:页表号

offset:页内偏移

table_base/page_base:页目录项/页表项的物理页面框号,作为地址的高位(其值左移12位得到基址)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: