JOS Lab2 保护模式下的内存映射机制:段机制 页机制

在Lab2中 我们将要建立基本的保护模式下的内存管理机制,我们有必要先弄清楚保护模式下是如何管理内存的。


概述

80x86在保护模式下内存机制主要分为段机制页机制,其中页机制是基于段机制的。

关于一个内存管理机制,有两个大的方面我们需要关心,一个是如何寻址,另一个是如何确定权限(即实现所谓保护)。段机制和页机制都提供了一定的寻址功能,但是其中有一定的重复。JOS没有使用段机制中的寻址功能,所有寻址只和页机制有关。段机制和页机制共同决定权限。


段机制

概述:

通过段选择符(selector)从段描述符表中获得段描述符,再加上offset,可以映射得到linear address(线性地址)。
这里写图片描述

段描述符:

Descriptor Table(段描述符表)是一个段描述符的数组,Segment Descriptor(段描述符)定义虚拟内存段的基本信息,如base,limit(从哪里开始,从哪里结束),访问权限等。具体的段描述符信息如下图:
这里写图片描述
由图可以看出,段描述符是一个64位长的符在JOS中我们通过inc/mmu.h下的SEG宏来快速定义。

#define SEG(type, base, lim, dpl) (struct Segdesc)          \
{ ((lim) >> 12) & 0xffff, (base) & 0xffff, ((base) >> 16) & 0xff,   \
    type, 1, dpl, 1, (unsigned) (lim) >> 28, 0, 0, 1, 1,        \
    (unsigned) (base) >> 24 }

type:访问权限(可执行STA_X,可读STA_R,可写STA_W)
base:基地址,在JOS中所有段描述符的基地址都定义为0
lim:长度,都定义为0xFFFFFFFF
dpl : DESCRIPTOR PRIVILEGE LEVEL(描述符权限级别),在*nix系统中分为0-3(越低权限越高),0为kernel态,1-3为用户态。在JOS中定义了0(kernel态)和3(user态)(Linux也是这样定义的)。

在kern/env.c中定义了段描述符表gdc

struct Segdesc gdt[NCPU + 5] =
{
    // 0x0 - unused (always faults -- for trapping NULL far pointers)
    SEG_NULL,

    // 0x8 - kernel code segment
    [GD_KT >> 3] = SEG(STA_X | STA_R, 0x0, 0xffffffff, 0),

    // 0x10 - kernel data segment
    [GD_KD >> 3] = SEG(STA_W, 0x0, 0xffffffff, 0),

    // 0x18 - user code segment
    [GD_UT >> 3] = SEG(STA_X | STA_R, 0x0, 0xffffffff, 3),

    // 0x20 - user data segment
    [GD_UD >> 3] = SEG(STA_W, 0x0, 0xffffffff, 3),

    // Per-CPU TSS descriptors (starting from GD_TSS0) are initialized
    // in trap_init_percpu()
    [GD_TSS0 >> 3] = SEG_NULL
};
段选择符(selector):

这里写图片描述
这里写图片描述


公式1:Linear Address=Base+Offset
由于段描述符定义的base=0,所以有
公式2:Linear Address=Offset

页机制

概述:

页机制通过多层页表,把Linear Address映射到实际内存地址空间。

Linear Address:

这里写图片描述

线性地址(linear address)是一个32位长的数,DIR(10位长)是在第一层页表中的index,PAGE是在第二层页表中的index(10位长),OFFSET是在该页中的偏移量(12位长)。由此我们可以看出,第一层页表有1024项,第二层页表也有1024项,一个单独的页(one page)的大小时4K。

具体的寻址方式见:
这里写图片描述
其中CR3是一个寄存器,用来存放第一层页表(Page Directory)的基地址。


总结:由于禁用了段机制的寻址功能(只用来做访问控制),实际用户和开发者使用的(虚拟)地址(virtual memory)即等于线性地址(Linear Address),再通过两层页表,最终映射到了物理地址(Physical Address)空间。


参考:

1.Intel 80386 Programmer’s Reference Manual
2.GuoJing’s Blog/linux-kernel-architecture/segment-selector

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值