最近一段時間在閱讀Linux的原始碼,想把看到的東西寫出來,覺得記憶體這一部分最簡單,就先寫了出 來。請指正!
記憶體最低4K的地址是一張頁目錄(page_dir),頁目錄共1024項,每項4位元組。目錄項的結構如下:
____________________________________|32-12位為頁框地址 | |U|R|p|| | |S|W| ||_________________|______ |_|_ |_|
隨後的16K,用來做了4張頁表,頁表項結構和頁目錄項結構一樣。頁表的每一項指向一個物理頁面,也 就是指向記憶體中的一個4K大小的空間。有了這4張頁表,已經能定址16M的記憶體了。下面就是在系統初始化 的時候在head.s程式中設定一張頁目錄和四張頁表的代碼。此時頁目錄中僅前4項有效,正是指向位於其 下面的4張頁表,而這4張頁表定址了記憶體的最低16M。
198 setup_paging:199 movl 24*5,%ecx /* 5 pages - pg_dir+4 page tables */200 xorl %eax,%eax201 xorl %edi,%edi /* pg_dir is at 0x000 */202 cld;rep;stosl203 movl $pg0+7,_pg_dir /* set present bit/user r/w */204 movl $pg1+7,_pg_dir+4 /* --------- " " --------- */205 movl $pg2+7,_pg_dir+8 /* --------- " " --------- */206 movl $pg3+7,_pg_dir+12 /* --------- " " --------- */207 movl $pg3+4092,%edi208 movl xfff007,%eax /* 16Mb - 4096 + 7 (r/w user,p) */209 std210 1: stosl /* fill pages backwards - more efficient :-) */211 subl x1000,%eax212 jge 1b
以後每次有fork新進程,都要為新進程分配記憶體。但具體是怎麼做的呢,我也想知道,一起看吧。當 執行fork時,它使用int0x80調用sys_fork函數,sys_fork的代碼位於system_call.s中,很短如下:
208 _sys_fork:209 call _find_empty_process210 testl %eax,%eax211 js 1f212 push %gs213 pushl %esi214 pushl %edi215 pushl %ebp216 pushl %eax217 call _copy_process218 addl ,%esp219 1: ret