Как писать системные вызовы на debian / ubuntu
Я пытаюсь написать свой собственный системный вызов. Он просто вернет текущее время. Я знаю концепцию того, что я должен делать, и я действительно прошел через пару ссылок, таких как:
Но я все еще в замешательстве и не получил желаемого результата. Ядро не компилируется и его сбой из-за проблем. У меня есть попробовал его на debian последней стабильной версии 3.X. XМожет ли кто-нибудь указать мне на чистую hello world
программу для разработки системных вызовов?
EDIT
На следующий ответ , Вот мои проблемы:
File 3: linux-x.x.x/arch/x86/kernel/syscall_table_32.S
не найден в моей папке linux. Мне пришлось импровизировать и поэтому я изменил следующий файл:linux-x.x.x/arch/x86/syscalls/syscall_64.tbl
-
Упомянутый выше (1) новый файл имел другой шаблон
<number> <64/x32/common> <name> <entry point>
, и моя запись была ' 313 common -
Образ ядра компилировался успешно, но я не мог вызвать функцию. Он дает
undefined reference" error
, Когда я компилирую его с gcc. Почему?
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).