Yaz araştırmamın bir kısmı için çekirdek işine giriyorum. Belirli RTT hesaplamalarında TCP'ye değişiklikler yapmak istiyoruz. Benim yapmak istediğim, tcp_input.c'deki işlevlerden birinin çözünürlüğünü, dinamik olarak yüklenmiş bir çekirdek modülü tarafından sağlanan bir işleve dönüştürmektir. Bunun, değişikliği geliştirip dağıtabileceğimiz hızı geliştireceğini düşünüyorum.Linux kernel işlevini bir modülle değiştirebilir miyim?
İlgilendiğim işlev statik olarak bildirildi, ancak çekirdeği statik olmayan ve EXPORT_SYMBOL tarafından dışa aktarılan işlevle yeniden derledim. Bu, fonksiyonun şimdi çekirdeğin diğer modülleri/bölümleri için erişilebilir olduğu anlamına gelir. Bunu "cat/proc/kallsyms" ile doğruladım.
Şimdi sembol adresini başlangıçtan dinamik olarak yüklenen işlevime yeniden yazabilen bir modül yüklemek istiyorum. Benzer şekilde, modül boşaltılacağı zaman, orijinal adresi geri yükler. Bu uygun bir yaklaşım mı? Bunun nasıl daha iyi uygulanabileceğine dair önerileriniz var mı?
Teşekkürler!
aynı
Düzenleme Overriding functionality with modules in Linux kernel olarak: Bu benim nihai yaklaşımdı
.
aşağıdaki işlevi göz önüne alındığında, (geçersiz kılmak için istediği ve dışa değildir):
static void internal_function(void)
{
// do something interesting
return;
}
şöyle değiştirin:
static void internal_function_original(void)
{
// do something interesting
return;
}
static void (*internal_function)(void) = &internal_function_original;
EXPORT_SYMBOL(internal_function);
Bu (beklenen işlevsel tanımlayıcısını bunun yerine bir işlev işaretçisi yeniden tanımlamakta Orijinal uygulamaya işaret eden benzer bir şekilde çağrılabilir. EXPORT_SYMBOL(), adresi global olarak erişilebilir kılar, böylece bir modülden (veya başka bir çekirdek konumundan) değişiklik yapabiliriz.
Şimdi aşağıdaki form ile bir çekirdek modülü yazabilirsiniz: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;
}
Bu modül dinamik olarak yüklenen sürümü ile orijinal uygulanmasını değiştirir. Boşaltma üzerine, orijinal referans (ve uygulama) geri yüklenir. Benim özel durumumda, TCP'deki RTT için yeni bir tahminci sağladım. Bir modül kullanarak, çekirdeği yeniden derlemek ve yeniden başlatmak zorunda kalmadan, küçük ince ayarlamalar yapabilir ve testleri yeniden başlatabilirim.
Genel bir kanca eklemeyi önerdiğiniz rotayı bitirdim. Tam olarak ihtiyacım olanı uygulamak ve sağlamak çok kolaydı. Sembol çözünürlüğü ile ilgili bilgiler için teşekkürler. Sembol tablosuna nasıl ve ne zaman erişildiğini kesin olarak açıklayan bir kaynak bulamadım (her fonksiyon çağrısında veya sadece bağlantıda). Bu yararlı bir tavsiyeydi. –