在作業系統中 記憶體管理 提供多種方式 將一部分記憶體分配給處理和 無須再重複使用 新型作業系統會使用位址空間區隔處理記憶體。
位址空間 代表程序用於參照記憶體的一組虛擬位址。 虛擬地址會直接對應到實際地址。Fuchsia 的用途 VMAR (虛擬記憶體位址地區) 代表位址空間。
VMAR、對應和 VMO
在 Fuchsia 中,每個程序都有根 VMAR,且能分區為 VMAR 和對應。對應指向基礎 VMO (虛擬記憶體物件):
VMAR 和 VM 對應關係
VMAR 在特定程序中是連續的虛擬位址範圍」地址 聊天室:
- VMAR 可包含子項 VMAR 和/或 VM 對應,以便用於非重疊 子區域
- 系統會將防護位元套用至記憶體區段 (讀寫、 可執行等)
- 他們的 WAVL 樹 想提升搜尋效率的孩子
VM 對應代表「已對應」在這個位址空間中定義範圍,例如 由實體頁面支援的位址:
- VM 對應沒有任何子項
- 能對應 VMO 中一系列的網頁
- 成功的網頁搜尋結束於此
以下是可用的 VMAR 和 VM 對應系統呼叫:
zx_vmar_allocate()
- 建立新的子項 VMARzx_vmar_map()
:將 VMO 對應至程序zx_vmar_unmap()
- 從程序取消對應記憶體區域zx_vmar_protect()
- 調整記憶體存取權限zx_vmar_destroy()
- 刪除 VMAR 及其所有子項
另請參閱虛擬記憶體位址地區參考資料。
VMOS
VMO 是記憶體位元組的容器 這類實體含有實體頁面,可透過 VM 對應功能對應到位址空間。 以下是 VMO 的系統呼叫:
zx_vmo_create()
:建立新的 VMOzx_vmo_create_child()
- 建立新的子 VMOzx_vmo_create_physical()
:建立新的實體 VMOzx_vmo_get_size()
- 取得 VMO 的大小zx_vmo_op_range()
:對 VMO 的範圍執行作業zx_vmo_read()
- 從 VMO 讀取zx_vmo_replace_as_executable()
:製作 VMO 的可執行版本zx_vmo_set_cache_policy()
- 為 VMO 保留的網頁設定快取政策zx_vmo_set_size()
:調整 VMO 的大小zx_vmo_write()
- 寫入 VMO
另請參閱虛擬記憶體物件參考資料。
虛擬記憶體管理員 (VMM)
虛擬記憶體管理員 (VMM) 負責維護程序位址 包括:
- 針對虛擬位址範圍,提供指向實際頁面的指標 物件之間會對應各個項目。
- 請確認位址範圍已設定正確的存取保護機制位元。
做法是管理 VMAR、VM 對應、VMO 和 「硬體頁面」表格。另請參閱 VMM 原始碼。
程序開始時,整個位址空間會顯示為一個 VMAR。 系統會對應位址空間的不同部分,因此 VMAR 階層樹狀結構 資料值建立及刪除樹狀結構中的節點時,會成為 VMAR 和 VM 系統隨即會建立並刪除對應關係。
節點代表 VMAR 或 VM 對應:
- VMAR 會指向其他 VMAR 和 VM 的子項清單 落在父項 VMAR 位址範圍內的對應。
- VM 對應會指向該 VMO 中對應的範圍 位址範圍
進一步瞭解 以視覺化方式呈現根 VMAR 的記憶體用量
VMM 會使用
位址空間版面配置隨機化
控制在位址空間內建立新的 VMAR 的位址範圍。
aslr.entropy_bits
敬上
核心指令列選項可用於控制熵的位元數
隨機排列順序熵越多,就會產生稀疏器位址空間,
以擴大 VMAR 和 VM 對應關係
實體記憶體管理工具 (PMM)
實體記憶體管理工具 (PMM) 會將系統上所有可用的實體記憶體 (RAM) 壓縮為頁 藉此控管機器的執行狀況 負責為 VMO 提供免費的實體頁面 他們需要的
VMO 會按需求分頁,即網頁會隨需填入 (已修訂)。 網頁會依照撰寫時的樣子獲得認可。在此之前,未修訂的網頁會 是由系統上的單一實體零網頁所呈現。這可避免 為尚未存取的頁面分配記憶體,或只為尚未存取的網頁分配記憶體 讀取資料
VMO 也能使用 使用者空間呼叫器 根據需求填入 VMO 中的特定內容 例如從磁碟中的檔案讀取的內容 瞭解如何編寫使用者呼叫器。
範例:對應 VMO
如何對應 VMO:
使用
zx_vmar_root_self()
取得程序的根 VMAR 控制代碼。 例如:zx_handle_t vmar = zx_vmar_root_self();
使用
zx_vmo_create(...)
建立 VMO。 這會回傳 VMO 控制代碼,例如:const size_t map_size = zx_system_get_page_size(); zx_vmo_create(map_size, 0, &vmo);
使用
zx_vmar_allocate(...)
在父項 VMAR 中建立子項 VMAR。 這會回傳 VMAR 處理常式及其起始位址,例如:const size_t region_size = zx_system_get_page_size() * 10; zx_vmar_allocate(vmar, ZX_VM_CAN_MAP_READ | ZX_VM_CAN_MAP_WRITE, 0, region_size, ®ion, ®ion_addr);
這是選擇性步驟。您也可以將 VMO 直接對應至父項
使用
zx_vmar_map(...)
在 VMAR 中對應 VMO。 此方法會傳回目前對應至 VMAR 的 VMO 起始位址, 範例:zx_vmar_map(region, ZX_VM_PERM_READ | ZX_VM_PERM_WRITE, 0, vmo, 0, map_size, &map_addr);
範例:存取 VMO 對應
在先前的範例中
假設 zx_vmar_map()
傳回 map_addr
0x4000,
如要存取對應地址 0x4000
程式碼可能如下所示:
zx_vmar_map(...&addr); // addr = 0x4000
auto arr = reinterpret_cast<int*>(addr);
arr[0] = 1; // page fault
指標解除參照會導致頁面錯誤。 為瞭解決頁面錯誤,核心會執行下列操作:
- 在開始程序的 VMAR 樹狀結構中搜尋 0x4000 位址
位於
root_vmar
,直到找到包含該位址的 VM 對應為止。 - VM 對應會包含 VMO 的參照 以及 VMO 頁面清單中的偏移值 對應第一個地址。 查詢與位址 0x4000 相對應的 VMO 偏移量。
- 如果 VMO 在該偏移位置沒有頁面,請分配新的頁面。 假設該網頁的實際地址為 0xf000。
- 將虛擬地址 0x4000 的結果新增至實際地址 0xf000
「硬體頁面」表格
ArchVmAspace
、 代表架構專屬頁面表格 追蹤虛擬機器所使用的虛擬與實際地址對應 MMU。