c - 如何创建物理和虚拟页面?
问题描述
我正在尝试使用一些示例创建一个物理和虚拟页面。我试图了解物理页面地址是如何确定的。我在这里有几个问题。
我们如何知道页面信息存储在哪里?我猜如果我们将虚拟地址除以
PAGE_SIZE
我们将得到页码。即val = ((size_t)*virtAddr)/PAGE_SIZE;
,但我不明白为什么我们要乘以 8?当我这样做
cat /proc/self/pagemap
时,它就挂在那里。似乎它正在阻止呼叫。当我的应用程序获取文件描述符时,它如何能够从中脱颖而出?为什么要乘以
PAGE_SIZE * pageInfo
得到物理地址?这种关系是怎么产生的?背后的场景是什么?
这是我的代码。
#include <sys/mman.h> //for mmap and mlock
#include <unistd.h> //for NULL, lseek
#include <stdlib.h> //for exit and for valloc
#include <stdio.h> //for printf
#include <fcntl.h> //for file opening
#include <stdint.h> //for uint32_t
#include <string.h> //for memset
#define PAGE_SIZE 4096 //mmap maps pages of memory, so we must give it multiples of this size
void makeVirtPhysPage(void **virtAddr, void **physAddr)
{
*virtAddr = valloc(PAGE_SIZE); // allocate one page of RAM
//force page into RAM
((int *)*virtAddr)[0] = 1;
//lock it there.
mlock(*virtAddr, PAGE_SIZE);
memset(*virtAddr, 0, PAGE_SIZE); // zero-fill the page for convenience
uint64_t pageInfo;
size_t val;
int file = open("/proc/self/pagemap", 'r');
printf("The virtAddr is %lu\r\n", *virtAddr);
printf("The Page size is %lu\r\n", PAGE_SIZE);
val = ((size_t)*virtAddr)/PAGE_SIZE; // probably getting page number.
val = val * 8;
printf("The val is %lu\r\n", val);
lseek(file, val, SEEK_SET);
read(file, &pageInfo,8);
printf("The pageInfo says %p\r\n", pageInfo);
*physAddr = (void*)(size_t)(pageInfo*PAGE_SIZE); // why multiply by page size?
printf("makeVirtualPhysPage virtual to phys: %p -> %p\r\n", *virtAddr, *physAddr);
}
void freeVirtPhysPage(void *virtAddr)
{
munlock(virtAddr, PAGE_SIZE);
free(virtAddr);
}
int main()
{
void *virtSrcPage, *PhysSrcPage;
makeVirtPhysPage(&virtSrcPage, &PhysSrcPage);
char *srcPage = (char *)virtSrcPage;
srcPage[0] = 'S';
srcPage[1] = 'U';
srcPage[1] = 'P';
srcPage[1] = 'E';
srcPage[1] = 'R';
freeVirtPhysPage(virtSrcPage);
printf("The value of virtSrcPage[0] is %c\r\n", srcPage[0]);
return 0;
}
解决方案
推荐阅读
- php - 仅当 searchstring 不是链接时 preg_replace
- angularjs - Angularjs datepicker在开始日期之后设置结束日期
- python - python: pip install opencv-python 给我错误
- r - 如何在 R 中将 2 位数字转换为小时格式?
- android - 如何中断 Xamarin 表单中的蓝牙文件传输?
- android - 如何根植 Android 9 Android Studio 模拟器以便与应用程序一起使用?
- r - 如何在 R 中创建核密度图网格
- angular - 使用 content-range 标头作为表中 NgbPagination 的 collectionSize
- rancher - 将 Helm Chart 部署到 Rancher 管理的 Kubernetes 集群不会在 GUI 中显示项目中的 pod
- swift - 无法在具有 Self.Index 类型的 Collection 上下标