我正在使用mmapLinux 系統呼叫分配記憶體。
mov x5, 0 ; offset is zero
mov x4, -1 ; no file descriptor
mov x3, 0x22 ; MAP_PRIVATE MAP_ANONYMOUS
mov x2, 3 ; PROT_READ PROT_WRITE
mov x1, 4096 ; initial region size in bytes
mov x0, 0 ; let Linux choose region address
mov x8, 222 ; mmap
svc 0
是否可以增加分配的記憶體區域的大小以保留其起始地址和內容?如何正確地做到這一點?
uj5u.com熱心網友回復:
在 Linux 上,使用mremap(2)Linux 特定的系統呼叫而不 MREMAP_MAYMOVE擴展現有映射,不考慮將這些物理頁面重新映射到不同的虛擬地址的選項,其中有足夠的空間用于更大的映射。
如果您想要擴展的頁面已經存在其他映射,它將回傳一個錯誤。(與mmap(MAP_FIXED)將默默替換這些映射不同。)
如果您使用 asm 撰寫,則對非 Linux 的可移植性幾乎不相關;其他作業系統將有不同的呼叫號碼,也許ABI的,所以只是仰望__NR_mremap的asm/unistd.h,并得到flags從圖案sys/mman.h。
僅使用可移植的 POSIX 呼叫,mmap()在現有映射之后使用非 NULL 提示地址 = ,但沒有MAP_FIXED; 如果頁面空閑,它將選擇該地址(正如@datenwolf 所說,與較早的映射合并為一個長范圍)。否則它會選擇其他地方。(然后你必須得到munmap那個最終不是你想要的映射。)
有一個特定于 Linux 的mmap選項:MAP_FIXED_NOREPLACE將回傳錯誤而不是映射到與提示不同的地址。早于 4.17 的內核不知道該標志,并且通常會將其視為除了 之外沒有使用其他標志MAP_ANONYMOUS,因此您應該根據提示檢查回傳值。
不要使用MAP_FIXED_NOREPLACE | MAP_FIXED; 這將MAP_FIXED在舊內核上起作用,也可能在知道MAP_FIXED_NOREPLACE.
假設您知道要擴展的映射的起點以及所需的新總大小,mremap則是比 更好的選擇mmap(MAP_FIXED_NOREPLACE)。它至少從 Linux 2.4 開始就得到支持,即幾十年,并自動保持現有的映射標志和權限(例如 MAP_PRIVATE、PROT_READ|PROT_WRITE)
如果您只知道現有映射的結束地址,mmap(MAP_FIXED_NOREPLACE)可能是一個不錯的選擇。
uj5u.com熱心網友回復:
如果您的原始區域后面有可用的虛擬地址空間,只需在原始區域后面創建一個額外的 mmap-ed 區域,使用MAP_FIXED | MAP_FIXED_NOREPLACE標志和相同的權限。如果兩個區域的頁面大小相同,它們將合并為單個映射。
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/352222.html
