Существует ли способ заставить Linux рассматривать initramfs как окончательную корневую файловую систему?

Вопрос или проблема

Я хочу загрузить систему с initramfs, который является фактической финальной файловой системой, а не временным initramfs для загрузки драйверов. К сожалению, Linux накладывает различные (и в моем случае, нежелательные) поведения при использовании initramfs, включая по крайней мере следующие различия:

  • devtmpfs не монтируется автоматически, по крайней мере, сначала, но, похоже, монтируется автоматически позже, что я не могу выяснить.
  • Вместо запуска /sbin/init (или программы init, указанной с помощью init= в командной строке) ядро пытается вызвать /init.

Я знаю, что можно обойти эти проблемы, добавив некоторые дополнительные файлы в initramfs, но мне бы хотелось, чтобы он вел себя как нормальная корневая файловая система. Есть ли способ достичь этого?

Если мне все же нужно обойти это с помощью скриптов пользовательского пространства в initramfs, я хотя бы хочу понять, что вызывает автоматическое монтирование devtmpfs.

Это возможно, если CONFIG_BLOCK не определен, поскольку init/do_mounts.c содержит в mount_root, который выполняется после того, как ядро не смогло выполнить /init на initramfs, следующее:

#ifdef CONFIG_BLOCK
    {
        int err = create_dev("/dev/root", ROOT_DEV);

        if (err < 0)
            pr_emerg("Не удалось создать /dev/root: %d\n", err);
        mount_block_root("/dev/root", root_mountflags);
    }
#endif

Источник: https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/init/do_mounts.c?id=c69e3c3a0c014e86750e78b7e2ae823f7a9b2cb2#n535

В этом случае mount_root проходит успешно, ничего не сделав, и ядро продолжает рассматривать initramfs как правильную корневую файловую систему.

К сожалению, отключение CONFIG_BLOCK не является практичным для большинства случаев использования. То, что навело меня на мысль, что это должно работать, так это то, что в патче для конкретной платформа разработки, с которой я работаю, условие было заменено на:

#if defined(CONFIG_BLOCK) && !defined(CONFIG_INITRAMFS_SOURCE)

Было бы неплохо добавить поддержку для root=initramfs, которая заставляет mount_root возвращаться, не выполняя никаких действий, и это должно быть тривиальным однострочным патчем. У меня нет представления о том, будет ли это приемлемо для upstream.

Ну, это довольно поздно, но у меня есть ответ, который может вам помочь:

Во-первых, вам нужно будет включить /dev/console в ваш initramfs. Это позволит вам получить функциональность sysinit, сообщающую обратно на консоль (выводы из пользовательского пространства снова отобразятся на вашем основном экране). Далее, если вы используете busybox для вашего процесса инициализации, добавьте символическую ссылку на busybox в корне вашей корневой файловой системы под названием init. Проблема в том, что файловый слой ядра Linux изменился несколько лет назад. Изначально вам нужно было иметь /init, чтобы запустить систему. Это считалось уязвимостью и было перемещено в /sbin/init. Позже, если я правильно помню, это стало linuxrc, но, как я думаю, это было полностью удалено.

В моем inittab первые две строки монтируют proc и devtmpfs. Все кажется работает правильно.

Для тех, кто пытается использовать initrd как корневую файловую систему и попал в эту тему, пожалуйста, убедитесь, что /init существует на initrd, или отрегулируйте это в командных аргументах ядра, используя rdinit=xxx по мере необходимости.

Ответ или решение

Для того чтобы Linux воспринимал initramfs как финальную корневую файловую систему, необходимо учитывать несколько нюансов, связанных с поведением ядра и конфигурацией системы. Инициализационные file systems (initramfs) традиционно используются для загрузки необходимых модулей и драйверов, а не как основная файловая система. Однако при определённых условиях это поведение можно изменить.

Проблемы с использованием initramfs

  1. Отсутствие автоматического монтирования devtmpfs. Это может привести к тому, что устройства не будут доступны до момента, когда devtmpfs будет смонтирован.

  2. Запуск файла init. В отличие от ожидаемого поведения, когда запускается /sbin/init, ядро пытается выполнить /init, что может вызвать путаницу.

Решение проблемы

Чтобы заставить Linux работать с initramfs как с окончательной корневой файловой системой, можно использовать следующие подходы:

  1. Изменение конфигурации ядра:

    • Если у вас есть возможность модифицировать настройки ядра, можно отключить CONFIG_BLOCK. Это позволит функции mount_root завершаться успешно без необходимости выполнять дополнительные шаги по монтированию корневой файловой системы, что, в свою очередь, позволит обращаться к initramfs в качестве финальной файловой системы. Однако данный подход может быть непрактичным для повседневного использования.
  2. Требования к содержимому initramfs:

    • Включите в initramfs файл /dev/console. Это позволит получать сообщения о состоянии и инициализации системы, что крайне важно при отладке.
    • Убедитесь, что в initramfs присутствует символьная ссылка на busybox, ведущее к /init. Это важно, поскольку линейка файловой системы Linux значительно изменилась, и наличие файла /init становится обязательным.
  3. Использование скриптов пользователей: Если вы решите обойти указанные проблемы с помощью пользовательских скриптов, вы можете создать скрипт инициализации, который будет:

    • Монтировать proc и devtmpfs в самом начале выполнения.
    • Обеспечить, чтобы файл /init существовал в initramfs или использовать параметр командной строки rdinit=xxx для указания пути к инициализирующему исполняемому файлу.

Понимание автозагрузки devtmpfs

Автозагрузка devtmpfs зависит от того, когда и как система будет инициализировать устройства. В современных версиях ядра процесс может активироваться при помощи отдельного модуля инициализации, который отвечает за создание специального файла /dev/root. Для понимания того, что именно вызывает автоматическое монтирование devtmpfs, рекомендуется просмотреть код ядра, особенно функции, связанные с инициализацией root файловой системы.

Заключение

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

Оцените материал
Добавить комментарий

Капча загружается...