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

#linux-kernel #kernel #kernel-module

#linux-ядро #ядро #kernel-module

Вопрос:

Я пытался сделать легкую разработку ядра на Android.

Я немного смущен тем, как встроенный, построенный с использованием

 obj-y  = module_name.o
  

модули ядра используют module_init() макрос вместо init_module() функции.

У меня есть два следующих простых модуля, первый:

 #include <linux/module.h>
#include <linux/kernel.h>
int init_module(void){
    printk(KERN_ALERT "This is our first program.");
    return 0;
}
void cleanup_module(void){
    printk(KERN_ALERT "End of our first program.");
}
  

И второй

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

static int __init test_module_init(void)
{
    pr_warn("Hello, worldn");

    return 0;
}

module_init(test_module_init);

static void __exit test_module_exit(void)
{
    pr_warn("Goodbyen");
}

module_exit(test_module_exit);
  

Когда я компилирую ядро с обоими встроенными модулями, второй модуль — это тот, в котором отображается сообщение dmesg . Однако первый модуль этого не делает.

Однако, если скомпилировать первый модуль отдельно и загрузить файл * .ko с помощью insmod ./module_name.ko первого модуля, сообщения будут выводиться на печать dmesg .

Это потому module_init() , что макросы необходимы для использования загрузки ELF модулей ядра во время загрузки? В то время insmod как загружается ELF динамически из файла * .ko, поэтому нам не нужно «регистрировать» его с помощью module_init() макроса?

Комментарии:

1. Первый модуль упускает из виду, как вести себя при встраивании. Это другая история, но вы можете заглянуть в include/linux/initcall.h (IIRC) и проверить, что там сделано. Для случая, когда он построен как модуль, я думаю, что это (очень) старый способ создания модулей до появления этих макросов. Не используйте его с современными ядрами.