Я пытаюсь создать собственный системный вызов, который вводит (длинный) массив и выводит некоторую базовую информацию об этом массиве для назначения класса.
У меня возникают некоторые проблемы при передаче соответствующих аргументов в системуcall.
Ниже приведена тестовая программа, которую я использую для отладки этого системного вызова:
#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:~#
Как видите, аргументы не передаются должным образом.Что я делаю не так?
Заранее спасибо!