ノートパソコンでもなくただのデスクトップなので起動時間が長いのもしょうがないかなーとか思っていたのですがやっぱり起動時間が長いとモチベーションが下がるのでちょうどArch LinuxからCachyOSに移行したのを機にいろいろ変えてみました
環境
- マザボ:MPG-Z590-GAMING-FORCE
- CPU:i5 11世代
- RAM:46GiB (49199524)
- OS:CachyOS
デバイス名 | マウントポイント | 詳細 |
---|---|---|
/dev/sda1 |
/boot |
/dev/sda はSSD |
/dev/sda2 |
/ |
|
/dev/sdb2 |
/run/media/hayattgd/HDD |
Windowsのときから使ってるデータ |
/dev/sdc2 |
/run/media/hayattgd/Arch |
前のArch Linuxが入ってる場所 |
/dev/sdc3 |
/home |
前のLinuxの/home と同じパーティション |
前提知識
- カーネル - ソフトウェア(initも含む)とハードウェアの中間にあるもの
- init - systemdなど、システム起動で呼び出されるプロセスやその仕組みのこと
目標
- ログイン画面にできるだけ早く到達する
- ssh, libvirtなど起動に関係ないものは起動時に使えなくても構わない(起動直後には使わないため)
- ただ、sshなどを使いたいときには使えるようにする
本題
まずはとりあえずChatGPTに聞いてみました
- SSDにOSをいれる
- 軽いLinux ディストリビューションを選ぶ
- systemd-analyzeで起動時間のボトルネックを調べる
- 不要なサービスを止める
initをsystemd以外に変える (今更面倒くさいので却下)
ということを言われたのでその通りにしていきます
SSDにOSを移す
これは難しいというか時間がかかっただけでした。
USBからGpartedを起動して、コピーしたり移動したりいろいろ...
もともとSSDにはWindowsが入っていたので外部のストレージに移しておきました。
一応前使ってたArch Linuxでも~/.config
などの設定が変わらずに使えるように/home
はHDDのパーティションをマウントしました。
/
や/boot
はすべてSSDにパーティションを置いて早く起動できるようにしました。
軽いLinux ディストロ
これはぶっちゃけインストール後に色々変えればどうとでもなる話ですが
- CachyOS(カーネルがカスタマイズされてる)
- Void(systemdの代わりにrunit)
- Alpine Linux(systemdの代わりにopenrc)
- Artix Linux(いろいろなinitから選べる)
などはインストール時にすでに最適化されています。
systemd-analyzeで起動時間を調べる
$ systemd-analyze
Startup finished in 17.469s (firmware) + 6.790s (loader) + 11.084s (kernel) + 7.852s (userspace) = 43.196s
graphical.target reached after 4.802s in userspace.
$ systemd-analyze critical-chain
graphical.target @4.802s
└─multi-user.target @4.802s
└─libvirtd.service @4.722s +79ms
└─network.target @4.719s
└─NetworkManager.service @4.535s +184ms
└─basic.target @4.532s
└─dbus-broker.service @4.499s +31ms
└─dbus.socket @4.490s
└─sysinit.target @4.484s
└─systemd-update-utmp.service @4.453s +31ms
└─systemd-tmpfiles-setup.service @4.364s +87ms
└─local-fs.target @4.359s
└─run-media-hayattgd-HDD.mount @1.538s +2.821s
└─dev-sdb2.device @955ms
ファームウェア17秒 + ローダー7秒 + カーネル11秒 + systemd
8秒 = 約43秒で起動していて、/dev/sdb2のマウントに3秒ほど時間をかけていることがわかります。
SSDでもないただのHDDでNTFSをマウントしようとしているのでそりゃ時間かかるよなぁ...
userspace
userspaceはsystemdなどのinitのところで、ログイン画面までの時間です。
ディスクにアクセスされたときだけマウントする
ついでに前のArch Linuxが入っている/dev/sdc2も一緒に必要なとき(アクセスされたとき)だけマウントするようにします。
...
# /dev/sdc2
UUID=.. /run/media/hayattgd/Arch ext4 noauto,x-systemd.automount,x-systemd.idle-timeout=600 ..
# /dev/sdb2 LABEL=HDD
UUID=.. /run/media/hayattgd/HDD ntfs noauto,x-systemd.automount,x-systemd.idle-timeout=600 ..
...
-
noauto
: 自動的にマウントしない -
x-systemd.automount
: アクセスされたときにマウントする -
x-systemd.idle-timeout
: どのくらいアクセスされなかったらアンマウントするか秒数指定
これで再起動してみたんですが...なんか勝手に/dev/sdb2がマウントされちゃう現象が発生
=> 起動するサービスの中に/dev/sdb2が必要なサービスがあった(libvirtdで/dev/sdb2のディスクを指定していた)のが原因
なので無効化しておきます。
$ sudo systemctl disable libvirtd
サービスの遅延起動
このままだと目標からそれてしまう(libvirtdが簡単に使えない)ので、ログイン画面が出る前に行われる処理(default.target)より後に起動させます。(ついでにNetworkManagerも遅延起動)
#!/bin/bash
systemctl start libvirtd.service
systemctl start NetworkManager.service
[Unit]
Description=Start delayed services to speed up boot
[Service]
Type=oneshot
ExecStart=/usr/local/bin/start-delayed-services.sh
[Unit]
Description=Actual timer file for delayed services
[Timer]
OnBootSec=30s
AccuracySec=1s
[Install]
WantedBy=timers.target
これで約3秒ほど起動時間が縮まりました!ちょうど/dev/sdb2のマウントにかかった時間と同じくらいです。
kernel
kernelはinitが呼び出されるまでの時間です。
ここが10秒くらいだったので、CachyOS Kernel Manager
というものを使って自分のCPU向けに最適化してコンパイルしました。コンパイルの時間はだいぶ長かったですが約6秒ほど起動時間が縮まりました!
loader
loaderはGRUBやsystemd-boot、rEFIndなどでlinuxが呼び出されるまでの時間です。
いままではGRUB
を使っていたのですが、systemd-boot
の方が早いということだったので変えてみました。
$ sudo bootctl install
それでもともと約5秒だったものが3秒ほどになって、2秒縮まりました!
しかしsystemd-boot
だと背景がなくなって黒い背景に白い文字という起動時間に全振りしたようなものなのでそこは要検討ですね...
firmware
firmwareはマザーボードがいろいろ起動処理をするのにかかる時間です。
ここは20秒とか結構大きい数値を叩き出してるのでどうにかしたいと思ったのですがやれることは少ないようです...
一応やったこととしては、
- マザーボードのBIOSにMSI Fast Bootという設定があったので有効化
- 使わないものをBIOSから無効化
結果
前:17.469s (firmware) + 6.790s (loader) + 11.084s (kernel) + 7.852s (userspace) = 43.196s
今:21.716s (firmware) + 2.774s (loader) + 3.958s (kernel) + 1.857s (userspace) = 30.306s
謎にfirmware
は増えていますがこれは結構起動するたびに変わるので、firmware
を除外して
6.790s (loader) + 11.084s (kernel) + 7.852s (userspace) = 25.726s
2.774s (loader) + 3.958s (kernel) + 1.857s (userspace) = 8.689s
25.726 - 8.689 = 17.037
つまり...
- 約17秒短縮できた
- 合計起動時間:約28.689秒になった
まとめ
- 起動に関係するものはSSDに移す
- systemd-analyzeで遅い原因を調べる
- 起動に関係ないデータのマウントはアクセス時だけにする
- ネットワークマネージャなどのサービスを遅延起動にする
- カーネルを自分のCPU向けに最適化する
- systemd-bootなどの軽いブートローダーを使う
- BIOSにFast Bootなどの項目があれば有効化する
もう前の環境には戻れませんね