免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 705 | 回复: 0
打印 上一主题 下一主题

linux section management [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2007-07-24 14:03 |只看该作者 |倒序浏览

段式管理用以将逻辑地址转化为线性地址。一个逻辑地址由一个16位的段选择子和一个32位的偏移量组成。
[color="#0000ff"]1、段选择子和段寄存器
    为了快速的对段进行访问,i386提供了6个段寄存器以存放段选择子,分别为CS(代码段寄存器)、SS(栈段寄存器)、DS(全局和静态数据段寄存器)、ES(后三个均为任意数据段寄存器)、FS和GS。此外,i386还提供了6个段描述符寄存器(对程序员不可见),用来缓存相应段寄存器所对应段的段描述符。段寄存器格式如下:
Index
TI
RPL
    其中,[color="#ff0000"]Index有13位,为访问段描述符数组项的下标;[color="#ff0000"]TI只有1位,为0表示使用GDT,1表示使用LDT;[color="#ff0000"]RPL有2位,用以表示当前进程的特权级别。
[color="#0000ff"]
[color="#0000ff"]2、段描述符
    每个段的属性在内存中由一个8字节的段描述符表示,段描述符存放在全局描述符表(GDT)或者局部描述符表(LDT)中,其地址和体积分别保存在GDTR和LDTR寄存器中。段描述符的结构如下:
Base24-Base31
G
D/B
L
AVL
Limit16-Limit19
P
DPL
S
Type
Base16-Base23
Base0-Base15
Limit0-Limit15
    其中,[color="#ff0000"]Base为32位的段基(线性)地址;[color="#ff0000"]Limit为20位的段长度;[color="#ff0000"]G只有1位,为0表示段长度以字节为单位,1表示段长度以4KB为单位;[color="#ff0000"]D/B只有1位,为0表示为16位段,1表示为32位段;L只有1位,未使用;[color="#ff0000"]AVL只有1位,供系统软件使用(Linux从未使用该位);[color="#ff0000"]P只有1位,表示该段内容是否在内存中(Linux从不将整个段替换出内存,故该位恒为1);[color="#ff0000"]DPL有2位,表示访问该段所需要的特权级别;[color="#ff0000"]S只有1位,为0表示段为存放关键数据的系统段,1表示段为普通段;[color="#ff0000"]Type有4位,定义了段类型和访问权限。

    在linux系统中,主要包括代码段描述符、数据段描述符(包含栈段)、任务状态段(TSS,Type字段值为9或11)描述符和局部描述符表(LDT,Type字段值为2)描述符四种段描述符。其中,前两者可以被包含在GDT或LDT中,TSSD和LDTD为系统关键段,仅能包含在GDT中。
[color="#0000ff"]
[color="#0000ff"]3Linux内核中的分段
    出于效率和兼容性的考虑,Linux内核中对分段的支持有限,仅在i386结构有要求时才使用分段。
(1)代码段和数据段
    在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
    即,这四个段均为覆盖整个地址空间的32位普通段,仅有Type和DPL存在差异。在发生特权级变化时,内核会自动将由相应宏表示的段载入到段寄存器中。

(2)Linux中的GDT
    在linux中,每个处理器需要一个GDT。所有的GDT都保存在arch/i386/kernel/head.S文件中的cpu_gdt_table数组中,其地址和体积则保存在同一文件的cpu_gdt_descr数组中。GDT表共有32项,其中包含了18个段描述符和14个保留项。这18个段描述符如下:
①段选择子为0x00的null;
②段选择子为0x30、0x38、0x40的三个线程本地存储段(TLS#1-TLS#3),用以辅助多线程程序在本地存储局部数据;
③段选择子为0x60的__KERNEL_CS,段选择子为0x68的__KERNEL_DS,段选择子为0x70的__USER_CS,段选择子为0x78的__USER_DS;
④段选择子为0x80的任务状态段(TSS),用以保存进程的状态,不同处理器的GDT中的TSS不同;
⑤段选择子为0x88的LDT;
⑥段选择子为0x90、0x98、0xA0、0xA8、0xB0的五个和Plug and Play(PnP)BIOS服务相关的段;
⑦段选择子为0xB8、0xC0、0xC8的三个和高级电源管理(APM)相关的段;
⑧段选择子为0xF8的一个特殊的TSS,由内核用以处理“Double fault”异常。

(3)Linux中的LDT
    由于Linux的大多数用户进程都不使用LDT,其内核仅在arch/i386/kernel/traps.c文件中定义了一个五元素的数组default_ldt来保存被进程共享的LDT。其中,只有两个可被内核使用:用于iBCS可执行代码的调用门,和用于Solaris /x86可执行代码的调用门。
    此外,用户进程可以调用modify_ldt()系统调用来管理自身的LDT,但内核不会对其进行严格的管理。
               
               
               

本文来自ChinaUnix博客,如果查看原文请点:http://blog.chinaunix.net/u1/41220/showart_345714.html
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP