每个进程都有自己的页表,还是只是将页面条目添加到一个大页表中?
operating-system memory-management virtual-memory page-tables
我试图了解多级页表如何节省内存.根据我的理解,多级页表总共消耗比单级页表更多的内存.
示例:考虑页面大小为64KB且32位处理器的内存系统.页表中的每个条目都是4个字节.
单级页表:表示页面偏移需要16(2 ^ 16 = 64KB)位.所以休息16位用于索引到页表.所以
*页面大小= 2 ^ 16(页数)*4字节(每页表项的大小)= 2 ^ 18字节*
多级页表:在两级页表的情况下,让我们使用前10个最高位来索引到第一级页表.接下来10位索引到第二级页表,其具有页码到帧号映射.其余12位表示页面偏移量.
第二级页表的大小= 2 ^ 10(条目数)*4字节(每个条目的大小)= 4 KB
所有二级页表的总大小= 2 ^ 10(二级页表的数量)*4KB(每个二级页表的大小)= 4 MB
第一级页表的大小= 2 ^ 10(条目数)*(10/8)字节(每个条目的大小)= 1.25 KB
存储第一级和第二级页表所需的总内存= 4 MB + 1.25 KB
因此我们需要更多内存来存储多级页表.
如果是这种情况,多级页表如何节省内存空间?
我的理解是,影子页面表消除了模拟VM内部物理内存的需要.
即.
代替:
客户操作系统 - > VMM +虚拟物理内存 - >主机操作系统 - >主机硬件
只是:
客户操作系统 - > VMM - >主机操作系统 - >主机硬件
影子页表只允许进程正确访问主机硬件的内存.我也不明白页面错误是如何工作的(或者由于所有物理内存都由主机处理,主机负责页面错误,交换等).
考虑具有38位虚拟字节地址,1KB页面和512 MB物理内存的虚拟内存系统.假设有效,保护,脏和使用位总共占用4位,并且所有虚拟页面都在使用中,则本机上每个进程的页表总大小是多少?(假设磁盘地址未存储在页表中.)
我一直在研究分页和页表。我不明白页表的位置。在堆栈交换的答案之一(https://unix.stackexchange.com/questions/487052/where-is-page-table-stored-in-linux)中,据说页表位于内核地址空间中,这是在虚拟内存中(据我所知)。然而,在伊利诺伊大学 ( https://courses.engr.illinois.edu/cs241/sp2014/lecture/09-VirtualMemory_II_sol.pdf ) 的讲座幻灯片中,页表似乎在 RAM 中,也就是物理内存。谁能清楚地告诉我页表的存储位置?
先感谢您。
此设置中的每个 PTE(页表项)都有一个 G 位(G = 全局),它控制该项映射的物理页的范围。
如果设置了 G 位,则该条目对于所有进程都是全局的,并且它们都可以访问它映射的物理页,但须遵守其他访问权限。如果 G 位为零,则该条目不是全局的,而是进程私有的。[内核为其页面设置 G 位,但通过禁用其页面上的 U 位(U = 用户模式)来阻止用户模式访问。]
如果在用户模式 PTE(设置了 U 位的 PTE)上设置 G 位,这不是一种安全漏洞,因为系统上的每个进程现在都可以访问 PTE 映射的页面?
我错过了什么吗?有没有办法在用户模式 PTE 上设置 G 位,但仅在一组受信任的进程中使其全局,而不是系统上的所有进程?我们可以在 PTE 中同时设置 G 和 U 位吗?
我无法理解页面大小和页表条目大小之间的区别。
根据我的理解,Page size 用于将 Page 表等分。称为 Pages 和相同大小的块用于将主内存划分为帧。
页面大小 = 帧大小。
对不起,绘画技巧不佳。这是我对页表的可视化
其中页表条目大小是每个页面条目占用的大小。所以,
页表条目大小 = 页大小。
但是页表条目大小是通过帧号中的位数来计算的。
谁能解释一下页面大小与页表条目大小的区别?为什么页表条目大小是根据帧中的位数而不是页来计算的?
请帮助我想象页表与上述所有组件的精确程度
目前我正在开发一些与研究相关的程序,我需要找到pte一些特定地址的。我的开发环境是Juno r1板(CPU是A53和A57),它运行arm64 Linux内核。
我使用一些典型的页表遍历代码,如下所示:
int find_physical_pte(void *addr)
{
pgd_t *pgd;
pud_t *pud;
pmd_t *pmd;
pte_t *ptep;
unsigned long long address;
address = (unsigned long long)addr;
pgd = pgd_offset(current->mm, address);
printk(KERN_INFO "\npgd is: %p\n", (void *)pgd);
printk(KERN_INFO "pgd value: %llx\n", *pgd);
if (pgd_none(*pgd) || pgd_bad(*pgd))
return -1;
pud = pud_offset(pgd, address);
printk(KERN_INFO "\npud is: %p\n", (void *)pud);
printk(KERN_INFO "pud value: %llx\n", (*pud).pgd);
if (pud_none(*pud) || pud_bad(*pud))
return -2;
pmd = pmd_offset(pud, address);
printk(KERN_INFO "\npmd is: %p\n", (void *)pmd);
printk(KERN_INFO …Run Code Online (Sandbox Code Playgroud) 当条目从 TLB 中驱逐时,页表是否更新?如果是这样,为什么?页表中更新了哪些信息?我认为当被驱逐的页面干净时不需要更新页表。
类似地,在 TLB 中缓存(引入)页面时是否更新了页表?
operating-system cpu-architecture virtual-memory tlb page-tables
首先,我很抱歉问了这么长的问题。
我做了一些模拟建模任务,我需要将用户空间虚拟地址转换为内核空间物理地址。我使用了三种不同的方法,得到了三种不同的结果。你能给我一个建议,什么方法是正确的,为什么它们会提供不同的结果?
CPU:Intel(R) Core(TM) i7-3770 CPU @ 3.40GHz
操作系统:Linux Fedora 22 版(二十二)
内核:4.4.4-200.fc22.x86_64
我阅读了许多不同的来源,但对许多与 2.6 内核版本之前或不与 64 位英特尔架构相关的旧信息感到困惑。
方法一。
据我了解,我只有一种方法可以从用户空间转换地址(VA->PA)。这可以通过使用 /proc/self/pagemap 来完成。该文件通过虚拟页码作为文件中的偏移量提供 PFN(页帧号)。
virtualPageNumber = virtualAddress / systemPageSize;
lseek(pageMapFile, virtualPageNumber * sizeof(void *), SEEK_SET);
size_t bytesRead = read(pageMapFile, &physicalAddressPFN, sizeof(void *));
Run Code Online (Sandbox Code Playgroud)
并且physicalAddressPFN + (virtualAddress - virtualPageNumber)将是物理地址本身。
这种方法为我提供了以下示例地址转换:
Virtual Address : PGD : PUD : PMD : PTE :offset: pagemap value :physical address: PGD address : PUD address : PMD address : PTE address
15920f0: 0: 0: a: 192: …Run Code Online (Sandbox Code Playgroud)