免费注册 查看新帖 |

Chinaunix

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

内核态与用户态数据传递遇到问题~求各位前辈帮我看看~ [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2006-03-14 10:50 |只看该作者 |倒序浏览
In function `sys_mysyscall2':
/root/modules/test.c:63: warning: passing arg 3 of `get_user_size' makes pointer from integer without a cast

以下是我做的练习:
static int sys_mysyscall2(struct abc *p_u,int index_u)
{       
        struct abc *p_k;
        int index_k;
        copy_from_user(&index_k,index_u,sizeof(int));
        a[index_k].b=1;
        p_k=&a[index_k];
        copy_to_user(p_k,p_u,sizeof(p_k));
        return 0;
}

[ 本帖最后由 dosnipe_judy 于 2006-3-14 10:52 编辑 ]

论坛徽章:
0
2 [报告]
发表于 2006-03-14 13:11 |只看该作者
找到原因了,改成
static int sys_mysyscall(int *p_u,int *index_u)
{       
        //int *p_k;
        int index_k;
        copy_from_user(&index_k,index_u,sizeof(int));
        printk("%d",index_k);
        a[index_k]=1;
        printk("%d",a[index_k]);
        copy_to_user(&a[index_k],p_u,sizeof(int));
        return 0;
}
但是,用户态显示copy后的数据失败~~
以下是用户态的代码:
#include <linux/unistd.h>
#define __NR_mysyscall 300
_syscall2(static int,mysyscall,int *,p,int ,index);
int a[256];
int main(int argc, char* argv[])
{        int *p;
        int index;
        printf("please input number of array you want to use!!");
        scanf("%d",&index);
        a[index]=0;
        p=&a[index];
                mysyscall(p,index);
        printf("a[%d]  is %d\n",index,*p);

        return 0;
}
显示的啊a[index]还是0 ,难道系统调用没有成功???
模块可以insmod,lsmod,rmmod 啊~~

论坛徽章:
1
荣誉版主
日期:2011-11-23 16:44:17
3 [报告]
发表于 2006-03-14 15:05 |只看该作者
写新的系统调用必须重新编译内核.

论坛徽章:
0
4 [报告]
发表于 2006-03-14 15:17 |只看该作者
我想用模块的机制添加系统调用,但是感觉好像没有用到自己写的系统调用,没有添加成功
用户态与核心态之间数据传递遇到问题
以下是用户态的代码
-------------------------------------------------------------------------------------------------
#include <linux/unistd.h>
#define __NR_mysyscall 300
_syscall2(static int,mysyscall,int *,p,int *,index_u);
int a[256];
int main(int argc, char* argv[])
{        int *p;
        int *index_u;
        int index;
        printf("please input number of array you want to use!!");
        scanf("%d",&index);
        p=&a[index];
        index_u=&index;
                mysyscall(p,index_u);
        printf("a[%d] of uerspase is %d\n",index,*p);

        return 0;
}

--------------------------------------------------------------------------------------------------
模块的代码:
#ifndef __SYSCALL_INCLUDE__
# define __SYSCALL_INCLUDE__
#endif
#ifdef MODVERSIONS
#include <linux/modversions.h>
#endif
#include <linux/module.h>
#include <linux/kernel.h>
#include <asm/uaccess.h>
MODULE_LICENSE("GPL");
MODULE_AUTHOR("judy");
#if !defined(symname)
#error symname not defined
#endif
#define CALLOFF 100
#define __NR_mysyscall 300
unsigned symname; /* #define */
struct {
unsigned short limit;
unsigned int base;
} __attribute__ ((packed)) idtr;

struct {
unsigned short off1;
unsigned short sel;
unsigned char none,
flags;
unsigned short off2;
} __attribute__ ((packed)) * idt;

int a[256];

void set_symbol_addr(unsigned old_value, unsigned new_value)
{
  struct module *mod;
  struct kernel_symbol *s;
  int i;
  for (mod = THIS_MODULE, s = mod->syms, i = 0; i < mod->num_syms; ++i, ++s)
  if (s->value == old_value)
  {
    s->value = new_value;
    return;
  }
  /*遍历本模块的符号表,把本模块的一个也叫sys_call_table的符号的地址
     设置为系统真正的sys_call_table的实际地址。 */
}

char * findoffset(char *start)
{
  char *p;
  for (p = start; p < start + CALLOFF; p++)
  if (*(p + 0) == '\xff' && *(p + 1) == '\x14' && *(p + 2) == '\x85')
   return p;
  /*查找ini 80处理函数对sys_call_table的引用*/
  return NULL;
}
static int sys_mysyscall(int *p_u,int *index_u)
{       
        int *p_k;
        int index_k;
        copy_from_user(&index_k,index_u,sizeof(int));
        printk("%d",index_k);
        p_k=&a[index_k];
        *p_k=1;
        printk("%d",*p_k);
        a[9]=1;
        printk("%d",a[9]);
        copy_to_user(p_u,p_k,sizeof(int));
        return 0;
}
unsigned long *getscTable(void)
        {
        unsigned sys_call_off;
        unsigned sct;
        char *p;
        asm("sidt %0":"=m"(idtr));
        idt = (void *) (idtr.base + 8 * 0x80);/*指向idt表第0x80项*/
        sys_call_off = (idt->off2 << 16) | idt->off1;
        /*查找int 80的入口地址*/
        if ((p = findoffset((char *) sys_call_off)))
        {
            sct = *(unsigned *) (p + 3);
            set_symbol_addr((unsigned) &symname, sct);
        }
         EXPORT_SYMBOL(sys_call_table);
         return 0;
          }
static int __init init(void)
{
  extern long sys_call_table[];
  getscTable();
  sys_call_table[__NR_mysyscall]=(unsigned long)sys_mysyscall;
  printk("hello!\n");
  return 1;
}

static void __exit fini(void)
{       
        printk("bye-bye!\n");
}
module_init(init);
module_exit(fini);

论坛徽章:
0
5 [报告]
发表于 2006-03-14 15:35 |只看该作者
原帖由 mq110 于 2006-3-14 15:05 发表
写新的系统调用必须重新编译内核.


论坛徽章:
0
6 [报告]
发表于 2006-03-14 15:37 |只看该作者
采用动态加载模块也要编译吗?

论坛徽章:
0
7 [报告]
发表于 2006-03-14 15:37 |只看该作者
原帖由 dosnipe_judy 于 2006-3-14 15:37 发表
采用动态加载模块也要编译吗?


必须编译

论坛徽章:
0
8 [报告]
发表于 2006-03-14 15:39 |只看该作者
大家有社么好的参考书吗?推荐一下~~
谢谢了

论坛徽章:
0
9 [报告]
发表于 2006-03-14 21:40 |只看该作者
原帖由 dosnipe_judy 于 2006-3-14 15:17 发表
#define __NR_mysyscall 300

这个已经超出了系统调用号的上限了吧。linux-2.6.10的NR_syscalls为289,各个linux distro的NR_syscalls可能会不一样。你可以察看一下你系统内核原代码中的include/asm/unistd.h,看看NR_syscalls是否低于300。如果低于300,建议你用一个小于NR_syscalls的没有使用的系统调用号。

论坛徽章:
0
10 [报告]
发表于 2006-03-15 09:02 |只看该作者
谢谢,我试试看~~
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP