zoukankan      html  css  js  c++  java
  • 操作系统开发系列—6.内存分页机制

    a.概述

    页尺寸是4KB,页表每个表项占4字节,CR3寄存器给出了页目录的物理基地址;页目录给出了所有页表的物理地址,而每个页表给出了它所包含的页的物理地址。

    处理器的页部件专门负责线性地址到物理地址的转换工作。它首先将段部件送来的32位线性地址截成3段,分别是高10位、中间的10位和低12位。高10位是页目录的索引,中间10位是页表的索引,低12位则作为页内偏移来用。

    假如某个任务加载后,操作系统根据它的实际情况在其4GB虚拟地址空间里创建了一个段,段的起始地址为0x00800000,段界限值为0x5000,字节粒度。当该任务执行时,段寄存器DS指向该段。又假设执行了下面一条指令:

    mov edx,[0x1050]

    此时,段部件会输出线性地址0x00801050。在没有开启分页机制时,这就是要访问的物理内存地址,但现在开启了分页机制,这是一个虚拟地址,要经过页部件的转换才能得到物理地址。

    当前任务页目录的物理地址在处理器的CR3寄存器中,假设它的内容为0x00005000.段管理部件输出的线性地址是0x00801050,其二进制的形式为0000 0000 1000 0000 0001 0000 0101 0000.高10位为0000000010,也就是十六进制的0x002,它是页目录表内的索引,处理器将它乘以4(因为每个目录项为4字节),作为偏移量访问页目录。最终,处理器从物理地址00005008处取得页表的物理地址0x08001000.

    页目录表的表项简称PDE,页表的表项简称PTE。分页机制是否生效的开关位于cr0的最高位PG位。如果PG=1,则分页机制生效。

    b.源码

    PageDirBase		equ	200000h	; 页目录开始地址: 2M
    PageTblBase		equ	201000h	; 页表开始地址: 2M+4K
    
    LABEL_DESC_PAGE_DIR: Descriptor PageDirBase, 4095, DA_DRW;Page Directory
    LABEL_DESC_PAGE_TBL: Descriptor PageTblBase, 1023, DA_DRW|DA_LIMIT_4K;Page Tables
    
    SelectorPageDir		equ	LABEL_DESC_PAGE_DIR	- LABEL_GDT
    SelectorPageTbl		equ	LABEL_DESC_PAGE_TBL	- LABEL_GDT
    
    ; 启动分页机制 --------------------------------------------------------------
    SetupPaging:
        ...
    

    PageDirBase和PageTblBase指定了页目录表和页表在内存中的位置。页目录表位于地址2MB处,有1024个表项,占用4KB空间。

    PDE(左)和PTE(右)格式如下:

    cr3的结构如下图,cr3又叫PDBR,它的高20位将是页目录表首地址的高20位,页目录表首地址的低12位会是零,也就是说,页目录表会是4KB对齐的。类似的,PDE中的页表基址以及PTE中的页基址也是用高20位来表示4KB对齐的页表和页。

    运行结果如下:

    d.分页机制的作用

    LinearAddrDemo	equ	00401000h
    ProcFoo		equ	00401000h
    ProcBar		equ	00501000h
    ProcPagingDemo	equ	00301000h
    
    	call	SetupPaging		; 启动分页
    	call	SelectorFlatC:ProcPagingDemo
    	call	PSwitch			; 切换页目录,改变地址映射关系,和SetupPaging代码差不多
    	call	SelectorFlatC:ProcPagingDemo
    
    PagingDemoProc:
    OffsetPagingDemoProc	equ	PagingDemoProc - $$
    	mov	eax, LinearAddrDemo
    	call	eax
    	retf
    LenPagingDemoAll	equ	$ - PagingDemoProc
    
    foo:
    OffsetFoo		equ	foo - $$
    	mov	ah, 0Ch			; 0000: 黑底    1100: 红字
    	mov	al, 'F'
    	mov	[gs:((80 * 17 + 0) * 2)], ax	; 屏幕第 17 行, 第 0 列。
    	mov	al, 'o'
    	mov	[gs:((80 * 17 + 1) * 2)], ax	; 屏幕第 17 行, 第 1 列。
    	mov	[gs:((80 * 17 + 2) * 2)], ax	; 屏幕第 17 行, 第 2 列。
    	ret
    LenFoo			equ	$ - foo
    
    bar:
    OffsetBar		equ	bar - $$
    	mov	ah, 0Ch			; 0000: 黑底    1100: 红字
    	mov	al, 'B'
    	mov	[gs:((80 * 18 + 0) * 2)], ax	; 屏幕第 18 行, 第 0 列。
    	mov	al, 'a'
    	mov	[gs:((80 * 18 + 1) * 2)], ax	; 屏幕第 18 行, 第 1 列。
    	mov	al, 'r'
    	mov	[gs:((80 * 18 + 2) * 2)], ax	; 屏幕第 18 行, 第 2 列。
    	ret
    LenBar			equ	$ - bar
    

     ProcFoo的值处的地址对应的是foo:函数,ProcBar的值处的地址对应的是bar:函数。PSwitch和SetupPaging差不多,只是紧接着程序增加了改变线性地址LinearAddrDemo对应的物理地址的语句。改变后,LinearAddrDemo将不再对应ProcFoo,而是对应ProcBar。切换的过程是通过改变cr3的值完成的。

    一个码农的日常 

    源码

  • 相关阅读:
    Error creating document instance. Cause: org.xml.sax.SAXParseException; lineNumber: 1; columnNumber: 1; 前言中不允许有内容。
    [Pulgin] jQuery插件之ajaxFileUpload
    [Plugin] JQuery.uploadify上传文件插件的使用详解For ASP.NET
    [Plugin] 文件上传利器SWFUpload使用指南
    [HTML] 微信开发之移动手机WEB页面(HTML5)Javascript实现一键拨号及短信发送功能
    [JavaEE] IBM
    [TB-Technology] 淘宝在数据处理领域的项目及开源产品介绍
    [Hacker] 端口大全
    [.Net] DataTable添加列和行的三种方法
    [.Net] 导出Excel中身份证等数字串的解决方式
  • 原文地址:https://www.cnblogs.com/joey-hua/p/5382690.html
Copyright © 2011-2022 走看看