免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 3213 | 回复: 2
打印 上一主题 下一主题

为什么用户态和内核态读取任务寄存器(tr)结果不一样 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2011-11-06 01:47 |只看该作者 |倒序浏览
根据intel的volume3的7.2.4对任务寄存器的描述:
The STR (store task register) instruction stores the visible portion of the task register
in a general-purpose register or memory. This instruction can be executed by code
running at any privilege level in order to identify the currently running task. However,
it is normally used only by operating system software.


str指令在用户态也可以使用,可是用户态和内核态读取的结果不一样,内核态得到的结果与预期一致。
用户态代码如下:
  1. #include <stdio.h>

  2. #define store_tr(tr) __asm__ ("str %0":"=mr" (tr))

  3. int main(void)
  4. {
  5.     unsigned short tr = 0;
  6.     store_tr(tr);
  7.     printf("tr=0x%x\n", tr);
  8.     return 0;
  9. }
复制代码
结果为:tr=0x4000

内核模块代码:
  1. #include <linux/module.h>
  2. #include <linux/moduleparam.h>
  3. #include <linux/init.h>

  4. #include <linux/kernel.h>       /* printk() */

  5. #define store_tr(tr) __asm__ ("str %0":"=mr" (tr))

  6. static int
  7. tr_module_init(void)
  8. {
  9.     unsigned short tr = 0;

  10.     printk(KERN_WARNING "tr_module_init\n");

  11.     store_tr(tr);
  12.     printk(KERN_WARNING "tr=0x%x\n", tr);
  13.     return 0;
  14. }

  15. static void
  16. tr_module_exit(void)
  17. {
  18.     printk(KERN_WARNING "tr_module_exit\n");
  19. }


  20. MODULE_AUTHOR("nobody");
  21. MODULE_LICENSE("Dual BSD/GPL");

  22. module_init(tr_module_init);
  23. module_exit(tr_module_exit);
复制代码
结果为tr=0x80

我的环境是CENTOS5,内核为2.6.18. 根据arch/i386/kernel/head.S中的全局段描述符的定义:
  1. ENTRY(cpu_gdt_table)
  2.         .quad 0x0000000000000000        /* NULL descriptor */
  3.         .quad 0x0000000000000000        /* 0x0b reserved */
  4.         .quad 0x0000000000000000        /* 0x13 reserved */
  5.         .quad 0x0000000000000000        /* 0x1b reserved */
  6.         .quad 0x0000000000000000        /* 0x20 unused */
  7.         .quad 0x0000000000000000        /* 0x28 unused */
  8.         .quad 0x0000000000000000        /* 0x33 TLS entry 1 */
  9.         .quad 0x0000000000000000        /* 0x3b TLS entry 2 */
  10.         .quad 0x0000000000000000        /* 0x43 TLS entry 3 */
  11.         .quad 0x0000000000000000        /* 0x4b reserved */
  12.         .quad 0x0000000000000000        /* 0x53 reserved */
  13.         .quad 0x0000000000000000        /* 0x5b reserved */

  14.         .quad 0x00cf9a000000ffff        /* 0x60 kernel 4GB code at 0x00000000 */
  15.         .quad 0x00cf92000000ffff        /* 0x68 kernel 4GB data at 0x00000000 */
  16.         .quad 0x00cffa000000ffff        /* 0x73 user 4GB code at 0x00000000 */
  17.         .quad 0x00cff2000000ffff        /* 0x7b user 4GB data at 0x00000000 */

  18.         .quad 0x0000000000000000        /* 0x80 TSS descriptor */
  19.         .quad 0x0000000000000000        /* 0x88 LDT descriptor */

  20.         /*
  21.          * Segments used for calling PnP BIOS have byte granularity.
  22.          * They code segments and data segments have fixed 64k limits,
  23.          * the transfer segment sizes are set at run time.
  24.          */
  25.         .quad 0x00409a000000ffff        /* 0x90 32-bit code */
  26.         .quad 0x00009a000000ffff        /* 0x98 16-bit code */
  27.         .quad 0x000092000000ffff        /* 0xa0 16-bit data */
  28.         .quad 0x0000920000000000        /* 0xa8 16-bit data */
  29.         .quad 0x0000920000000000        /* 0xb0 16-bit data */
  30. ...
复制代码
TSS descriptor是第16个entry,每个entry是8bytes,所以tr中的段选择子为16*8=128=0x80.

请教各位大牛为什么同样的指令在用户态得到的结果不对呢?

小弟为内核菜鸟,请各位前辈多多赐教

论坛徽章:
0
2 [报告]
发表于 2011-11-06 01:55 |只看该作者
自己顶一个

论坛徽章:
0
3 [报告]
发表于 2011-11-07 13:56 |只看该作者
本帖最后由 wangjianchangdx 于 2011-11-07 13:58 编辑
The STR instruction is useful only in operating-system software. It can only be
executed in protected mode.


FROM intel manual volume 2b: STR

具体在用户态获取的值是如何生成的,不得而知。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP