Я получаю работу ядра в течение нескольких летних исследований. Мы хотим внести изменения в TCP, в конкретных расчетах RTT. То, что я хотел бы сделать, это заменить разрешение одной из функций в tcp_input.c на функцию, предоставляемую динамически загруженным модулем ядра. Я думаю, что это улучшит темпы, с которыми мы можем развить и распространить модификацию.
Функция, которая меня интересует, была объявлена как статическая, однако я перекомпилировал ядро с функцией non-static и экспортировал EXPORT_SYMBOL. Это означает, что теперь функция доступна для других модулей/частей ядра. Я подтвердил это с помощью "cat/proc/kallsyms".
Теперь я хотел бы иметь возможность загрузить модуль, который может переписать адрес символа из начальной в мою динамически загруженную функцию. Аналогичным образом, когда модуль должен быть выгружен, он восстановит исходный адрес. Это приемлемый подход? У вас есть предложения по улучшению этой функции?
Спасибо!
То же, что Переопределение функциональности с помощью модулей в ядре Linux
Edit:
Это был мой возможный подход.
Учитывая следующую функцию (которую я хотел бы переопределить и не экспортировал):
static void internal_function(void)
{
// do something interesting
return;
}
измените так:
static void internal_function_original(void)
{
// do something interesting
return;
}
static void (*internal_function)(void) = &internal_function_original;
EXPORT_SYMBOL(internal_function);
Это переопределяет ожидаемый идентификатор функции вместо этого как указатель функции (который можно вызвать аналогичным образом), указывающий на первоначальную реализацию. EXPORT_SYMBOL() делает адрес глобально доступным, поэтому мы можем изменить его из модуля (или другого местоположения ядра).
Теперь вы можете написать модуль ядра со следующей формой:
static void (*original_function_reference)(void);
extern void (*internal_function)(void);
static void new_function_implementation(void)
{
// do something new and interesting
// return
}
int init_module(void)
{
original_function_reference = internal_function;
internal_function = &new_function_implementation;
return 0;
}
void cleanup_module(void)
{
internal_function = original_function_reference;
}
Этот модуль заменяет исходную реализацию динамически загруженной версией. При разгрузке восстанавливается исходная ссылка (и реализация). В моем конкретном случае я представил новую оценку для RTT в TCP. Используя модуль, я могу сделать небольшие настройки и перезапустить тестирование, без перекомпиляции и перезагрузки ядра.