Linux内核学习之syscall的使用

前言:本篇我们将讨论如何向系统调用传递的参数,包括单向参数和双向参数的传递,以及如何实现内核态到用户态的批量数据传递。

关于syscall的说明
syscall是x64的系统调用(在用户程序中使用,需要#include<unistd.h>)
其参数通过标签为pt_regs的结构体进行传递,x86_64下的sysdep.h文件给出如下说明

/* The Linux/x86-64 kernel expects the system call parameters in
   registers according to the following table:
    syscall number  rax
    arg 1    rdi
    arg 2    rsi
    arg 3    rdx
    arg 4    r10
    arg 5    r8
    arg 6    r9
......
*/
#define DO_CALL(syscall_name, args)                \
  lea SYS_ify (syscall_name), %rax;                \
  syscall

经过测试,syscall调用号通过rax进行传递,其余参数传递顺序为:rdi,rsi,rdx,r10,r8,r9

关于asmlinkage的说明
asmlinkage作用就是告诉编译器,函数参数不是用寄存器来传递,而是用堆栈来传递。
采用asmlinkage,原因是因为用户态在系统调用时进入到内核态,会吧用户态的寄存器全部圧栈,通过合理的构造。正好满足用户态通过寄存器传递参数,内核态通过栈取参数的标准要求。

本实验不采用上面的方式,采用直接用寄存器传参。
1.单向参数传递(传递整型)

static int mycall(struct pt_regs *regs)
{
	int res = (regs->di+regs->si+regs->dx+regs->r10);
	printk("My syscall is successful!\n");
	return res;
}

int main()
{
        unsigned long x = 0;
        x = syscall(399,101,202,303,404);    //测试399号系统调用,增加四个参数
        printf("syscall result: %ld\n", x);
        return 0;
}

makefile
obj-m:=mycall.o
PWD:= $(shell pwd)
KERNELDIR:= /lib/modules/$(shell uname -r)/build
EXTRA_CFLAGS= -O0
​
all:
    make -C $(KERNELDIR)  M=$(PWD) modules
​
ins:
    sudo insmod mycall.ko
​
rm:
    sudo rmmod mycall
​
.PHONY:test
test:test.c
    gcc -g test.c -o test.exe
    ./test.exe
​
.PHONY:clean
clean:
    make -C $(KERNELDIR) M=$(PWD) clean
    rm *.exe
计算结果与预期一致,表明四个整型参数都传递成功

2.双向参数传递(传递指针)
2.1在内核态直接写入用户态内存

/* 采用寄存器传递参数 */
//di,rsi,rdx,r10,r8,r9
static int mycall(struct pt_regs *regs)
{
    int* A = (int*)regs->di;int i;
    for(i=0;i<512;i++)
    {
        A[i]=i;
    }printk("My syscall is successful!\n");return 0;
}
int A[512];int main()
{
        unsigned long x = 0;
        x = syscall(399,A);    //测试399号系统调用
        
        int i;
        for(i=0;i<512;i++)
        {
                printf("%d\n", A[i]);
        }
        
        return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值