我在暑期研究中从事内核工作。我们希望在特定的RTT计算中对TCP进行修改。我想做的是将tcp_input.c中的功能之一的分辨率替换为由动态加载的内核模块提供的功能。我认为这将改善我们开发和分发修改的速度。
我感兴趣的函数被声明为静态的,但是我用非静态函数重新编译了内核,并由EXPORT_SYMBOL导出。这意味着该功能现在可供内核的其他模块/部分访问。我已经通过“
cat / proc / kallsyms”验证了这一点。
现在,我希望能够加载一个模块,该模块可以将符号地址从初始重写为动态加载的函数。同样,当要卸载模块时,它将恢复原始地址。这是可行的方法吗?大家都有建议如何更好地实施吗?
谢谢!
与Linux内核中的模块的覆盖功能 相同
编辑:
这是我最终的方法。
给定以下功能(我想覆盖它,但不导出):
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;
}
该模块将原来的实现替换为动态加载的版本。卸载后,将还原原始参考(和实现)。在我的特定情况下,我为TCP中的RTT提供了一个新的估算器。通过使用模块,我可以进行细微调整并重新开始测试,而无需重新编译和重新启动内核。