Откуда Linux знает, где находятся rootfs?

Ответ на вопрос 1:

mplayer жалуется, что File not found: '-', хотя он должен читать стандартный ввод. Это не имеет никакого отношения к netcat или сетевым технологиям вообще. Проблема заключается в интерпретации командной строки. Если есть символ тире - (шестнадцатеричный код 2D), то mplayer читает стандартный ввод. Но командная строка содержит символы - (шестнадцатеричный код 96). Визуальное сходство этих символов - просто совпадение.

Ответ на вопрос 2:

Это простой случай использования, и существует множество ответов и примеров, как туннелировать что-то через ssh. Например, ssh tunnelling explanation дает хорошее введение, как использовать ssh для туннелирования.

1
02.11.2018, 20:50
2 ответа

So if I want my rootfs to be in RAM, I need to set CONFIG_INITRAMFS_SOURCE to point to my rootfs (in cpio format presumably).

Это один способ сделать это, да, но это не единственный способ.

Если у вас есть загрузчик, который можно настроить для загрузки ядра и initramfs как отдельных файлов, вам не нужно использовать CONFIG_INITRAMFS_SOURCEпри сборке ядра. Достаточно установить CONFIG_BLK_DEV_INITRDв конфигурации ядра. (До initramfs существовала более старая версия метода с именем initrd, и старое название до сих пор встречается в некоторых местах. )Загрузчик загрузит файл initramfs, а затем заполнит некоторую информацию о его расположении в памяти и размере в структуру данных в определенном месте уже -загруженного образа ядра. В ядро ​​встроены -подпрограммы, которые будут использовать эту информацию для поиска файлов initramfs в оперативной памяти системы и их распаковки.

Наличие initramfs в виде отдельного файла позволит вам легче изменять файл initramfs, и если ваш загрузчик может принимать данные от пользователя, возможно, укажите другой файл initramfs для загрузки вместо обычного во время загрузки. (Это очень удобно, если вы попытаетесь создать настроенный initramfs и что-то сделаете не так. Был там, сделал это.)

Для традиционной системы x86 на основе BIOS -вы найдете информацию об этих деталях в(исходном коде ядра )/Documentation/x86/boot.txt . Системы на основе UEFI -делают это немного иначе (, также описанным в том же файле ), а другие архитектуры, такие как ARM, имеют свои собственные наборы деталей о передаче информации от загрузчика к ядру.

Furthermore, what if I want my rootfs to be on physical storage (like eMMC, flash drive, etc.) and not in RAM?

В обычных невстроенных -системах файлы initramfs обычно содержат достаточно функций, чтобы активировать важные подсистемы -. На обычном ПК это, как правило, драйверы для клавиатуры, дисплея и драйвер контроллера хранилища для вашей корневой файловой системы, а также любые модули ядра и инструменты, необходимые для активации таких подсистем, как LVM, шифрование диска и т. д.и/или программный RAID, если вы используете эти функции.

Когда основные подсистемы -активны и корневая файловая система доступна, initramfs обычно выполняет операцию pivot_root(8)для переключения с initramfs на реальную корневую файловую систему. Но встроенная система или специализированная утилита, такая как DBAN , может упаковать все, что ей нужно, в initramfs и просто никогда не выполнять операцию pivot_root.

Обычно сценарии и/или инструменты в initramfs получают необходимую информацию для обнаружения реальной корневой файловой системы из параметров в командной строке ядра. Но у вас нет необходимости сделать это :с настроенным initramfs, вы можете сделать что-то вроде переключения на другую корневую файловую систему, если определенная клавиша или кнопка мыши удерживается нажатой в определенное время в последовательность загрузки.

Со сложной конфигурацией хранилища (, например. зашифрованный LVM поверх программного RAID, в системе, которая использует избыточное хранилище SAN с несколькими путями ), вся информация, необходимая для активации корневой файловой системы, может не поместиться в командную строку ядра, поэтому вы можете включить более крупные фрагменты в initramfs.


Современные дистрибутивы обычно используют генератор initramfs для создания специализированных файлов initramfs для каждого установленного ядра. Различные дистрибутивы имели свои собственные генераторы initramfs :. RedHat использовал mkinitrd, а Debian update-initramfs. Но после введения systemdпохоже, что многие дистрибутивы стандартизируютdracutкак генератор initramfs.

Современный файл initramfs может быть конкатенацией нескольких .cpioархивов, и каждая часть может быть сжата или нет. Типичный файл initramfs в современной системе x86 _64 может иметь файл «раннего обновления микрокода» в качестве первого компонента (, обычно это всего лишь один файл в несжатом архиве cpio, поскольку файл микрокода обычно зашифрован и поэтому не очень сжимаемый.После этого идет обычное содержимое initramfs в виде сжатого файла .cpio.

Чтобы лучше понять вашу систему, я бы посоветовал вам извлечь файл initramfs во временный каталог, а затем изучить его содержимое. В Debian есть инструмент unmkinitramfs(8), который можно использовать для простого извлечения файла initramfs. В RedHat 7 вам может понадобиться использовать /usr/lib/dracut/skipcpio <initramfs file>, чтобы пропустить файл обновления микрокода, а затем передать полученный вывод в gzcatи далее в cpio -i -d, чтобы извлечь содержимое initramfs в текущий рабочий каталог. Ubuntu может использовать lzcatвместо gzcat.

3
27.01.2020, 23:14

Прежде всего, не пугайтесь ссылок на "2.6" в документации по ядру. Текущие ядра по-прежнему относятся к линейке «2.6», но они прошли два раунда перенумерации только в «маркетинговых целях» (, поэтому 2.6.40 стало 3.0, а 3.20 — 4.0 ). Ваше ядро ​​4.19 обычно должно быть помечено как 2.6.79.

Похоже, здесь происходит некоторая путаница со значением «rootfs». «rootfs» — это специальная файловая система, основанная на оперативной памяти -, используемая внутри ядра. Это точно так же, как файловые системы «tmpfs», которые обычно монтируются в такие места, как /run, /dev/shmили иногда /tmp. (Ну, если функция "tmpfs" не скомпилирована в ядро, в этом случае вместо нее используется урезанный -"tmpfs", называемый "ramfs". )Эти файловые системы просто живут в кэше страниц, для ramfs вообще нет резервного устройства, в то время как tmpfs поддерживается свопом, если он доступен.

Таким образом, ядру не нужно беспокоиться о «нахождении» «rootfs», но ему нужно как-то заполнить его, потому что весь кэш страниц при загрузке пуст. Вот где в игру вступает «файл initramfs». Это просто (сжатый)cpioархив (, а не tarпо причинам, упомянутым в документации ), который распаковывается ядром в пустую "rootfs". Этот архив можно либо напрямую встроить в образ ядра, установив CONFIG_INITRAMFS_SOURCEво время сборки, либо предоставить загрузчику (, что и делает опция initrdв GRUB ). Этот архив обычно создается с помощью инструментов пользовательского пространства, таких как dracutили (сбивающих с толку)mkinitrd.

Если образ cpio недоступен или не содержит исполняемого файла /init, ядро ​​возвращается к другому методу, при котором оно просматривает аргумент командной строки root=и интерпретирует его как местоположение реальной корневой файловой системы., монтирует его в /и выполняет initнапрямую. Однако в настоящее время это редко используется, поскольку требует, чтобы все необходимые драйверы хранилища и файловой системы были скомпилированы непосредственно в ядро. В большинстве систем аргумент root=не используется ядром, а обрабатывается /initв initramfs. Тот /init(, который обычно является либо systemd, либо сценарием оболочки ), отвечает за загрузку необходимых модулей, монтирование реальной корневой файловой системы и переключение на нее.

Давным-давно вместо современного «initramfs» использовался другой механизм, называемый «initrd». «initrd» («init ramdisk» )представлял собой блочное устройство на основе ОЗУ -, которое было инициализировано реальной файловой системой (, такой как ext2 ), образ которой поставлялся точно так же, как современный cpioархив. Вот почему во многих местах до сих пор используется имя «initrd» для обозначения этих ранних -загрузочных вещей.

8
27.01.2020, 23:14

Теги

Похожие вопросы