Ошибка: конфликтующие типы при попытке сделать простой системный вызов - PullRequest
0 голосов
/ 31 января 2020

Я новичок в Linux программировании и пытаюсь реализовать простой системный вызов, следуя этому руководству: https://medium.com/anubhav-shrimal/adding-a-hello-world-system-call-to-linux-kernel-dad32875872. В моем каталоге ядра linux я создал новый каталог с именем my_syscall. В этом каталоге я создал my_syscall.c. Вот my_syscall.c

#include <linux/syscalls.h>
#include <linux/kernel.h>

asmlinkage long sys_my_syscall(int i) {
   prink(KERN_INFO "This is the system call.");
   return(0);
}

Затем я создал Makefile в каталоге my_syscall одной строкой:

obj-y := my_syscall.o

Затем я отредактировал эту строку в Makefile в каталоге ядра:

core-y         += kernel/ certs/ mm/ fs/ ipc/ security/ crypto/ block/ my_syscall/

Затем в каталоге linux-5.4.15/arch/x86/entry/syscalls я отредактировал syscall_64.tbl, добавив в самом конце следующую строку:

548     64         my_syscall          sys_my_syscall

Наконец, в каталоге linux-5.4.15/include/linux я отредактировал файл syscalls.h, чтобы включить эту строку перед #endif:

asmlinkage long sys_my_syscall(int i);

Теперь, когда я запускаю команду sudo make, я сталкиваюсь с следующая ошибка вскоре после:

./arch/x86/include/generated/asm/syscalls_64.h:2664:19: error: conflicting types for 'sys_my_syscall'
__SYSCALL_64(548, sys_my_syscall, )

arch/x86/entry/syscall_64.c:18:60: note: in definition of macro '__SYSCALL-64'
  #define __SYSCALL_64(nr, sym, qual) extern asmlinkage long sym(const struct pt_regs *);

In file included from arch/x86/entry/syscall_64.c:7:0:
./include/linux/syscalls.h:1423:17: note: previous declaration of 'sys_my_syscall' was here
 asmlinkage long sys_my_syscall(int i);
                 ^
make[3]: *** [arch/x86/entry/syscall_64.o] Error 1
make[2]: *** [arch/x86/entry] Error 2
make[1]: *** [arch/x86] Error 2
make: *** [sub-make] Error 2

Я не знаю, как подойти к этой ошибке. С ошибкой конфликтующих типов, я думаю, я где-то объявил системный вызов по-разному, но и в файлах my_syscall.c и syscalls.h объявление одно и то же. Это были только два файла, в которых объявлен системный вызов, но он также назван в пределах syscall_64.tbl, и кажется, что именно здесь linux пытается указать мне. Тем не менее, я не вижу, что не так с тем, как я объявил это в таблице, поскольку я следовал непосредственно руководству. Любая помощь с этим будет принята с благодарностью!

Информация:

Версия ядра: 5.4.15

Linux Распространение: Ubuntu 14

Ответы [ 4 ]

1 голос
/ 13 марта 2020

Я только что изменил место, где номер системного вызова определен в syscall_64.tbl .

Вместо этого:

548     64         my_syscall          sys_my_syscall

Я написал это:

436     common     my_syscall          __x64_sys_my_syscall

Снимок экрана моей конфигурации

Это сработало.

1 голос
/ 31 января 2020

Я делаю нечто подобное и получил точно такую ​​же ошибку.

Что исправило ошибку для меня, так это изменение последней части записи таблицы syscall_64.tbl с "sys_my_syscall" на "__x64_sys_my_syscall". Если вы прокрутите вверх, другие записи будут иметь такой же префикс. Ядро начало компилироваться после того, как я сделал это изменение.

0 голосов
/ 03 февраля 2020

В конце концов я перестал пытаться реализовать это в ядре 5. К сожалению, ни одно из других решений не привело к компиляции моего ядра. Я откатил свое ядро ​​и выполнил шаги здесь . Это привело к тому, что системный вызов работает правильно. Я не уверен, как сделать эту функцию в ядре 5+.

0 голосов
/ 31 января 2020

Некоторые архитектуры (включая x86-64) используют оболочки syscall для вызова реального обработчика syscall. Чтобы определить настоящий обработчик системного вызова и его оболочки (для архитектур, использующих оболочки системного вызова), используйте один из макросов SYSCALL_DEFINE<n> перед телом обработчика системного вызова. Параметрами макросов SYSCALL_DEFINE<n> являются имя функции, за которыми следуют <n> пары `` type , param '' для параметров функции.

Ваша функция обработчика системного вызова sys_my_syscall имеет один параметр, поэтому используйте макрос SYSCALL_DEFINE1 перед телом функции:

#include <linux/syscalls.h>
#include <linux/kernel.h>

SYSCALL_DEFINE1(sys_my_syscall, int, i)
{
   printk(KERN_INFO "This is the system call (param %d).\n", i);
   return(0);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...