Skip to content

1.1.1 System Boot Time

PortalMario edited this page Jan 18, 2023 · 2 revisions

System Boot Time

The GCN itself boots very fast into games, giving the player nearly no waiting time at all. Of course, having an underlying OS that launches an emulator, desktop and other background stuff results in longer boot times. To resolve this challenge, i added many system customizations that results in the fastest boot time that I was able to achieve while preserving all needed functionality resulting in an absolute minimal graphical ubuntu environment. All customizations that are explained here, are implemented within the script.

Analyze Boot Time

Disclaimer: Commands shown in this article are executed on a virtual machine and don't represent boot times of actual hardware.

First of all, we need a way to figure out how much time each part of the OS boot process takes. Systemd provides a great method to figure it out! Execute the following command`s on a freshly installed ubuntu desktop.

systemd-analyze

$ systemd-analyze
Startup finished in 2.418s (kernel) + 23.622s (userspace) = 26.041s
graphical.target reached after 23.614s in userspace

Executing systemd-analyze shows you how long systemd took to fully start your system. In this case booting the kernel took: 2.418s. All other relevant services needed to reach your chosen userspace or runlevel (like the ubuntu graphical desktop) took 23.622s. The last output line shows the chosen/desired/present end target. In this case: graphical.target which points to the launch of the ubuntu gnome desktop and all of its subsystems.

systemd-analyze critical-chain

$ systemd-analyze critical-chain
The time when unit became active or started is printed after the "@" character.
The time the unit took to start is printed after the "+" character.

graphical.target @23.614s
└─multi-user.target @23.614s
  └─plymouth-quit-wait.service @2.150s +21.463s
    └─systemd-user-sessions.service @2.118s +18ms
      └─network.target @2.097s
        └─wpa_supplicant.service @1.799s +297ms
          └─dbus.service @1.668s
            └─basic.target @1.650s
              └─sockets.target @1.650s
                └─cups.socket @2.326s
                  └─sysinit.target @1.641s
                    └─snapd.apparmor.service @1.439s +201ms
                      └─apparmor.service @1.236s +201ms
                        └─local-fs.target @1.234s
                          └─run-snapd-ns-snap\x2dstore.mnt.mount @4.549s
                            └─run-snapd-ns.mount @3.766s
                              └─local-fs-pre.target @453ms
                                └─systemd-tmpfiles-setup-dev.service @421ms +31ms
                                  └─systemd-sysusers.service @381ms +38ms
                                    └─systemd-remount-fs.service @346ms +30ms
                                      └─systemd-journald.socket @302ms
                                        └─-.mount @297ms
                                          └─-.slice @297ms

As you can see, systemd-analyze critical-chain shows all systemd targets and how long each takes to reach the default systemd target. (In this case the graphical.)

systemd-analyze blame

$ systemd-analyze blame | head -n 30
21.779s plymouth-quit-wait.service
 1.752s systemd-random-seed.service
 1.658s snapd.service
 1.258s dev-sda3.device
 1.152s networkd-dispatcher.service
 1.014s NetworkManager-wait-online.service
  963ms udisks2.service
  926ms dev-loop8.device
  923ms dev-loop10.device
  917ms dev-loop11.device
  889ms accounts-daemon.service
  880ms dev-loop12.device
  877ms dev-loop9.device
  744ms systemd-logind.service
  705ms dev-loop4.device
  694ms dev-loop3.device
  691ms dev-loop1.device
  670ms dev-loop2.device
  668ms apport.service
  658ms gpu-manager.service
  651ms dev-loop6.device
  650ms ModemManager.service
  619ms power-profiles-daemon.service
  615ms e2scrub_reap.service
  611ms grub-common.service
  602ms dev-loop5.device
  589ms dev-loop7.device
  510ms dev-loop0.device
  466ms avahi-daemon.service
  462ms cups.service

systemd-analyze blame outputs all services ordered by the time they took to initialize. This is very useful when figuring out which service took the most time to initiate during the boot.

Default systemd target

First, we want to tell systemd not to always boot into the ubuntu desktop environment (graphical.target). Otherwise, we would have to wait until some desktop subsystems are launched before the emulator actually starts. The following command will tell systemd to always boot into the CLI, changing the default systemd target. (to mulit-user.target).

$ sudo systemctl set-default multi-user.target

Next, you should reboot the system.

If you now run systemd-analyze you will see a very high decrease regarding the userspace:

$ systemd-analyze
Startup finished in 1.675s (kernel) + 3.920s (userspace) = 5.596s
multi-user.target reached after 3.893s in userspace

Disabling unnecessary systemd services

Now that we got "rid" of the Ubuntu desktop and its dependencies, we can take another look at systemd-analyze blame or systemd-analyze critical-chain.

$ systemd-analyze blame
1.374s systemd-random-seed.service
 604ms dev-sda3.device
 555ms snapd.service
 484ms dev-loop8.device
 471ms networkd-dispatcher.service
 454ms NetworkManager-wait-online.service
 300ms ModemManager.service
 287ms dev-loop12.device
 260ms dev-loop6.device
 259ms dev-loop9.device
 255ms dev-loop3.device
 254ms dev-loop10.device
 251ms ssh.service
 250ms dev-loop11.device
 237ms dev-loop5.device
 230ms dev-loop4.device
 213ms dev-loop7.device
 213ms dev-loop2.device
 197ms dev-loop0.device
 192ms dev-loop1.device
 187ms NetworkManager.service
 181ms avahi-daemon.service
 179ms systemd-modules-load.service
 177ms polkit.service
 167ms systemd-udev-trigger.service
 165ms systemd-resolved.service
 156ms snapd.apparmor.service
 155ms cups.service
 153ms apparmor.service
 149ms systemd-timesyncd.service

Even though the boot time highly decreased, there are still some services that we definitely don’t need on the system. Disabling those could give us a few more extra seconds. Those can be disabled and masked with the following commands:

$ systemctl disable snapd.service plymouth.service snapd.seeded.service NetworkManager-wait-online.service
$ systemctl mask snapd.service plymouth.service snapd.seeded.service NetworkManager-wait-online.service

Services

  • Plymouth: Displays the ubuntu splashscreen during boot.
  • Snapd: Provides support for snap application packages.
    • We do not need those packages. (Optional: you can uninstall snapd: apt purge snapd -y)
  • NetworkManager-wait-online: Delays the boot process until all networking devices become ready.
    • Systemd continues to boot even though if not all networking devices are up. (So, the boot process doesn’t need to wait for that in our case.)

Once those systemd services are disabled and masked, they will not start during the boot process of the system resulting in slightly faster boot times! When running one of the above systemd-analyze commands, those disabled services won’t show up again as they don’t affect the boot process anymore.

Command Explanations

  • systemctl disable <SERVICE>
    • The service won’t be started during boot.
  • systemctl mask <SERVICE>
    • The service state cannot be altered until it gets unmasked. (This prevents other services to start the service)

/etc/hosts

Due to some weird DNS-Reasons (Probably when the networking stacks starts during boot) an extra second can be saved by adding the hostname of the system to /etc/hosts at the localhost record.

$ sed '0,/localhost/s//localhost '"$(hostname)"'/' /etc/hosts

This adds the system's hostname to the desired record.

Note: Default grub CMDLINE Parameters

There are two cmdline parameters that also helps decreasing the system boot time a bit. Those steps are further explained within: "Silent Boot". (fsck.mode=skip and nowatchdog)

Conclusion

When everything's done right, the system's boot time should be about ~3 seconds.

$ systemd-analyze
Startup finished in 2.012s (kernel) + 1.768s (userspace) = 3.781s
multi-user.target reached after 1.743s in userspace

Clone this wiki locally