シングルボードコンピュータ・起動高速化 – Ubuntu編

目次

はじめに

世界は今、新型コロナウィルス禍で始まった半導体不足に包まれています。そんな中、Raspberry PiやArduino、Tinker Boardに代表されるシングルボードコンピューターで要件を満たせることも多くなってきました。

価格が安く、ARM版Linuxに対応していることで、初期導入コストも交換コストも安価に仕上げられるので、これからの需要はますます増えていくと想定しています。

一方で、シングルボードコンピューターはやはり性能面で劣ります。特に、電源OFFから起動し、アプリケーションが動作するまでの時間が問題になることが多いため、今回、起動時間の改善をしてみました。

利用OS

本記事では、「Ubuntu 18.04.6 LTS (Bionic Beaver)」を以下からダウンロードし、利用することにしました。

今回はUbuntuとしましたが、Debianも結局は派生なので、ひとつずつプロセスを確認、停止していけば同じだと思います。

初期状態

インストール後、起動するとGUI(グラフィカルユーザーインターフェース)で起動しました。

起動時間は、電源投入後、40秒ほどでした。

そして、「systemd-analyze blame」コマンドや「systemd-analyze critical-chain」コマンドを利用し、起動完了までに長時間を要している各プロセスの時間を見てみました。

systemd-analyze blame

6.608s NetworkManager-wait-online.service  
2.343s dev-mmcblk1p9.device                
1.581s accounts-daemon.service             
1.226s avahi-daemon.service                
1.103s apport.service                      
 863ms networkd-dispatcher.service         
 833ms udisks2.service                     
 680ms bluetooth.service                   
 673ms snapd.service                       
 664ms upower.service                      
 660ms systemd-resolved.service            
 576ms NetworkManager.service              
 536ms ua-timer.service                    
 519ms polkit.service                      
 432ms systemd-timesyncd.service           
 372ms switcheroo-control.service          
 334ms wpa_supplicant.service              
 331ms systemd-udev-trigger.service        
 301ms systemd-logind.service              
 292ms systemd-journald.service            
 289ms keyboard-setup.service              
 273ms systemd-udevd.service               
 259ms ModemManager.service                
 244ms snapd.seeded.service                
 212ms systemd-journal-flush.service       
 204ms [email protected]                   
 195ms e2scrub_reap.service                
 190ms gdm.service                         
 167ms sys-kernel-debug.mount              
 167ms sys-kernel-tracing.mount            
 152ms dev-mqueue.mount                    
 124ms rsyslog.service                     
 118ms packagekit.service                  
 110ms colord.service                      
 108ms systemd-modules-load.service        
 104ms [email protected]       
 100ms systemd-remount-fs.service          
  95ms sys-fs-fuse-connections.mount       
  86ms sys-kernel-config.mount             
  78ms pppd-dns.service                    
  60ms kerneloops.service                  
  58ms systemd-sysusers.service            
  57ms systemd-random-seed.service         
  57ms alsa-restore.service                
  54ms systemd-sysctl.service              
  39ms systemd-update-utmp-runlevel.service
  39ms systemd-user-sessions.service       
  39ms setvtrgb.service                    
  30ms systemd-tmpfiles-setup-dev.service  
  30ms systemd-update-utmp.service         
  29ms systemd-tmpfiles-setup.service      
  28ms systemd-rfkill.service              
  27ms binfmt-support.service              
  25ms rtkit-daemon.service                
  25ms openvpn.service                     
  24ms console-setup.service               
  24ms plymouth-read-write.service         
  21ms snapd.socket                        
  19ms plymouth-quit-wait.service

systemd-analyze critical-chain

graphical.target @10.144s
└─multi-user.target @10.143s
  └─kerneloops.service @10.080s +60ms
    └─network-online.target @10.068s
      └─NetworkManager-wait-online.service @3.454s +6.608s
        └─NetworkManager.service @2.850s +576ms
          └─dbus.service @2.836s
            └─basic.target @2.071s
              └─sockets.target @2.066s
                └─snapd.socket @1.998s +21ms
                  └─sysinit.target @1.842s
                    └─systemd-timesyncd.service @1.408s +432ms
                      └─systemd-tmpfiles-setup.service @1.354s +29ms
                        └─systemd-journal-flush.service @1.135s +212ms
                          └─systemd-journald.service @803ms +292ms
                            └─systemd-journald.socket @714ms
                              └─system.slice @379ms
                                └─-.slice @378ms

ゴールが見えれば簡単です。あとは、起動シーケンスから不要プロセスを一つずつ止めていくだけです。

最適化開始

まずは、停止していきます。要件としては以下です。

  • グラフィカルユーザーインターフェース不要
  • ネットワーク接続不要
  • 起動シーケンスの処理時間短縮が最優先

アプリケーションでネットワーク接続が必要になるのであれば、そのアプリケーションの起動シーケンス内に対応すれば良い、ということにします。

ここからは、各プロセスについての理解と停止対象プロセスです。

停止するプロセス

NetworkManager-wait-online.service

概要・理由
  • ネットワーク
  • WantsやRequiresで他サービスから指定されればいずれにしても起動する
  • network-online.targetにより、ネットワークが必要な際には結局は起動される
停止コマンド
sudo systemctl disable NetworkManager-wait-online.service

avahi-daemon.service

概要・理由
  • Bonjour(Apple)向けのサービスのため
停止コマンド
sudo systemctl disable avahi-daemon.service

apport.service

概要・理由
  • Ubuntuへの送信するための、Ubuntu専用障害時ダンプサービスであり、DebianではExperimental扱いの別のサービスのため
停止コマンド
sudo systemctl disable apport.service

networkd-dispatcher.service

停止コマンド
sudo systemctl disable networkd-dispatcher.service

bluetooth.service

概要・理由
  • Bluetooth起動サービスのため、必要であれば起動すればよい
停止コマンド
sudo systemctl disable bluetooth.service

systemd-resolved.service

概要・理由
  • ローカル DNS スタブリスナによるネットワーク名前解決をローカルアプリケーションに提供している
停止コマンド
sudo systemctl disable systemd-resolved.service

NetworkManager.service

概要・理由
  • ネットワーク接続は、利用するアプリケーション起動時に含めるため
停止コマンド
sudo systemctl disable NetworkManager.service

ua-timer.service

概要・理由
  • タイマーサービスの利用は行わないため
停止コマンド
sudo systemctl disable ua-timer.service

wpa_supplicant.service

概要・理由
  • 無線LAN暗号化だが、無線は基本利用しないため
  • 停止しても起動してくる・・・
停止コマンド
sudo systemctl disable wpa_supplicant.service

keyboard-setup.service

概要・理由
  • キーボードのセットアップのためのサービスは不要のため
停止コマンド
sudo systemctl disable keyboard-setup.service

ModemManager.service

概要・理由
  • ダイヤルアップ(モデム)を利用することがないため
停止コマンド
sudo systemctl disable ModemManager.service

snapd.seeded.service

概要・理由
  • クロスプラットフォームパッケージ管理関連のため
停止コマンド
sudo snapd.seeded.service

e2scrub_reap.service

概要・理由
  • LVMマウント時にe2fsckを実行するプロセスのため、不要
停止コマンド
sudo systemctl disable e2scrub_reap.service

sys-kernel-debug.mount

概要・理由
  • kernelによるマウントのデバッグなので、高速化のためには不要
停止コマンド

sys-kernel-tracing.mount

概要・理由
  • kernelによるマウントのデバッグなので、高速化のためには不要
停止コマンド
sudo systemctl disable sys-kernel-tracing.mount

packagekit.service

概要・理由
  • GNOMEのパッケージ管理のため
停止コマンド
sudo systemctl disable packagekit.service

pppd-dns.service

概要・理由
  • PPPoE接続は利用しないため
停止コマンド
sudo systemctl disable pppd-dns.service

systemd-update-utmp-runlevel.service

概要・理由
  • SysV経由でのランレベルサポートは不要のため
停止コマンド
sudo systemctl disable systemd-update-utmp-runlevel.service

systemd-update-utmp.service

概要・理由
  • SysV経由でのランレベルサポートは不要のため
停止コマンド
sudo systemctl disable systemd-update-utmp.service

systemd-rfkill.service

概要・理由
  • RFKill は、コンピュータシステムの無線送信器が、クエリ、アクティベート、非アクティブ化されるインターフェースを提供する Linux カーネルのサブシステム
  • 無線送信器が非アクティブ化されると、それらはソフトウェアが再アクティベートできる状態 (ソフトブロック) に置かれるか、またはソフトウェアが再アクティベートできない状態 (ハードブロック) に置かれる。
停止コマンド
sudo systemctl disable systemd-rfkill.service

rtkit-daemon.service

概要・理由
  • リアルタイムスケジューリングは不要のため
停止コマンド
sudo systemctl disable rtkit-daemon.service

openvpn.service

概要・理由
  • OpenVPNは不要のため
停止コマンド
sudo systemctl disable openvpn.service

plymouth-read-write.service

概要・理由
  • GUIは極力排除したいため
  • Red Hat Enterprise Linux 系列のグラフィカルなブートシステム・ロガー、カーネルベースモード設定 (KMS) およびダイレクトレンダリングマネージャー (DRM) を使用している
  • このサービスはGDM経由でグラフィカルユーザーインターフェース(GUI)を利用するのであれば停止しても起動する。起動速度を優先するのであればグラフィカルユーザーインターフェース(GUI)でのログインを「sudo systemd set-default multi-user.target」でコマンドラインインターフェース(CUI)に切り替えたのち、、以下削除コマンドを行う
停止コマンド
sudo apt-get purge --remove plymouth

snapd.socket

概要・理由
  • クロスプラットフォームパッケージ管理関連は停止、必要なときに起動すれば良いため
停止コマンド
sudo systemctl disable snapd.socket

plymouth-quit-wait.service

概要・理由
  • GUIは極力排除したいため
  • Red Hat Enterprise Linux 系列のグラフィカルなブートシステム・ロガー、カーネルベースモード設定 (KMS) およびダイレクトレンダリングマネージャー (DRM) を使用している
  • このサービスはGDM経由でグラフィカルユーザーインターフェース(GUI)を利用するのであれば停止しても起動する。起動速度を優先するのであればグラフィカルユーザーインターフェース(GUI)でのログインを「sudo systemd set-default multi-user.target」でコマンドラインインターフェース(CUI)に切り替えたのち、、以下削除コマンドを行う
停止コマンド
sudo apt-get purge --remove plymouth

維持するプロセス

dev-mmcblk1p9.device

概要・理由
  • 今回の要件が、eMMC起動のため、起動時に必要

accounts-daemon.service

概要・理由
  • Gnome等GUIを利用するのであれば必要だが、最終的にはランレベル3(multi-user.target)で起動するため、ここでは設定不要

udisks2.service

概要・理由
  • ブロックデバイス管理のために必要なため

upower.service

概要・理由
  • 電源管理システムのため

polkit.service

概要・理由
  • GNOMEなどのデスクトップ操作の権限を設定するセキュリティツール

systemd-timesyncd.service

概要・理由
  • 時刻同期サービスのため

switcheroo-control.service

概要・理由
  • DBus経由で、GPUが複数う搭載しているかチェックするサービスであり、DBus関連は維持した方が安全のため

systemd-udev-trigger.service

概要・理由
  • initramfs (INITial RAM File System; 初期 RAM ファイルシステム) は小さな cpio アーカイブで、カーネルが RAM ディスク内に読み込むことができる仕組み
  • ルートファイルシステムがマウントできるようになり、オペレーティングシステムが開始できるようになるには、カーネルはルートファイルシステムの存在するデバイスにアクセスするためのドライバを読み込む必要がある
  • ドライバは特殊なハードディスク向けのドライバであったり、ネットワーク経由でアクセスする場合はネットワークドライバであったりする場合もあり、ルートファイルシステムに対して必要なモジュールは、 initramfs 内にある init が読み込みまれる
  • 必要なモジュールが読み込まれると、 udev が initramfs に対して必要なデバイスを提供するようになる

systemd-logind.service

概要・理由
  • ユーザーログイン管理を実施するため

systemd-journald.service

概要・理由
  • システム監査ログ保存、rsyslogと連携しているため

systemd-udevd.service

概要・理由
  • jarnaldと連携しているため

systemd-journal-flush.service

概要・理由
  • journal管理・ログ削除のため

[email protected]

概要・理由
  • GDM含め、ユーザー管理を行うサービスを起動するユーザーサービスのため

gdm.service

概要・理由
  • Gnome等GUIを利用するのであれば必要だが、最終的にはランレベル3(multi-user.target)で起動するため、ここでは設定不要

dev-mqueue.mount

概要・理由
  • POSIX準拠のプロセス間メッセージングのため

rsyslog.service

概要・理由
  • journal連携のため

colord.service

概要・理由
  • DBus経由で接続するデバイスとのカラープロファイル管理を行う可能性があるため

systemd-modules-load.service

概要・理由
  • 静的設定に基づく、起動の初期段階でカーネルモジュールをロードするサービスのため

systemd-remount-fs.service

概要・理由
  • fstabで列挙されている、systemd-gpt-auto-generatorにより検知されたパーティションテーブルを起動初期でマウントするためのサービスのため

sys-fs-fuse-connections.mount

概要・理由
  • FUSE Control File Systemを利用し、FUSE のカーネルモジュールとデーモンの通信をサポートするサービスのため

sys-kernel-config.mount

概要・理由
  • kernel設定ファイルのマウント・ロードを行うため

kerneloops.service

概要・理由
  • kernel panicが発生した際の自動再起動を行うサービスのため

systemd-sysusers.service

概要・理由
  • ユーザー・グループ管理のため

systemd-random-seed.service

概要・理由
  • ハードウェア乱数生成器のための乱数生成に必要なため

alsa-restore.service

概要・理由
  • サウンドカードのデバイスドライバを提供する Open Sound System (OSSv3) を置き換えるために開発された Linux カーネルコンポーネント(Advanced Linux Sound Architecture (ALSA)のため

systemd-sysctl.service

概要・理由
  • systemctlのための呼び出しサービスのため

systemd-user-sessions.service

概要・理由
  • 起動後のユーザーログインを許可し、シャットダウン時のユーザーログインを制限するサービスのため

setvtrgb.service

概要・理由
  • 仮想コンソールのカラーマップ設定のため

systemd-tmpfiles-setup-dev.service

概要・理由
  • システムによる一時ファイルに関わるため

systemd-tmpfiles-setup.service

概要・理由
  • システムによる一時ファイルに関わるため

binfmt-support.service

概要・理由
  • システム管理者がファイル拡張子をベースにして各種バイナリ 形式をインタプリタに登録し、該当するファイルが実行された時には適切なインタプリタが呼び出されるように設定しているため

console-setup.service

概要・理由
  • コンソールに対して X Window System と同じキーボード設定(スキー ム)を提供しているため

CUIモードに切り替え、再起動

ここまで設定を終えたら、グラフィカルユーザーインターフェース(GUI)での起動を、コマンドラインインターフェース(CUI)での起動に切り替えます。

sudo systemd set-default multi-user.target

その後、sudo rebootとすれば、再起動します。

結果

これで、だいぶ起動が早くなりました。

コマンドラインインターフェース(CUI)ではありますが、電源投入後14秒でログイン画面が表示されました。

今回のところは、これで十分かなと思います。

さいごに

ハイバネーションからの起動等、もっとやり込めば突き詰められます。

ですが、各プロセスが何をしているのかを理解し、LinuxベースのOSを利用する上で不要なものだけを削除する、という観点をで設定した方が、その後の運用・開発に役に立つと思い、このようにしました。

今回はUbuntuとしましたが、Debianも結局は派生なので、ひとつずつプロセスを確認、停止していけば同じだと思います。

この記事が気に入ったら
いいね または フォローしてね!

よかったらシェアしてね!

コメント

コメントする

CAPTCHA

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください

目次
閉じる