为什么 x86 上的 Linux 对用户进程和内核使用不同的段? [英] Why does Linux on x86 use different segments for user processes and the kernel?

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

问题描述

所以,我知道 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 时,则称为 ring 0,这是最有特权的.Linux 内核的段描述符是 ring 0,而用户空间的段描述符是 ring 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(内核代码段,base=0,limit=4GB,type=10,DPL=0)
  • __KERNEL_DS(内核数据段,base=0,limit=4GB,type=2,DPL=0)
  • __USER_CS(用户代码段,base=0,limit=4GB,type=10,DPL=3)
  • __USER_DS(用户数据段,base=0,limit=4GB,type=2,DPL=3)

四个的base和limit都是一样的,但是内核段是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).

另见:

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

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆