免费注册 查看新帖 |

Chinaunix

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

关于多参数系统调用的实现 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2008-10-11 15:59 |只看该作者 |倒序浏览
新手一个,看了linux0.11系统调用过程以后,
由于寄存器有限,所以最多只能传三个参数。
现在的想法是添加一个int ** ,调用system_Ncall,专门处理。
不禁想知道多参数如何调用,请指教。

实验报告中写的,如下:

--在可用寄存器为有限情况下:
参数传递是在堆栈中实现的(as far as  i can see),包括系统调用,中的系统函数,读的亦是系统的堆栈,而linux0.11
时,调用afun(int a,int b, int c)系统堆栈是这样的

                |%edx| 值为c
                |%ecx| 值为b
                |%eax| 值为a
                |   pc  |
%ebp->        |%ebp|
                |.........|
                ...........
%esp->  |..........|
参数通过ebp读入

现在,
实现 void forfun(int a, int b, int c, int d)
我们可以通过修改unistd.h
unistd.h定义的宏函数运行在用户空间,我们可以加一个宏函数,里面的asm代码
相应地:
%ebx 用户堆栈中最小地址的,

#define _syscall4(type,name,atype,a,btype,b,ctype,c,dtype,d) \
type name(atype a,btype b, ctype c, dtype d ) \
{ \
long __res; \
int*__pt__=__&a;\
int__num__=__4;\       //<-格式暂不知道是否正确
__asm__ volatile ("int $0x80" \
        : "=a" (__res) \
        : "0" (__NR_##name),"b" ((long)(pt)),"c" ((long)(num))); \
if (__res >= 0) \
        return (type) __res; \
errno = -__res; \
return -1; \
}
然后修改     system_call.s   通过fs 读用户空间的堆栈,pt得到地址,num控制边界。将得到的数据压栈然后再call相应的内核的函数
但是这样的话并不会的到效率的提高,相反,由于无论大小,只用一套(基址,个数...),所以,大大的减低了三个以下参数的系统调用的实现。
也是由于这样,暂不知道怎样测试。
折中的方法是不修改system_call.s 修改内核函数的定义,或者再用另外一个中断专门给system_call2(专为多参版本服务的),但不知道可不可行。
到头来感觉不如不改,直接在有需要的时候再通过传指针方式减少参数就算了。

剩下个问题,当时怎样传long long  ??

论坛徽章:
0
2 [报告]
发表于 2008-10-11 17:55 |只看该作者
不解,为什么最多只能传三个参数呢?目前系统调用时候参数按照ebx,ecx,edx,esi,edi,ebp使用寄存器,所以可以有6个寄存器使用啊,比如系统调用最终跳转到的函数
asmlinkage long sys_open(const char __user *filename, int flags, int mode)
{
        long ret;

        if (force_o_largefile())
                flags |= O_LARGEFILE;

        ret = do_sys_open(AT_FDCWD, filename, flags, mode);
        /* avoid REGPARM breakage on x86: */
        asmlinkage_protect(3, ret, filename, flags, mode);
        return ret;
}
此处使用的三个参数就是通过ebx,ecx,edx传递的,eax传递系统调用号。

论坛徽章:
0
3 [报告]
发表于 2008-10-12 13:44 |只看该作者
不用想太麻烦,想传多个参数,可以把它们封装在一个结构体中,以指针形式传下去,然后copy_from_user。
这是最标准的做法

论坛徽章:
0
4 [报告]
发表于 2008-10-12 18:39 |只看该作者

回复 #3 zx_wing 的帖子

就是说,我们可以通过修改库函数实现了?

论坛徽章:
0
5 [报告]
发表于 2008-10-12 22:05 |只看该作者
原帖由 jasonjan1987 于 2008-10-12 18:39 发表
就是说,我们可以通过修改库函数实现了?

不是。
你想自己给内核加系统调用?这个不现实。
如果你想完成类似功能,可以自己写一个模块,然后通过ioctl实现
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP