Posso substituir uma função de kernel do Linux por um módulo?

Estou entrando no trabalho do kernel para um pouco da minha pesquisa de verão. Estamos procurando fazer modificações no TCP, em cálculos RTT específicos. O que eu gostaria de fazer é substituir a resolução de uma das funções em tcp_input.c para uma função fornecida por um módulo de kernel carregado dinamicamente. Acho que isso melhoraria o ritmo em que podemos desenvolver e distribuir a modificação.

A função em que estou interessado foi declarada como estática, porém eu recompilei o kernel com a função não-estática e exportada por EXPORT_SYMBOL. Isso significa que a função agora está acessível para outros módulos / partes do kernel. Eu verifiquei isso por "cat / proc / kallsyms".

Agora eu gostaria de poder carregar um módulo que possa reescrever o endereço do símbolo desde a inicial até a minha função carregada dinamicamente. Da mesma forma, quando o módulo é para ser descarregado, ele irá restaurar o endereço original. Esta é uma abordagem viável? Vocês todos têm sugestões de como isso pode ser melhor implementado?

Obrigado!

Igual aSubstituindo a funcionalidade com módulos no kernel do Linux

Editar:
Esta foi a minha abordagem final.
Dada a seguinte função (que eu queria substituir e não é exportada):

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

modificar assim:

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

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

Isso redefine o identificador de função esperado como um ponteiro de função (que pode ser chamado de maneira semelhante) apontando para a implementação original. EXPORT_SYMBOL () torna o endereço globalmente acessível, para que possamos modificá-lo a partir de um módulo (ou outro local do kernel).

Agora você pode escrever um módulo do kernel com o seguinte formato:

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 substitui a implementação original por uma versão carregada dinamicamente. Ao descarregar, a referência original (e a implementação) é restaurada. No meu caso específico, forneci um novo estimador para o RTT no TCP. Usando um módulo, eu posso fazer pequenos ajustes e reiniciar o teste, tudo sem ter que recompilar e reiniciar o kernel.

questionAnswers(4)

yourAnswerToTheQuestion