MacBookが起動するまで何が起こっているのか?
すべてはMacBookの電源ボタンを押した瞬間に、始まる。フラッシュ ストレージ搭載のAirにおいては、その僅か15秒後には起動が完了して、美しいGUIがユーザーの操作を待ち構える。その15秒間に一体何が起こっているのか?
前回は、プロセスID 0 まで遡ってみた。しかし、それより前の世界がまだ全然見えていない。今回は、電源オンから時系列に辿ってみようと思う。
概要・基礎知識
CPUの本能
- CPUは複雑怪奇なスイッチの集合体だけど、できることは非常にシンプル。メモリの内容を読み込んで、読み込んだ命令に従って演算して、結果をまたメモリへ出力するだけ。
- つまり、メモリにプログラムとして実行可能な意味のある数列が展開されていないと、CPUは無意味な動作を永遠と続けるだけなのだ。
- だから、電源オンでCPUが稼働した瞬間から、何らかの意味のあるプログラムが用意されていて、それが忠実に実行され、美しいGUIを操作できる環境まで至っているはず。
電源オン直後の世界
保証された値
- 電源オフで値が消えてしまうRAMというメモリがある一方、ROMやフラッシュメモリなら、電源オフでも値が永続的に保持されている。
- だから、MacBookの電源オンした瞬間は、これらのROMやフラッシュメモリに存在するプログラムを実行するような仕組みになっているのだ。
- 電源オン直後のCPU内のプログラムカウンタ(レジスタ)には、リセットベクタ(0xFFFF0)が設定されるらしい。
- ブート ストラップ コンピュータの起動手順 - eのらぼらとり(システムレベルで詳細に解説されている素晴らしいページ!感謝です!)
- そのようなROMやフラッシュメモリに保存されている起動用のプログラムはファームウェアと呼ばれている。
- MacBookを電源オンした直後にも、このファームウェアが実行され、いくつかの段階を経てOSの起動まで漕ぎ着けている。
追跡するための作戦
- 15秒で起動してしまうMacBookAirと違って、自分の白MacBookは余裕で1分以上、一生懸命に起動処理をしている。
- 普段は再起動に時間がかかってイライラするけど、じっくり観察したいこんな時には、のんびりしたMacBookもまた良い。
- しかし、ただ眺めているだけでは得られるものは少ない。
- OSが起動するまでのステップごとに、なるべく立ち止まれるような方法で起動してみる。
- そして、普段は表示されないが、起動中のメッセージも画面に出力するようにしておく。
その手順は以下のようにしてみた。
- システム環境設定 >> アカウント >> ログインオプションで、自動ログインは「切」にしておく。
出力されたメッセージ(OSX10.6.8のみインストールした環境において)
- (1)optionキーを押しながら、電源オン。
- (2)Startup Manager(スタートアップ マネージャー)が表示される。
- (3)Startup Managerで、起動ディスクを選択する。
- (4)「command + S」キーを押しながら、returnキーを押して実行する。
- (5)シングルユーザーモードで起動が始まり、起動中のメッセージが画面に出力される。
efiboot loaded from device: Acpi(PNP0A03,0)/Pci(1A10)/Usb(1, 0)/HD(Part4,Sig5A02D2E4-05B8-4072-07BAF8ACC685) boot file path: \System\Library\CoreServices\boot.efi .Loading ’mach_kernel’... ..................... root device uuid is ’22EB6B8B-1310-8ACD-A90A-A7A682A6094D’ Loading drivers... Loading System\Library\Caches\com.apple.kext.caches\Startup\Extensions.mkext... .....
-
- カーネルの起動が始まる。
- 以下のメッセージは、コンソール.app の kernel.log でも確認できる。
npvhash=4095 PAE enabled 64 bit mode enabled Darwin Kernel version 10.5.0: Fri Nov 5 23:20:39 PDT 2010; root:xnu-1504.9.17~1/RELEASE_I386 vm_page_bootstrap: 1533522 free pages and 31150 wired pages standard timeslicing quantum is 10000 us mig_table_max_displ = 73 AppleACPICPU: ProcessorID=0 LocalApicID=0 Enabled AppleACPICPU: ProcessorID=1 LocalApicID=1 Enabled calling mpo_policy_init for Quarantine Security policy loaded: Quarantine policy (Quarantine) calling mpo_policy_init for Sandbox Security policy loaded: Seatbelt sandbox policy (Sandbox) calling mpo_policy_init for TMSafetyNet Security policy loaded: Safety net for Time Machine (TMSafetyNet) Copyright (c) 1982, 1986, 1989, 1991, 1993 The Regents of the University of Callifornia. All rights reserved. MAC Framework successfully initialized using 16384 buffer headers and 4896 cluster IO buffer headers IOAPIC: Version 0x20 Vectors 64:87 ACPI: System State [S0 S3 S4 S5] (S3) AppleIntelCPUPowerManagement: initialization complete mbinit: done (64 MB memory set for mbuf pool) rooting via boot_uuid from /chosen: 22EB6B8B-1318-3ACD-A98A-A7A632A6894D Waiting on <dict ID=“8”><key>IOProviderClass</key><string ID=“1”>IOResources</string><key>IOResourceMatch</key><string ID=“2”>boot-uuid-media</string></dict> com.apple.AppleFSCompressionTypeZlib kmod start com.apple.AppleFSCompressionTypeZlib load succeeded AppleIntelCPUPowerManagementClient: ready FireWire (OHCI) Lucent ID 5811 built-in now active, GUID 082332fffe8e1e7c; max speed s400. USBMSC Identifier (non-unique): 888888888888 0x152d 0x2336 0x100 [Bluetooth::CSRHIDTransition] Single User - waiting WindowServer Got boot device = IOService:/AppleACPIPlatformExpert/PCI0/AppleACPIPCI/EHC2@1A,7/AppleUSBEHCI/JM20336 SATA, USB Combo@fa200000/Bulk-In, Bulk-Out Interface@0/IOUSBMassStorageClass/IOSCSIPeripheralDeviceNub/IOSCSIPeripheralDeviceType00/IOBlockSto BSD root: disk1s4, major 14, minor 7 com.apple.launchd 1 com.apple,launchd 1 *** launchd[1] has started up. *** Singleuser boot ―- fsck not done Root device is mounted read-only If you want to make modifications to files: /sbin/fsck -fy /sbin/mount -uw / If you wish to boot the system: exit :/ root#
- (6)コマンド待ちの状態になる。
-
- いくつかコマンドを実行して、現在の状態を調べみた。
- / root#
- bold;">launchctl list
- / root#
- bold;">ps -axj
- / root#
- bold;">kextstat | grep -v com.apple
- (7)exitコマンドでシングルユーザーモードを抜け出し、通常の起動処理が始まる。
- 以下のメッセージは、コンソール.app の kernel.log でも確認できる。
- / root#
- bold;">exit
- (8)ログインウィンドウが表示される。
- (9)ログインする。
- ログインする時には、以下の項目が起動される。
- LaunchAgents で指定された項目。
- ログイン項目。
時系列に追跡する
以上の起動時のメッセージと、いくつかの文献を参考に、自分が理解した手順を時系列に並べてみる。
現在のOSXでは launchd が活躍しているが、以下のページの解説は非常に面白い!とっても参考になる。(感謝です!)
電源オン
- 「ウィン、ウィーン」光学ドライブの駆動音が聞こえる。
電源LED点灯
ブラック画面
- POST = Boot-ROM/RAM 等のチェックを開始
- 電源投入時の自己診断テストを POST (Power-On Self Test) と呼ぶ。
- 幾つかのハードウェアの初期化や確認,メモリのテスト等を行うらしい。
- 再起動した場合は実行されない。
- RAM エラーの場合
- ブラック画面のまま、電源LEDが1秒間に1回の点滅を繰り返している = RAM が物理的に損傷している、間違った種類の RAM が取り付けられている、または RAM が取り付けられていない。
- グレー画面になって、警告が3回鳴り、電源LEDが3回点滅を繰り返している = RAM がオペレーティングシステムに対応していない。
- 上記エラーは、メモリの取り付け直しで解決する可能性あり。
Startup Managerが起動(optionキーを押している場合)
- この時点ではまだ、起動ディスクをリストアップするだけ。
- ハードディスク内の起動プログラムの読み込みは、行われていない。
グレー画面
アップルロゴの表示
- ネットワークブートの場合
- 点滅する球体が表示されている場合 ― ネットワークブート用サーバでのブーター/カーネルの検索中。
- 回転する地球儀の下にメタリックなアップルのロゴが表示されている場合 ― ネットワークブート用サーバのブーター/カーネルのロード。
- boot.efi ファイルのロード エラーの場合
アップルロゴの下でイージケーターが回転
ブルー画面
- launchdの起動。
- LaunchDaemons で指定された項目が起動される。
POSTとは?
- 電源投入後の自己診断プログラムで、メモリやCPUの状態をテストしている。
- おなじみの「ジャーン」の起動音が鳴れば、POSTが問題なく完了した証。
- 「ジャーン」が鳴らない時は、ビープ音や電源LEDの点滅によって、エラーの状態を教えてくれる。
- POSTエラーを体験してみたい場合は、RAMメモリを抜いてMacBookを起動してみる。
- ビープ音が1回鳴って、電源LEDが1回点滅、それを5秒間隔で繰り返した。
EFIとは?
- EFIは、基本的なグラフィックスやネットワーク機能等のドライバを提供する。
- EFIは、GUIDパーティションテーブルをサポートしている。(認識できる)
EFIパーティション
$ diskutil list /dev/disk0 #: TYPE NAME SIZE IDENTIFIER 0: GUID_partition_scheme *500.1 GB disk0 1: EFI 209.7 MB disk0s1 2: Apple_HFS Leopard HD 499.8 GB disk0s2
NVRAM
- NVRAM(電源オフでも値が保持されるRAM)にも、EFIブートのための情報が保存されていた。
$ nvram -p boot-args arch=i386 IORegistryCurrentSleepMode true%00 SmcFlasherResult %00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00 prev-lang:kbd ja:0 platform-uuid %00%00%00%00%00%00%10%00%80%00%00#2%97%92%1a boot-image %02%01%0c%00%d0A%03%0a%00%00%00%00%01%01%06%00%00%1a%03%05%06%00%01%00%04%04%18%005%001%00c%005%001%00b%000%000%000%00%00%00%7f%ff%04%00 efi-boot-device <array><dict><key>IOMatch</key><dict><key>IOProviderClass</key><string>IOMedia</string><key>IOPropertyMatch</key><dict><key>UUID</key><string>C9A8AD8A-E4EB-4EDA-B0FE-DCB17DD0E2A3</string></dict></dict><key>BLLastBSDName</key><string>disk0s2</string></dict></array>%00 fmm-computer-name zari-MacBook efi-apple-payload0 <array><dict><key>IOMatch</key><dict><key>IOProviderClass</key><string>IOMedia</string><key>IOPropertyMatch</key><dict><key>UUID</key><string>0B00F75C-090C-47AE-B7B4-F356F91E246B</string></dict></dict><key>BLLastBSDName</key><string>disk0s1</string></dict><dict><key>IOEFIDevicePathType</key><string>MediaFilePath</string><key>Path</key><string>\EFI\APPLE\FIRMWARE\k36a.smc</string></dict></array>%00 efi-apple-payload0-data %02%01%0c%00%d0A%03%0a%00%00%00%00%01%01%06%00%02%1f%03%12%0a%00%00%00%00%00%00%00%04%01*%00%01%00%00%00(%00%00%00%00%00%00%00%00@%06%00%00%00%00%00\%f7%00%0b%0c%09%aeG%b7%b4%f8V%f9%1e$k%02%02%04%04>%00\%00E%00F%00I%00\%00A%00P%00P%00L%00E%00\%00F%00I%00R%00M%00W%00A%00R%00E%00\%00k%003%006%00a%00.%00s%00m%00c%00%00%00%7f%ff%04%00 efi-boot-device-data %02%01%0c%00%d0A%03%0a%00%00%00%00%01%01%06%00%02%1f%03%12%0a%00%00%00%00%00%00%00%04%01*%00%02%00%00%00(@%06%00%00%00%00%00%e0%1f.:%00%00%00%00:%ad%a3%c9%eb%e4%daN%b0%fe%dc%b1}%d0%e2%a8%02%02%7f%ff%04%00 SystemAudioVolume '
起動時のキーコンビネーション
http://support.apple.com/kb/HT1533?viewlocale=ja_JP
キー入力 説明 起動時に「C」キーを押す。 起動可能な CD または DVD から起動する。 起動時に「D」キーを押す。 Apple Hardware Test で起動する。 起動時に「option + command + P + R」キーを押し続ける。
(ビープ音が 2 度鳴るまで)NVRAM をリセットする。 起動時に「option」キーを押す。 Startup Manager で、起動する Mac OS X ボリュームが選択できる。 起動時に「N」キーを押す。 互換性のあるネットワークサーバ (NetBoot) から起動しようとする。 起動時に「opition + N」キーを押す。 Startup Manager で、起動する Mac OS X ボリュームが選択できる。
(ネットワークボリュームも含む)起動時に「T」キーを押す。 FireWire ターゲットディスクモード で起動する。 起動時に「shift」キーを押す。 セーフブートモードで起動し、ログイン項目を一時的に無効にする。 起動時に「command + V」キーを押す。 Verbose モード(詳細な起動ログを出力するモード)で起動する。 起動時に「command + S」キーを押す。 シングルユーザモード (Single-User mode) で起動する。 起動時に「イジェクト」キー、「F12」キー、マウスのボタン、
トラックパッドのボタン、いずれかを押し続ける。光学式ディスクなどのリムーバブルメディアをすべて取り出す。
起動までに実行されるステップまとめ
- POST(電源投入自己診断プログラム)の実行
- 電源オン
- kernel_taskの起動処理(可能であれば /System/Library/Caches/com.apple.kext.caches/ を利用して起動時間の短縮を目指す)
- Appleロゴの下で歯車イージケーターが回転する
- launchdの起動
- ブルー画面が見える
- LaunchDaemonsを実行
- ログインウィンドウが表示される
- LaunchAgents・ログイン項目の実行
- ログイン