首页 > 代码库 > [转载] 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 的访问