地址映射与共享

本次已经是OS的第五次实验了,这次要做的内容有:

  1. 用Bochs调试工具跟踪Linux 0.11的地址翻译(地址映射)过程,了解IA-32和Linux 0.11的内容管理机制;
  2. 在Ubuntu上编写多进程的生产者—消费者程序,用共享内存做缓冲区;
  3. 在信号量实验的基础上,为Linux 0.11增加共享内存功能,并将生产者—消费者程序移植到Linux 0.11。
第一个内容,跟踪地址的翻译过程。指导书上的顺序是有一点乱的。这个过程是比较机械的,下面主要是截图说明每步的操作。

首先,是编译运行test.c。可以看到下图中的结果。


接着是,按下“Ctrl+C”,进入调试状态,可以看见下图中的结果。


接着使用“u/7”命令,可以看到上图中的反汇编结果,会发现ds:ox3004,说明了变量i保存在这个地址中。我们要找的便是他所对应的物理地址。根据Linux0.11的内存分段管理机制,可以知道的是ds寄存器中存的就是ds段的段选择子。

用“sreg”命令可以看到ds段的具体信息。段选择子是16位的寄存器,他的每一位都有特殊的含义。在下图中看到的ds的信息时0x0017,根据段选择子的各位的含义,可以知道TI值为1,所以我们要去LDT中去查询,索引值为2,表示是LDT的第三项(从0开始)。还是从下图中,我们可以看到ldtr的值和gdtr的值,ldtr的值显示了LDT表存放在GDT表的位置,即LDT在GDT的13号位置,而gdtr的值表示了GDT的位置,在物理地址的0x00005cb8。


接下来,通过命令“0x00005cc8 +13* 8”。“xp /2w 0x00005cb8 + 13 * 8”,可以找到我们要找的那个表项,可以在下图中看到。根据我们刚才看到的内容的某种组合形式,我们可以知道LDT表的物理地址。

再用命令“xp /8w 0x00f9c2d0”就可以看到LDT表的前4项内容了。根据我们之前得到的结果,我们知道我们要找的是LDT的第三项,即“0x00003fff 0x10c0f300“。根据这一项的某种组合,可以知道的是,ds段的基地址0x10000000

好了,我们的ds段的线性地址已经可以得出了,是段基址+段内偏移,为0x10003004。可以用命令“calc ds:0x3004”可以验证这个结果,如下:


接下来的工作是,根据这个线性地址得到物理地址了。

根据这个线性地址可以算出页目录号,页表号,页内偏移。0x10003004对应的页目录号是64,页表号时3,页内偏移是4。

通过命令“creg”可以看到,CR3寄存器的内容,这里存着页目录表的位置。根据上图可以看到CR3= 0x00000000,说明页目录表的基址是0.

通过命令“xp /68w 0”可以查看页目录表内容:


而我们需要的内容可以通过这个命令“xp /w 0+64*4”来查看:


可以对看到的这个内容进行分析,发现页表所在物理页框号为0x00fa7,通过0x00fa7000这个位置来查找3号页表项,通过命令“xp /w 0x00fa000+3*4”可以看到如下结果:


线性地址0x10003004对应的物理页框号为0x00fa6,和页内偏移0x004接到一起,得到0x00fa6004,这就是变量i的物理地址

可以通过两种方法验证。

第一种方法是用命令“page 0x10003004”,可以得到信息:“linear page 0x10003000 maps to physical page 0x00fa6000”。

第二种方法是用命令“xp /w 0x00fa7004”,可以看到:

现在,通过直接修改内存来改变i的值为0,命令是: setpmem 0x00fa6004 4 0,表示从0x00fa6004地址开始的4个字节都设为0。然后再用“c”命令继续Bochs的运行,可以看到test退出了,说明i的修改成功了。


至于后面的两个内容,等到这周有空闲的时间再写吧。


报告:

1.根据我们得到的结果,我认为最重要的有一下几步:
(1)根据反汇编的结果,我们可以知道变量i处于ds段,那么我们通过命令查看ds寄存器的内容时(也即查看ds段的选择子时),要根据段选择子各个二进制位的定义得到一些信息,比如我们要查找LDT表而非GDT表,这步比较重要,结果如下:
u /7
10000063: ( ): cmp dword ptr ds:0x3004, 0x00000000 ; 833d0430000000
1000006a: ( ): jz .+0x00000004 ; 7404
1000006c: ( ): jmp .+0xfffffff5 ; ebf5
1000006e: ( ): add byte ptr ds:[eax], al ; 0000
10000070: ( ): xor eax, eax ; 31c0
10000072: ( ): jmp .+0x00000000 ; eb00
10000074: ( ): leave ; c9
sreg
cs:s=0x000f, dl=0x00000002, dh=0x10c0fa00, valid=1
ds:s=0x0017, dl=0x00003fff, dh=0x10c0f300, valid=3
ss:s=0x0017, dl=0x00003fff, dh=0x10c0f300, valid=1
es:s=0x0017, dl=0x00003fff, dh=0x10c0f300, valid=1
fs:s=0x0017, dl=0x00003fff, dh=0x10c0f300, valid=1
gs:s=0x0017, dl=0x00003fff, dh=0x10c0f300, valid=1
ldtr:s=0x0068, dl=0xc2d00068, dh=0x000082dd, valid=1
tr:s=0x0060, dl=0xc2e80068, dh=0x00008bdd, valid=1
gdtr:base=0x00005cb8, limit=0x7ff
idtr:base=0x000054b8, limit=0x7ff


(2) 通过sreg命令看到ldtr的值,即LDT在GDT中的描述符的索引。GDT的位置已经由gdtr明确给出,知道了GDT的位置和我们要找的LDT描述符在GDT中的索引值,就可以找到我们要找的描述符
sreg
cs:s=0x000f, dl=0x00000002, dh=0x10c0fa00, valid=1
ds:s=0x0017, dl=0x00003fff, dh=0x10c0f300, valid=3
ss:s=0x0017, dl=0x00003fff, dh=0x10c0f300, valid=1
es:s=0x0017, dl=0x00003fff, dh=0x10c0f300, valid=1
fs:s=0x0017, dl=0x00003fff, dh=0x10c0f300, valid=1
gs:s=0x0017, dl=0x00003fff, dh=0x10c0f300, valid=1
ldtr:s=0x0068, dl=0xc2d00068, dh=0x000082dd, valid=1
tr:s=0x0060, dl=0xc2e80068, dh=0x00008bdd, valid=1
gdtr:base=0x00005cb8, limit=0x7ff
idtr:base=0x000054b8, limit=0x7ff
xp /32w 0x00005cb8
[bochs]:
0x00005cb8 : 0x000000000x000000000x00000fff0x00c09a00
0x00005cc8 : 0x00000fff0x00c093000x000000000x00000000
0x00005cd8 : 0xa44800680x000089010xa43000680x00008201
0x00005ce8 : 0xf2e800680x000089ff0xf2d000680x000082ff
0x00005cf8 : 0xb2e800680x000089fa0xb2d000680x000082fa
0x00005d08 : 0xf2e800680x000089fb0xf2d000680x000082fb
0x00005d18 : 0xc2e800680x00008bdd0xc2d000680x000082dd
0x00005d28 : 0xe2e800680x000089e10xe2d000680x000082e1


(3)根据上面的描述符找到了LDT表的起始地址,和我们要找的描述符在这个LDT中的偏移量,就能知道ds段的描述符了。
xp /8w 0x00ddc2d0
[bochs]:
0x00ddc2d0 : 0x000000000x000000000x000000020x10c0fa00
0x00ddc2e0 : 0x00003fff0x10c0f3000x000000000x00ddd000
sreg
cs:s=0x000f, dl=0x00000002, dh=0x10c0fa00, valid=1
ds:s=0x0017, dl=0x00003fff, dh=0x10c0f300, valid=3
ss:s=0x0017, dl=0x00003fff, dh=0x10c0f300, valid=1
es:s=0x0017, dl=0x00003fff, dh=0x10c0f300, valid=1
fs:s=0x0017, dl=0x00003fff, dh=0x10c0f300, valid=1
gs:s=0x0017, dl=0x00003fff, dh=0x10c0f300, valid=1
ldtr:s=0x0068, dl=0xc2d00068, dh=0x000082dd, valid=1
tr:s=0x0060, dl=0xc2e80068, dh=0x00008bdd, valid=1
gdtr:base=0x00005cb8, limit=0x7ff
idtr:base=0x000054b8, limit=0x7ff


(4)知道了变量i的线性地址,进行线性地址到物理地址的映射时,要根据线性地址的各个位的含义找到页目录表和页表,再进行地址翻译。
creg
CR0=0x8000001b: PG cd nw ac wp ne ET TS em MP PE
CR2=page fault laddr=0x10002fac
CR3=0x00000000
PCD=page-level cache disable=0
PWT=page-level writes transparent=0
CR4=0x00000000: osxmmexcpt osfxsr pce pge mce pae pse de tsd pvi vme
xp/68w 0
[bochs]:
0x00000000 : 0x000010270x000020070x000030070x00004027
0x00000010 : 0x000000000x0002a6bc0x000000000x00000000
0x00000020 : 0x000000000x000000000x000000000x00000000
0x00000030 : 0x000000000x000000000x000000000x00000000
0x00000040 : 0x00ffe0270x000000000x000000000x00000000
0x00000050 : 0x000000000x000000000x000000000x00000000
0x00000060 : 0x000000000x000000000x000000000x00000000
0x00000070 : 0x000000000x000000000x000000000x00000000
0x00000080 : 0x00fa00270x000000000x000000000x00000000
0x00000090 : 0x000000000x000000000x000000000x00000000
0x000000a0 : 0x000000000x000000000x000000000x00000000
0x000000b0 : 0x000000000x000000000x000000000x00fa2027
0x000000c0 : 0x00fa50270x000000000x000000000x00000000
0x000000d0 : 0x000000000x000000000x000000000x00000000
0x000000e0 : 0x000000000x000000000x000000000x00000000
0x000000f0 : 0x000000000x000000000x000000000x00fa7027
0x00000100 : 0x00da30270x000000000x000000000x00000000
xp/w 0+64*4
[bochs]:
0x00000100 : 0x00da3027
xp/w 0x00da3000+3*4
[bochs]:
0x00da300c : 0x00da2067
xp/w 0x00da2004
[bochs]:
0x00da2004 : 0x12345678








我的跟踪地址映射的过程如下:
open@open-Lenovo ~/oslab $./dbg-asm
========================================================================
Bochs x86 Emulator 2.3.7
Build from CVS snapshot, on June 3, 2008
========================================================================
00000000000i[ ] reading configuration from ./bochs/bochsrc.bxrc
00000000000i[ ] installing x module as the Bochs GUI
00000000000i[ ] using log file ./bochsout.txt
Next at t=0
(0) [0xfffffff0] f000:fff0 (unk. ctxt): jmp far f000:e05b ; ea5be000f0
c
^CNext at t=899505258
(0) [0x00dcf06a] 000f:0000006a (unk. ctxt): jz .+0x00000004 (0x10000070) ; 7404
n
Next at t=899505259
(0) [0x00dcf06c] 000f:0000006c (unk. ctxt): jmp .+0xfffffff5 (0x10000063) ; ebf5
n
Next at t=899505260
(0) [0x00dcf063] 000f:00000063 (unk. ctxt): cmp dword ptr ds:0x3004, 0x00000000 ; 833d0430000000
u /7
10000063: ( ): cmp dword ptr ds:0x3004, 0x00000000 ; 833d0430000000
1000006a: ( ): jz .+0x00000004 ; 7404
1000006c: ( ): jmp .+0xfffffff5 ; ebf5
1000006e: ( ): add byte ptr ds:[eax], al ; 0000
10000070: ( ): xor eax, eax ; 31c0
10000072: ( ): jmp .+0x00000000 ; eb00
10000074: ( ): leave ; c9
sreg
cs:s=0x000f, dl=0x00000002, dh=0x10c0fa00, valid=1
ds:s=0x0017, dl=0x00003fff, dh=0x10c0f300, valid=3
ss:s=0x0017, dl=0x00003fff, dh=0x10c0f300, valid=1
es:s=0x0017, dl=0x00003fff, dh=0x10c0f300, valid=1
fs:s=0x0017, dl=0x00003fff, dh=0x10c0f300, valid=1
gs:s=0x0017, dl=0x00003fff, dh=0x10c0f300, valid=1
ldtr:s=0x0068, dl=0xc2d00068, dh=0x000082dd, valid=1
tr:s=0x0060, dl=0xc2e80068, dh=0x00008bdd, valid=1
gdtr:base=0x00005cb8, limit=0x7ff
idtr:base=0x000054b8, limit=0x7ff
xp /32w 0x00005cb8
[bochs]:
0x00005cb8 : 0x000000000x000000000x00000fff0x00c09a00
0x00005cc8 : 0x00000fff0x00c093000x000000000x00000000
0x00005cd8 : 0xa44800680x000089010xa43000680x00008201
0x00005ce8 : 0xf2e800680x000089ff0xf2d000680x000082ff
0x00005cf8 : 0xb2e800680x000089fa0xb2d000680x000082fa
0x00005d08 : 0xf2e800680x000089fb0xf2d000680x000082fb
0x00005d18 : 0xc2e800680x00008bdd0xc2d000680x000082dd
0x00005d28 : 0xe2e800680x000089e10xe2d000680x000082e1
xp /32w 0x00005cb8
[bochs]:
0x00005cb8 : 0x000000000x000000000x00000fff0x00c09a00
0x00005cc8 : 0x00000fff0x00c093000x000000000x00000000
0x00005cd8 : 0xa44800680x000089010xa43000680x00008201
0x00005ce8 : 0xf2e800680x000089ff0xf2d000680x000082ff
0x00005cf8 : 0xb2e800680x000089fa0xb2d000680x000082fa
0x00005d08 : 0xf2e800680x000089fb0xf2d000680x000082fb
0x00005d18 : 0xc2e800680x00008bdd0xc2d000680x000082dd
0x00005d28 : 0xe2e800680x000089e10xe2d000680x000082e1
xp /2w 0x00005cb8+13*8
[bochs]:
0x00005d20 : 0xc2d000680x000082dd
sreg
cs:s=0x000f, dl=0x00000002, dh=0x10c0fa00, valid=1
ds:s=0x0017, dl=0x00003fff, dh=0x10c0f300, valid=3
ss:s=0x0017, dl=0x00003fff, dh=0x10c0f300, valid=1
es:s=0x0017, dl=0x00003fff, dh=0x10c0f300, valid=1
fs:s=0x0017, dl=0x00003fff, dh=0x10c0f300, valid=1
gs:s=0x0017, dl=0x00003fff, dh=0x10c0f300, valid=1
ldtr:s=0x0068, dl=0xc2d00068, dh=0x000082dd, valid=1
tr:s=0x0060, dl=0xc2e80068, dh=0x00008bdd, valid=1
gdtr:base=0x00005cb8, limit=0x7ff
idtr:base=0x000054b8, limit=0x7ff
xp /8w 0x00ddc2d0
[bochs]:
0x00ddc2d0 : 0x000000000x000000000x000000020x10c0fa00
0x00ddc2e0 : 0x00003fff0x10c0f3000x000000000x00ddd000
sreg
cs:s=0x000f, dl=0x00000002, dh=0x10c0fa00, valid=1
ds:s=0x0017, dl=0x00003fff, dh=0x10c0f300, valid=3
ss:s=0x0017, dl=0x00003fff, dh=0x10c0f300, valid=1
es:s=0x0017, dl=0x00003fff, dh=0x10c0f300, valid=1
fs:s=0x0017, dl=0x00003fff, dh=0x10c0f300, valid=1
gs:s=0x0017, dl=0x00003fff, dh=0x10c0f300, valid=1
ldtr:s=0x0068, dl=0xc2d00068, dh=0x000082dd, valid=1
tr:s=0x0060, dl=0xc2e80068, dh=0x00008bdd, valid=1
gdtr:base=0x00005cb8, limit=0x7ff
idtr:base=0x000054b8, limit=0x7ff
calc ds:0x3004
0x10003004 268447748
creg
CR0=0x8000001b: PG cd nw ac wp ne ET TS em MP PE
CR2=page fault laddr=0x10002fac
CR3=0x00000000
PCD=page-level cache disable=0
PWT=page-level writes transparent=0
CR4=0x00000000: osxmmexcpt osfxsr pce pge mce pae pse de tsd pvi vme
xp /68w 0
[bochs]:
0x00000000 : 0x000010270x000020070x000030070x00004027
0x00000010 : 0x000000000x0002a6bc0x000000000x00000000
0x00000020 : 0x000000000x000000000x000000000x00000000
0x00000030 : 0x000000000x000000000x000000000x00000000
0x00000040 : 0x00ffe0270x000000000x000000000x00000000
0x00000050 : 0x000000000x000000000x000000000x00000000
0x00000060 : 0x000000000x000000000x000000000x00000000
0x00000070 : 0x000000000x000000000x000000000x00000000
0x00000080 : 0x00fa00270x000000000x000000000x00000000
0x00000090 : 0x000000000x000000000x000000000x00000000
0x000000a0 : 0x000000000x000000000x000000000x00000000
0x000000b0 : 0x000000000x000000000x000000000x00fa2027
0x000000c0 : 0x00fa50270x000000000x000000000x00000000
0x000000d0 : 0x000000000x000000000x000000000x00000000
0x000000e0 : 0x000000000x000000000x000000000x00000000
0x000000f0 : 0x000000000x000000000x000000000x00fa7027
0x00000100 : 0x00dce0270x000000000x000000000x00000000
xp /w 0+64*4
[bochs]:
0x00000100 : 0x00dce027
xp /w 0x00dce000+3*4
[bochs]:
0x00dce00c : 0x00dcd067
page 0x10003004
linear page 0x10003000 maps to physical page 0x00dcd000
xp /w 0x00dcd004
[bochs]:
0x00dcd004 : 0x12345678
setpmem 0x00dcd004 4 0
c






2. test.c退出后,如果马上再运行一次,并再进行地址跟踪,你发现有哪些异同?为什么?
xp /w 0+64*4
[bochs]:
0x00000100 : 0x00dce027
xp /w 0x00dce000+3*4
[bochs]:
0x00dce00c : 0x00dcd067
page 0x10003004
linear page 0x10003000 maps to physical page 0x00dcd000
xp /w 0x00dcd004
[bochs]:
0x00dcd004 : 0x12345678
在查看页表的物理内存地址时出现了不同。因为系统是以页为单位分配的,而这种分配是随机的,具有不确定性。



你可能感兴趣的:(地址映射与共享)