内存管理---分页机制
创始人
2024-03-12 18:55:39
0

目录

物理内存管理带来的问题

直接映射

一级页表

二级页表


参考:

(C语言内存七)分页机制究竟是如何实现的? - Smah - 博客园

物理内存管理带来的问题

  • 比如4GB的flash, 如果应用程序可直接访问物理内存,那么可能一个非法的操作会导致程序无法正常工作,常见于跑裸机的单片机程序。
  • 而操作系统为了保护程序可正常运行,引入了虚拟内存的概念,换句话说:对应用程序来讲:操作的内存是虚拟内存。
  • 而操作系统做的事情就是把虚拟内存映射到物理内存。那么如何映射就是需要设计的关键。即物理地址 = func_map(虚拟内存); 这个func_map就叫页表,以下有常见的现有的设计实现

直接映射

  • 页表方案:比如一个4GB的flash,那么需要2^32个地址去访问,而地址从0-2^32,这么大的数需要4字节的数据去存,也就是需要 uint64 flash[2^32]; 
  • 内存开销:这样的数组去访问每个物理地址。这样的数组有多大呢? 4*4GB = 16GB, 就是说访问4GB的flash需要16GB的内存,这肯定是不可以的。

这一样的实现是 physical_addr = flash[virtual_addr];

一级页表

  • 页表方案:
  1. 为了减少内存开销,有了分页机制:把4GB的flash,分为一页4K。
  2. 如果需要访问flash的物理地址,需要页数+页内偏移。
  3. 一页大小为4K,需要访问所有内存,即0-2^12,即至少12位来得到偏移量
  4. 而访问所有的页数:4GB/4K = 2^32/ 2^12 = 2^20页,故需要20位来访问所有的页
  5. 综上:可设计虚拟地址的31-12位得到页表数,11-0得到页内的偏移。

这样的实现通过虚拟地址访问物理地址的伪代码如下:

#define PAGE_SIZE 2^12 // 4K大小的页
//通过传入的virtual_addr访问物理地址
uint32 Func_map(uint32 virtual_addr)
{// 得到高20位uint32 page_Number = virtual_addr & 0xfffff000;  // 得到低12位uint32 ofst= virtual_addr & 0x00000fff; // 得到页表位置uint32 phy_page = page_Number * PAGE_SIZE;// 返回页表内存+偏移得到具体的物理位置return phy_page + ofst;
}
  • 页表的开销:一个虚拟地址为4字节,共需要4GB/4K = 2^32/ 2^12 = 2^20个虚拟地址,一共占4*2^20字节== 4M,即维护一级页表:可访问4G的物理内存,开销为4M

二级页表

前人又设计了二级页表实现:

  1. 将虚拟地址分割为三分部,高10位作为页目录中元素的下标,中间10位作为页表中元素的下标,最后12位作为页内偏移

  2. 其中通过页表下标和页内偏移得到物理内存地址和一级页表的方法是一样的。
  3. 一级页表可知:4M的页表开销,并不需要完全使用(物理内存用不到4G)。而二级页表就是通过页目录来管理。需要使用物理内存,则通过页目录记录下页表,通过页表访问一段内存。
  4. 页表需要4M来感知4G的物理内存,而页目录需4K+ 页目录4M--》可访问4K个页表。
  5. 一个页目录下标可访问一组页表(页表下标是10位,共2^10个),即可访问2^10个页表,而每个页表配合页内偏移12位( 2^12的地址,即4M的内存),所以一个页目录可访问2^12 * 2^10=4M的内存。
  6. 而一共可以有2^10个页目录,而一个页目录可用2^10个页表,而一个页表占4K,故共可访问2^10 * 2^10 * 4K = 4GB 的物理内存。
  7. 伪代码如下:
    uint32 g_pageDir[2^12]; //4K的页目录//传入虚拟地址,得到物理地址
    uint32 func_map(uint32 virtual_addr)
    {// 得到高10位uint32 page_dir= virtual_addr & 0xffC00000;  // 得到中10位uint32 page_tbl= virtual_addr & 0x002ff000; // 得到低12位uint32 ofst= virtual_addr & 0x00000fff;uint32_t* pageTable = g_pageDir[page_dir];//指向页表块uint32 phy_addr = pageTable [page_tbl];  //指向物理块return (phy_addr  + ofst);  //得到物理内存的具体位置
    }

综上:可通过32位的虚拟地址 + 二级页表访问4GB的物理内存,

  • 为什么需要额外的4K的页目录来操作物理内存呢?因为实际使用中,我们并不需要用完4GB的flash, 所以并不需要4M的开销。用多少页表生成多少,而需要的额外开销就是找到页表index的页目录,远小于4M+4K,更加灵活。

相关内容

热门资讯

AWSECS:访问外部网络时出... 如果您在AWS ECS中部署了应用程序,并且该应用程序需要访问外部网络,但是无法正常访问,可能是因为...
AWSElasticBeans... 在Dockerfile中手动配置nginx反向代理。例如,在Dockerfile中添加以下代码:FR...
银河麒麟V10SP1高级服务器... 银河麒麟高级服务器操作系统简介: 银河麒麟高级服务器操作系统V10是针对企业级关键业务...
北信源内网安全管理卸载 北信源内网安全管理是一款网络安全管理软件,主要用于保护内网安全。在日常使用过程中,卸载该软件是一种常...
AWR报告解读 WORKLOAD REPOSITORY PDB report (PDB snapshots) AW...
AWS管理控制台菜单和权限 要在AWS管理控制台中创建菜单和权限,您可以使用AWS Identity and Access Ma...
​ToDesk 远程工具安装及... 目录 前言 ToDesk 优势 ToDesk 下载安装 ToDesk 功能展示 文件传输 设备链接 ...
群晖外网访问终极解决方法:IP... 写在前面的话 受够了群晖的quickconnet的小水管了,急需一个新的解决方法&#x...
不能访问光猫的的管理页面 光猫是现代家庭宽带网络的重要组成部分,它可以提供高速稳定的网络连接。但是,有时候我们会遇到不能访问光...
Azure构建流程(Power... 这可能是由于配置错误导致的问题。请检查构建流程任务中的“发布构建制品”步骤,确保正确配置了“Arti...