¿Puedo reemplazar una función del kernel de Linux con un módulo?

Me estoy metiendo en el trabajo del núcleo para un poco de mi investigación de verano. Estamos buscando hacer modificaciones al TCP, en cálculos específicos de RTT. Lo que me gustaría hacer es reemplazar la resolución de una de las funciones en tcp_input.c por una función proporcionada por un módulo de kernel cargado dinámicamente. Creo que esto mejoraría el ritmo al que podemos desarrollar y distribuir la modificación.

La función en la que estoy interesado fue declarada como estática, sin embargo, he recompilado el kernel con la función no estática y exportado por EXPORT_SYMBOL. Esto significa que la función ahora es accesible a otros módulos / partes del kernel. He verificado esto por "cat / proc / kallsyms".

Ahora me gustaría poder cargar un módulo que pueda reescribir la dirección del símbolo de la función inicial a mi función dinámicamente cargada. Del mismo modo, cuando se descargue el módulo, se restaurará la dirección original. ¿Es este un enfoque factible? ¿Todos tienen sugerencias de cómo esto podría implementarse mejor?

¡Gracias!

Igual queReemplazo de la funcionalidad con módulos en el kernel de Linux.

Editar:
Este fue mi enfoque final.
Dada la siguiente función (que quise anular y no se exporta):

static void internal_function(void) 
{
  // do something interesting
  return;
}

modifica así

static void internal_function_original(void)
{
  // do something interesting
  return;
}

static void (*internal_function)(void) = &internal_function_original;
EXPORT_SYMBOL(internal_function);

Esto redefine el identificador de función esperado como un puntero de función (que se puede llamar de una manera similar) que apunta a la implementación original. EXPORT_SYMBOL () hace que la dirección sea accesible globalmente, por lo que podemos modificarla desde un módulo (u otra ubicación del kernel).

Ahora puedes escribir un módulo de kernel con el siguiente formulario:

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;
}

Este módulo reemplaza la implementación original con una versión cargada dinámicamente. Al descargar, se restaura la referencia original (y la implementación). En mi caso específico, proporcioné un nuevo estimador para el RTT en TCP. Al usar un módulo, puedo hacer pequeños ajustes y reiniciar las pruebas, todo sin tener que volver a compilar y reiniciar el kernel.

Respuestas a la pregunta(4)

Su respuesta a la pregunta