Linux 記憶體管理

2021-06-14 04:12:20 字數 3835 閱讀 2995

記憶體是 linux 核心所管理的最重要的資源之一;

記憶體管理子系統是作業系統中最重要的部分之一.

對於立志從事核心開發的工程師來說,熟悉linux 的記憶體管理系統非常重要.

實體地址是指出現在 cpu 位址匯流排上的 定址物理記憶體的位址訊號,

是位址變換的最終結果;

線性位址又名虛擬位址,在 32 位 cpu 架構下,可以表示 4g 的位址空間,

用 16進製制 表示就是 0x00000000 到 0xffffffff.

程式**經過編譯後,在匯程式設計序中使用的位址;

cpu 要將乙個 邏輯位址   轉換為   實體地址,

需要兩步:

首先 cpu 利用 段式記憶體管理 單元,將邏輯位址 轉換成線性位址

再利用 頁式記憶體管理 單元,把線性位址最終轉換為實體地址.

16 位 cpu 內部擁有 20 位的位址線,它的定址範圍就是 2 的 20 次方,也就是 1m 的記憶體空間.

但是 16 位 cpu 用於存放位址暫存器( ip , sp ......)只有 16位,因此只能訪問 65536 個儲存單元,64k.

為了能夠訪問 1m 的記憶體空間,cpu 就採用了 記憶體分段 的管理模式,並在 cpu 內部加入了段暫存器.

16 位 cpu 把 1m 記憶體空間分為若干個邏輯段,

每個邏輯段的要求如下:

1,邏輯段的起始位址 ( 段位址 ) 必須是 16 的倍數,即 最後 4 個 二進位制位必須全為 0.

2,邏輯段 的最大容量為 64 k.

由於段位址 必須是 16 的倍數,所以值的一般形式 為 ***x0h , 即 前 16 位 二進位制是變化的,後 4 位 是固定的.

鑑於段位址的這種特性,可以只儲存前 16 位 二進位制來儲存整個段基位址,

所以每次使用時要用段暫存器左移補 4 個 0  ( 乘以16 ) ,來得到實際的段位址.

在確定了某個儲存單元所屬的段後,只是知道了該儲存單元所屬的範圍( 段位址 -> 段位址 + 65536 )

如果想確定 該記憶體單元的具體位置,還必須知道 該單元在記憶體的偏移,有了段位址 和偏移量

就可以唯一的 確定記憶體單元在 儲存器中的具體位置.

邏輯位址 = 段基位址 + 段內偏移量

由 邏輯位址 得到 實體地址 的公式為:

pa = 段暫存器的值 * 16 + 邏輯位址

段暫存器是為了對記憶體進行分段管理而增加的,

16位 cpu 有四個段暫存器,

程式可同時訪問四個不同含義的段:

1,cs + ip :

用於**段的訪問, cs 指向 存放程式的段基址, ip 指向下條要執行的指令在 cs 段的偏移量,

用這兩個 暫存器就可以得到乙個記憶體實體地址,該位址存放著一條要執行的指令.

2,ss + sp :

用於堆疊段的訪問, ss 指向棧頂,

可以通過 ss 和 sp 兩個暫存器直接訪問棧頂單元的記憶體物理位置.

3,ds + bx :

用於資料的訪問. ds 中的值左移四位得到資料段起始位址,再加上 bx 中的偏移量,

得到乙個儲存單元 的實體地址.

4,es + bx :

得到乙個儲存單元的 實體地址.

32 位 pc 的記憶體管理仍然採用 " 分段 " 的管理模式,邏輯位址同樣由段位址和偏移量兩部分組成,

32 位 pc 的記憶體管理和 16 位 pc 的記憶體管理有 相同 和不同之處,因為 32位 pc 採用了兩種不同的工作模式:

實模式 和 保護模式.

實模式:

在實模式下, 32 位 cpu 的記憶體管理 與 16 位 cpu 是一致的.

保護模式:

段基位址長達 32 位,每個 段的最大容量可達 4g ,段暫存器的值是段位址的 「 選擇器 」 ( selector ),

用該 「選擇器」 從記憶體中得到乙個 32 位的段位址,儲存單元的實體地址就是 該段位址加上 段內偏移量,

這與 32 位 cpu 的實體地址計算方式完全不同.

三十二  位 cpu 內有 6 個段暫存器

其值在不同的模式下具有不同的意義:

1,在實模式下:

段暫存器的值 * 16 就是 段位址.

2,在保護模式下:

段暫存器的值是乙個選擇器,間接指出乙個 32 位 的段位址.

從管理 和效率 的角度出發,線性位址被分為固定長度的組,稱為頁 ( page )

這樣整個線性位址就被劃分為 2 的 20 次方個頁.

另一類 「 頁 」 ,稱之為物理頁,或者是頁框頁幀.

分頁單元把所有的物理記憶體也劃分為固定的長度的管理單位,

它的長度一般與線性位址頁是相同的.

linux 核心的設計並沒有全部採用 intel 所提供的段機制,

僅僅是有限度的使用了分段機制,這不僅簡化了 linux 核心的設計,

而且 為把 linux 移植到其他平台創造了條件,因為很多的 risc 處理器並不支援段機制.

所有段的基位址均為0

由此可以得出,每個段的邏輯位址空間範圍 為 0 - 4 gb,

因為每個段的基位址為 0 ,因此,邏輯位址 與 線性位址保持一致( 即 邏輯位址 的偏移量 欄位的值 與 線性位址的值 總是 相同的 ),

在 linux 中所提到的邏輯位址 和線性位址( 虛擬位址 ),可以認為是 一致的.

看來 , linux 巧妙的把 段機制給繞過去了,而完全利用了分頁機制.

Linux記憶體管理

本文首先介紹一下linux記憶體管理方式,著重說明一下使用者空間的記憶體管理,包括linux虛擬對映以及glibc中malloc的實現 然後簡要介紹單程序多執行緒的記憶體管理方式,主要涉及各執行緒堆疊空間的分配 linux 採用兩級保護機制,隔離核心空間和使用者程式空間,使使用者程式無法直接訪問核心...

Linux記憶體管理

本文首先介紹一下linux記憶體管理方式,著重說明一下使用者空間的記憶體管理,包括linux虛擬對映以及glibc中malloc的實現 然後簡要介紹單程序多執行緒的記憶體管理方式,主要涉及各執行緒堆疊空間的分配 linux採用兩級保護機制,隔離核心空間和使用者程式空間,使使用者程式無法直接訪問核心,...

Linux記憶體管理

首先我要說,我這是轉貼,轉的cu論壇上 nonameboy 的帖子,你可以連線過去看看。今天因為要解釋系統中可用記憶體的大小,用google看了半天,還有在cu上找了關天,竞然沒有發現有比較好的章,估計很多人都沒有注意到,懂了以後又沒有整理出來。在cu上看了很多文章說什麼memory leak和li...