linux 0 11 原始碼學習(十一)

2022-02-21 01:07:36 字數 1976 閱讀 1465

memory.c

在x86的保護模式中,線性位址由頁目錄表(10位)+頁表(10位)+ 偏移(12位)組成,因此對線性位址而言可以定址4g的位址空間。而實際中linux支援16m的記憶體,因此在memory.c或者說linux的記憶體管理模組中,維護了線性位址和實際實體地址的對映。本篇部落格主要記錄記憶體管理的幾個主要函式學習。

下面幾個巨集定義可以看出物理頁面的分配數:

#define used 100    //mem_map中的對映值,unused是初始化值0,在mem_init中完成

#define paging_memory (15*1024*1024) //實際的主記憶體15m,最低端的1m分配給核心

#define paging_pages (paging_memory>>12) //實際的物理頁,每頁表項是12位偏移位址,因此長度為4096

/*

* get physical address of first (actually last :-) free page,

andmark it

* used. if no free pages left, return 0.

*/unsigned long get_free_page(void)

addr -=low_mem;

addr >>= 12

; //上述兩行**,將addr由實際實體地址轉換為mem_map中的索引

if (mem_map[addr]--) return

; mem_map[addr]=0;//對應的addr的mem_map設定為未使用

if

(copy_page_tables(old_data_base,new_data_base,data_limit))

注: 此處的from/to都是線性位址,如上述描述由10+10+12表示,但要注意的是這裡的10\10\都是在頁目錄表和頁表中的索引,因此對於實際的實體地址要*4b。

int copy_page_tables(unsigned long

from,unsigned long to,long

size)}}

invalidate();

return0;

}

在linux中採用了寫時複製技術,也就是當某個線性位址被寫時,觸發相應的缺頁錯誤。該缺頁錯誤會導致分配物理頁面,實現的**是page.s,

void do_no_page(unsigned long error_code,unsigned long

address)//address是產生異常頁面的線性位址

if(share_page(tmp))//申請共享記憶體,如果有其他程序已執行了一樣的檔案

return

;

if (!(page =get_free_page()))//獲取乙個page

oom();

/*remember that 1 block is used for header

*/block = 1 + tmp/block_size;

for (i=0 ; i<4 ; block++,i++)

nr[i] = bmap(current->executable,block);//尋求程序相應位址在檔案系統中的邏輯號

bread_page(page,current->executable->i_dev,nr);//將檔案中的內容讀入到分配的記憶體頁中

i = tmp + 4096 - current->end_data;

tmp = page + 4096

;

while (i-- > 0

)

if(put_page(page,address))

return

; free_page(page);

oom();

}

linux 0 11 原始碼學習(六)

main.c main函式其實是核心的初始化,如果把核心功能比作業務軟體的話,就相當於是業務的初始化,從該檔案的資料夾歸屬 init資料夾 也可以看出這一點。main主函式很短,從 中可以基本看出整個核心的功能模組,如下 void main void for pause 注 在linux中fork乙...

linux 0 11 原始碼學習(五)

head.s head.s 是系統模組的入口,其編譯器已經是gnu彙編,但從功能上將仍然屬於核心啟動階段,主要的功能是對386 cpu的初始化,如使用者堆疊 idt gdt和頁表。因此從資料夾的歸屬看,它仍然放在boot資料夾中,與bootsect和setup一塊。head.s的核心功能 簡單的暫存...

linux 0 11 原始碼學習(十三)

字元裝置驅動 在linux 0.11版本中,字元裝置驅動原始碼分為三塊 向上暴露的字元裝置驅動介面tty io.c與tty ioctl.c,與塊裝置驅動一樣,在字元驅動檔案 read write.c 操作中被呼叫 實現串列埠的驅動rs io.s和serial.c 實現鍵盤驅動的keyboard.s以...