段选择符和段寄存器

来源:互联网 发布:淘宝刀具店 编辑:程序博客网 时间:2024/05/17 02:57

段选择符和段寄存器

sujinxiu-linux

 转载地址:http://home.lupaworld.com/home-space-uid-401174-do-blog-id-231280.html

首先看一下段选择符。段选择符为16位。为了方便查找段选择符,CPU提供了段寄存器来存放段选择符。段寄存器有cs, ss, ds, es, fs, gs(为16位),主要的有cs:代码段寄存器。包含程序指令的段;ss:栈段寄存器。指向当前程序栈的段。ds:数据段。指向静态数据或者全局数据段

段选择符的字段如下(相应的图):

 

其中,TI表示是存放在GDT还是存放在LDT,是0表示存放在GDT。否则存放在LDT。

    INDEX表示的是选择索引号。就是用此索引号来在GDT中检索相应的段描述符。

    RPL(requested privilege level)表示的是请求者的特权级。这里的特权指的是访问相应段的权限。在linux里面有用户态和内核态两种。这里的RPL(2位)是因为默认的是4级,linux里面使用的是0级来表示内核态,3级表示用户态。内核态能够访问用户态和内核态的地址空间和数据,用户态不可以访问内核态的数据空间(除了使用系统调用这个接口以外)。

 

具体的段描述符格式如下图:

 

接下来看看段描述符在内核中相应的表示(以下所有源码分析均是2.6.34):

linux/arch/x86/include/asm/desc_defs.h

  13

  14/*

  15 * FIXME: Accessing the desc_struct through its fields is more elegant,

  16 * and should be the one valid thing to do. However, a lot of open code

  17 * still touches the a and b accessors, and doing this allow us to do it

  18 * incrementally. We keep the signature as a struct, rather than an union,

  19 * so we can get rid of it transparently in the future -- glommer

  20 */

  21/* 8 byte segment descriptor */

  22structdesc_struct {

  23        union {

  24                struct {

  25                        unsigned inta;

  26                        unsigned intb;

  27                };

  28                struct {

  29                       u16limit0;

  30                       u16base0;

  31                        unsignedbase1: 8, type: 4, s: 1,dpl: 2,p: 1;

  32                        unsignedlimit: 4, avl: 1, l: 1,d: 1,g: 1,base2: 8;

  33                };

  34        };

  35}__attribute__((packed));

这也就是传说中的8个字节的段描述符。每个段都会有一个段描述符。它描述了段的相应特征。具体的看相应字段。base0(占16位)和base1(占8位)和base2(占8位)组合形成了段的首字节的线性地址。

limit:存放段的最后一个内存单元的偏移量。这样就可以确定段的长度。但是这个还跟g位(占1位)有关。g:表示的是粒度。如果是0,则表示的是段的大小以字节为单位。否则,则表示的是以4k字节的倍数记。(通常一页为4k个字节)。

type字段(4位)表示的是最高位表示的是数据段还是代码段?为0则表示是数据段,为1表示是代码段。如果是数据段,则低三位表示: accessed (A)第8位, write-enable (W), and expansion-direction (E)。

如果是代码段,则低三位表示:accessed (A), read enable (R), and conforming (C)。                                                    代码段可以被execute- only或者execute/read, 设置的是read enable位。其他的先不考虑

s位表示的是系统表示。清0了则代表是系统段,存储诸如LDT这种关键的数据结构。否则为代码段或者数据段。

dpl:表示的是descriptor privilege level.表示的是描述符特权级。与上面提到的请求特权级概念内涵一样。对于为0时(表明这个描述附所代表的信息是来自内核的),表示只有当CPL为0时才可以访问这个描述符。如果为3(表明这个描述符所代表的信息来自用户态的),则表明cpl为0俄3都可以访问这个描述符。

p表示是否存在内存中。为1表示在内存中。为0表示在磁盘中。通常都是为1。因为一般不把整个段全部放到磁盘。

结合具体的内核态数据段、代码段和用户态的数据段、代码段分析如下(图):

 

分析如下:

如用户数据段。

Base   0x00000000表示基址为0x00000000

G      1表示粒度为4K个字节

Limit Oxfffff结合G理解如下:限制大小为0xfffff也就是(0xfffff+1)*4k=4G也就是整个用户数据段的地址空间为4G大小。

S      1表示为普通的数据段,而不是系统段

Type   10对应的位为1010,表示此描述符是数据段,此段可写。

DPL    3表示是用户态的

D/B    3这个先不考虑。

P      1表示在内存中。

0 0
原创粉丝点击