В чем разница между module_init и init_module в модуле ядра Linux?

Я пытаюсь подключить несколько Linux-драйверов и понял, что существует существенная разница между версиями Linux версии 2.4 и 2.6.

В версии 2.4 версии ядра программирование модуля было следующим:

#define MODULE
#include <linux/module.h>
#include <linux/kernel.h>

int init_module(void)      
{ 
printk(KERN_INFO "Hi \n"); 
return 0; 
}

void cleanup_module(void)  
{ 
printk(KERN_INFO "Bye \n"); 
}

Но, с версией ядра 2.6, для модулей нужно сделать следующее:

#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>

static int hi_init(void)
{
    printk(KERN_ALERT "Hi \n");
    return 0;
}

static void hi_exit(void)
{
    printk(KERN_ALERT "Bye \n");
}

module_init(hi_init);
module_exit(hi_exit);

В чем преимущество таких изменений в Kernel 2.6 и почему это изменение требуется в ядре 2.6 linux?

Ответ 1

Если вы посмотрите на определение новых функций:

/* Each module must use one module_init(). */
#define module_init(initfn)                 \
static inline initcall_t __inittest(void)       \
{ return initfn; }                  \
int init_module(void) __attribute__((alias(#initfn)));

/* This is only required if you want to be unloadable. */
#define module_exit(exitfn)                 \
static inline exitcall_t __exittest(void)       \
{ return exitfn; }                  \
void cleanup_module(void) __attribute__((alias(#exitfn)));

Вы увидите, что это гарантирует, что правильный шаблон включен, так что эти специальные функции могут корректно обрабатываться компилятором. То, что делает внутренний API Linux, развивается, если есть лучшие способы решения проблемы.

Ответ 2

В чем преимущество [module_init] в ядре 2.6

module_init также выйдет в 2.4, заметьте.

Он добавляет необходимый шаблон для инициализации модуля и запускает функцию ввода, когда файл модуля компилируется в ядро, а не как модуль.

Ответ 3

Одно из преимуществ - читаемость. cdrom_init() мгновенно сообщает вам, что это вызов init() для драйвера cdrom.