Як ядро ​​монтує кореневий розділ?


29

Моє запитання щодо завантаження системи Linux з окремого / завантажувального розділу. Якщо більшість файлів конфігурації розташовані на окремому / розділі, як ядро ​​правильно монтує його під час завантаження?

Будь-яка розробка цього питання була б чудовою. Я відчуваю себе так, ніби пропускаю щось базове. Я здебільшого переймаюся процесом та порядком операцій.

Спасибі!

EDIT: Я думаю, що мені потрібно було запитати, це більше уздовж рядків файлу dev, який використовується в параметрі кореневого ядра. Наприклад, скажіть, я даю свій параметр root як root = / dev / sda2. Як ядро ​​має відображення файлу / dev / sda2?


Хоча люди внизу висвітлюють initrd, мало обговорюється, чому використовується initrd. Моє враження полягає в тому, що дистрибутиви на зразок Debian хочуть використовувати одне ядро ​​на багатьох різних машинах тієї самої архітектури, але, можливо, в іншому обладнання. Це стає можливим завдяки модуляції апаратної підтримки через модулі ядра. Інітдр не потребує великої апаратної підтримки для завантаження, і після цього він завантажує необхідні апаратні модулі для продовження. Розробка / виправлення до цього оцінені.
Faheem Mitha

Ви не можете монтувати / завантажуватись, не встановивши / встановивши спочатку, оскільки немає / каталог завантаження без /.
psusi

Відповіді:


20

Linux спочатку завантажується з ramdisk (званий an initrd, для "INITial RamDisk") як /. На цьому диску достатньо просто на ньому, щоб можна було знайти справжній кореневий розділ (включаючи будь-які необхідні драйвери та модулі файлової системи). Він монтує кореневий розділ на тимчасову точку монтажу на initrd, після чого викликає pivot_root(8)для заміни кореневих та тимчасових точок монтування, залишаючи initrdпозицію для umountредагування та фактичну кореневу файлову систему /.


2
Що робити, якщо у вас немає initrd на зразок LFS (linuxfromscratch.org)?
Містер Шикаданс

@Містер. Шикаданс: Не дивлячись на те, як LFS робить справи, я б припустив, що вони впевнені, що ядро ​​має всі необхідні модулі, зібрані в нього (або завантажено через GRUB 2, яка можливість є достатньо новою, що не так багато дистрибутивів помітили це), так що може запускатися на фактичному кореневому розділі.
geekosaur

4
@Містер. Шикаданс. Початок не тільки LFS не має. Кожен, хто збирає власне ядро, має можливість не використовувати initrd, що я роблю в Gentoo.
jonescb

1
@Faheem: grub2 модулі не збігаються з модулями ядра. Я бачу певну здатність grub2 завантажувати модулі ядра, але одне, що я не знаю, - це буде працювати для ядра Linux або лише для * BSD (де нормальне завантаження модулів завантажувача завантажувача). Я підозрюю, що ядро ​​потрібно навчити, де знайти карту адрес для завантажених модулів, і всім потрібно перейти до grub2 (grub1 все ще є стандартним у деяких дистрибутивах).
geekosaur

1
Інітрд був замінений на initramfs, оскільки pivot_root розглядався як брудний злом.
psusi

41

У стародавні часи ядро ​​було важко закодовано, щоб знати основну / меншу кількість кореневих файлів і встановити цей пристрій після ініціалізації всіх драйверів пристроїв, вбудованих у ядро. rdevУтиліта може бути використана для зміни кількості кореневого пристрою в образі ядра без необхідності перекомпілювати його.

Врешті-решт завантажувачі завантажуються і можуть передати командний рядок до ядра. Якщо root=аргумент був переданий, він повідомив ядро, де знаходиться корінь fs замість вбудованого значення. Для доступу до драйверів, які ще мали бути вбудовані в ядро, потрібні були драйвери. Хоча аргумент виглядає як звичайний вузол пристрою в /devкаталозі, очевидно, що /devдо монтажу кореня fs немає каталогу, тому ядро ​​не може шукати там вузол dev. Натомість деякі відомі імена пристроїв важко кодуються в ядро, тому рядок може бути переведений на номер пристрою. Через це ядро ​​може розпізнавати такі речі /dev/sda1, але не більш екзотичні речі, такі /dev/mapper/vg0-rootяк UUID.

Пізніше initrdприйшов у світ картину. Поряд з ядром завантажувач завантажував initrdзображення, яке було якось стислим зображенням файлової системи (gzipped зображення ext2, зображення gzipped romfs, нарешті стали домінуючими). Ядро декомпресує це зображення на рамковий диск і монтує ramdisk як root fs. Це зображення містило деякі додаткові драйвери та сценарії завантаження замість реального init. Ці сценарії завантаження виконували різні завдання з розпізнавання апаратного забезпечення, активації таких речей, як рейдові масиви та LVM, виявлення UUID та розбору командного рядка ядра, щоб знайти справжній корінь, який тепер може бути визначений UUID, міткою тома та іншими розширеними речами. Потім він встановив справжній root fs /initrd, а потім виконав pivot_rootсистемний виклик, щоб ядро ​​змінилось /і/initrd, то виконайте виконання /sbin/initсправжнього кореня, який потім відключить /initrdта звільнить рамбіск.

Нарешті, сьогодні у нас є initramfs. Це схоже на initrdфайл, але замість того, щоб бути стислим зображенням файлової системи, завантаженим у рамковий диск, це стислий архів cpio. Tmpfs змонтовано як корінь, і там архів витягується. Замість використання pivot_root, яке розцінювалося як брудний хак, initramfsзавантажувальні скрипти монтують справжній корінь /root, видаляють усі файли в корені tmpfs, потім chrootу /root, і exec /sbin/init.


1
Після Chroot tmpfs автоматично не відключається? Це просто зникає?
jiggunjer

@jiggunjer, ні, він все ще є, він просто порожній (окрім вмісту каталогу / root) і більше не використовується.
psusi

Я дізнався щось нове про кожну ітерацію root fs, яку ви згадали. Чудова відповідь!
jpaugh

3

Здається, ви запитуєте, як ядро ​​"знає", який розділ є кореневим розділом, без доступу до файлів конфігурації в / і т.д.

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

Один з таких варіантів командного рядка - це те root, де ви можете вказати кореневу файлову систему, тобто root=/dev/sda1.

Якщо ядро ​​використовує initrd, завантажувач відповідає за те, щоб повідомити ядро, де він знаходиться, або поставити initrd у стандартне місце пам'яті (я думаю) - це, принаймні, так, як це працює на моєму Guruplug.

Неможливо вказати його, а потім змусити ядро ​​панікувати одразу після того, як почати скаржитися, що він не може знайти кореневу файлову систему.

Можуть бути й інші способи передачі цієї опції до ядра.


3
Це правильне пояснення, коли немає initrd / initramfs, але в ньому відсутній фрагмент головоломки. Зазвичай ядро ​​ідентифікує такий пристрій, як, наприклад, /dev/sda1тому, що це запис у файловій системі. Ви могли б зробити cp -p /dev/sda1 /tmp/fooі /tmp/fooпредставляти один і той же пристрій. У командному рядку ядра ядро ​​використовує вбудований аналізатор, який відповідає звичайному умові іменування пристрою: sda1означає перший розділ першого диска, схожого на SCSI.
Жил "ТАК - перестань бути злим"

@Gilles, так що сучасні ядра все ще не можуть впоратися з монтажем гучності на основі UUID? без initrdабо initramfsя маю на увазі. Це повинен бути "простий" розділ у /dev/sdxформі?
джиггуньєр

1
@jiggunjer Сучасні ядра підтримують пошук обсягу за допомогою UUID. Див init/do_mounts.c.
Жил "ТАК - перестань бути злим"

1

Grub монтує /bootрозділ, а потім виконує ядро. У конфігурації Grub він повідомляє ядру, що використовувати як кореневий пристрій.

Наприклад у Grub menu.lst:

kernel /boot/linux root=/dev/sda2

1

Скажімо, GRUB не "монтується" / завантажується, він просто читає "menu.lst" та деякі модулі, він також не є частиною ядра LINUX. Коли ви викликаєте ядро, ви передасте аргумент "root" з кореневим розділом. У гіршому випадку ядро ​​знає, що just / boot було встановлено (LOL).

Далі: geekosaur вірно, Linux використовує початковий рамдіск у стисненому форматі зображення, а потім монтує реальну кореневу файлову систему за допомогою виклику pivot_root. Отже, Linux починає працювати з зображення, а потім із локального дисковода.


1
Grub, безумовно, має можливість "монтувати" файлову систему, особливо в grub2. Звичайно, все, на що він здатний / робить /, це шукати завантажувальні ядра тієї чи іншої смуги, але це все-таки монтується. Крім того, для Linux не потрібен initrd, якщо ваше ядро ​​не зібрало драйвери, які мають важливе значення для вашого жорсткого диска як модулів.
Шадур

5
ibm.com/developerworks/linux/library/l-linuxboot Це досить стислий підсумок того, що робить ядро ​​Linux під час завантаження.
jsbillings

2
@Shadur, зі сторінки монтування : Усі файли, доступні в системі Unix, розташовані в одному великому дереві, ієрархія файлів - корінь у /. Ці файли можна поширити на декілька пристроїв. Команда mount служить для приєднання файлової системи, знайденої на якомусь пристрої, до великого дерева файлів. - Оскільки файлові системи, використовувані GRUB, не приєднані до ієрархії файлів, це НЕ монтується .
D4RIO

1
@Shadur, BTW: Очевидно, що initrd не потрібен, оскільки це просто інша коренева файлова система, але він, як правило, використовується як невеликий корінь завантажувального часу, оскільки ядро ​​завантажує необхідне для завантаження, потім завантажує і нарешті завантажує все інше.
D4RIO

1
@ d4rio Вони встановлені GRUB, а не Linux - це стає легше зрозуміти, коли ви розглядаєте grub як власну мікроядерну ОС, а не просто завантажувач.
Шадур

1

Завантажувач, будь то grub або lilo або будь-який інший, повідомляє ядро, куди шукати root=прапор, і необов'язково завантажує початковий ramdisk в пам'ять, initrdперш ніж завантажувати ядро.

Потім ядро ​​завантажується, тестує драйвери обладнання та пристроїв і оглядає систему на предмет того, що воно може бачити (ви можете переглянути цю діагностичну інформацію, ввівши dmesg; в даний час це можливо, прокручується занадто швидко, щоб побачити), потім намагається встановити розділ, згаданий в root=параметр.

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

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.