内存管理---分页机制
创始人
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,更加灵活。

相关内容

热门资讯

前端-session、jwt 目录:   (1)session (2&#x...
linux入门---制作进度条 了解缓冲区 我们首先来看看下面的操作: 我们首先创建了一个文件并在这个文件里面添加了...
关于测试,我发现了哪些新大陆 关于测试 平常也只是听说过一些关于测试的术语,但并没有使用过测试工具。偶然看到编程老师...
前缀和与对数器与二分法 1. 前缀和 假设有一个数组,我们想大量频繁的去访问L到R这个区间的和,...
nodejs:本地安装nvm实... 一、背景-使用不同版本node的原因 vue3+ts、nuxt3版本,node...
JAVA集合知识整理 Java集合知识整理 HashMap相关 HashMap的底层数据结构:jdk1.8之...
无刷直流电机介绍及单片机控制实... 无刷直流电机介绍及单片机控制实例前言基本概念优势与劣势使用寿命基本结构使用单片机控制实例电子调速器&...
fwdiary(2) dp2 1.传纸条  AcWing 275. 传纸条 - AcWing 走两条路,走一条最大的...
常用的DOS命令 常用的DOS命令 DOS(Disk Operating System,磁...
<C++> 类和对象(下) 1.const成员函数将const修饰的“成员函数”称之为const成员函数,cons...