操作系统,二级页表存储方式
标签(空格分隔): 操作系统
题目:
有一个24bit的操作系统,
4kb / page (每个页表占4kb),
4byte / page table entry(每个页表项占4b)
问:给你一个虚拟地址,要求你求出其在内存中的物理地址
解:
由每个页表占4kb,可得
4kb=212
24bit4kb=212=4096
所以映射表,由 [0 ~ 4095] 的页表项组成,每个页表项占4byte
一级页表的情况:
现在有虚拟地址virArr
[0,224−1]
每个页表 pageTable = 4096
页号 virPageNo = virAddr / 4096
位偏移 offset = virAddr % 4096
物理地址块号 phyPageNo,要从映射表中查询
最后实际的物理地址
phyPage=phyPageNo∗4096+offset
程序实现如下
#define PAGE_SIZE 4096
int pageTable[PAGE_SIZE];
unsigned int getPhyAddr(unsigned int virAddr) {
virAddr &= 0xffffff; // 保留虚拟地址的后24位
int virPageNo = virAddr / PAGE_SIZE;
int offset = virAddr % PAGE_SIZE;
int phyPageNo = pageTable[virPageNo];
return phyPageNo * PAGE_SIZE + offset;
}
二级页表的情况:
对于要求连续的内存空间来存放页表的问题,可利用将页表进行分页,并离散地将各个页面分别存放在不同的物理块中的办法来加以解决,同样也要为离散分配的页表再建立一张页表,称为外层页表,在每个页表项中记录了页表页面的物理块号。
下面我们仍以前面的24位逻辑地址空间为例来说明。
由于总容量16kb的页表,太大了,所以要拆分成4个1kb的页表
每个页表项 4byte = 4096 bit
现在 24 位的操作系统被分为
index1(内层页表) | index2(外层页表) | offset(页内偏移) |
---|---|---|
2 bit | 10 bit | 12 bit |
程序实现如下
#define PAGE_SIZE 4096
typedef int ARRAY[1024]; //一级页表
ARRAY *outTable[1024];
//初始化,4个二级页表
void init() {
for(int i = 0; i < 4; i++) {
outTable[i] = (ARRAY*)malloc(sizeof(ARRAY));
}
}
unsigned int getPhyAddr(unsigned int virArr) {
virAddr &= 0xffffff; // 保留虚拟地址的后24位
int index1 = virAddr >> 22; //获取一级页表索引
int index2 = (virAddr >> 12) & 0x3ff; //获取二级页表索引
int offset = virAddr & 0x3ff; // 获取页内偏移 virAddr % 4096
int phyPageNo = outTable[index1][index2];
return phyPageNo * PAGE_SIZE + offset;
}