1. 程式人生 > >哈工大作業系統實驗 5 地址對映與共享

哈工大作業系統實驗 5 地址對映與共享

//=====================================================================================

========================================================================
                       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=121516790
(0) [0x00faa06c] 000f:0000006c (unk. ctxt): jmp .+0xfffffff5 (0x10000063) ; ebf5

<bochs:2> n
Next at t=121516791
(0) [0x00faa063] 000f:00000063 (unk. ctxt): cmp dword ptr ds:0x3004, 0x00000000 ; 833d0430000000
<bochs:3> 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:4> 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=0x52d00068, dh=0x000082fd, valid=1
tr:s=0x0060, dl=0x52e80068, dh=0x00008bfd, valid=1
gdtr:base=0x00005cb8, limit=0x7ff
idtr:base=0x000054b8, limit=0x7ff
<bochs:5> xp /2w 0x00005cb8 +13*8
[bochs]:
0x00005d20 <bogus+       0>:0x52d000680x000082fd
<bochs:6> xp /8w 0x0052d0fd
[bochs]:
0x0052d0fd <bogus+       0>:0x000000000x000000000x000000000x00000000
0x0052d10d <bogus+      16>:0x000000000x000000000x000000000x00000000
<bochs:7> xp /8w 0x00fd52d0
[bochs]:
0x00fd52d0 <bogus+       0>:0x000000000x000000000x000000020x10c0fa00
0x00fd52e0 <bogus+      16>:0x00003fff0x10c0f3000x000000000x00fd6000
<bochs:8> calc ds:0x3004
0x10003004 268447748
<bochs:9> 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:10> xp /68w 0
[bochs]:
0x00000000 <bogus+       0>:0x000010270x000020070x000030070x00004027
0x00000010 <bogus+      16>:0x000000000x0002ace40x000000000x00000000
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>:0x00ff30270x000000000x000000000x00000000
0x00000090 <bogus+     144>:0x000000000x000000000x000000000x00000000
0x000000a0 <bogus+     160>:0x000000000x000000000x000000000x00000000
0x000000b0 <bogus+     176>:0x000000000x000000000x000000000x00ffb027
0x000000c0 <bogus+     192>:0x00ff60270x000000000x000000000x00000000
0x000000d0 <bogus+     208>:0x000000000x000000000x000000000x00000000
0x000000e0 <bogus+     224>:0x000000000x000000000x000000000x00000000
0x000000f0 <bogus+     240>:0x000000000x000000000x000000000x00ffa027
0x00000100 <bogus+     256>:0x00fa70270x000000000x000000000x00000000
<bochs:11> xp /w 0+64*4
[bochs]:
0x00000100 <bogus+       0>:0x00fa7027
<bochs:12> page 0x10003004
linear page 0x10003000 maps to physical page 0x00fa6000
<bochs:13> xp /w 0x00fa6004            
[bochs]:
0x00fa6004 <bogus+       0>:0x12345678
END

1.

      獲得邏輯地址。

      根據ldtr與gdtr,尋找LDT表的在GDT中實體地址。 

      檢視LDT內容,得到線性地址。

      檢視線性地址在頁表中對應的頁目錄號,將所得頁框號與偏移地址拼接得到實體地址。


2.   發現線性地址的獲得與上次相同,而實體地址卻與上次不同,因為系同會隨機分配空閒實體地址,對映時邏輯地址是我們指定的。

//=====================================================================================

這次試驗需要寫的程式碼量很少,需要修改的地方比挺多。

需要修改 

       mm/makefile 

       mm/memory.c 

       kernel/system_call.s 

       include/linux/sys.h 

       include/unistd.h這幾個檔案來新增系統呼叫shmat() 與 shmget() 兩個系統呼叫。

       kernal/makefile  和第四次實驗一樣就好。

需要編寫 

       mm/shm.c    

       producer.c     

       consumer.c   三個檔案,其實後兩個只需要改寫一下上一次的pc.c就可以了。

mm/nakefile 修改成這樣

shm.s 後面的一大坨是中間檔案,依賴檔案什麼的,詳細看我部落格裡的轉載。

  1. CC  =gcc-3.4 -march=i386
  2. CFLAGS  =-m32 -g -Wall -O -fstrength-reduce -fomit-frame-pointer \  
  3.     -finline-functions -nostdinc -I../include  
  4. AS  =as --32  
  5. AR  =ar
  6. LD  =ld
  7. LDFLAGS =-m elf_i386  
  8. CPP =gcc-3.4 -E -nostdinc -I../include  
  9. .c.o:  
  10.     $(CC) $(CFLAGS) \  
  11.     -c -o $*.o {1}lt;  
  12. .s.o:  
  13.     $(AS) -o $*.o {1}lt;  
  14. .c.s:  
  15.     $(CC) $(CFLAGS) \  
  16.     -S -o $*.s {1}lt;  
  17. OBJS    = memory.o page.o shm.o  
  18. all: mm.o  
  19. mm.o: $(OBJS)  
  20.     $(LD) -m elf_i386 -r -o mm.o $(OBJS)  
  21. clean:  
  22.     rm -f core *.o *.a tmp_make  
  23.     for i in *.c;do rm -f `basename $i .c`.s;done  
  24. dep:  
  25.     sed '/\#\#\# Dependencies/q' <Makefile> tmp_make  
  26.     (for i in *.c;do $(CPP) -M $i;done) >> tmp_make  
  27.     cp tmp_make Makefile  
  28. ### Dependencies:  
  29. shm.s shm.o: shm.c ../include/linux/kernel.h ../include/unistd.h  
  30. memory.o: memory.c ../include/signal.h ../include/sys/types.h \  
  31.   ../include/asm/system.h ../include/linux/sched.h \  
  32.   ../include/linux/head.h ../include/linux/fs.h ../include/linux/mm.h \  
  33.   ../include/linux/kernel.h  

memory.c 的修改方法   如果執行程式時出現trying to free free page 錯誤 可以單純的把panic註釋掉,防止程式中斷。

呼叫shmat()成功時,mam_map[] 對應的數值將會加一。

因為我們沒有寫int shmdt(const void *shmaddr) 這個用來釋放共享記憶體的函式。程序結束時,系統會自動檢測程序中對映的共享記憶體

並釋放該對映,並將mam_map[]減一。

如果你的shm沒寫好,或呼叫shmat失敗,程式退出時會出現,上述錯誤。

如果shm寫的好,memory.c 是不用修改的。

不過本人比較懶。還是修改memory.c方便啊    : P

  1. /* 
  2.  * Free a page of memory at physical address 'addr'. Used by 
  3.  * 'free_page_tables()' 
  4.  */
  5. void free_page(unsigned long addr)  
  6. {  
  7.     if (addr < LOW_MEM) return;  
  8.     if (addr >= HIGH_MEMORY)  
  9.         panic("trying to free nonexistent page");  
  10.     addr -= LOW_MEM;  
  11.     addr >>= 12;  
  12.     if (mem_map[addr]) {mem_map[addr]--;return;}  
  13.     mem_map[addr]=0;  
  14.     //panic("trying to free free page");
  15. }  


其他三個檔案,修改過很多次了,我也懶得說了。

producer.c這樣寫 

當我們使用系統呼叫時,需要包含進<unistd.h>之前定義的符號 __LIBRARY__

頁的大小為4kb

key 為10

shmat()返回一個指標,指向對映的虛擬記憶體的首地址。

  1. #define   __LIBRARY__
  2. #include <unistd.h>
  3. #include <stdlib.h>
  4. #include <stdio.h>
  5. #include <sys/types.h>
  6. #include <fcntl.h>
  7. #define EINVAL      22
  8. #define ENOMEM      12
  9. #define N               600
  10. #define KEYNUM          10
  11. #define PAGE            4096
  12.     _syscall2(int,sem_open, constchar*, name, unsigned int , value)  
  13.     _syscall1(int, sem_wait, sem_t  *, sem)  
  14.     _syscall1(int, sem_post, sem_t  *, sem)  
  15.     _syscall1(int, sem_unlink, constchar  *, name)  
  16.     _syscall2(int