Как поставить проверку в коде для обеспечения зависимости модуля ядра от ядра Linux?

У меня есть два модуля. Я хочу, чтобы модули были взаимозависимы при выполнении insmod или rmmod. В настоящее время мой модуль 2 зависит от модуля 1. Если я вставляю module1, то module2, он работает нормально. С другой стороны, обратное не работает. Это логично в объяснении. Тем не менее, я хочу аккуратный код, чтобы избежать таких зависимостей. Если я сделаю insmod для mod2, тогда mod1 должен автоматически быть insmod, или каким-нибудь другим достойным способом решить эту проблему. Вот мои два модуля.

static int multiplyMod1(int a, int b);
/** Once the symbol is exported, check in /proc/kallsyms **/
/** Call multiplyMod1 from other module **/
/** Ensure that this symbol doesn't exist somewhere **/
EXPORT_SYMBOL(multiplyMod1);

static int multiplyMod1(int a, int b)
{
  return a*b;
}

static int mod1_init(void)
{
    printk(KERN_ALERT "Hello mod1..Init\n");
    return 0;
}

static void mod1_exit(void)
{
    printk(KERN_ALERT "Goodbye..mod1\n");
}

module_init(mod1_init);
module_exit(mod1_exit);

Makefile -

obj-m += mod1.o

all:
    make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules modules_install

clean:
    make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean

Вот мой второй модуль. Это зависит от модуля 1.

/ ** Убедитесь, что mod1 является insmod, чтобы был доступен символ multiplyMod1 **/

extern int multiplyMod1(int,int);

static int mod2_init(void)
{
    printk(KERN_ALERT "Hello mod2..Init\r\n");
    printk(KERN_ALERT "The Multiplication result from Mod2 is..%d\r\n",multiplyMod1(49,7));
    return 0;
}

static void mod2_exit(void)
{
    printk(KERN_ALERT "Goodbye..mod2\r\n");
}

module_init(mod2_init);
module_exit(mod2_exit);

1 ответ

Решение

Вы можете использовать API request_module в модуле mod2 в котором вы хотите использовать экспортированный символ, это загружает требуемый модуль по требованию, если он не был загружен ранее.

В модуле mod2,

static int __init module_two_init_module(void)
{
        int ret;
        const char *name;
        struct module * fmodule;
        pr_info("Module two started");
        name = "module_one";
        /* This will find module is loaded or not */
        fmodule = find_module(name); 
        if (fmodule == NULL) {
                ret = request_module(name);
                if (ret == 0) {
                        pr_info("Module one loaded");
                }
        }
        /* Do rest of code here */

Не забудьте увеличить счетчик ссылок на модуль с помощью try_module_get()

Другие вопросы по тегам