Це неможливо, оскільки таблиця системних викликів (call sys_call_table) - це масив статичного розміру. А його розмір визначається в момент компіляції за кількістю зареєстрованих системних дзвінків. Це означає, що немає місця для іншого.
Ви можете перевірити реалізацію, наприклад, архітектури x86 у arch/x86/kernel/syscall_64.cфайлі, де sys_call_tableвизначено. Її розмір рівно __NR_syscall_max+1. __NR_syscall_maxвизначається arch/x86/kernel/asm-offsets_64.cяк sizeof(syscalls) - 1(це номер останнього систематичного виклику), де syscallзнаходиться таблиця з усіма системними дзвінками.
Одне можливе рішення - повторно використовувати деякий існуючий (або застарілий), якщо у вашій архітектурі є такий, див., sys_setaltrootНаприклад, номер системного виклику з вашим, оскільки це не потребує більше місця в пам'яті. Деякі архітектури також можуть мати отвори в таблиці syscall (наприклад, 64-бітна версія x86), тому ви можете також використовувати це.
Ви можете використовувати цю техніку, якщо ви розробляєте нові syscall і просто хочете уникнути перезавантаження під час експериментів. Вам потрібно буде визначити ваш новий системний виклик, знайти існуючий запис у таблиці syscall та замінити його у своєму модулі.
Зробити це з модуля ядра не тривіально, оскільки ядро не експортує sys_call_tableдо модулів, починаючи з версії 2.6 (остання версія ядра, яка експортувала цей символ 2.5.41).
Один із способів подолати це - змінити ваше ядро на експорт sys_call_tableсимволу в модулі. Для цього вам потрібно додати наступні два рядки до kernel/kallsyms.c( не робити цього на виробничих машинах ):
extern void *sys_call_table;
EXPORT_SYMBOL(sys_call_table);
Ще одна методика - динамічно знаходити таблицю syscall. Ви перебираєте пам'ять ядра, порівнюючи кожне слово із вказівником із відомою функцією системного виклику. Оскільки ви знаєте зміщення цього системного виклику знань у таблиці, ви можете обчислити початкову адресу таблиці.