Linux细分

Linux细分,linux,memory-management,linux-kernel,kernel,cpu-registers,Linux,Memory Management,Linux Kernel,Kernel,Cpu Registers,最近,我读了一本名为《理解linux内核》的书。有一句话让我很困惑。谁能给我解释一下吗 如前所述,CPU的当前特权级别指示 处理器是处于用户模式还是内核模式,并且由 存储在cs寄存器中的段选择器的RPL字段。 每当改变CPL时,必须使用一些分段寄存器 相应地更新。例如,当CPL等于3时 (用户模式),ds寄存器必须包含 用户数据段,但当CPL等于0时,ds寄存器必须包含内核数据段的段选择器 ss寄存器也会出现类似的情况。它必须引用一个 CPL为3时,用户数据段内的用户模式堆栈 必须引用内核数据段

最近,我读了一本名为《理解linux内核》的书。有一句话让我很困惑。谁能给我解释一下吗

如前所述,CPU的当前特权级别指示 处理器是处于用户模式还是内核模式,并且由 存储在cs寄存器中的段选择器的RPL字段。 每当改变CPL时,必须使用一些分段寄存器 相应地更新。例如,当CPL等于3时 (用户模式),ds寄存器必须包含 用户数据段,但当CPL等于0时,ds寄存器必须包含内核数据段的段选择器

ss寄存器也会出现类似的情况。它必须引用一个 CPL为3时,用户数据段内的用户模式堆栈 必须引用内核数据段内的内核模式堆栈 CPL为0。从用户模式切换到内核模式时,Linux 始终确保ss寄存器包含段选择器 内核数据段的

保存指向指令或数据结构的指针时 内核不需要存储 逻辑地址,因为ss寄存器包含当前段 选择器。

例如,当内核调用函数时,它执行一个调用 仅指定偏移量分量的汇编语言指令 它的逻辑地址;段选择器被隐式选择为 cs登记册中提到的一个。因为只有一个 “内核模式下可执行文件”类型的段,即代码段 由_KERNEL_CS标识,将_KERNEL_CS加载到 每当CPU切换到内核模式时,使用cs。同样的论点也存在 用于指向内核数据结构的指针(隐式使用ds 寄存器),以及指向用户数据结构(内核)的指针 显式使用es寄存器)

我的理解是,ss寄存器包含指向堆栈底部的段选择器点。ss寄存器是否与指向影响数据结构的指令的指针有关?如果没有,为什么在这里提及

我的理解是ss寄存器包含段选择器 指向堆栈的底部

ss寄存器是否与指向数据结构指令的指针有关

不,ss寄存器与影响数据段的指令无关

如果没有,为什么在这里提及

因为ss寄存器影响影响堆栈的指令的结果(例如:
pop
push
,等等)

他们只是解释Linux还维护两个堆栈段(一个用于用户模式,一个用于内核模式)以及两个数据段(一个用于用户模式,一个用于内核模式)

至于数据段,如果在从用户模式切换到内核模式时未更新,ss选择器仍将指向用户堆栈,内核将与用户堆栈一起工作(这将非常糟糕,对吧?)。因此内核负责更新ss寄存器和ds寄存器

注意:
让我们回忆一下,指令可以访问/修改数据段(
mov
到内存地址)以及堆栈段(
pop
push
,等等)中的位。

最后,我澄清了该段的含义。实际上,这段描述演示了分段在Linux中是如何工作的。它确实有隐式的比较对象——这些系统利用分段而不是分页。这些系统是如何工作的?每个进程的逻辑地址中都有不同的段选择器,它们指向全局描述符表中的不同条目。每个段不一定需要有相同的基础。在这种情况下,当您保存指向指令或数据结构的指针时,您确实需要注意它的段基。请注意,每个逻辑地址都有一个16位段选择器和一个32位偏移量。如果只保存偏移量,就不可能再次找到该指针,因为GDT中有许多不同的段。对于Linux,情况就不同了。所有段选择器都具有相同的基数0。这意味着指针的偏移量足够特殊,可以从内存中提取它。你可能会问,当有很多进程在那里运行时,它能工作吗?它起作用了!请记住,每个进程都有其页表,它具有将相同地址映射到不同物理地址的神奇能力。感谢所有关心这个问题的人

所有段选择器寄存器(userland中线程本地存储的
fs
除外)都包含相同的信息。不要评论您自己的问题,但请编辑您的问题以改进它。