Навіщо мені потрібно initramfs?


17

Я з’ясував, що якщо я виберу jffsабо sdяк файлову систему (а не initramfs), розмір ядра буде дуже малим (1,4 Мб порівняно з тим, initramfsщо становить 3,4 Мб). Це означає, що initramfsзаймає значно великий простір. Тож якщо я можу, я б повністю її видалив, і, таким чином, у мене буде дуже маленьке ядро, чого я хочу.

Основне питання, що виникає в моїй думці, це: навіщо мені це потрібно initramfs? Неможливо завантажувати ядро ​​Linux, не маючи початкової файлової системи?

Мій кінцевий додаток буде робити тільки обчислення та зв’язок - взагалі немає місця для зберігання даних. Тож ОС без файлової системи має сенс - принаймні, для мого застосування.


2
Вам не обійтися без initramfs. Можна обійтися і без додаткового файлу initramfs, але незалежно від того, що ви робите, ядро ​​включає його власне порожнє чи ні. Тож я не розумію вашого запитання - про який розподіл ви говорите? Як ви будуєте ядро? Чи можете ви надати файл .config ядра? Вони дуже важливі. Я підозрюю, що ваш дистрибутив збирає його initramfs безпосередньо в ядро ​​- і тому заповнює інакше порожні initramfs, які він містить - але я не можу знати, виходячи з наданої вами інформації.
mikeserv

2
@mikeserv, очевидно, вбудований, але порожній / невикористаний initramfs не зараховується.
psusi

Що ж, @psusi документи ядра не згодні. І я настільки прихильний до цього, тому що не потрібно бути ніякої таємниці - просто її /root- це все. Єдине, що він робить інакше, switch_rootале це навіть у тому випадку, якщо за умови дотримання належних заходів обережності з певними завантаженими модулями ядра, це можна зробити в будь-який час. Initramfs - це не що інше, як образ диска - це набридне чи ні, воно є. І ти ніколи без цього - це твій корінь. Це я не повинен бути таємницею, - я вважаю, і мені не подобається вся непотрібна плутанина навколо нього.
mikeserv

2
@mikeserv, ні, / root - домашня директорія для кореневого користувача. Корінь є /, який потім має реальний корінь, встановлений поверх нього. Ви просто аргументуєте семантику. Для цілей цієї дискусії відсутність initramfs означає відсутність файлу на диску, який завантажувач завантажує та передає до ядра.
psusi

Це правда, я / використовував / root тільки для наочності, але я дам вам це. Але ні, вони не семантика, вони фундаментальна механіка вашого ядра Linux. Це основні речі. Давайте просто спробуємо їх виправити.
mikeserv

Відповіді:


12

Збільшення розміру наявності initramfs пов'язане не з драйвером ramfs (це всього лише кілька кБ, і так чи інакше потрібно для інших речей), а самим initramfs. У initramfs містяться програми, необхідні для збирання та монтажу реальної кореневої файлової системи.

Initramfs значно спрощує, а в деяких випадках можливо (наприклад, зашифровано /), завантажувати систему. Настійно рекомендується зберігати його на апаратному забезпеченні в стилі ПК з великою кількістю гарячих підключень периферійних пристроїв. З іншого боку, має багато сенсу завантажувати вбудований пристрій без жодних initramfs із ядром, яке просто підтримує конкретну конфігурацію апаратури, для якої він створений.

Звичайно, ядро ​​повинне завантажуватись у файлову систему: він повинен мати певний спосіб завантаження будь-якої програми, яку ви хочете запустити. Якщо ви нічого не збираєтеся запускати, то ви можете також тримати живлення машини.

Якщо ви не хочете використовувати initramfs, просто скажіть завантажувачу, щоб він не проходив його. Крім того, не включайте його у висновок збірки ядра - як це відбувається, якщо взагалі залежить від архітектури та завантажувача: наприклад, vmlinuxі bzImageне включайте initramfs (вони відповідно є сирим та стислим ядром ), але uImage(для U-Boot) пакує і ядро, і initramfs, якщо таке є.

(Технічно, як зазначає mikeserv , завжди є initramfs - але за замовчуванням це порожній, 134-байтний архів. Те, що ви бачите та хочете позбутися, - це "справжній", не порожній інітрамф, створений процес збирання та містить інструменти, які потім використовуються для монтажу кореневої файлової системи.)

Зауважте, що initramfs може бути розумним способом створення єдиної програми без постійних даних: помістіть всю програму в initramfs, завантажте її та зберігайте її. Це полегшує організацію постійного зберігання або завантажувального зображення (все, що вам потрібно, - це ядро ​​та initramfs, які можна поставити в комплекті). Однак у цього підходу є і мінуси: всі дані в initramfs будуть постійно зберігатися в оперативній пам'яті, і ви не можете легко змінити файли на завантажувальному зображенні, вам доведеться відновити архів.


Якщо ви використовуєте ядро ​​2.6 або новішого Linux, у вас є initramfs. Незалежно від того, використовуєте ви чи ні вторинний образ initramfs, як це прийнято, інша справа, але initramfs не є обов'язковою.
mikeserv

2
@mikeserv У вас є, так. Але порожній інітрамф - це арахіс. Його не потрібно використовувати (що вимагає, щоб він містив достатню кількість програм для монтажу реального кореня, що збільшує розмір несуттєвим чином у типовій вбудованій системі).
Жил "ТАК - перестань бути злим"

Обов’язковий арахіс все одно. І я не знаю, коли я сказав інакше! Автор запитував запит на інформацію про те, як видалити його як файлову систему - що неможливо.
mikeserv

І так, це все-таки потрібно використовувати - без initramfs немає кореня. Колись.
mikeserv

8

Від LFS :

Єдиною метою initramfs є встановлення кореневої файлової системи. Initramfs - це повний набір каталогів, який ви знайдете у звичайній кореневій файловій системі. Він поєднується в єдиний архів cpio і стискається за допомогою одного з декількох алгоритмів стиснення.

...

Існує лише чотири основні причини наявності initramfs у середовищі LFS: завантаження коренів із мережі, завантаження її з логічного тома LVM, наявність зашифрованих файлів rootfів, де потрібно ввести пароль, або для зручності вказівки rootfs як ЕТИКЕТ або UUID. Зазвичай все означає, що ядро ​​не було налаштовано належним чином.

...

Для більшості дистрибутивів модулі ядра є найбільшою причиною наявності initramfs. У загальному розповсюдженні є багато невідомих, таких як типи файлової системи та макети диска. Зрештою, це протилежність LFS, де відомі можливості системи та компонування системи, і звичайно будується спеціальне ядро. У цій ситуації інітрамф рідко потрібен.

Ще одне джерело www.kernel.org

Поруч з цим існує багато систем Linux, які люблять роутери, які не використовують initramfs.


1

Вам потрібні initramfs для більш складних налаштувань, таких як завантаження мережі або lvm або raid, оскільки для налаштування доступу до кореневих файлів вони потребують деяких утиліт користувача. Для простого звичайного розділу на диску, якщо у вас є вбудовані драйвери диска в ядро, і вкажіть кореневий аргумент шляхом шляху пристрою, а не UUID, тоді ви можете обійтися без initramfs. Звичайно, шлях до пристрою може змінюватися, залежно від того, які пристрої підключення та відтворення (тобто usb) ви підключили, або навіть просто випадкові відхилення в часі, саме тому майже всі користувачі використовують uuids та initramfs для надійності.


Це також неправильно.
mikeserv

6
@mikeserv, ваш коментар марний. Якщо ви збираєтесь це стверджувати, вам потрібно пояснити, чому.
psusi

Я зробив, а точніше, документацію ядра, яка становить приблизно 99% моєї відповіді.
mikeserv

@mikeserv, це правильно. Я працюю Gentoo linux протягом багатьох років без initramfs.
Тім

1

Це старе запитання, але все ще, здається, немає прийнятої відповіді, тому я викину це (я тут не експерт, я намагаюся це зрозуміти для себе).

Від https://www.kernel.org/doc/Documentation/early-userspace/README (внизу, в якій говориться, що він не оновлювався з 2004 року)

В даний час у ядра є три способи монтажу кореневої файлової системи:

а) всі необхідні драйвери пристрою та файлової системи, зібрані в ядро, не мають initrd. init / main.c: init () викличе просто підготовити_namepace () для монтажу кінцевої кореневої файлової системи на основі параметра root = та необов'язковий init = для запуску іншої бінарної програми init, ніж зазначено в кінці init / main.c: init ().

б) деякі драйвери пристроїв і файлових систем, побудовані як модулі та збережені в інітдр. Інітдр повинен містити двійковий '/ linuxrc', який повинен завантажувати ці драйверні модулі. Також можливо встановити остаточну кореневу файлову систему через linuxrc та використовувати svotcall pivot_root. Інітдр монтується та виконується за допомогою простору_файлів ().

в) за допомогою initramfs. Виклик на сторінку_файлу_пробіру () повинен бути пропущений. Це означає, що бінарний повинен виконувати всю роботу. Згаданий бінарний файл може зберігатися в initramfs або через модифікацію usr / gen_init_cpio.c або через новий формат initrd, архів cpio. Він повинен називатися "/ init". Цей двійковий файл несе відповідальність за все те, що робиться у просторі_файлів ().

Для підтримки зворотної сумісності бінарний файл / init запускається лише в тому випадку, якщо він надходить через архів cpio initramfs. Якщо це не так, init / main.c: init () запустить Prepa_namespace () для монтажу остаточного кореня та виконує один із попередньо визначених бінарних файлів init.

Я вважаю, що пристрої / дистрибутиви, такі як Raspberry Pi тощо, не використовують initramfs; в деяких випадках ядро ​​знаходиться на кореневому розділі (монтується завантажувачем, який має необхідні модулі fs.) В інших випадках, коли ядро ​​є, наприклад, на /bootрозділі, до initramfs на цьому ж розділі можна отримати доступ безпосередньо перед монтажем rootfs, як інші заявили.

У деяких випадках initramfs може бути вбудований у той самий файл, що і ядро, але це не завжди так. (а), здається, досить чітко заявляє, що в деяких випадках initramfs не є необхідним.


0

Я вважаю таке пояснення більш зрозумілим,

initramfsце коренева файлова система, яка вбудовується в ядро ​​і завантажується на ранній стадії процесу завантаження. Це наступник initrd. Він надає простір користувачів, який може робити те, що ядро ​​не може легко зробити самостійно під час завантаження.

Використання initramfs необов’язково. За замовчуванням ядро ​​ініціалізує апаратне забезпечення за допомогою вбудованих драйверів, монтує вказаний кореневий розділ, завантажує систему init встановленого дистрибутива Linux. Потім система init завантажує додаткові модулі та запускає сервіси до тих пір, поки це не дозволить вам увійти. Це хороша поведінка за замовчуванням і достатня для багатьох користувачів. initramfs призначений для користувачів з просунутими вимогами; для користувачів, яким потрібно робити завдання якомога раніше, ще до встановлення кореневого розділу.

Ось кілька прикладів того, що можна зробити з initramfs:

  • Змонтувати кореневий розділ (для зашифрованих, логічних та спеціальних розділів);
  • Забезпечте мінімалістичний рятувальний снаряд (якщо щось піде не так);
  • Налаштувати процес завантаження (наприклад, надрукувати привітальне повідомлення, сплеск завантаження тощо);
  • Завантажують модулі (наприклад, сторонні драйвери);
  • Нічого не може зробити ядро ​​(доки ви можете це робити в користувальницькому просторі, наприклад, виконуючи команди). Якщо ви не маєте розширених вимог, вам не потрібно initramfs.

-1

Що б ви не робили, у вас є initramfs. Без цього не обійтися - це єдина файлова система, нав'язана вам. З kernel.org :

Що таке корінці?

Rootfsє спеціальним екземпляром ramfs(або tmpfs, якщо це ввімкнено), який завжди присутній в системах 2.6. Ви не можете відключитиrootfs приблизно з тієї ж причини, що не можете вбити процес init; замість того, щоб мати спеціальний код для перевірки та обробки порожнього списку, це менше і простіше для ядра, щоб переконатися, що певні списки не можуть стати порожніми.

Більшість систем просто змонтують іншу файлову систему rootfsта ігнорують її. Обсяг місця, який займає порожній екземпляр ramfs, невеликий.

Якщо * CONFIG_TMPFS * увімкнено, rootfsвикористовуватиметься tmpfsзамість ramfsза замовчуванням. Щоб примусити ramfs, додайте "rootfstype=ramfs"до командного рядка ядра.

Що таке initramfs?

Всі 2.6 ядра Linux містять"cpio"архів форматуgzipped, який витягується під rootfsчас завантаження ядра. Після вилучення ядро ​​перевіряє, чиrootfsмістить він файл"init" , і якщо так, він виконує його як PID 1. Якщо його знайдено, цейinitпроцес відповідає за те, що система підведе решту шляху, включаючи пошук та встановлення реального кореневого пристрою ( якщо якийсь). Якщо програмаrootfsне міститьinitпрограму післяcpioвилученнявбудованогоархіву, ядро ​​потрапить до старого коду, щоб знайти та змонтувати кореневий розділ, а потім/sbin/initвиконатиякийсь варіантіз цього.

Все це відрізняється від старого initrd кількома способами:

  • Старий initrd завжди був окремим файлом, а архів initramfs пов'язаний із зображенням ядра Linux. (Каталог linux - * / usr присвячений генерації цього архіву під час збирання.)

  • Старий файл initrd являв собою зображення файлової системи gzipped (у деякому форматі файлу, наприклад, ext2, для якого потрібен драйвер, вбудований у ядро), а новий архів initramfs - це gzipped архів cpio (як-от tar, простіше, див. Cpio (1) і Документація / рано-користувацький простір / буфер-формат.txt). Код вилучення cpio ядра не лише надзвичайно малий, він також __init тексту та даних, які можна відкинути під час завантаження.

  • Програма, запущена старим initrd (яка називалася / initrd, не / init), зробила деяку настройку, а потім повернулася до ядра, тоді як програма init з initramfs не очікується повернення до ядра. (Якщо / init потребує передачі керування, він може змінити / з новим кореневим пристроєм та виконати іншу програму init. Див. Утиліту switch_root, нижче.)

  • Під час перемикання іншого кореневого пристрою, initrd би перемикав_root, а потім маніпулює ramdisk. Але initramfs - це rootfs: ви не можете ні pivot_root rootfs, ні демонтувати його. Замість цього видаліть усе із кореневих файлів, щоб звільнити простір (знайдіть -xdev / -exec rm '{}' ';'), переставте rootfs новим коренем (cd / newmount; mount --move. /; Chroot.), додайте stdin / stdout / stderr до нової / dev / console та виконайте новий init.

Оскільки це надзвичайно складний процес (і включає видалення команд перед тим, як їх запустити), пакет klibc представив програму-помічник (utils / run_init.c), щоб зробити це все за вас. Більшість інших пакетів (наприклад, зайнятий) назвали цю команду "switch_root".

Популяція initramfs:

Процес збирання ядра 2.6 завжди створює архів initramfs формату gzipped cpio і пов'язує його в отриманий бінарний файл ядра. За замовчуванням цей архів порожній (на x86 витрачається 134 байти).

Параметр config CONFIG_INITRAMFS_SOURCE (у загальній установці в menuconfig та проживає в usr / Kconfig) може бути використаний для визначення джерела для архіву initramfs, який автоматично буде включений у отриманий бінарний файл. Цей параметр може вказувати на існуючий архів gpіp cpio, каталог, що містить файли, що підлягають архівуванню, або специфікацію текстового файлу, наприклад наступний приклад:

  dir /dev 755 0 0
  nod /dev/console 644 0 0 c 5 1
  nod /dev/loop0 644 0 0 b 7 0
  dir /bin 755 1000 1000
  slink /bin/sh busybox 777 0 0
  file /bin/busybox initramfs/busybox 755 0 0
  dir /proc 755 0 0
  dir /sys 755 0 0
  dir /mnt 755 0 0
  file /init initramfs/init.sh 755 0 0

Запустіть "usr / gen_init_cpio" (після побудови ядра), щоб отримати повідомлення про використання, що документує вищевказаний формат файлу.

Однією з переваг конфігураційного файлу є те, що кореневий доступ не потрібен для встановлення дозволів або створення вузлів пристроїв у новому архіві. (Зверніть увагу, що ці два приклади "файлових" файлів очікують, що файли з назвою "init.sh" та "busybox" знайдуться в каталозі під назвою "initramfs", в каталозі linux-2.6. *. Детальніше.)

Ядро не залежить від зовнішніх інструментів cpio. Якщо ви вказали каталог замість файлу конфігурації, інфраструктура збирання ядра створює файл конфігурації з цього каталогу (usr / Makefile викликає сценарії / gen_initramfs_list.sh) і переходить до упаковки цього каталогу за допомогою файлу config (подаючи його в usr / gen_init_cpio, який створюється з usr / gen_init_cpio.c). Код створення файлів cpio часу нарощування ядра повністю автономний, а екстрактор часу завантаження ядра також (очевидно) самостійний.


1
Ви можете завантажуватися без initramfs. Ваша відповідь пояснює переваги initramfs, але це не стосується типових вбудованих систем і навіть на настільних комп'ютерах або серверах, де рекомендується initramfs, це не є обов'язковим.
Жил "ТАК - перестань бути злим"

@Gilles - не можеш. Незалежно від того, чим займаєтесь, у вас є initramfs. Він компілюється в ядро ​​- саме зараз ваше ядро, моє ядро, всі наші ядра. Прочитайте документи ядра - весь мій пост був копіювальною пастою. Ви невірні. Як можна оскаржити офіційну документацію?
mikeserv

1
Я не оспорюю офіційну документацію, я спростовую висновки, які ви робите з неї. Ви читаєте документацію, яка пояснює, як користуватися initramfs. Ніде не зазначено, що initramfs доводиться використовувати.
Жил "ТАК - перестань бути злим"

@Gilles Якщо це недостатньо добре: "Процес збирання ядра 2.6 завжди створює архів initramfs формату gzipped cpio і посилає його на отриманий бінарний файл ядра. За замовчуванням цей архів порожній (витрачає 134 байти на x86) .... "Я можу зробити краще. Вище сказано, що це 2 або 3 хвилини пошуку в Інтернеті.
mikeserv

3
Я прочитав документацію. Я цим займаюся на життя. Це не питання думки. Завжди є initramfs, але він не обов'язково використовується для завантаження. Я не можу знайти гідне пояснення структури ядра для цього випадку, імовірно, тому що це класичний випадок, який, на думку, не вимагає пояснення. Основна логіка полягає в do_mounts.cконкретному prepare_namespace, в якому saved_root_nameпоповнюється root=аргумент командного рядка.
Жил "ТАК - перестань бути злим"
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.