当前位置: 首页 > news >正文

Linux内核——段描述符详解

在 x86 架构的保护模式下,段描述符(Segment Descriptor) 是分段机制的核心数据结构,定义了内存段的属性(如基地址、界限、权限等)。Linux 通过全局描述符表(GDT)和局部描述符表(LDT)管理这些段描述符。每个段描述符占用 8 字节(64 位),其二进制布局如下:

用户段描述符,以字节形式表示如下:

关键字段详解

  1. 基地址(Base Address)

    • 32 位字段(由 Base[31:24]、Base[23:16]、Base[15:0] 组成),表示段的起始物理地址。
    • Linux 中基地址通常设为 0(平坦模型),因此逻辑地址偏移量直接等于线性地址。
  2. 段界限(Limit)

    • 20 位字段(由 Limit[19:16] 和 Limit[15:0] 组成),表示段的最大偏移量,即段长。
    • 单位由 G 标志位(第55位)决定
      • G=0:界限(段长)单位为字节,这时一个段最大空间为 1MB=220字节 。
      • G=1:界限(段长)单位为 4KB 页,这时一个段最大空间 为4GB 。
    • Linux 中段界限设为 0xFFFFFFFF(即 4GB),覆盖整个 32 位地址空间。
  3. A位(第5字节第0位):

用于请求分段不分页的系统中,每当该段被访问时,将 A 置 1。对于分页系统,则 A 被忽略未用。

  1. 类型(Type,第5字节第1、2、3位)

    • 定义段的类型和访问权限:
      • 代码段(Type[3]=1):可执行,可读(Type[1]=1)。
      • 数据段(Type[3]=0):可读/写(Type[1]=1`)。
    • 类型占 3 位,第 3 位为 E 位,表示段是否可执行。当 E=0 时,为数据段描述符,这时的第 2 位 ED 表示扩展方向。当 ED=0 时,为向地址增大的方向扩展,这时存取数据段中的数据的偏移量必须小于或等于段界限,当 ED=1 时,表示向地址减少的方向扩展,这时偏移量必须大于界限。当表示数据段时,第 1 位(W)是可写位,当 W=0 时,数据段不能写,W=1 时,数据段可写入。在 80386 中,堆栈段也被看成数据段,因为它本质上就是特殊的数据段。当描述堆栈段时,ED=0,W=1,即堆栈段朝地址增大的方向扩展。

Type[3]

Type[2]

Type[1]

说明

0(数据段)

ED=0(向地址增大的方向扩展)

W=0,不能写

W=1,可写入

数据段

ED=1(向地址减少的方向扩展)

1(代码段)

C=1

R=0,不能读

R=1,可读

代码段

    3.  当段为代码段时,第 3 位 E=1,这时第 2 位为一致位(C)。当 C=1 时,如果当前特权级低于描述符特权级,并且当前特权级保持不变,那么代码段只能执行。所谓当前特权级(Current Privilege Level),就是当前正在执行的任务的特权级。第 1 位为可读位 R,当R=0 时,代码段不能读,当 R=1 时可读。

  1. 权限(DPL,第5字节,第6、7位)

    • DPL字段(Descriptor Privilege Level),定义访问该段所需的最低特权级:
      • 0:内核态(Ring 0)。
      • 3:用户态(Ring 3)。
  2. 段存在标志(P,第5字节,第8位)

    • P=1:段存在于内存中;P=0:段无效(访问会触发异常)。
  3. 其他标志

    • S(System,第5字节第5位):S=1 表示代码/数据段;S=0 表示系统段(如 TSS、LDT)。
    • D/B(Default Operation Size,第6字节,第7位):D 位表示缺省操作数的大小,如果 D=0,操作数为 16 位,如果 D=1,操作数为 32 位。具体在代码段和数据段中含义如下
      • 代码段:D=1 表示 32 位指令,D=0 表示 16 位指令。
      • 数据段:B=1 表示 32 位栈,B=0 表示 16 位栈。
    • L(Long Mode,第6字节,第6位):L=1 表示 64 位代码段(仅 x86-64 有效)。对于长模式下的任务状态段(Task State Segment)或局部描述符表(Local Descriptor Table),段描述符(Segment Descriptor)的格式会有所不同,以确保基地址(Base)字段能够容纳一个 64 位的线性地址(Linear Address)。此类段描述符在表中占据两个常规表项的空间,并以小端字节序(Little Endian)排列,即该条目的低半部分在表中位于高半部分之前。

长模式下,一个表项占两个段描述符(128 bit),以扩充基址(Base)部分长度到64位。

  • AVL(Available,第6字节,第5位)

保留给操作系统自由使用。

Linux 采用平坦内存模型,所有段的基地址为 0,段界限为 0xFFFFFFFF,主要通过段描述符实现权限隔离,而非实际分段。

系统段特殊说明

以上介绍了用户段的段描述符基本结构,对一系统段,结构和用户段类似

区别在于:

    1. S(System,第5字节第5位):S=0 表示系统段(如 TSS、LDT)。
    2. G位固定位0(第55位),单位:字节。所以,系统段最长1M
    3. 存取字节(第5字节)的类型占4个bit(用户段占3个)。Linux定义了16种系统段
http://www.dtcms.com/a/113735.html

相关文章:

  • SeaTunnel系列之:Apache SeaTunnel编译和安装
  • 《SQL赋能人工智能:解锁特征工程的隐秘力量》
  • python基础-11-调试程序
  • DrissionPage高级技巧:从爬虫到自动化测试
  • Python FastApi(13):APIRouter
  • 操作系统知识点(二)
  • 超级科学软件实验室(中国) : Super Scientific Software Laboratory (SSSLab)
  • Vue2与Vue3不同
  • Deformable DETR(复习专用)
  • 基于Spark的哔哩哔哩舆情数据分析系统
  • 【RK3588 嵌入式图形编程】-SDL2-扫雷游戏-创建网格
  • liunx输入法
  • 网安小白筑基篇五:web后端基础之Python(补充Python的魔术方法)
  • Scade One - 将MBD技术从少数高安全领域向更广泛的安全嵌入式软件普及
  • 使用MATIO库读取Matlab数据文件中的cell结构数据
  • 【设计模式】命令模式
  • mine craft经典信封
  • 力扣刷题-热题100题-第31题(c++、python)
  • 博途 TIA Portal之1200做主站与200SMART的S7通讯
  • 《减压宝典》Python篇
  • leetcode每日一题:替换子串得到平衡字符串
  • vue3实现markdown预览和编辑
  • Cursor 无限续杯 Windows版
  • 智能体开发实战指南:提示词设计、开发框架与工作流详解
  • ROS多设备交互
  • 用C语言控制键盘上的方向键
  • LightRAG核心原理和数据流
  • Cisco Packet Tracer 8.0(新版)
  • 【神经网络】python实现神经网络(三)——正向学习的模拟演练
  • Unity插件SuperScrollView详解(进阶篇)