Подтвердить что ты не робот

Разница между initrd и initramfs?

Насколько я знаю, initrd действует как блочное устройство, поэтому требуется драйвер файловой системы (например, ext2). Ядро должно иметь как минимум один встроенный модуль для обнаружения файловой системы initrd. В этой статье Представляя initramfs, новую модель для начальных RAM-дисков, написано, что:

Но ramdisks фактически тратит еще больше памяти из-за кэширования. Linux - это предназначен для кэширования всех файлов и записей в каталогах, считанных или написанных для блокировки устройств, поэтому Linux копирует данные в и из ramdisk в "кэш страниц" (для данных файла) и "кэш-дентин" (для записи в каталоге). Недостатком ramdisk, претендующим на роль блочное устройство обрабатывается как блочное устройство.

Что page cache и dentry cache? В этом параграфе означает, что данные были дублированы, потому что ramdisk рассматривается как блок-устройство, поэтому все данные кэшируются?

В режиме контрастности ramfs:

Несколько лет назад у Линуса Торвальдса была отличная идея: что, если кеш Linux может быть смонтирован как файловая система? Просто храните файлы в кеше и никогда не избавляйтесь от них, пока они не будут удалены или система не перезагрузится? Линус написал крошечную обертку вокруг кеша под названием "ramfs", а другой разработчики ядра создали улучшенную версию под названием "tmpfs" (которая могут записывать данные для замены пространства и ограничивать размер данного монтирования так что он заполняется, прежде чем потреблять всю доступную память). Initramfs является экземпляром tmpfs.

Эти файловые системы на основе ram автоматически растут или сжимаются, чтобы соответствовать размер данных, которые они содержат. Добавление файлов в ramfs (или расширение существующие файлы) автоматически выделяет больше памяти и удаляет или усекающиеся файлы освобождают эту память. Нет дублирования между блочное устройство и кеш, поскольку нет блочного устройства. Копия в кеш является единственной копией данных. Лучше всего, это не ново но новое приложение для существующего кода кэширования Linux, который означает, что он добавляет почти никакого размера, очень прост и основан на очень хорошо протестированная инфраструктура.

В сумме, ramfs - это просто файл, открытый и загруженный в память, не так ли?

Оба initrd и ramfs зажимаются во время компиляции, но разница в том, что initrd - это блок-устройство, распакованное для установки ядром при загрузке, тогда как ramfs распаковывается через cpio в память. Я прав? Или ramfs очень минимальная файловая система?

Наконец, до сих пор изображение initrd все еще отображается в последнем ядре. Однако, что initrd на самом деле ramfs используется сегодня, и имя предназначено только для исторической цели?

4b9b3361

Ответ 1

Кэш dentry (и inode)

Подсистема файловой системы в Linux имеет три уровня. VFS (виртуальная файловая система), которая реализует интерфейс системных вызовов и обрабатывает пересекающие точки монтирования и разрешения по умолчанию и ограничения. Ниже приводятся драйверы для отдельных файловых систем, а те, которые в свою очередь взаимодействуют с драйверами для блочных устройств (диски, карты памяти и т.д., Сетевые интерфейсы являются исключением).

Интерфейсом между VFS и файловой системой являются несколько классов (это просто C, поэтому структуры, содержащие указатели на функции и т.д., но это объектно-ориентированный интерфейс концептуально). Основными тремя классами являются inode, который описывает любой объект (файл или каталог) в файловой системе dentry, который описывает запись в каталоге и file, которая описывает файл, открытый процессом. При установке драйвер файловой системы создает inode и dentry для него root, а другие создаются по требованию, когда процесс хочет получить доступ к файлу и, в конечном итоге, истек. Это кэш-память и inode.

Да, это означает, что для каждого открытого файла и любого каталога до корня должны быть inode и dentry структуры, выделенные в ядре памяти, представляющие его.

Кэш страниц

В Linux каждая страница памяти, содержащая данные пользовательской области, представлена ​​единой структурой page. Это может означать, что страница является анонимной (может быть заменена на место подкачки, если она доступна) или связать ее с inode на некоторой файловой системе (может быть записана и перечитана из файловой системы), и она может быть частью любого числа карт памяти, то есть видимых в адресном пространстве некоторого процесса. Сумма всех загружаемых в память страниц - это кеш страниц.

Страницы используются для реализации интерфейса mmap, и, хотя регулярные системные вызовы чтения и записи могут быть реализованы файловой системой другими способами, большинство интерфейсов использует общую функцию, которая также использует страницы. Существуют общие функции, которые, когда запрашивается чтение файла, выделяют страницы и вызывают файловую систему, чтобы заполнить их один за другим. Для файловой системы на основе блок-устройств он просто вычисляет соответствующие адреса и делегирует это заполнение драйверу блочного устройства.

ramdev (ramdisk)

Ramdev является обычным блочным устройством. Это позволяет размещать любую файловую систему поверх нее, но она ограничена интерфейсом блочного устройства. И у этого есть только методы, чтобы заполнить страницу, выделенную вызывающим и записать ее обратно. Именно это необходимо для реальных блочных устройств, таких как диски, карты памяти, запоминающее устройство USB и т.д., Но для ramdisk это означает, что данные существуют в памяти дважды, один раз в памяти ramdev и один раз в памяти, выделенной вызывающий абонент.

Это старый способ реализации initrd. Со времен, когда initrd был редким и экзотическим происшествием.

TMPFS

Tmpfs отличается. Это фиктивная файловая система. Методы, которые он предоставляет VFS, являются абсолютным минимальным минимумом, чтобы заставить его работать (как таковая он отлично документирует то, что должны делать методы inode, dentry и file). Файлы существуют только в том случае, если в кэше inode имеется соответствующий inode и dentry, созданный при создании файла и никогда не истек, пока файл не будет удален. Страницы связаны с файлами, когда данные записываются и в противном случае ведут себя как анонимные (данные могут храниться в swap, структуры page остаются в использовании до тех пор, пока файл существует).

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

Это новый способ реализации initrd (initramfs, но изображение по-прежнему называется просто initrd).

Это также способ реализации "posix shared memory" (который просто означает, что tmpfs смонтирован на /dev/shm, и приложения могут свободно создавать файлы там и mmap, простые и эффективные) и недавно даже /tmp и /run (или /var/run) часто имеют tmpfs, специально предназначенные для ноутбуков, для того, чтобы диски не могли вращаться или избегать износа в случае SSD.

Ответ 2

Я думаю, что ты прав во всем.

Разницу легко увидеть, если вы выполните шаги, необходимые при загрузке:

initrd

  • Создано блочное устройство A ramdev. Это блочное устройство на основе ram, которое представляет собой имитируемый жесткий диск, который использует память вместо физических дисков.
  • Файл initrd считывается и распаковывается в устройство, как если бы вы делали zcat initrd | dd of=/dev/ram0 или что-то подобное.
  • initrd содержит изображение файловой системы, поэтому теперь вы можете монтировать файловую систему как обычно: mount /dev/ram0 /root. Естественно, файловой системе нужен драйвер, поэтому, если вы используете ext2, драйвер ext2 должен быть скомпилирован в ядре.
  • Готово!

initramfs

  • A tmpfs: mount -t tmpfs nodev /root. Tmpfs не нужен драйвер, он всегда включен. Не требуется никаких устройств, никаких дополнительных драйверов.
  • initramfs несжато непосредственно в этой новой файловой системе: zcat initramfs | cpio -i или аналогичный.
  • Готово!

И да, он по-прежнему называется initrd во многих местах, хотя это initramfs, особенно в загрузчиках, так как для них это просто BLOB. Разница заключается в том, что ОС загружается.

Ответ 3

Чтобы добавить еще одно примечательное различие между initrd и initramfs не упомянутыми в превосходном ответе выше.

  • С initrd ядро по умолчанию передает pid 1 пользовательского пространства в /sbin/init
  • Более новые initramfs, однако, изменяют ситуацию и выполняют pid 1 в /init

как это может стать ловушкой (см. https://unix.stackexchange.com/a/147688/24394)

Ответ 4

Минимальные выполнимые примеры QEMU и объяснение новичка

В этом ответе я буду:

  • предоставьте минимальный исполняемый пример Buildroot + QEMU для тестирования
  • объясните самое фундаментальное различие между обоими для начинающих, которые, вероятно, прибегают к помощи

Надеемся, что они послужат основой для проверки и понимания более специфических деталей разницы.

Минимальная настройка полностью автоматизирована, и это соответствующее начало.

Программа установки выводит команды QEMU по мере их выполнения, и, как объясняется в этом репозитории, мы можем легко создать три следующих рабочих типа загрузок:

  1. корневая файловая система находится в ext2 на "жестком диске":

    qemu-system-x86_64 -kernel normal/bzImage -drive file=rootfs.ext2
    
  2. корневая файловая система находится в initrd:

    qemu-system-x86_64 -kernel normal/bzImage -initrd rootfs.cpio
    

    -drive не предоставляется.

    rootfs.cpio содержит те же файлы, что и rootfs.ext2, за исключением того, что они имеют формат CPIO, аналогичный .tar: он сериализует каталоги, не сжимая их.

  3. корневая файловая система находится в initramfs:

    qemu-system-x86_64 -kernel with_initramfs/bzImage
    

    Ни -drive ни -initrd не приведены.

    with_initramfs/bzImage - это ядро, скомпилированное с параметрами, идентичными параметрам normal/bzImage, за исключением одного: CONFIG_INITRAMFS_SOURCE=rootfs.cpio указывающего на тот же CPIO, что и в -initrd.

Сравнивая настройки, мы можем заключить наиболее фундаментальные свойства каждого:

  1. в настройках жесткого диска QEMU загружает bzImage в память.

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

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

  2. в настройке initrd, QEMU выполняет дополнительную загрузку, помимо загрузки ядра в память: также:

    На этот раз ядро просто использует rootfs.cpio из памяти напрямую, поскольку жесткого диска нет.

    Пишет не персистентно при перезагрузках, так как все в памяти

  3. в настройке initramfs мы собираем ядро немного по-другому: мы также даем rootfs.cpio системе сборки ядра.

    Затем система сборки ядра знает, как соединить образ ядра и CPIO в один образ.

    Поэтому все, что нам нужно сделать, это передать bzImage в QEMU. QEMU загружает его в образ, как и для других настроек, но больше ничего не требуется: CPIO также загружается в память, поскольку он приклеен к образу ядра!