Linux Mapping نطاق الذاكرة الافتراضية إلى نطاق الذاكرة الافتراضية الحالية؟
-
25-09-2019 - |
سؤال
في Linux ، هل هناك طريقة (في مساحة المستخدم) لتعيين نطاق عنوان افتراضي للصفحات الفعلية التي تدعم نطاق العنوان الافتراضي الحالي؟ تسمح وظيفة MMAP () فقط لخريطة الملفات أو الصفحات الفعلية "الجديدة". أحتاج إلى أن أكون قادرًا على فعل شيء كهذا:
int* addr1 = malloc(SIZE);
int* addr2 = 0x60000; // Assume nothing is allocated here
fancy_map_function(addr1, addr2, SIZE);
assert(*addr1 == *addr2); // Should succeed
assert(addr1 != addr2); // Should succeed
المحلول
كنت فضوليًا ، لذا اختبرت فكرة الذاكرة المشتركة المقترحة في تعليقات السؤال ، ويبدو أنها تعمل:
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/mman.h>
#include <assert.h>
#define SIZE 256
int main (int argc, char ** argv) {
int fd;
int *addr1, *addr2;
fd = shm_open("/example_shm", O_RDWR | O_CREAT, 0777);
ftruncate( fd, SIZE);
addr1 = mmap(0, SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
addr2 = mmap(0, SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
printf("addr1 = %p addr2 = %p\n", addr1, addr2);
*addr1 = 0x12345678;
assert(*addr1 == *addr2); // Should succeed
assert(addr1 != addr2); // Should succeed
return 0;
}
(من الواضح أن الرمز الحقيقي سيرغب في التحقق من قيمة إرجاع syscalls للأخطاء والتنظيف بعد نفسه)
نصائح أخرى
إذا كان لديك FD للملف المعين على addr1
, ، يمكنك ببساطة mmap
مرة أخرى في addr2
.
خلاف ذلك ، خاصة Linux remap_file_pages
يمكن تعديل العنوان الظاهري ⇆ ترجمة إزاحة الملف داخل VMA واحد ، مع الحبيبات بحجم الصفحة ، بما في ذلك تعيين إزاحة الملف نفسها إلى عناوين متعددة.
يفتح /proc/self/mem
و mmap
نطاق العناوين الافتراضية التي تحتاجها منها.