本文介绍了为什么Linux在x86上为用户进程和内核使用不同的段?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

因此,我知道Linux对x86处理器使用四个默认段(内核代码,内核数据,用户代码,用户数据),但是它们都有相同的基数和限制(0x00000000和0xfffff),这意味着每个段映射到同一组线性地址.

So, I know that Linux uses four default segments for an x86 processor (kernel code, kernel data, user code, user data), but they all have the same base and limit (0x00000000 and 0xfffff), meaning each segment maps to the same set of linear addresses.

鉴于此,为什么还要有用户/内核段?我知道为什么代码和数据应该有单独的段(仅由于x86处理器如何处理cs和ds寄存器),但是为什么不只有一个代码段和一个数据段呢?内存保护是通过分页完成的,并且用户段和内核段始终映射到相同的线性地址.

Given this, why even have user/kernel segments? I understand why there should be separate segments for code and data (just due to how the x86 processor deals with the cs and ds registers), but why not have a single code segment and a single data segment? Memory protection is done through paging, and the user and kernel segments map to the same linear addresses anyway.

推荐答案

x86体系结构将类型和特权级别与每个段描述符关联.描述符的类型允许将段设为只读,读/写,可执行等,但是不同段具有相同基数和限制的主要原因是允许使用不同的描述符特权级别(DPL).

The x86 architecture associates a type and a privilege level with each segment descriptor. The type of a descriptor allows segments to be made read only, read/write, executable, etc., but the main reason for different segments having the same base and limit is to allow a different descriptor privilege level (DPL) to be used.

DPL是两位,允许对值0到3进行编码.当特权级别为0时,则被称为环为0 ,这是最特权的. Linux内核的段描述符为环0,而用户空间的段描述符为环3(最低特权).对于大多数分段操作系统而言,这都是正确的.操作系统的核心是环0,其余的是环3.

The DPL is two bits, allowing the values 0 through 3 to be encoded. When the privilege level is 0, then it is said to be ring 0, which is the most privileged. The segment descriptors for the Linux kernel are ring 0 whereas the segment descriptors for user space are ring 3 (least privileged). This is true for most segmented operating systems; the core of the operating system is ring 0 and the rest is ring 3.

正如您提到的,Linux内核设置了四个部分:

The Linux kernel sets up, as you mentioned, four segments:

  • __ KERNEL_CS(内核代码段,基本= 0,限制= 4GB,类型= 10,DPL = 0)
  • __ KERNEL_DS(内核数据段,基本= 0,限制= 4GB,类型= 2,DPL = 0)
  • __ USER_CS(用户代码段,基数= 0,限制= 4GB,类型= 10,DPL = 3)
  • __ USER_DS(用户数据段,基数= 0,限制= 4GB,类型= 2,DPL = 3)

这四个的基数和限制是相同的,但是内核段是DPL 0,用户段是DPL 3,代码段是可执行和可读的(不可写的),而数据段是可读可写的(不可执行).

The base and limit of all four are the same, but the kernel segments are DPL 0, the user segments are DPL 3, the code segments are executable and readable (not writable), and the data segments are readable and writable (not executable).

另请参阅:

  • Segmentation in Linux
  • x86 Segmentation for the 15-410 Student
  • 5.1.1 Descriptors
  • 6.3.1 Descriptors Store Protection Parameters

这篇关于为什么Linux在x86上为用户进程和内核使用不同的段?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-24 10:32