11.linux的分段机制与分页机制

时间:2022-12-30 23:47:56

1段式管理.

32位CPU两种工作方式:由实模式和保护模式组成。

1、  实模式:内存管理与 16位CPU是一致的。

2、  保护模式:(一般X86运行模式)

段基地址长达32位,每个段的最大容量可达4G,段寄存器的值时段地址的“选择器”(selecor),用该“选择器”从内存中得到一个32位的段地址,存储单元的

线性地址=该段基地址(Base)+段内偏移地址(offset),Linux对分段使用非常有限。作为一个跨硬件体系的操作系统,要支持多种硬件体系,而一些硬件体系结构式不支持分段的,Linux把所有段起始地址都设为0。所以逻辑地址=虚拟地址

 一个逻辑地址由两部份组成,段标识符: 段内偏移量。段标识符是由一个16位长的字段组成,称为段选择符。其中前13位是一个索引号。后面3位包含一些硬件细节,如图

11.linux的分段机制与分页机制

 索引号就是“段描述符(segment descriptor)”,段描述符具体描述了一个段。这样,很多个段描述符,就组了一个数组,叫“段描述符表”,这样,可以通过段标识符的前13位,直接在段描述符表中找到一个具体的段描述符,这个描述符就描述了一个段,每一个段描述符由8个字节组成。

段描述符

    每个段的属性在内存中由一个 8 字节的段描述符表示,段描述符存放在全局描述符表( GDT )或者局部描述符表( LDT )中,其地址和体积分别保存在 GDTR LDTR 寄存器中。段描述符的结构如下:

Base24-Base31

G

D/B

L

AVL

Limit16-Limit19

P

DPL

S

Type

Base16-Base23

Base0-Base15

Limit0-Limit15

    其中, Base 32 位的段基(线性)地址; Limit 20 位的段长度; G 只有 1 位,为 0 表示段长度以字节为单位, 1 表示段长度以 4KB 为单位; D/B 只有 1 位,为 0 表示为 16 位段, 1 表示为 32 位段; L 只有 1 位,未使用; AVL 只有 1 位,供系统软件使用( Linux 从未使用该位); P 只有 1 位,表示该段内容是否在内存中( Linux 从不将整个段替换出内存,故该位恒为 1 ); DPL 2 位,表示访问该段所需要的特权级别; S 只有 1 位,为 0 表示段为存放关键数据的系统段, 1 表示段为普通段; Type 4 位,定义了段类型和访问权限。

    在 linux 系统中,主要包括代码段描述符、数据段描述符(包含栈段)、任务状态段( TSS Type 字段值为 9 11 )描述符和局部描述符表( LDT Type 字段值为 2 )描述符四种段描述符。其中,前两者可以被包含在 GDT LDT 中, TSSD LDTD 为系统关键段,仅能包含在 GDT 中。

linux中,所有用户进程都使用相同的代码段(__USER_CS)和数据段(__USER_DS),所有的内核进程都使用相同的代码段(__KERNEL_CS)和数据段(__KERNEL_DS)。这四个段的段描述符主要字段如下:

Segment

Base

G

Limit

S

Type

DPL

D/B

P

__USER_CS

0x00000000

1

0xFFFFF

1

10

3

1

1

__USER_DS

0x00000000

1

0xFFFFF

1

2

3

1

1

__KERNEL_CS

0x00000000

1

0xFFFFF

1

10

0

1

1

__KERNEL_DS

0x00000000

1

0xFFFFF

1

2

0

1

1


11.linux的分段机制与分页机制

 严格说Linux采用段页式内存管理,也就是既分段,又分页。地址映射的时候,先确定对应的段,确定段基地址;段内分页,再找到对应的页表项,确定页基地址;再由逻辑地址低位确定的页偏移量,就能找到最终的物理地址。但是,实际上Linux采用的是页式内存管理。原因是Linux中的段基地址都是0,相当于所有的段都是相同的。这样做的原因是某些体系结构的硬件限制,比如Intel的i386。作为软件的操作系统,必须要符合硬件体系。虽然所有段基地址都是0,但是段的概念在Linux内核中是确实存在的。比如常见的内核代码段、内核数据段、用户态代码段、用户态数据段等。除了符合硬件要求外,段也是有实际意义的。

11.linux的分段机制与分页机制

逻辑地址分为两部分组成:段标识符和指定段内相对地址的偏移量。

段描述符:用来存放段起始地址,段大小,存储权限等。
段描述符表:存放段描述的表项。
段寄存器:存放段标识符。6个段寄存器称为cs(代码段寄存器),ss(栈段寄存器),ds(数据段寄存器),es,fs 和gs。
段基地址寄存器:指向段描述符表地址。

2.2页式管理(分页管理)

1、  线性地址页:从管理和效率的角度出发,线性地址被分为固定长度的组,称为页(page)。例如32位机器,线性地址最大可为4G,如果用4KB为页容量,这样将线性地址划分为2^20个页。

2、  物理页:另一类“页”,称为“物理页”,或者是“页框、页帧”。分页单元把所有的物理内存也划分为固定长度的管理单位,它的长度一般与线性地址页是相同。

如何将两者之间的映射?通过页式管理实现映射。

11.linux的分段机制与分页机制

页式管理具体流程:

1、  分页单元中,页目录的地址放在CPU的CR3寄存器中,是进行地址转换的起始点。

2、  每个进程,都有其独立的虚拟地址空间,运行一个进程,首先需要将它的页目录地址放到CR3寄存器中,将其他进程保存下来。

3、  每一个32位的线性地址被划分三部分:页目录索引(10位):页表索引(10位):偏移(12位)

下面是地址转换的步骤:

第一步:装入进程的页目录地址(操作系统在调度进程时,把这个地址装入CR3)

第二步:根据线性地址前十位,在页目录中,找到对应的索引项 即页表地址

第三步:根据线性地址中间十位,在页表中,找到对应的索引项 即页的起始地址

第四步:将页的起始地址与线性地址最后12相加,等到物理地址。

在二级模式下,页容量由线性地址[bit11:0]决定,页容量=2^12=4Kbyte。