Как писать системные вызовы на debian / ubuntu


Я пытаюсь написать свой собственный системный вызов. Он просто вернет текущее время. Я знаю концепцию того, что я должен делать, и я действительно прошел через пару ссылок, таких как:

Но я все еще в замешательстве и не получил желаемого результата. Ядро не компилируется и его сбой из-за проблем. У меня есть попробовал его на debian последней стабильной версии 3.X. X

Может ли кто-нибудь указать мне на чистую hello world программу для разработки системных вызовов?

EDIT

На следующий ответ , Вот мои проблемы:

  1. File 3: linux-x.x.x/arch/x86/kernel/syscall_table_32.S не найден в моей папке linux. Мне пришлось импровизировать и поэтому я изменил следующий файл: linux-x.x.x/arch/x86/syscalls/syscall_64.tbl

  2. Упомянутый выше (1) новый файл имел другой шаблон <number> <64/x32/common> <name> <entry point> , и моя запись была ' 313 common

  3. Образ ядра компилировался успешно, но я не мог вызвать функцию. Он дает undefined reference" error , Когда я компилирую его с gcc. Почему?

2 3

2 ответа:

Это просто пример того, как написать простой системный вызов ядра. Рассмотрим следующую функцию C system_strcpy (), которая просто копирует одну строку в другую: аналогично тому, что делает strcpy ().

#include<stdio.h>

long system_strcpy(char* dest, const char* src)
{
   int i=0;
   while(src[i]!=0)
      dest[i]=src[i++];

   dest[i]=0;
   return i;
}

Прежде чем писать, получите исходный код ядра tar и распакуйте его, чтобы получить каталог linux-x.x.x.

Файл 1: linux-x. x. x/test / system_strcpy.c Создайте в linux-x.x.x каталог с именем test и сохраните в нем этот код в виде файла system_strcpy.c.

#include<linux/linkage.h>
#include<linux/kernel.h>
asmlinkage long system_strcpy(char*dest, const char* src)
{
   int i=0;
   while(src[i]!=0)
      dest[i]=src[i++];

   dest[i]=0;
   return i;
}

Файл 2: linux-x.x. x/test / Makefile Создайте Makefile в том же каталоге test, который вы создали выше, и поместите в него следующую строку:

obj-y := system_strcpy.o

Файл 3: linux-x.x. x/arch / x86 / kernel/syscall_table_32.S Теперь необходимо добавить системный вызов в таблицу системных вызовов. Добавьте к файлу следующую строку:

.long system_strcpy

примечание: для ядра 3.3 и более поздних версий.

*см.: linux-3.3.ХХ/арки/х86/системных вызовов/syscall_64.tbl*

И в теперь добавьте в конце следующей серии строк:

310 64 process_vm_readv sys_process_vm_readv

311 64 process_vm_writev sys_process_vm_writev

312 64 kcmp sys_kcmp

313 64 system_strcpy system_strcpy

Формат для версии 3.3 находится в: number abi name entry point

Файл 4: linux-x.x. x/arch / x86 / include/asm / unistd_32.h

Примечание: этот раздел является избыточным для версий ядра 3.3 и выше

В этом файле имена всех системных вызовов будут связаны с уникальным номером. После последней пары системный вызов-номер добавьте строку

#define __NR_system_strcpy 338

(если 337-номер, связанный с последним системным вызовом в паре системный вызов-номер).

Затем замените значение NR_syscalls, указав общее число системных вызовов с (существующее число увеличивается на 1), то есть в этом случае NR_syscalls должно было быть 338, а новое значение-339.

#define NR_syscalls 339

Файл 5: linux-x. x. x / include / linux / syscalls.h

Добавьте в файл прототип нашей функции.

asmlinkage long system_strcpy(char *dest,char *src);

Непосредственно перед строкой #endif в файле.

Файл 6: Makefile в корне исходного каталога.

Откройте Makefile и найдите строку, в которой определено core-y, и добавьте Каталог test до конца этой строки.

core-y += kernel/ mm/ fs/ test/

Теперь скомпилируем ядро. Вопрос: make bzImage -j4

Установите ядро, выполнив следующую команду как root(или с правами root): make install

Перезагрузите систему.

Для использования недавно созданного системного вызова используйте:

syscall(338,dest,src); (или syscall(313,dest,src); для ядра 3.3+) вместо обычной библиотечной функции strcpy.

#include "unistd.h"
#include "sys/syscall.h"
int main()
{
 char *dest=NULL,*src="Hello";
 dest=(char*)malloc(strlen(src)+1);
 syscall(338,dest,src);//syscall(313,dest,src); for kernel 3.3+
 printf("%s \n %s\n",src,dest);
 return 0;
}

Вместо таких чисел,как 313 и т. д. В syscall, вы также можете напрямую использовать __NR_system_strcpy

Это общий пример. Вам нужно будет немного поэкспериментировать, чтобы увидеть, что работает для вашей конкретной версии ядра.

Приведенный выше ответ не работает для ядер 3.5.0 и 3.7.6, вызывая неопределенную ошибку компиляции ссылок. Чтобы устранить проблему linux / syscalls.h должен быть включен в system_strcpy.c вместо linux / linkage.h. кроме того, для определения системного вызова лучше использовать SYSCALL_DEFINE2(strcpy, dest, src).