所以,我知道
Linux为x86处理器(内核代码,内核数据,用户代码,用户数据)使用四个默认段,但它们都具有相同的基数和限制(0x00000000和0xfffff),这意味着每个段映射到一组线性地址.
鉴于此,为什么甚至有用户/内核分段?我明白为什么应该有代码和数据的单独部分(只是由于x86处理器处理cs和ds寄存器的方式),但是为什么没有单个代码段和单个数据段?通过分页完成内存保护,无论如何,用户和内核分段映射到相同的线性地址.
解决方法
x86架构将类型和特权级别与每个段描述符相关联.描述符的类型允许段被做成只读,读/写,可执行等,但是具有相同基数和限制的不同段的主要原因是允许使用不同的描述符特权级别(DPL).
DPL是两位,允许值0到3被编码.当权限级别为0时,就被称为ring 0,这是最特权的. Linux内核的段描述符为环0,而用户空间的段描述符为环3(最低权限).大多数分段操作系统都是如此;操作系统的核心为环0,其余为环3.
正如你所提到的那样,Linux内核设置了四个部分:
> __KERNEL_CS(内核代码段,base = 0,limit = 4GB,type = 10,DPL = 0)
> __KERNEL_DS(内核数据段,type = 2,DPL = 0)
> __USER_CS(用户代码段,DPL = 3)
> __USER_DS(用户数据段,DPL = 3)
所有四个的基本和限制是相同的,但是内核段是DPL 0,用户段是DPL 3,代码段是可执行的和可读的(不可写),并且数据段是可读写的(不可执行) .
也可以看看:
> Segmentation in Linux
> x86 Segmentation for the 15-410 Student
> 5.1.1 Descriptors
> 6.3.1 Descriptors Store Protection Parameters