歡迎您光臨本站 註冊首頁

linux-0.11的memory management

←手機掃碼閱讀     火星人 @ 2014-03-26 , reply:0

  今天心血來潮,研究了一下Linux-0.11的源碼。主要看了一下關於memoy管理的部分。這個部分的主要內容是在memory.c中。

  linux用的是virtual memory management。每個page 有4k。它用到了二級頁表結構。第一級頁表存在物理地址空間0開始的位置,一共有1024個表項,每個表項有4個位元組。也就是說,一級頁表佔了one page。二級頁表和一級頁表的結構相同。頁表目錄(也就是一級頁表)表項和頁表(這裡指的是二級頁表)表項每個有4位元組,也即32位,他們的前20(31-12)為對應的頁表或物理頁的基地址,後面的12位為其他信息,如當前頁面是否在內存中等。在Linux中,每個虛擬地址(32位)可以認為有三部分組成:頁表目錄索引(31-22),頁表索引(21-12),物理頁的偏移(11-0)。

  對於所有physical pages的管理用的是一個char數組mem_map, 用於記錄每個物理頁面當前被引用的次數。當然,如果物理頁面為free的話,該mem_map中對應的值為0. 如果mem_map中的值大於1的話,表示該物理頁為多個虛擬頁面共享(可以是不同進程的虛擬頁面,從而實現進程間的共享)。在對內存的處理中,幾個經常用到的操作,是根據虛擬地址找到它所在的頁表目錄以及頁表。使用的公式為:

  dir = (unsigned long*)(addr >> 20) & 0xffc;

  page_table = (unsigned long*)(0xfffff000 & *dir);

  physic_addr = (unsigned long*)(0xfffff000& *page_table);

  要了解這些公式的含義,首先需要弄明白在linux中虛擬地址的結構以及頁表目錄表項和頁表表項的結構。現在來分析上面三個公式的含義:

  1. dir = (addr >> 20) & 0xffc; 等價於 dir = ((addr >> 22) << 2) & 0xffc。根據地址結構,addr >> 22得到的是頁表目錄的索引,但每個頁表目錄表項佔用了4個地址並且頁表目錄在內存中的起始位置是0,所以(addr >> 22) << 2也就是該地址對應的頁表目錄表項在內存中的物理地址。這裡&0xffc是為了保證所得的地址的位數為12位(10位為頁表目錄索引,而每個頁表目錄表項佔用了4個位元組,所有另外的兩位相當於這4個位元組裡面的索引。)。

  2. page_table = (0xfffff000 & *dir); *dir獲得頁表目錄的表項內容。0xfffff000 & *dir獲取該表項中的前20位,所得結果就是頁表所在物理內存中的地址。我們可以利用page_table++或page_table--在頁表中遊走,從而得到不同的虛擬頁面對應的物理地址。

  3. physic_addr(0xfffff000 & *page_table);和上面這個公式的含義差不多,只不過我們這裡得到的是虛擬頁面對應的物理頁面的地址。

[火星人 ] linux-0.11的memory management已經有216次圍觀

http://coctec.com/docs/linux/show-post-186962.html