Linux kernel 为什么Linux内核中4个段的基址相同?

Linux kernel 为什么Linux内核中4个段的基址相同?,linux-kernel,Linux Kernel,__用户\u CS、\uuuuu内核\u CS、\uuuuu用户\u DS、\uuuuuu内核\u DS,都具有base=0x00000000和limit=0xfffff。 我不能理解的是,这些线性地址将给出相同的物理地址 (我想我可能错了)。生成的线性地址(因此物理地址)在所有情况下都是相同的,这意味着用户和内核结构存储在同一个位置。 另外,请向我解释,与此相反,我们如何说内核结构存储在较高的1GB,用户结构存储在较低的3MB 请指出我在理解分页和分段方面的错误。 谢谢。你说的是哪个平台?对于

__用户\u CS、\uuuuu内核\u CS、\uuuuu用户\u DS、\uuuuuu内核\u DS,都具有base=0x00000000和limit=0xfffff。 我不能理解的是,这些线性地址将给出相同的物理地址 (我想我可能错了)。生成的线性地址(因此物理地址)在所有情况下都是相同的,这意味着用户和内核结构存储在同一个位置。 另外,请向我解释,与此相反,我们如何说内核结构存储在较高的1GB,用户结构存储在较低的3MB

请指出我在理解分页和分段方面的错误。
谢谢。

你说的是哪个平台?对于x86,它们都是不同的(从
arch/x86/include/asm/segment.h
):


假设线性地址以1:1的方式映射到物理地址是错误的。相反,页面表用于将线性地址映射到物理地址。每个进程都有一组不同的页表,提供地址分离和虚拟内存。在内核空间中,前3GB的页表指向“虚拟”地址;最后的GB以大约1:1的方式映射到物理地址(在某些配置中)。内核模式页面的保护是通过(不)在页面表条目中设置用户访问位来实现的。

操作仍然正确:虽然段不同,但它们都有基数0,限制fffff,请看,这正是我的疑问。非常感谢你!!尽管如此,当所有的保护和分离都由寻呼单元完成时,分段的用途是什么?实际上,分段不再使用了。但是,它们是硬件体系结构的一部分,不能删除。在64位模式(AMD64)下,段寄存器CS、DS、SS、ES失效。FS和GS仍可用作线程本地存储的指针(因此在AMD64上保留)。段寄存器
CS
DS
SS
ES
仍在使用-它们所指向的段选择器中的基址被忽略。例如,CPL仍然选择特权级别。
#define __KERNEL_CS     (GDT_ENTRY_KERNEL_CS * 8)
#define __KERNEL_DS     (GDT_ENTRY_KERNEL_DS * 8)
#define __USER_DS     (GDT_ENTRY_DEFAULT_USER_DS* 8 + 3)
#define __USER_CS     (GDT_ENTRY_DEFAULT_USER_CS* 8 + 3)
  #define GDT_ENTRY_DEFAULT_USER_CS       14
  #define GDT_ENTRY_DEFAULT_USER_DS       15
  #define GDT_ENTRY_KERNEL_BASE   12
  #define GDT_ENTRY_KERNEL_CS             (GDT_ENTRY_KERNEL_BASE + 0)
  #define GDT_ENTRY_KERNEL_DS             (GDT_ENTRY_KERNEL_BASE + 1)