地址映射與共享

本次已經是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表,這步比較重要,結果如下:
<bochs:4> 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
<bochs:5> 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中的索引值,就可以找到我們要找的描述符
<bochs:5> 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
<bochs:6> xp /32w 0x00005cb8
[bochs]:
0x00005cb8 <bogus+       0>: 0x000000000x000000000x00000fff0x00c09a00
0x00005cc8 <bogus+      16>: 0x00000fff0x00c093000x000000000x00000000
0x00005cd8 <bogus+      32>: 0xa44800680x000089010xa43000680x00008201
0x00005ce8 <bogus+      48>: 0xf2e800680x000089ff0xf2d000680x000082ff
0x00005cf8 <bogus+      64>: 0xb2e800680x000089fa0xb2d000680x000082fa
0x00005d08 <bogus+      80>: 0xf2e800680x000089fb0xf2d000680x000082fb
0x00005d18 <bogus+      96>: 0xc2e800680x00008bdd0xc2d000680x000082dd
0x00005d28 <bogus+     112>: 0xe2e800680x000089e10xe2d000680x000082e1


  (3)根據上面的描述符找到了LDT表的起始地址,和我們要找的描述符在這個LDT中的偏移量,就能知道ds段的描述符了。
<bochs:10> xp /8w 0x00ddc2d0
[bochs]:
0x00ddc2d0 <bogus+       0>: 0x000000000x000000000x000000020x10c0fa00
0x00ddc2e0 <bogus+      16>: 0x00003fff0x10c0f3000x000000000x00ddd000
<bochs:11> 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的線性地址,進行線性地址到物理地址的映射時,要根據線性地址的各個位的含義找到頁目錄表和頁表,再進行地址翻譯。
<bochs:31> 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
<bochs:32> xp/68w 0
[bochs]:
0x00000000 <bogus+       0>: 0x000010270x000020070x000030070x00004027
0x00000010 <bogus+      16>: 0x000000000x0002a6bc0x000000000x00000000
0x00000020 <bogus+      32>: 0x000000000x000000000x000000000x00000000
0x00000030 <bogus+      48>: 0x000000000x000000000x000000000x00000000
0x00000040 <bogus+      64>: 0x00ffe0270x000000000x000000000x00000000
0x00000050 <bogus+      80>: 0x000000000x000000000x000000000x00000000
0x00000060 <bogus+      96>: 0x000000000x000000000x000000000x00000000
0x00000070 <bogus+     112>: 0x000000000x000000000x000000000x00000000
0x00000080 <bogus+     128>: 0x00fa00270x000000000x000000000x00000000
0x00000090 <bogus+     144>: 0x000000000x000000000x000000000x00000000
0x000000a0 <bogus+     160>: 0x000000000x000000000x000000000x00000000
0x000000b0 <bogus+     176>: 0x000000000x000000000x000000000x00fa2027
0x000000c0 <bogus+     192>: 0x00fa50270x000000000x000000000x00000000
0x000000d0 <bogus+     208>: 0x000000000x000000000x000000000x00000000
0x000000e0 <bogus+     224>: 0x000000000x000000000x000000000x00000000
0x000000f0 <bogus+     240>: 0x000000000x000000000x000000000x00fa7027
0x00000100 <bogus+     256>: 0x00da30270x000000000x000000000x00000000
<bochs:33> xp/w 0+64*4
[bochs]:
0x00000100 <bogus+       0>: 0x00da3027
<bochs:34> xp/w 0x00da3000+3*4
[bochs]:
0x00da300c <bogus+       0>: 0x00da2067
<bochs:35> xp/w 0x00da2004
[bochs]:
0x00da2004 <bogus+       0>: 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
<bochs:1> c
^CNext at t=899505258
(0) [0x00dcf06a] 000f:0000006a (unk. ctxt): jz .+0x00000004 (0x10000070) ; 7404
<bochs:2> n
Next at t=899505259
(0) [0x00dcf06c] 000f:0000006c (unk. ctxt): jmp .+0xfffffff5 (0x10000063) ; ebf5
<bochs:3> n
Next at t=899505260
(0) [0x00dcf063] 000f:00000063 (unk. ctxt): cmp dword ptr ds:0x3004, 0x00000000 ; 833d0430000000
<bochs:4> 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
<bochs:5> 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
<bochs:6> xp /32w 0x00005cb8
[bochs]:
0x00005cb8 <bogus+       0>: 0x000000000x000000000x00000fff0x00c09a00
0x00005cc8 <bogus+      16>: 0x00000fff0x00c093000x000000000x00000000
0x00005cd8 <bogus+      32>: 0xa44800680x000089010xa43000680x00008201
0x00005ce8 <bogus+      48>: 0xf2e800680x000089ff0xf2d000680x000082ff
0x00005cf8 <bogus+      64>: 0xb2e800680x000089fa0xb2d000680x000082fa
0x00005d08 <bogus+      80>: 0xf2e800680x000089fb0xf2d000680x000082fb
0x00005d18 <bogus+      96>: 0xc2e800680x00008bdd0xc2d000680x000082dd
0x00005d28 <bogus+     112>: 0xe2e800680x000089e10xe2d000680x000082e1
<bochs:7> xp /32w 0x00005cb8
[bochs]:
0x00005cb8 <bogus+       0>: 0x000000000x000000000x00000fff0x00c09a00
0x00005cc8 <bogus+      16>: 0x00000fff0x00c093000x000000000x00000000
0x00005cd8 <bogus+      32>: 0xa44800680x000089010xa43000680x00008201
0x00005ce8 <bogus+      48>: 0xf2e800680x000089ff0xf2d000680x000082ff
0x00005cf8 <bogus+      64>: 0xb2e800680x000089fa0xb2d000680x000082fa
0x00005d08 <bogus+      80>: 0xf2e800680x000089fb0xf2d000680x000082fb
0x00005d18 <bogus+      96>: 0xc2e800680x00008bdd0xc2d000680x000082dd
0x00005d28 <bogus+     112>: 0xe2e800680x000089e10xe2d000680x000082e1
<bochs:8> xp /2w 0x00005cb8+13*8
[bochs]:
0x00005d20 <bogus+       0>: 0xc2d000680x000082dd
<bochs:9> 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
<bochs:10> xp /8w 0x00ddc2d0
[bochs]:
0x00ddc2d0 <bogus+       0>: 0x000000000x000000000x000000020x10c0fa00
0x00ddc2e0 <bogus+      16>: 0x00003fff0x10c0f3000x000000000x00ddd000
<bochs:11> 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
<bochs:12> calc ds:0x3004
0x10003004 268447748
<bochs:13> 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
<bochs:14> xp /68w 0
[bochs]:
0x00000000 <bogus+       0>: 0x000010270x000020070x000030070x00004027
0x00000010 <bogus+      16>: 0x000000000x0002a6bc0x000000000x00000000
0x00000020 <bogus+      32>: 0x000000000x000000000x000000000x00000000
0x00000030 <bogus+      48>: 0x000000000x000000000x000000000x00000000
0x00000040 <bogus+      64>: 0x00ffe0270x000000000x000000000x00000000
0x00000050 <bogus+      80>: 0x000000000x000000000x000000000x00000000
0x00000060 <bogus+      96>: 0x000000000x000000000x000000000x00000000
0x00000070 <bogus+     112>: 0x000000000x000000000x000000000x00000000
0x00000080 <bogus+     128>: 0x00fa00270x000000000x000000000x00000000
0x00000090 <bogus+     144>: 0x000000000x000000000x000000000x00000000
0x000000a0 <bogus+     160>: 0x000000000x000000000x000000000x00000000
0x000000b0 <bogus+     176>: 0x000000000x000000000x000000000x00fa2027
0x000000c0 <bogus+     192>: 0x00fa50270x000000000x000000000x00000000
0x000000d0 <bogus+     208>: 0x000000000x000000000x000000000x00000000
0x000000e0 <bogus+     224>: 0x000000000x000000000x000000000x00000000
0x000000f0 <bogus+     240>: 0x000000000x000000000x000000000x00fa7027
0x00000100 <bogus+     256>: 0x00dce0270x000000000x000000000x00000000
<bochs:15> xp /w 0+64*4
[bochs]:
0x00000100 <bogus+       0>: 0x00dce027
<bochs:16> xp /w 0x00dce000+3*4            
[bochs]:
0x00dce00c <bogus+       0>: 0x00dcd067
<bochs:17> page 0x10003004
linear page 0x10003000 maps to physical page 0x00dcd000
<bochs:18> xp /w 0x00dcd004
[bochs]:
0x00dcd004 <bogus+       0>: 0x12345678
<bochs:19> setpmem 0x00dcd004 4 0
<bochs:20> c






2. test.c退出後,如果馬上再運行一次,並再進行地址跟蹤,你發現有哪些異同?爲什麼?
<bochs:15> xp /w 0+64*4
[bochs]:
0x00000100 <bogus+       0>: 0x00dce027
<bochs:16> xp /w 0x00dce000+3*4            
[bochs]:
0x00dce00c <bogus+       0>: 0x00dcd067
<bochs:17> page 0x10003004
linear page 0x10003000 maps to physical page 0x00dcd000
<bochs:18> xp /w 0x00dcd004
[bochs]:
0x00dcd004 <bogus+       0>: 0x12345678
   在查看頁表的物理內存地址時出現了不同。因爲系統是以頁爲單位分配的,而這種分配是隨機的,具有不確定性。



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章