2014-11-15 2 views
3

У меня возникли трудности с вызовом системного вызова из модуля ядра Linux. Системные вызовы были протестированы и исправлены из стандартной программы пользовательского пространства c, но я не могу заставить модуль ядра компилировать и запускать их.Как использовать системный вызов Linux из модуля ядра Linux

В моей программе я включил следующий код и работу системных вызовов:

#include <linux/unistd.h> 
#define __NR_sys_mycall 343 

extern long int _syscall(long int_sysno,...)__THROW; 

//and then a simple call is done as such 
long value = syscall(__NR_sys_mycall); 

printf("The value is %ld\n",value); 

Но когда я пытаюсь то же самое в моем модуле ядра Linux я получаю кучу ошибок, либо сказать, ошибка: неявный объявление функции «syscall» (если я не включаю определение _syscall) или длинный список ошибок в синтаксисе, если я это сделаю ... поэтому мое предположение заключается в том, что мне нужна версия пространства ядра для вызова системного вызова. Я прав или неправ?

//My LKM code 
#include <linux/module.h> 
#include <linux/unistd.h> 
#define __NR_sys_mycall 343 

static int start_init(void) 
{ 
    long value = syscall(__NR_sys_mycall); 
    printk("The value is %ld\n",value); 

    return 0; 
} 

static void finish_exit(void) 
{ 
     printk("Done!\n"); 
} 

module_init(start_init); 
module_exit(finish_exit); 
+4

Почему вы пытаетесь использовать системные вызовы в модуле ядра? 99,95% времени, используя системные вызовы в модуле ядра, является неправильным способом делать все, что вы пытаетесь сделать. – tangrs

+0

Мне нужно использовать kmalloc несколько раз, а затем измерять среднюю фрагментацию, вызванную моей доработкой одного из распределителей памяти Linux. Системные вызовы предоставляют результирующую информацию, а LKM позволяет мне использовать kmalloc ... скорее это требование ... поэтому я хотел бы иметь возможность выделять, а затем звонить по системным вызовам сразу после. – dimlee

+3

Это звучит как работа для * sysfs *, которая построена для того, что вам нужно: экспорт информации из ядра в пользовательское пространство. Вы также можете написать драйвер устройства символов. Также есть * procfs * и * netlink *. Написание всего нового системного вызова, вероятно, является наименее правильным способом делать то, что вы пытаетесь сделать. – tangrs

ответ

4

Вы можете напрямую позвонить sys_mycall.

#include <linux/module.h> 
#include <linux/unistd.h> 


static int start_init(void) 
{ 
    long value = sys_mycall (pass_arguments) 
    printk("The value is %ld\n",value); 

    return 0; 
} 

static void finish_exit(void) 
{ 
     printk("Done!\n"); 
} 

module_init(start_init); 
module_exit(finish_exit); 
3

В большинстве системных вызовов используется asmlinkage, что означает поиск аргументов в стеке, а не регистров. Убедитесь, что при вызове системного вызова передайте аргументы в стеке.

Также много системных вызовов просто использует copy_from_user. Если вы передаете адрес ядра в такой системный вызов, они терпят неудачу.

+0

плюс 1 для copy_from_user получения упоминания об ошибке адреса ядра. – RootPhoenix

+0

syscall аргументы не всегда передаются в стек; это зависит от вашей архитектуры, а также от ядра. Например, см. [Что такое вызовы для системных вызовов UNIX и Linux на x86-64] (http://stackoverflow.com/questions/2535989/what-are-the-calling-conventions-for-unix-linux -Система-звонки-на-x86-64) – jrodatus

Смежные вопросы