虚拟地址
看了《操作系统真象还原》中关于虚拟地址的部分,故此做一下笔记,以做备忘。
页表项及页目录项
- 第0位:Present,表示是否在内存中,1表示在内存中,0表示不在内存中
- 第1位:RW,读写位,1表示可读可写,0表示只可读
- 第2位:普通用户/超级用户位,1表示普通用户(0,1,2,3特权级均可访问),0表示超级用户(仅0,1,2特权级可访问)(这里的特权级既保护模式下的特权级)
- 第3位:PWT,页级通写位,1表示使用write-through缓冲策略,0表示使用Write-back缓冲策略
- 第4位:PCD,页级高速缓存禁止位,1表示页或页表不可以被缓冲,0表示页或页表可以被缓冲
- 第5位:Accessed,访问位,1表示该页被CPU访问过,0表示还未被CPU访问
- 第6位:Dirty,1表示CPU对该页执行过写操作,主要是在换出内存时有用
- 第7位:PAT,页属性表位,直接置0(作用尚未明确)。
- 第8位:Global,1表示全局页,该页在高速缓存TLB中一直保存,0表示非全局页
虚拟地址到物理地址的转化([]表示取地址):
页表基地址 = [(页目录项基地址 + (虚拟地址 » 22) * 4)] & 0xfffff000
物理地址 = [(页表基地址 + (虚拟地址 » 12 & 0x3ff) * 4)] & 0xfffff000 + 虚拟地址 & 0xfff
进入虚拟地址
首先获取物理地址大小
可以用int 0x15中断获得,参数如下:
-
ARDS结构体
偏移量 描述 0 基地址低32位 4 基地址高32位 8 内存大小低32位 12 内存大小高32位 16 本段内存属性,1可用,2不可用 -
int 0x15参数
寄存器 描述 eax 0xe820子功能号,返回时会被设置为ebx的值 ebx ARDS后续值,初始为0,当没有更多信息时返回为0 ecx ARDS结构大小,指示BIOS写入的大小,一般为20 edx 0x534d4150,固定值 edi 缓冲区,指向ARDS结构体的地址 -
可用下面代码获得内存大小
Get_Men: push bp mov bp,sp sub sp,0x200 mov di,sp sub sp,4 mov dword [bp-0x204],0 mov edx,0x534d4150 xor ebx,ebx mem_loop: mov eax,0xe820 mov ecx,20 int 0x15 jc mem_failed inc dword [bp-0x204] add edi,ecx cmp ebx,0 jnz mem_loop sub edi,ecx mov ecx,[bp-0x204] xor eax,eax mem_max: mov edx,[edi] add edx,[edi+8] cmp eax,edx jge next_one mov eax,edx next_one: sub edi,20 loop mem_max leave ret mem_failed: xor eax,eax leave ret
cr3寄存器保存页目录表的物理地址,cr0寄存器第32位为1表示开启虚拟地址
- 下面代码将低4M虚拟内存映射到低4M物理内存
set_virtual_addr: mov eax,0x100000|ADDR_P|ADDR_RW mov [VIRTUAL_DIR_TABLE],eax mov ecx,1023 mov edi,4 loop_zero: mov dword [edi],0 add edi,4 loop loop_zero mov eax,0 | ADDR_P | ADDR_RW mov edi,0x100000 mov ecx,1024 set_virtual_table: mov [edi],eax add eax,0x1000 add edi,4 loop set_virtual_table mov eax,VIRTUAL_DIR_TABLE mov cr3,eax mov eax,cr0 or eax,0x80000000 mov cr0,eax