现在的位置: 首页 > 综合 > 正文

lab2 内存管理

2014年02月01日 ⁄ 综合 ⁄ 共 4977字 ⁄ 字号 评论关闭

关于lab2中对内存的分配:

示意图如下:

/*
 * Virtual memory map:                                Permissions
 *                                                    kernel/user
 *
 *    4 Gig -------->  +------------------------------+
 *                     |                              | RW/--
 *                     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 *                     :              .               :
 *                     :              .               :
 *                     :              .               :
 *                     |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~| RW/--
 *                     |                              | RW/--
 *                     |  Physical Memory             | RW/--
 *                     |                              | RW/--
 *    KERNBASE ----->  +------------------------------+
 *                     |  Kernel Virtual Page Table   | RW/--    PDMAP
 *    VPT,KSTACKTOP--> +------------------------------+                 --+
 *                     |        Kernel Stack          | RW/--  KSTKSIZE   |
 *                     | - - - - - - - - - - - - - - -|                 PDMAP
 *                     |       Invalid memory         | --/--             |
 *    ULIM     ------> +------------------------------+                 --+
 *                     |      R/O User VPT            | R-/R-    PDMAP
 *    UVPT      ---->  +------------------------------+
 *                     |        R/O PAGES             | R-/R-    PDMAP
 *    UPAGES    ---->  +------------------------------+
 *                     |        R/O ENVS              | R-/R-    PDMAP
 * UTOP,UENVS -------> +------------------------------+
 * UXSTACKTOP -/       |      user exception stack    | RW/RW   BY2PG 
 *                     +------------------------------+
 *                     |       Invalid memory         | --/--   BY2PG
 *    USTACKTOP  ----> +------------------------------+
 *                     |     normal user stack        | RW/RW   BY2PG
 *                     +------------------------------+
 *                     |                              |
 *                     |                              |
 *                     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 *                     .                              .
 *                     .                              .
 *                     .                              .
 *                     |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~|
 *                     |                              |
 *    UTEXT ------->   +------------------------------+
 *                     |                              |  2 * PDMAP
 *    0 ------------>  +------------------------------+
 */


具体的意义:

内核与用户的分界:ULIM

注意在UTOP-ULIM这段用户与内核的权限是一样的,都只有读的权限。在这里放着一些核心的数据结构。这样做可以让用户读取这些结构。

可以看到,在i386_vm_init(void)中我们完成了下面这些布局:

[KSTACKTOP-PDMAP, KSTACKTOP)   kernel stack,部分无用        bootstack

[KERNBASE, 2^32 - 1]                                   physical memory              [0,2^32-1]

[UPAGES,UPAGES+ ROUND(npage*sizeof(struct Page), BY2PG)]  user page pages

[UENVS,UENVS+ ROUND(NENV*sizeof(struct Env), BY2PG)]   user envs envs

 

IA-32结构采用段页式的内存管理,而页式管理是可选的。

通过段式管理把一个虚拟地址(virtual address)转换成一个线性地址(liner address)。如果没有页式管理,那么把这个线性地址直接转换到物理地址。否则通过页面映射到一个物理地址。

通过设置PG (paging) flag. Bit 31 of CR0 (available in all IA-32 processors beginning with the

Intel386 processor).来开启页面映射。

在这个试验中所做的是一开始并没有打开页面映射机制,通过把段寄存器设置成-KERNBASE完成了从一个内核的链接地址(0xf0100000开始)到物理地址的一个映射的过程(就像我们在试验一中所做的那样)。完成了页表的初始化后开始打开页面映射机制,把段寄存器都清零,从而实现了KERNBASE+x => KERNBASE+x => x这样似乎关掉了段映射机制的地址映射过程。

 

关于页面的访问权限:

x86的结构是通过设置页表项的相关位来决定页的访问权限的:

下面是在/inc/mmu.h中定义的访问权限的宏定义:

/* Page Table/Directory Entry flags

 *   these are defined by the hardware

 */

#define PTE_P 0x1               /* Present */

#define PTE_W 0x2               /* Writeable */

#define PTE_U 0x4               /* User */

#define PTE_PWT 0x8             /* Write-Through */

#define PTE_PCD 0x10            /* Cache-Disable */

#define PTE_A 0x20              /* Accessed */

#define PTE_D 0x40              /* Dirty */

#define PTE_PS 0x80             /* Page Size */

#define PTE_MBZ 0x180           /* Bits must be zero */

#define PTE_USER 0xe00          /* Bits for user processes */

#define PTE_FLAGS 0xfff         /* All flags */

在这个试验中我们需要设置的位只是PTE_P, PTE_W, PTE_U这三个位

PTE_P: 该页是否存在。由操作系统或者应用程序来设置

PTE_W: 0代表只读,1代表可读写。

PTE_U: 0需要supervisor权限,1只需user权限

If the processor is currently operating at a CPL of 0, 1, or 2, it is in supervisor mode; if it is operating at a CPL of 3, it is in user mode. When the processor is in supervisor mode, it can access all pages; when in user mode, it can access only user-level pages.                                                                                                                       -- System Programming Guide

这样就可以理解为什么要像注释中给出的那样设置权限了,也就可以理解为什么linux只是使用了CPL03这两个级别了

例如

Permissions: kernel RW, user NONE

就是置PTE_WPTE_P位就可以了

而对于下面这段代码就应该这样写:

//////////////////////////////////////////////////////////////////////

// Make 'pages' point to an array of size 'npage' of 'struct Page'.  

// Map this array read-only by the user at UPAGES (ie. perm = PTE_U | PTE_P)

// Permissions:

//    - pages -- kernel RW, user NONE

//    - the image mapped at UPAGES  -- kernel R, user R

// Your code goes here:

pages = alloc ( ROUND(npage*sizeof(struct Page), BY2PG), BY2PG , 1 ) ;

boot_map_segment ( pgdir, pages , ROUND(npage*sizeof(struct Page), BY2PG), PADDR(pages), PTE_W ) ;

boot_map_segment  ( pgdir, UPAGES , ROUND(npage*sizeof(struct Page), BY2PG), PADDR(pages) , PTE_U ) ;


 

【上篇】
【下篇】

抱歉!评论已关闭.