Єдина Країна! Единая Страна!

Як додати системний виклик до ядра 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;
}

Коментарі

коментарі

Powered by Facebook Comments

Leave a Reply