免费注册 查看新帖 |

Chinaunix

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

读/dev/kmem错误 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2006-03-20 16:15 |只看该作者 |倒序浏览
RHEL3,内核与gcc全部是系统自带。
程序中相关代码:

  1.         fd_kmem = open("/dev/kmem", O_RDWR);
  2.         ptr_idt = get_addr_idt();
  3.         descriptor = (struct descriptor_idt *) malloc(sizeof(struct descriptor_idt));
  4.         ......
  5.         readkmem(descriptor, ptr_idt + 8 * x, sizeof(struct descriptor_idt));

  6.         ......

  7. void readkmem(void *m, unsigned off, int size)
  8. {
  9.         int i;
  10.         if (lseek(fd_kmem, off, SEEK_SET) != off) {
  11.                 fprintf(stderr, "Error lseek. Are you root? \n");
  12.                 exit(-1);
  13.         }
  14.         if (read(fd_kmem, m, size) != size) {
  15.                 fprintf(stderr, "Error read kmem\n");
  16.                 exit(-1);
  17.         }
  18. }

  19. unsigned long get_addr_idt(void)
  20. {
  21.         unsigned char idtr[6];
  22.         unsigned long idt;
  23.         __asm__ volatile ("sidt %0":"=m" (idtr));
  24.         idt = *((unsigned long *) &idtr[2]);
  25.         return (idt);
  26. }
复制代码

每次运行都会提示"Error read kmem",调试发现read(fd_kmem, m, size)的返回值总是0。
不知道为什么?

[ 本帖最后由 sailer_sh 于 2006-3-20 18:08 编辑 ]

论坛徽章:
1
2015年辞旧岁徽章
日期:2015-03-03 16:54:15
2 [报告]
发表于 2006-03-20 17:54 |只看该作者
size 太大?

论坛徽章:
0
3 [报告]
发表于 2006-03-20 18:03 |只看该作者
原帖由 flw 于 2006-3-20 17:54 发表
size 太大?


我跟踪下来sizeof(descriptor) = 4,sizeof(struct descriptor_idt) = 8,ptr_idt + 8 * x = 0xffc18000
结构申明:

  1. struct descriptor_idt {
  2.         unsigned short offset_low, seg_selector;
  3.         unsigned char reserved, flag;
  4.         unsigned short offset_high;
  5. };

  6.        .......

  7.         struct descriptor_idt *descriptor;
复制代码

我觉得有点奇怪,结构是8个字符,为什么descriptor是4个字符。

这个程序来自《玩转IDT》的checkidt.c

[ 本帖最后由 sailer_sh 于 2006-3-20 18:07 编辑 ]

论坛徽章:
0
4 [报告]
发表于 2006-03-20 18:59 |只看该作者
RHEL3好象不再提供/dev/kmem了吧。

论坛徽章:
0
5 [报告]
发表于 2006-03-20 22:27 |只看该作者
原帖由 richardhesidu 于 2006-3-20 18:59 发表
RHEL3好象不再提供/dev/kmem了吧。


rhel3里有/dev/kmem这个文件,sles9里也有的。
那么到底是哪里有问题呢?

论坛徽章:
0
6 [报告]
发表于 2006-03-20 23:10 |只看该作者
原帖由 sailer_sh 于 2006-3-20 22:27 发表


rhel3里有/dev/kmem这个文件,sles9里也有的。
那么到底是哪里有问题呢?


看来是我记错了
readkmem(descriptor, ptr_idt + 8 * x, sizeof(struct descriptor_idt));


你确定你能理解这段程序吗?我看应该是这样才对:
readkmem(descriptor, ptr_idt + 8 *0x80, sizeof(struct descriptor_idt));


至于
sizeof(descriptor) = 4 

因为descriptor是指针,所以在这里是4
sizeof(struct descriptor_idt) = 8

这就不用说啦。

论坛徽章:
0
7 [报告]
发表于 2006-03-21 09:35 |只看该作者
关于这一句里的x是这样的,它是for循环的变量,我前面忘记把这一句加上了:

  1.                 for (x = 0; x < (get_size_idt() + 1) / 8; x++) {
  2.                         readkmem(descriptor, ptr_idt + 8 * x, sizeof(struct descriptor_idt));

  3.         ......

  4. unsigned short get_size_idt(void)
  5. {
  6.         unsigned idtr[6];
  7.         unsigned short size;
  8.         __asm__ volatile ("sidt %0":"=m" (idtr));
  9.         size = *((unsigned short *) &idtr[0]);
  10.         return (size);
  11. }
复制代码


x变量是这样来di...


另外,我把程序做了一点改动:

  1. #include <errno.h>

  2.         ......

  3.         if ((i = read(fd_kmem, m, size)) != size) {
  4.                 fprintf(stderr, "Error read kmem\n");
  5.                 perror("read");
  6.                 exit(-1);
  7.         }
复制代码


程序输出:

  1. Error read kmem 1
  2. read: Success
复制代码

[ 本帖最后由 sailer_sh 于 2006-3-21 09:47 编辑 ]

论坛徽章:
0
8 [报告]
发表于 2006-03-21 10:35 |只看该作者
  1. ptr_idt + 8 * x = 0xffc18000
复制代码
似乎有点问题

什么平台?是不是有endian的问题?

使用这个试试:

  1. struct {
  2.         unsigned short limit;
  3.         unsigned int base;
  4. } __attribute__ ((packed)) idtr;
复制代码

  1. unsigned long get_addr_idt(void)
  2. {
  3.         __asm__ volatile ("sidt %0":"=m" (idtr));
  4.         return idtr.base;
  5. }
复制代码
  1. unsigned short get_size_idt(void)
  2. {
  3.         __asm__ volatile ("sidt %0":"=m" (idtr));
  4.         return idtr.limit;
  5. }
复制代码

[ 本帖最后由 jobman 于 2006-3-21 10:45 编辑 ]

论坛徽章:
0
9 [报告]
发表于 2006-03-21 13:52 |只看该作者
我在sles9和rhel3上运行这个程序,全部使用默认环境。
加入你给的第一段代码,根据你的第二、三段代码修改相应函数,得出的结果还是:
Error read kmem 1
read: Success

有什么办法测试read()函数读/dev/kmem吗?

论坛徽章:
0
10 [报告]
发表于 2006-03-21 14:04 |只看该作者

回复 9楼 sailer_sh 的帖子

把lseek()换成llseek()看看,你用的kernerl版本可能是新的2.4.25以上的.
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP