以下讨论的内容是以i平台为基础的
Linux将G的地址划分为用户空间和内核空间两部分在Linux内核的低版本中(X)通常G为用户空间GG为内核空间这个分界点是可以可以改动的
正是这个分界点的存在限制了Linux可用的最大内存为G而且要通过重编内核调整这个分界点才能达到
实际上还可以有更好的方法来解决这个问题由于内核空间与用户空间互不重合所以可以用段机制提供的保护功能来保护内核级代码以下为X的部分代码
/usr/src/linux/arch/i/kernel/entryS
A: quad xccaffff /* x kernel GB code at xC *
B: quad xccffff /* x kernel GB data at xC *
C: quad xcbfaffff /* x user GB code at x *
D: quad xcbfffff /* xb user GB data at x *
AB为内核代码段及数据段的描述符CD为用户代码及数据段的描述符从以上我们可以清楚的看到AB的特权级为而CD的特权级为当内核存取用户空间的内容时他借助于fs寄存器同过将FS寄存器的内容置为D来达到访问用户空间的目的
X版的 内核对此进行了改动这样内核空间扩张到了G所以可以直接进行拷贝了
quad xcfaffff /* x kernel GB code at x *
quad xcfffff /* x kernel GB data at x *
quad xcffaffff /* x user GB code at x *
quad xcffffff /* xb user GB data at x *
从表面上看内核的基地址变为了但实际上内核通常仍在虚址G以上其中奥妙在与 不同的连接描述文件
X
= xC + x;
_text = ; /* Text and readonly data */
text : {
*(text)
*(fixup)
*(gnuwarning)
} = x
textlock : { *(textlock) } /* outofline lock text */
rodata : { *(rodata) }
kstrtab : { *(kstrtab) }
X
faint内核被删除了 (
不管怎莫说请大家相信我X的起址为x这样一来二者就相等了都是xC + x
用户空间在X中从直观上变为G让人迷惑其不是可以直接访问内核了?其实不然 同过使用页机制提供的保护阻止了用户程序访问内核空间
这样存取用户空间实际上已不需要FSGS的支持但在内核中仍保留set_fs(X)等宏上你设的值用来验证随后的操作是否合适是否超过设定的X此处X不再是一个段描述符而是一个具体的值
此处就有一个陷阱如果你将Set_fs的值设置为Kernel_DS而没有将其该回去当用户通过系统调用将一个Buffer的地址(应该在用户空间)设置为一个内核空间而内核在访问该地址前认为默认当前的阀值仍为User_DS事情就大大?了