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