Подробиці процесу завантаження Linux
Подорож від Master Boot Record до першої програми, що виконується у просторі користувача
Давайте спочатку кинемо найзагальніший погляд на процес початкового завантаження Linux, щоб охопити картину повністю. Потім ми докладніше розглянемо, що відбувається кожному етапі процесу. Посилання на вихідний код, які будуть наводитися постійно у процесі викладу, допоможуть щодо дерева вихідних кодів ядра і підкажуть, де отримати додаткову інформацію.
На малюнку 1 показаний вид з "висоти пташиного польоту".Малюнок 1. Вид на процес початкового завантаження в Linux з висоти пташиного польоту

Після того, як пристрій, з якого здійснюватиметься початкове завантаження, знайдено, початковий завантажувач першого ступеня завантажується в оперативну пам'ять і починається його виконання. Цей початковий завантажувач має розмір менше 512 байт (один сектор), і його завданням є завантаження початкового завантажувача другого ступеня.
Після того, як в оперативну пам'ять завантажується і починає виконуватися початковий завантажувач другого ступеня, на екрані зазвичай відображається заставка і в пам'ять завантажуються Linux разом з початковим необов'язковим RAM-диском (тимчасова система кореневих файлів). Після того, як ці образи будуть завантажені, початковий завантажувач другого ступеня передає управління ядру і виконується декомпресія та ініціалізація ядра. На цій стадії початковий завантажувач другого ступеня перевіряє апаратне забезпечення системи, виконує нумерацію підключених пристроїв, монтує кореневий пристрій і завантажує необхідні модулі ядра. Після завершення цих завдань запускається перша програма користувача (
) а потім виконується ініціалізація системи високого рівня.
Такий загалом процес початковоїзавантаження в Linux. Тепер давайте заглибимося трохи далі і розглянемо деякі подробиці початкового завантаження в Linux.
Запуск системи визначається апаратною платформою, на якій виконується початкове завантаження Linux. На платформах, що вбудовуються, при включенні живлення системи або при перезавантаженні використовується bootstrap-середовище. Як приклади можна навести U-Boot, RedBoot та MicroMonitor від компанії Lucent. Ці програми зберігаються в спеціальній області flash-пам'яті, розташованої у системі, що вбудовується: вони надають засоби для завантаження образу ядра Linux у flash-пам'ять і надалі забезпечують виконання цього ядра. На додаток до функцій зберігання та завантаження образу Linux ці монітори завантаження також виконують тестування системи на якомусь рівні та ініціалізацію апаратного забезпечення. У системах, що вбудовуються, подібні монітори завантаження зазвичай поєднують функції завантажувачів першого і другого ступеня.
Перегляд вмісту MBR
, яка виконується з правами root, зчитує перші 512 байт з /dev/hda (перший жорсткий диск IDE) і записує їх у файл
виконує друк отриманого двійкового файлу у форматах hex та ASCII.
Якщо враховувати різне призначення функцій BIOS, можна вважати, що BIOS і двох частин: коду POST і сервісів часу виконання. Після завершення POST відповідний код видаляється з пам'яті, проте сервіси часу виконання BIOS залишаються в пам'яті та доступні для операційної системи.
Для виконання завантаження операційної системи сервіси часу виконання BIOS виконують пошук таких пристроїв, які є активними та здатні виконувати завантаження – причому пошук виконується в порядку, який визначається налаштуваннями, збереженими в пам'яті CMOS. Як завантажувальні пристроїможуть бути флоппі-диски, CD-ROM, розділи на жорсткому диску, підключений до мережі пристрій або навіть портативний USB-накопичувач.
Зазвичай завантаження Linux проводиться з жорсткого диска, на якому MBR міститься первинний початковий завантажувач. MBR є сектор розміром 512 байт, який розташовується в першому секторі диска (сектор 1 циліндра 0, головка 0). Після того, як MBR завантажується в пам'ять, BIOS передає йому керування.
Завантажувач 1-го ступеня
Первинний початковий завантажувач, що зберігається в MBR, є образом розміром 512 байт, який містить як програмний код, так і невелику таблицю розділів (див. малюнок 2). Перші 446 байт є власне первинним завантажувачем, який містить як програмний код, так і текст повідомлень про помилки. Наступні 64 байта є таблицею розділів, яка містить запис для кожного з чотирьох розділів диска (по 16 байт кожна). В кінці MBR розташовуються два байти, які звуться "магічного числа" (0xAA55). Це магічне число служить для перевірки MBR.Малюнок 2. Будова MBR

Завдання первинного завантажувача - знайти і завантажити вторинний завантажувач (завантажувач другого ступеня). Він робить це, переглядаючи таблицю розділів у пошуку активного розділу. Коли первинний завантажувач виявляє активний розділ, він переглядає розділи, що залишилися, з метою переконатися, що вони не є активними. Після завершення цієї перевірки з пристрою до оперативної пам'яті зчитується завантажувальний запис активного розділу.
Завантажувач 2-го ступеня
Вторинний завантажувач або завантажувач другого ступеня було б більш логічно назвати завантажувачем ядра. Його завданням на даній стадії є завантаження ядра Linux і, можливо, завантаження початкового RAM-диска.
Завантажувачі GRUB різних ступенів
, а також деякі альтернативні завантажувачі (наприклад, CR-ROM використовує
Завантажувачі для середовища x86, які об'єднують у собі завантажувачі першої та другої стадії, звуться Linux Loader (LILO) або GRand Unified Bootloader (GRUB). Так як LILO мав деякі недоліки, які були виправлені у GRUB, то далі ми розглядатимемо саме GRUB. (Велика кількість додаткових посилань на матеріали з GRUB, LILO та пов'язаних з ними тем міститься в розділі Ресурсу наприкінці цієї статті.)
Однією з найбільших переваг GRUB є те, що він здатний розуміти файлові системи, що використовуються в Linux. Замість того, щоб подібно до LILO, звертатися безпосередньо до секторів жорсткого диска, завантажувач GRUB здатний завантажувати ядро Linux з файлових систем ext2 або ext3. Це досягається завдяки перетворенню двоступінчастого завантажувача на триступінчастий. Ступінь 1 (MBR) завантажує завантажувач 1.5-ступеня, здатний розуміти файлову систему, де зберігається образ ядра Linux. Прикладами можуть бути
(для завантаження з файлової системи з журналом Reiser) або
(Для завантаження з файлових систем ext2 або ext3). Після того, як завантажувач 1.5 ступеня завантажений та виконується, може бути завантажений завантажувач 2-го ступеня.
Після завантаження 2 ступеня GRUB здатний за запитом показати список наявних ядер (які визначаються в
, з підтримкою м'яких посилань з
). Можна вибрати потрібне ядро і навіть передати йому додаткові параметри ядра. Також існує можливість скористатися оболонкою з підтримкою командного рядка, що забезпечує більший ступінь контролю за завантаженням.
Після того як завантажувач другої стадії завантажений на згадку, він звертається до файловоїсистемі та виконує завантаження в пам'ять встановленого за умовчанням образу ядра та образу
. Коли ці образи готові до роботи, завантажувач 2 стадії викликає образ ядра.
Ручне завантаження в GRUB
З командного рядка в GRUB можна завантажити потрібне ядро із зазначеним чином
Якщо відомо назву ядра, яке ви хочете завантажити, просто введіть символ прямого слеша (/) і потім натисніть клавішу Tab. Після цього GRUB відобразить список ядер та образів
Після того як образ ядра виявляється в пам'яті і йому передається керування від завантажувача 2-го ступеня, настає стадія ядра. Однак образ ядра не є виконаним, це стислий образ ядра. Зазвичай це zImage (стислий образ розміром менше 512KB) або bzImage (великий стислий образ, розміром понад 512KB), який був стиснутий за допомогою zlib. На початку такого образу ядра розташовується програма, яка виконує мінімальне налаштування апаратного забезпечення і потім розпаковує ядро, що зберігається всередині ядра, і поміщає його у верхню область пам'яті. Якщо є образ початкового RAM-диска, то програма також переміщає їх у пам'ять і позначає подальшого використання, та був викликає саме ядро, після чого починається завантаження ядра.
При викликі bzImage (образ для i386) виконання починається в
з асемблерної функції
(Основні етапи показані малюнку 3). Ця програма виконує основне налаштування апаратного забезпечення та викликає процедуру
. Процедура налаштовує базове середовище (стек тощо) та очищає Block Started by Symbol (BSS). Потім виконується декомпресія ядра за допомогою виклику C-функції
(яка зберігається в
). Після декомпресії ядра на згадку відбувається його виклик. Це ще одна функція
, але вона розміщується у файлі
У новійфункції
(яка називається swapper або process 0) ініціалізуються таблиці сторінок (page tables) та забезпечується підключення функції memory paging (відображення сторінок). Також визначається тип центрального процесора та співпроцесора для обчислень з плаваючою точкою (FPU), якщо він є, і дана інформація зберігається для подальшого використання. Далі викликається функція
), яка здійснює перехід у частину ядра Linux, яка залежить від особливостей конкретної апаратної платформи. Можна сказати, що це функція
для ядра Linux.Малюнок 3. Виконання основних функцій під час завантаження ядра Linux для i386

При зверненні до
викликається довгий список функцій ініціалізації, які виконують налаштування переривань, роблять подальше конфігурування пам'яті та завантажують початковий диск RAM. Після цього викликається функція
яка є першим процесом, що виконується в просторі користувача. На закінчення запускається idle task, після чого управління може взяти на себе планувальник (scheduler) (після виклику
). Якщо дозволено переривання, витісняючий планувальник (pre-emptive scheduler) періодично перехоплюватиме контроль для підтримки багатозадачності.
У процесі завантаження ядра виконується завантаження в оперативну пам'ять та монтаж початкового RAM-диска (
), який був завантажений у пам'ять завантажувачем 2-го ступеня. Даний
служить тимчасової кореневої файлової системою в оперативній пам'яті і дозволяє ядру повністю завантажитись, не виконуючи монтування якихось фізичних дисків. Оскільки модулі, необхідні взаємодії з периферійними пристроями, можуть бути частиною
, то ядро виходить дуже компактним і тим не менш здатне підтримуватирізноманітні апаратні конфігурації. Після завантаження ядра коренева файлова система замінюється (за допомогою
); при цьому коренева файлова система
видаляється та монтується дійсна коренева файлова система.
Виведення функції decompress_kernel
відповідає за ті звичайні повідомлення про розархівування, які з'являються на екрані:
дозволяє створити компактне ядро Linux, де драйвери скомпільовані як модулі, що завантажуються. Ці модулі, що завантажуються, забезпечують доступ ядра до дисків і файлових систем, які є на цих дисках. Також є драйвери інших апаратних пристроїв. Так як коренева файлова система є файловою системою на диску, то функція
забезпечує для завантажувача можливість звернутися до диска та змонтувати дійсну кореневу файлову систему. У системі без жорсткого диска
може бути остаточною файловою системою, або ж остаточна файлова система може монтуватися за допомогою мережної файлової системи (Network File System, NFS).
Після завантаження та ініціалізації ядра запускається перша програма у просторі користувача. Це перша з програм, що викликаються, які скомпільовані зі стандартною бібліотекою C. До цього моменту процесу стандартні C-додатки ще не виконувались.
На звичайних настільних системах з операційною системою Linux зазвичай першим додатком, що запускається
. Однак це неодмінно. У системах, що вбудовуються, рідко потрібна така велика ініціалізація, яку забезпечує
(яка конфігурується за допомогою
). У багатьох випадках можна запустити простий shell-скрипт, який запускає необхідні програми, що вбудовуються.
Як і сама операційна система Linux, процесЗавантаження ядра є надзвичайно гнучким та універсальним і підтримує велику кількість процесорів та апаратних платформ. На початку завантажувач loadlin забезпечував простий спосіб завантаження Linux без підтримки будь-яких необов'язкових аксесуарів. Завантажувач LILO розширив коло функцій, що підтримуються, проте його недоліком була відсутність підтримки файлових систем. Останнє покоління завантажувачів, таких як GRUB, дозволяє завантажувати Linux з різних файлових систем (починаючи з Minix і закінчуючи Reiser).
Навчитися
Отримати продукти та технології
- MicroMonitor надає середовище для завантаження для великої кількості компактних пристроїв. Ви можете використовувати його для спостереження за процесом завантаження Linux у додатках, що вбудовуються. Додаток портований на процесори ARM, XScale, MIPS, PowerPC, Coldfire та Super-H (Hitachi).
- GNU GRUB надає оболонку для завантаження, яка підтримує велику кількість опцій і відрізняється високою гнучкістю.(EN)
- LinuxBIOS – це заміна BIOS. Ця програма не тільки дозволяє завантажити Linux, LinuxBIOS само є стислим ядром Linux.(EN)
- OpenBIOS - це інший проект переноситься BIOS, який здатний працювати на різних архітектурах, таких як x86, Alpha і AMD64.(EN)
- На сайті kernel.org ви можете знайти останнє дерево ядра.(EN)
- Замовте SEK для Linux - комплекс із двох DVD з новітніми ознайомлювальними версіями програмного забезпечення IBM для Linux: DB2®, Lotus®, Rational®, Tivoli® та WebSphere®.(EN)
- Використовуйте ознайомлювальні версії програмного забезпечення IBM, які можна завантажити безпосередньо з сайту developerWorks, у наступному проекті для Linux.(EN)
Обговорити