[devel] Модульный initrd.img
Michael A. Kangin
mak на complife.ru
Вс Май 6 19:55:25 MSK 2018
Здравствуйте!
Не секрет, хотя и не широкоизвестно, что популярные загрузчики позволяют
указывать несколько cpio-образов, которые при загрузке будут объединены
в памяти в единую initramfs.
Этим можно воспользоваться, и разделить текущий монолитный initrd.img на
отдельные образы - собственно сам initrd, early-микрокод, и модули ядра
[с фирмварью].
Зачем это может быть нужно?
- ускорение генерации новых initrd при установке нового ядра. Если
микрокод и само тело initrd остаётся такими же, достаточно только
быстренько слепить образ с новыми модулями.
- уменьшение суммарного размера микрокода / разных вариантов initrd /
разных версий ядра. Например, мы выносим микрокод отдельным образом - и
нам не нужно включать его в каждую новую версию initrd, которую мы
делаем. Если мы генерим себе -debug initrd, то достаточно сделать
крохотный diff-образ с bash / lsmod / whatever, а модули и основной
initrd у нас уже есть. Мы можем предложить загрузить на выбор std-def и
un-def, причём разница (кроме самих vmlinuz'ов) будет достаточно
небольшая, архивы из десятка модулей ядра.
- возможность оперативно фиксить уже существующий initrd, добавив сбоку
в отдельном образе или недостающий модуль, или конфиг там какой со скриптом.
- возможность полностью отвязать сам initrd от версии ядра. И иметь
возможность загрузить систему с, например, RHEL-овским ядром, но нашим
initrd, не ломая никакой совместимости.
Минимальная поддержка, необходимая в initrd для сторонних образов с
модулями - вызов "depmod -a" перед загрузкой модулей, например, в стадии
pre-udev. Если сторонние образы содержат что-то другое, то и поддержки
особой не надо.
Возможно, удалось бы сделать продвинутую поддержку сторонних модулей,
чтобы выносить из основного тела отдельные фичи. Плимут просто
напрашивается, например.
Вот пара вполне работающих примеров:
syslinux с семейством (iso, pxe):
=======================
LABEL test-modular-initrd
MENU LABEL Test modular initrd
KERNEL clb/vmlinuz
INITRD clb/microcode.img,clb/initrd-thin.img,clb/supermicro_boot.modules
APPEND root=http://xxxxx/rescue-base-sm.manifest rootdelay=5
=======================
Работает как с legacy bios, так и с uefi.
grub2:
=======================
...
echo 'Loading Linux 4.9.71-std-def-alt0.M80P.1 ...'
linux /boot/vmlinuz-4.9.71-std-def-alt0.M80P.1
root=UUID=a397ac93-3b06-4023-83e4-18b29a28b033 ro quiet
resume=/dev/disk/by-uuid/6481d48d-8403-4049-adfc-87e94b950361 panic=30
splash
echo 'Loading initial ramdisk ...'
initrd /boot/microcode.img
/boot/initrd-4.9.71-std-def-alt0.M80P.1-thin.img /boot/modules.img
=======================
c uefi не пробовал.
Так же, не знаю, умеют ли это хитрые uefi-загрузчики типа refind'а.
Подробная информация о списке рассылки Devel