Як Linux завантажує зображення "initrd"?


13

Я намагався зрозуміти процес завантаження, але є лише одне, що переживає мою голову.

Як тільки ядро ​​Linux буде завантажено та встановлено кореневу файлову систему (/), можна запустити програми та додатково інтегрувати модулі ядра для надання додаткових функцій. Для монтажу кореневої файлової системи повинні бути виконані певні умови. Ядро потребує відповідних драйверів для доступу до пристрою, на якому розташована коренева файлова система (особливо драйвери SCSI). Ядро також повинно містити код, необхідний для читання файлової системи (ext2, reiserfs, romfs тощо). Можливо також, що коренева файлова система вже зашифрована. У цьому випадку потрібен пароль для монтажу файлової системи.

Початковий рамдиск (також його називають initdisk або initrd) вирішує саме описані вище проблеми. Ядро Linux надає можливість завантаження невеликої файлової системи на диск RAM та запуску програм там до монтажу фактичної кореневої файлової системи. Завантаження initrd виконується завантажувачем (GRUB, LILO тощо). Завантажувачі завантажують лише підпрограми BIOS для завантаження даних із завантажувального середовища. Якщо завантажувач може завантажити ядро, він також може завантажити початковий ramdisk. Спеціальні водії не потрібні.

Якщо / boot не є іншим розділом, але він присутній у / розділі, то чи не повинен завантажувач вимагати драйверів SCSI, щоб отримати доступ до зображення 'initrd' та зображення ядра? Якщо ви можете отримати доступ до зображень безпосередньо, то навіщо саме нам потрібні драйвери SCSI ??

Відповіді:


20

Nighpher, я спробую відповісти на ваше запитання, але для більш повного опису процесу завантаження спробуйте статтю IBM .

Гаразд, я припускаю, що ви використовуєте GRUB або GRUB2 як завантажувач для пояснення. По-перше, коли BIOS звертається до вашого диска для завантаження завантажувача, він використовує вбудовані підпрограми для доступу до дисків, які зберігаються у відомому 13-годинному перериванні. Завантажувач (і ядро ​​на етапі налаштування) використовує ці підпрограми під час доступу до диска. Зауважте, що BIOS працює в режимі процесора в реальному (16 бітовому) режимі, таким чином він не може адресувати більше 2 ^ 20 байт оперативної пам’яті (2 ^ 20 не 2 ^ 16, оскільки кожна адреса в реальному режимі складається з сегмента_адреса * 16 + зміщення , де адреса сегменту та зміщення є 16-бітними, див. http://en.wikipedia.org/wiki/X86_memory_segmentation ). Таким чином, ці підпрограми не можуть отримати доступ більше 1 Мбайт оперативної пам’яті, що є суворим обмеженням і великою незручністю.

BIOS завантажує код завантажувача прямо з MBR - перші 512 байти вашого диска і виконує його. Якщо ви використовуєте GRUB, цей код є етапом 1. GRUB. Цей код завантажує етап GRUB 1.5, який розташований або в першому 32 КБ дискового простору, який називається областю сумісності DOS, або з фіксованої адреси файлової системи. Для цього не потрібно розуміти файлову систему, тому що навіть є етап 1.5 у файловій системі, це "сирий" код і може бути безпосередньо завантажений в оперативну пам'ять та виконаний: http://www.pixelbeat.org/ docs / диск / . Завантаження етап1.5 з диска в оперативну пам'ять використовує підпрограми доступу до диска BIOS.

введіть тут опис зображення

Stage1.5 містить утиліти файлової системи, так що вона може читати stage2 з файлової системи (ну, вона все ще використовує BIOS 13h для читання з диска на оперативну пам’ять, але тепер вона може розшифрувати інформацію про файли в індексах і т.д. диск). Старіші BIOS можуть не мати доступу до всього HD через обмеження в режимі адресації їхніх дисків - вони можуть використовувати систему Cylinder-Head-Sector, не в змозі вирішити більше, ніж перші 8 Гб дискового простору: http: //uk.wikipedia. org / wiki / Циліндр-головний сектор .

Stage2 завантажує ядро в оперативну пам'ять (знову ж таки, використовуючи дискові утиліти BIOS). Якщо це ядро ​​2.6+, воно також містить initramfs, зібрані всередині, тому не потрібно його завантажувати. Якщо це більш старе ядро, завантажувач також завантажує в пам'ять окреме зображення initrd, щоб ядро ​​могло його змонтувати та отримати драйвери для монтажу реальної файлової системи з диска.

Проблема полягає в тому, що ядро ​​(і ramdisk) важать більше 1 МіБ, таким чином, щоб завантажити їх в оперативну пам’ять, ви повинні завантажити ядро ​​спочатку на 1 МіБ, потім перейти в захищений режим (32 біт), перемістити завантажене ядро ​​у високу пам'ять (безкоштовно перший 1 Мб для реального режиму), потім знову поверніться до реального (16 бітового) режиму, отримайте рамковий диск з диска на перший 1 МБ (якщо це окремий інітарій та старіше ядро), можливо, знову перейдіть у захищений (32 бітний) режим, помістіть його туди, куди належить, можливо поверніться до реального режиму (чи ні: /programming/4821911/does-grub-switch-to-protected-mode ) та виконайте код ядра. Попередження: Я не зовсім впевнений у ґрунтовності та точності цієї частини опису.

Тепер, коли ви, нарешті, запустите ядро, у нього вже є і ramdisk завантажений в оперативну пам'ять завантажувачем , тому ядро ​​може використовувати дискові утиліти з ramdisk для монтажу вашої реальної кореневої файлової системи та підключення до неї кореня. драйвери ramfs присутні в ядрі, тому він, зрозуміло, може зрозуміти вміст initramfs.


Чи не може завантажувач просто завантажити ядро ​​кусками, замість того, щоб стрибати в захищений режим ?? І в чому потреба звільнити 1 Мб .. (Вибачте .. не могла це зрозуміти ..)
rpthms

Необхідність звільнення першого 1MiB полягає в наступному: завантажувач може отримати доступ до вашого жорсткого диска лише в реальному режимі, викликати доступ до нього з утилітами BIOS, які є в реальному режимі (вони працюють на 16-бітних аргументах і використовують 16-бітні операції). Реальний режим просто не бачить жодної оперативної пам’яті, окрім першого 1 МБ. Але вам потрібно завантажити ядро ​​+ initramfs в оперативну пам’ять, і вони займають ~ 5 MiB місця в оперативній пам'яті. Ці утиліти BIOS просто не зможуть вичавити 5 Мб на перший 1 Мбайт. Отже, завантажувач повинен скопіювати їх з диска спочатку 1 Мб, потім перейти в захищений режим і перемістити їх з першої 1 Мб оперативної пам'яті у більшу оперативну пам'ять. Чи зрозуміліше зараз? :)
Борис Бурков

1
Весь етап 1 / 1,5 / 2 - це застаріла спадщина.
psusi

1
@CMCDragonkai Так, завантажувач stage2 знаходиться у файловій системі (а саме в /bootрозділі). На даний момент ядро ​​не завантажується - це етап grub1.5, який отримує доступ до stage2 у /bootфайловій системі (наприклад, у /boot/grubфайлі) через свої мінімалістичні драйвери файлової системи. Ядро також зможе читати з /bootрозділу, але це станеться пізніше, після виконання коду grub2 та завантаження ядра та після того, як ядро ​​зчитує initramfs. Ви говорите про init.shinitramfs? Він знаходиться в /bootрозділі вашого жорсткого диска, потім stage2 grub вводить його в оперативну пам'ять, а Kernel читає його з оперативної пам'яті.
Борис Бурков

1
Інітрд повинен був бути окремим файлом. Новіші initramfs можуть бути пов'язані з ядром, але це не обов'язково - завантажувач також може бути завантажений як окремий файл. Оскільки файл initramfs визначений як послідовність архівів cpio, деякі завантажувачі (наприклад, iPXE) навіть дозволяють декілька файлів initramfs, які завантажуватимуться в пам'ять один за одним. Крім того, деякі дистрибутиви Linux використовують імена файлів у стилі initrd для зворотної сумісності, хоча власне використовувана технологія зараз є initramfs.
telcoM

1

Я вважаю, що це зводиться до того, які функції підтримує конкретний завантажувач. Напр. вона не повинна знати конкретної файлової системи вашого комбінованого (завантажувального + root) розділу. У цьому випадку ви просто створите окремий завантажувальний розділ за умови, що він працює з вашим завантажувачем, і будь-яка інша складність того, як змонтувати кореневий розділ, залишається на ядрі та initrd-зображенні, завантаженому з завантажувального розділу. Завантажувач знає, як отримати доступ до пристроїв SCSI (і до інших пристроїв теж, залежно від того, який завантажувач використовується) або за допомогою власних драйверів, або за допомогою підпрограм BIOS. Більше того, він знає, як читати деякі файлові системи тощо.

Розглянемо напр. Спосіб завантаження UEFI, де фактично прошивка UEFI вже знає, як отримати доступ до розділу EFI, прочитати його та завантажити звідти ядро ​​Linux без необхідності проміжного завантажувача. У такому випадку зображення linux живе відокремленим від кореневого розділу та прошивки UEFI не повинні знати всіх екзотичних файлових систем для доступу до нього. Я вважаю, що розділення "завантажувальних" зображень від "кореневого" розділу має велике значення. Якщо ні для чого іншого, то це необхідно при налаштуванні шифрування кореневої файлової системи.


0

Тільки для запису, якщо завантажувач не завантажує initrd, варто перевірити інший завантажувач; Я просто побіг в такій ситуації , як це , коли LILO проігнорована правильно вказано Initrd середнього розміру (<4Mb, поодинокі ext4 кореневої файлової системи на SATA SSD, GPT) і GRUB 2.00 вдалося.

Процес завантаження швидко закінчився типовим

RAMDISK: Couldn't find valid RAM disk image starting at 0.
Kernel panic - not syncing: VFS: Unable to mount root fs on unknown-block(8,3)
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.