進入我的暑期研究的核心工作。我們希望在特定的RTT計算中對TCP進行修改。我想要做的是將tcp_input.c中的一個函數的分辨率替換爲由動態加載的內核模塊提供的函數。我認爲這會提高我們開發和分發修改的速度。我可以使用模塊替換Linux內核函數嗎?
我感興趣的函數被聲明爲靜態的,但是我已經用非靜態函數重新編譯了內核,並通過EXPORT_SYMBOL導出了內核。這意味着該功能現在可以被內核的其他模塊/部分訪問。我通過「cat/proc/kallsyms」驗證了這一點。
現在我想能夠加載一個模塊,可以重寫從最初的符號地址到我的動態加載函數。同樣,當模塊要卸載時,它會恢復原來的地址。這是一種可行的方法嗎?你們都有建議如何更好地實施?
謝謝!
同Overriding functionality with modules in Linux kernel
編輯:
這是我最後的辦法。
鑑於下面的函數(我想要覆蓋,並且不輸出):
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提供了一個新的估計器。通過使用模塊,我可以進行小小的調整並重新開始測試,而無需重新編譯和重新引導內核。
我最終選擇了添加全局鉤子的路線。這很容易實現,並提供了我所需要的。 感謝有關符號解析的信息。我沒有找到明確解釋符號表訪問的方式和時間的來源(在每個函數調用或僅在連接時)。這是一條有用的建議。 – 2009-07-29 03:00:42