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

#c #networking #linux-kernel #linux-device-driver

Вопрос:

Я хочу передать пользовательский параметр ядру во время загрузки, который будет использоваться моим новым кодом. Этот параметр представляет собой число.

Я знаю, как передать значение модулю ядра с помощью командной строки ядра module_param() , т. е. Теперь я хочу передать значение из u-boot.

Есть ли способ сделать это во время или после загрузки?

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

1. Добро пожаловать в SO! Всегда полезно оставить немного кода, чтобы потенциальные плакаты получили некоторый контекст.

Ответ №1:

Если вы знаете, как передать значение модулю ядра, вы знаете достаточно 🙂

insmod my_module param=value

Если ваш модуль встроен в ядро, вы можете добавить свой параметр в параметры ядра

vmlinux ... my_module.param=value ...

Вот ссылка: kernel-parameters.txt

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

1. Выше приведено решение для архитектуры x86.

2. Выше приведено решение для архитектуры x86. Я работаю над архитектурой ARM и использую U-boot в качестве загрузчика. Как я могу сделать то же самое с uboot.

3. Это решение также подходит для любой другой архитектуры, с любым другим загрузчиком. В uboot у вас есть среда загрузки.

Ответ №2:

Измените файл платы, присутствующий в include/config/board_xxx.h U-Boot, измените $bootargs аналогично последней переменной, заданной в этом примере:

 setenv bootargs display=${display} console=${consoledev},${baudrate} root=/dev/mmcblk0p1 rw rootdelay=1 control.cmd1={cmd1}
 

управление-это имя встроенного модуля драйвера, который я не могу включить, потому что он нужен мне для полной загрузки в приглашение Linux.

cmd1-это глобальная переменная, которую я определил в модуле, в котором я использовал:

 module_param(cmd1, int, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP);
 

таким образом, к вашему var $bootargs просто нужно добавить что-то вроде:

<your_mod_name>.<your_mod_parameter_var_name>=<an_appropriate_value>

Ответ №3:

Исходная документация Linux

Я предпочитаю это из уст hourse v4.12/Документация/руководство администратора/параметры ядра.первый:

 Module parameters can be specified in two ways: via the kernel command
line with a module name prefix, or via modprobe, e.g.:

    (kernel command line) usbcore.blinkenlights=1
    (modprobe command line) modprobe usbcore blinkenlights=1

Parameters for modules which are built into the kernel need to be
specified on the kernel command line.  modprobe looks through the
kernel command line (/proc/cmdline) and collects module parameters
when it loads a module, so the kernel command line can be used for
loadable modules too.
 

Простой способ попробовать это

 CONFIG_DUMMY_IRQ=y
 

затем в командной строке:

 dummy-irq.irq=12
 

и когда ядро загрузится, вы увидите:

 dummy-irq: registered for IRQ 12
 

который напечатан с init оф dummy-irq.c .

Кодовый путь

Мне еще не удалось пройти полный путь кода, но я думаю . , что он закодирован в https://github.com/torvalds/linux/blob/v4.12/include/linux/moduleparam.h#L13:

 #define MODULE_PARAM_PREFIX KBUILD_MODNAME "."
 

который расширяется в водопаде module_param макросов, на одном из шагов которого содержится комментарий Лайнуса, указывающий, насколько понятен этот код:

 /* Lazy bastard, eh? */
 

Обратный watch путь QEMU GDB, для которого он устанавливается, dummy-irq.c:irq является:

 #0  kstrtouint (s=<optimized out>, base=<optimized out>, res=0xffffffff81a8d820 <irq>) at lib/kstrtox.c:225
#1  0xffffffff8106e124 in param_set_uint (val=<optimized out>, kp=<optimized out>) at kernel/params.c:295
#2  0xffffffff8106ed98 in parse_one (handle_unknown=<optimized out>, arg=<optimized out>, max_level=<optimized out>, min_level=<optimized out>, num_params=<optimized out>, params=<optimized out>, doing=<optimized out>, val=<optimized out>, param=<optimized out>) at kernel/params.c:148
#3  parse_args (doing=<optimized out>, args=0xffff880007fdb99f "", params=<optimized out>, num=<optimized out>, min_level=<optimized out>, max_level=<optimized out>, arg=0x0 <irq_stack_union>, unknown=0xffffffff81aeb8e5 <unknown_bootoption>) at kernel/params.c:243
#4  0xffffffff81aebc6d in start_kernel () at init/main.c:518