linux子系統包括:linux
物理地址:出如今CPU地址總線上的尋址物理內存的地址信號,是地址變換的最終結果。架構
線性地址(虛擬地址):在32位CPU架構下,能夠表示4G的地址空間,16進制0xffffffff。spa
邏輯地址:操作系統
邏輯地址--->物理地址:code
首先cpu利用段氏內存管理單元,將邏輯地址轉換成線性地址。blog
再利用頁式內存管理單元,把線性地址最終轉換成物理地址。進程
段氏管理(16位CPU):16位CPU內部擁有20位的地址線,尋址範圍是2的20次方,也就是1M的內存空間。但只有16位CPU用於存放地址的寄存器(只能訪問65536個存儲單元,64K)。內存
爲了可以訪問1M的內存空間,CPU就採用了內存分段的管理模式,並在CPU內部加入了段寄存器。16位CPU把1M內存空間分爲若干個邏輯段,每一個邏輯段要求以下:內存管理
1.邏輯段的起始地址(段地址)必須是16的倍數,即最後4個二進制位必須是全0.class
2.邏輯段的最大容量爲64K
頁式管理:線性地址被分爲固定長度的組,稱爲頁(page)。
32位PC採用兩種不一樣的工做方式:實模式和保護模式。
通常工做在保護模式。
內存管理子系統職能:1.管理:虛擬地址與物理地址的映射。
2.管理:物理內存的分配。
linux內存管理:
全部段的基地址均爲0.
由於每一個段的基地址爲0,所以,邏輯地址與線性地址保持一致。也就是在linux中所提到的邏輯地址和線性地址可認爲一致。
虛擬內存:linux操做系統採用虛擬內存管理技術,使得每一個進程都有獨立的進程地址空間。用戶看到和接觸的都是虛擬地址,沒法看到實際的物理地址。
利用這種虛擬地址不但能起到保護操做系統的做用,並且更重要的是用戶進程可以使用比實際物理內存更大的地址空間。
進程空間:用戶空間對應進程,每當進程切換,用戶空間就會跟着變化。
每一個進程的用戶空間都是徹底獨立、互不相干的。( 如把同一個程序同時運行10次,會看到10個進程使用的線性地址如出一轍)
ps aux
cat /proc/<pid>/maps
實際物理內存只有當進程真的去訪問新獲取的虛擬地址時,纔會由「請頁機制」產生「缺頁」異常,進而進入分配實際頁框的程序。以後虛擬地址才實實在在地映射到了物理地址上。
在linux中,由kmalloc來分配動態內存(應用程序中malloc)
#include <linux/slab.h> void *kmalloc(size_t size,int flags) //size:要分配的內存大小 //flags:分配標誌。它控制kmalloc的行爲。
分配標誌:
內存使用:
內核空間:內核空間是由內核負責映射,它並不會跟着進程改變,是固定的。
高端內存:物理內存896M以上的部分稱爲高端內存。
4G的虛擬地址空間又分爲:
1.用戶空間(0~3G):用戶程序
2.內核空間(3G~4G):
直接映射區(3G~3G+896M):由於該區域的線性地址和物理地址之間存在線性轉換關係:線性地址=3G+物理地址。
動態內存映射區(Vmalloc區):線性地址空間連續,對應物理空間不必定連續。vmalloc分配的線性地址所對應的物理頁可能處於低端內存,頁可能處於高端內存。
KMAP區(永久內存映射區):
固定映射區: