首页 > 代码库 > [转载] data segment 的访问
[转载] data segment 的访问
这里的 data segment 访问控制针使用对 DS、ES、FS 以及 GS selector register 进行访问,不包括 SS selector register,stack segment 访问与一般的 data segment 有些差别。
以 DS 为例代表所有的 data segment 访问(ES、FS 以及 GS),需要的权限条件是:RPL(DS.RPL) <= DPL 且 CPL(CS.DPL) <= DPL。 这里的 RPL 就是 DS.RPL,即:使用 ds selector 进行 data segment 访问时,使用什么级别的 RPL。CPL 就是当前 CS selector 里的 DPL,代表 processor 处于什么权限级别。 DPL 就是目标 data segment descriptor 所定义的访问 data segment 所需要的权限。
用简单的式子表达为:
if (RPL <= DPL && CPL <= DPL) { /* 通过权限检查,允许访问,加载 descriptor 进入 DS */ } else { /* 拒绝访问,产生 #GP 异常 */ goto do_#GP } |
式子中的比较表示在数字上大小关系。数字越大权限越低,所以 RPL <= DPL 是判断 RPL 权限级别是否大于 DPL 的权限级别 RPL 和 CPL 的权限极别必须大于或等于 DPL 的权限级别。
在得到允许访问后的后续处理:目标 data segment descriptor 将加到了 DS 寄存器中。在不改变访问的目标 data segment 的情况下,processor 不会对 DS 进行更新,也就是:不会得新加载 data segment descriptor。 DS 寄存器保持着内部的 descriptor 记录不变,直至到更新 DS 寄存器。因此,对同一个 data segment 的访问仅需要加载 1 次 descriptor 。这种情况对于所有的 selector registers 都是一样的。
情景提示: 当 processor 发现 descriptor 的 P 标志位为 0 时,将引发 #NP 异常。所以系统必须要设定 descriptor 的 P 标志位为 1,processor 不会对 P 标志位进行更改。 系统将 P 标志置为 0,有时会特定的用途,大多数OS 会在软件中会引发类似 segment falut 错误提示,指示程序员犯了某些错误。 |
7.1.1.1、 x64 的 long mode 下 data segment 的访问
在 long mode 下的兼容模式与 x86 下的 data segment 的控制访问检查并无两样。但是在 64 bit 模式下就完全改变了。
在 64 bit 模式下:
processor 不对 data segment 的访问进行任何的权限检查!data segment descriptor 中仅有 P 标志位是有效的,其它都无效。也就是 DS、ES、FS、GS 以及 SS 中除 P 属性有效外,其它都是无效的。 所有基于 DS、ES 以及 SS 的 data segment 的 base 是无效的,被强制为 0。而基于 FS 与 GS 的 data segment 的 base 是有效的,故 FS 与 GS 的 data segment 可以定位在 64 位地址空间的任何位置。
所以:
1、所有的 data segment 的访问都不进行权限检查,包括 DS、ES、FS、GS 以及 SS。这是因为,在 64bit 下所有的 data segment descriptor 的 DPL 属性是无效的。
2、所有的 data segment 的访问也不进行 type、limit 检查,这些属性都是无效的。64 bit 下,所有的 data segment 都是 Readable/writable 属性。所有的 data segment 都具有 64 位地址空间。
3、所有的地址 limit 检查都变为 canonical-address 的地址形式检查。
[转载] data segment 的访问