Это невозможно, потому что таблица системных вызовов (называемых 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Например) номер системного вызова с вашим, так как для этого не потребуется больше места в памяти. Некоторые архитектуры также могут иметь дыры в таблице системных вызовов (например, 64-битная версия x86), так что вы также можете использовать это.
Вы можете использовать эту технику, если вы разрабатываете новый системный вызов и просто хотите избежать перезагрузки во время экспериментов. Вам нужно будет определить новый системный вызов, найти существующую запись в таблице системных вызовов, а затем заменить ее из вашего модуля.
Делать это из модуля ядра нетривиально, поскольку ядро не экспортирует sys_call_tableв модули начиная с версии 2.6 (последняя версия ядра, в которой был экспортирован этот символ 2.5.41).
Один из способов обойти это - изменить свое ядро, чтобы экспортировать sys_call_tableсимвол в модули. Чтобы сделать это, вы должны добавить следующие две строки kernel/kallsyms.c( не делайте этого на производственных машинах ):
extern void *sys_call_table;
EXPORT_SYMBOL(sys_call_table);
Другой метод заключается в динамическом поиске таблицы системных вызовов. Вы перебираете память ядра, сравнивая каждое слово с указателем на известную функцию системного вызова. Поскольку вы знаете смещение этого известного системного вызова в таблице, вы можете вычислить начальный адрес таблицы.