Як додати системний виклик до ядра Linux
Серпень 1st, 2010Системний виклик — це інтерфейс між адресним простором користувача (user-space) і сервісами, які надаються ядром Linux. Оскільки даний сервіс надається ядром, виконати функцію ядра напряму не є можливим; тому слід використовувати спеціальний інтерфейс між простором ядра та користувача. Таким інтерфейсом є системний виклик (system call).
Ядро використовує системні виклики для надання програмам, які працюють у просторі користувача спосіб для запиту на отримання певних сервісів від неї, які у звичайних умовах не дозволяються. До таких сервісів належать постійна пам’ять, оперативна пам’ять, мережа, управління процесами, тощо.. Наприклад, якщо процес у просторі користувача захоче прочитати файл — йому доведеться виконати системні виклики ‘open’ та ‘read’.
Системні виклики не викликаються процесами безпосередньо. Зазвичай, у стандартній бібліотеці мови С присутні функції-обгортки, які надають зручні інтерфейси до усіх системних викликів.
У цій статті я коротенько опишу Linux system calls interface, і покажу, як додати до ядра новий системний виклик. Я використовував ядро версії 2.6.32.
Для платформи x86:
1. Додаємо у кінець таблиці системних викликів, яка міститься у файлі arch/x86/include/asm/unistd_32.h:
1 | #define __NR_myage 337 |
Якщо платформа x86_64 — до файлу arch/x86/include/asm/unistd_64.h додаємо:
1 2 | #define __NR_myage 299 __SYSCALL(__NR_myage, sys_myage) |
2. Змінюємо лічильник NR_syscalls, у тому ж файлі:
1 | #define NR_syscalls 338 |
3. Додаємо до файлу arch/x86/kernel/syscall_table_32.S
1 | .long sys_myage /* 337 */ |
4. Додаємо прототип функції системного виклику до файлу include/linux/syscalls.h
1 | asmlinkage long sys_myage(void); |
5. Пишемо сам системний виклик
1 2 3 4 5 6 7 8 | #include <linux/syscalls.h> #include <linux/linkage.h> asmlinkage long sys_myage(void) { return 22; } |
Тепер найцікавіше — перевірка нашого syscall`а шляхом його виклику з простору користувача. Для цього використовується функція syscall(), прототип якої міститься у заголовному файлі sys/sycall.h.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | #include <stdio.h> #include <linux/unistd.h> #include <sys/syscall.h> #define __NR_myage 299 int main(void) { long myage; myage = syscall(__NR_myage); printf("Sashko, u r %ld years old.\n", myage); return 0; } |



Comments
Powered by Facebook Comments