Давно хотів розглянути процес завантаження Mac OS X, давайте зробимо це разом. Попереджу - це моя спроба розібратися, і не розглядайте на цю статтю, як істину в останній інстанції. Це перша частина, далі я буду розглядати більш детально початкову і завершальну стадії - BootROM / EFI і launchd.
В процесі написання я використовував таку інформацію:
Процес завантаження Intel Mac (Snow Leopard):
1. При включенні харчування запускається BootROM firmware.
1.1. Виконується POST (Power-On Self Test), започатковано деякі системні інтерфейси, і перевіряючий, що в системі встановлено достатню кількість пам'яті і вона знаходиться в нормальному стані.
1.2. Запускається EFI (Extensible Firmware Interface). ініціалізувавши інше базове системне "залізо", і що виробляє вибір операційної системи.
2. Управління передається завантажувачу boot.efi. що знаходиться на розділі обраної Mac OS X. Його основне завдання - підготувати все для завантаження ядра. boot.efi знаходиться в / System / Library / CoreServices / (і копія - в / usr / standalone / i386 /).
2.1. Дисплей закрашивается світло-сірим кольором.
2.2. Завантажувач намагається завантажити прелінкованную версію ядра (самої ядро - / mach_kernel), що включає всі драйвера, необхідні для завантаження. Через це час завантаження значно скорочується. Каталог /System/Library/Caches/com.apple.kext.caches/Startup/, файли виду kernelcache_i386.2B109974 (тут вказана архітектура і 8 символів контрольної суми, що обчислюється за алгоритмом Adler-32).
2.3. З'являється лого Apple і з'являється обертається курсор.
2.4. Якщо прелінкованная версія ядра відсутня, застаріла (наприклад, час модифікації драйвера новіше, ніж це ядро) або пошкоджена, завантажувач намагається завантажити всі драйвера з кеша mkext /System/Library/Caches/com.apple.kext.caches/Startup/Extensions.mkext . Опис кеша знаходиться в /usr/standalone/bootcaches.plist.
2.5. Якщо кеш відсутня, застарів або пошкоджений, завантажувач шукає в каталозі / System / Library / Extensions драйвера і розширення ядра, і завантажує ті, у яких OSBundleRequired встановлено в значення, що відповідає типу завантаження (наприклад, локальна, мережева, etc). Детальніше можна подивитися в "Loading Kernel Extensions at Boot Time". наприклад,
-
Варіанти OSBundleRequired:
- Root. This KEXT is required to mount root, regardless of where root comes from - for example, platform drivers and families, PCI, or USB.
- Network-Root. This KEXT is required to mount root on a remote volume-for example, the network family, Ethernet drivers, or NFS.
- Local-Root. This KEXT is required to mount root on a local volume - for example, the storage family, disk drivers, or file systems.
- Console. This KEXT is required to provide character console support (single-user mode) - for example, keyboard drivers or the ADB family.
- Safe Boot. This KEXT is required even during safe-boot (unnecessary extensions disabled) -for example, mouse drivers or graphics drivers.
2.6. Коли ядро і всі необхідні драйвера завантажені (не запущені, а саме "loaded" в пам'ять), завантажувач запускає процедуру ініціалізації ядра. На цій стадії завантажено достатню кількість драйверів для того, щоб було знайдено пристрій, на якому розташована коренева файлова система (більш зрозуміло - root device).
2.7. Ядро инициализирует структури даних Mach і BSD, а потім I / O Kit (колекцію системних фреймворків і бібліотек, що підтримують інші драйвера пристроїв). I / O Kit лінки драйвера в ядро, використовуючи дерево пристроїв для визначення, які саме драйвера лінковані. Це дерево будувалося на стадії EFI. Подивитися його вже з завантаженої системи можна так:
4. На завершення launchd запускає loginwindow (вікно входу в систему).