我正在尝试创建一个自定义系统调用,该系统调用输入一个(长)数组并输出有关该数组的一些基本信息以进行类分配。
我在将适当的参数传递给系统调用时遇到了一些麻烦。
下面是我用来调试这个系统调用的测试程序:
#include <stdio.h>
#include <unistd.h>
#include <sys/syscall.h>
#include "array_stats.h"
#define _ARRAY_STATS_ 341 // for a 64 bit system
int main () {
struct array_stats * stats;
long ary[3];
ary[0] = 1;
ary[1] = 2;
ary[2] = 3;
long s = 3;
printf("\nDiving to kernel level\n\n");
// Calling array_stats syscall
int result = syscall(_ARRAY_STATS_, &stats, ary, s);
printf("\nRising to user level w/ result = %d\n\n", result);
return 0;
}
这是array_stats
系统调用,我插入了一堆printk()
用于调试目的的语句:
#include <linux/kernel.h>
#include <asm/errno.h>
#include <linux/uaccess.h>
#include "array_stats.h"
asmlinkage long sys_array_stats (struct array_stats *stats, long data[], long size) {
printk("1. %s\n", "System call started");
long loc_max;
long loc_min;
long loc_sum;
long local_data[size];
int i = 1;
int result = 0;
printk("2. %s\n", "Variables created");
printk("Size %lu\n", size);
printk("data[0] = %lu\n", data[0]);
printk("data[1] = %lu\n", data[1]);
printk("data[2] = %lu\n", data[2]);
if (size <= 0) return -EINVAL;
printk("3. %s\n", "Size validated");
result = copy_from_user (local_data, data, size * sizeof * data);
if (!result) return EFAULT;
loc_max = local_data[0];
loc_min = local_data[0];
loc_sum = local_data[0];
for (; i < loc_sum; i++) {
loc_sum += local_data[i];
if (local_data[i] < loc_min) loc_min = local_data[i];
if (local_data[i] > loc_max) loc_max = local_data[i];
}
stats -> min = loc_min;
stats -> max = loc_max;
stats -> sum = loc_sum;
printk("Min: %lu\n", loc_min);
printk("Max: %lu\n", loc_max);
printk("Sum: %lu\n", loc_sum);
return result;
}
测试程序的运行结果如下:
root@debian-amd64:~# ./array_stats_test
Diving to kernel level
[ 92.735994] 1. System call started
[ 92.737851] 2. Variables created
[ 92.738037] Size 0
[ 92.738155] data[0] = 0
[ 92.738417] data[1] = 6955032
[ 92.738565] data[2] = 0
Rising to user level w/ result = -1
root@debian-amd64:~#
如您所见,参数没有正确传递。我究竟做错了什么?
提前致谢!