« View all posts

The Android Boot Process

Posted by Team Copperhead on December 07, 2022

Android Boot Process

Have you ever wondered what happens when you turn on your Android device? Have you ever asked:

  • What actually goes on behind the screen when that boot animation or splash screen appears?
  • How exactly does a device boot an Android Operating System (OS)?

The answer is the Android Boot Process.

What is the Android Boot Sequence

The Android Boot Sequence happens each time an Android device is powered on. For example, if you press and hold the Power key on a Pixel device briefly, you will be given the Power menu in which you can tap ‘Power Off’, or ‘Restart’. The boot sequence will either begin when you power the device on again, or almost immediately if you chose ‘Restart’.

Android Boot Process graph 1. Boot ROM code execution 2. The bootloader 3. The Linux kernel 4. The ‘Init’ process 5. Zygote and Dalvik VM 6. The System Server and Managers

Boot ROM code execution

Execution begins when the Android device is powered on. This boot ROM code is specific to the SOC the device is using. During this stage 2 things happen:

  • When the boot ROM code is executed, it initializes the device hardware and tries to scan and detect the boot media. This is a pre-defined location which is hardwired in the boot ROM. Its almost similar to the BIOS function in the boot process of a computer.
  • Once the boot sequence is set, the initial boot loader is copied to the internal RAM. After this, it starts executing code loaded in RAM.

Bootloader

The bootloader is a small program which runs before Android OS starts to function. Surprisingly, it is not part of the Android Operating System. This program is where the OEM would normally put their locks and restrictions.

Bootloaders are present in desktop computers, laptops, and mobile devices and their functions are similar. On Android Devices' the bootloader is divided into 2 stages:

  1. Initial Program Load (IPL)
  2. Second Program Load (SPL)
Initial Program Load (IPL)

IPL deals with detecting and setting up the external RAM which helps in SPL. Once the external RAM is available, SPL is copied into the RAM and execution is transferred to it.

Second Program Load (SPL)

The SPL is responsible for loading the main Android operating system and provides access to other boot modes, such as fastboot and recovery. The SPL also initializes several hardware components such as the display, keyboard, file systems, virtual memory, consoles and other features. After this, SPL then attempts to find the Linux kernel. Since the kernel is found in boot media it will copy from there to RAM. Following this, SPL will transfer execution to the kernel.

Linux Kernel

The Android kernel starts in a similar way as the Linux kernel. As the kernel fires up, it starts to setup cache, protected memory, scheduling and loads drivers. When the kernel finishes the system setup, it looks for “init" in the system files.

If Android kernel is similar to Linux kernels then what is difference between these two ? Lets find out below!

  • Binder: An Android specific inter-process communication mechanism and remote method invocation system.

  • Android Shared Memory (ASHMEM): New shared memory allocator, similar to POSIX SHM but with a different behavior and sporting a simpler file-based API.

  • Process Memory Allocator (PMEM): Used to manage large (1-16+ MB) physically contiguous regions of memory shared between user space and kernel drivers.

  • Logger: Kernel support for the logcat command.

  • Paranoid Networking: Restricts access to some networking features depending on the group of the calling process.

  • Wake locks: A way for an app to keep the CPU/screen/other things awake when the phone is idle in order to perform a specific background task. It is used for power management files. It holds the machine awake on a per-event basis until wake lock is released.

  • OOM Handling: Has the unique task of checking if the system has enough memory available to execute tasks, verify when the system is running low on memory, and kill processes to free up memory.

  • Alarm Manager: Allows user space to communicate with the kernel when it would like to wake up.

  • Timed output / Timed GPIO: GPIO is a mechanism to allow programs to access and manipulate GPIO registers from user space.

  • RAM Console: An area in RAM which is reserved at boot. This area is a persistent property, and is used to store the last kernel log messages in the event the kernel reboots or crashes. Logs stored here can be useful for kernel debugging, granting insight into the kernel process immediately prior to a crash or unexpected reboot. Viewed from /proc/last_kmsg

  • USB Gadget Driver for ADB

  • yaffs2 flash filesystem

  • Many more!

Init Process

Init is the very first process, we can say it is a root process, or the grandfather of all processes. The Init process has two responsibilities.

  1. Mounts directories like /sys, /dev or /proc

  2. Runs init.rc script

  • The init process can be found at /init :: <android source>/system/core/init

  • The init.rc file can be found at :: <android source>/system/core/rootdir/

Android has a specific format and rules for init.rc files.

At this stage, you can finally see the Android logo on your screen.

Zygote and Dalvik

In Java a separate Virtual Machine instance will popup in memory to separate per app. Android’s Dalvik (the virtual machine) is different because it needs to be as quick as possible. That poses a problem.

What happens if you have several apps launching several instances of the Dalvik, exhausting the available memory stores?

Android solves this with a system called Zygote.

Zygote is one of the first init processes created after the device boots. Zygote enables code sharing across the Dalvik VM achieving a lower memory footprint and minimal startup time. It is a virtual machine process that starts at system boot and tries to create multiple instances to support each Android process. Zygote preloads and initializes core library classes.

The Zygote loading process
  • Load ZygoteInitclass: This loads the ZygoteInit class. Source Code: <Android Source>/frameworks/base/core/java/com/android/internal/os/ZygoteInit.java

  • registerZygoteSocket(): This registers a server socket for zygote command connections.

  • preloadClasses(): This is a simple text file containing a list of classes that need to be preloaded will be executed here. This file can be seen at this location: <Android Source>/frameworks/base.

  • preloadResources(): This deals with native themes and layouts and everything that includes the android.R file will be loaded using this method:

You will now see the boot animation!

System service

Zygote launches the system services and forks a new process to launch.

System service graph

Core services
  • Starting power manager

  • Creating the Activity Manager

  • Starting telephony registry

  • Starting package manager

  • Set activity manager service as system process

  • Starting context manager

  • Starting system contact providers

  • Starting battery service

  • Starting alarm manager

  • Starting sensor service

  • Starting window manager

  • Starting Bluetooth service

  • Starting mount service

Other services
  • Starting status bar service

  • Starting hardware service

  • Starting NetStat service

  • Starting connectivity service

  • Starting Notification Manager

  • Starting DeviceStorageMonitor service

  • Starting Location Manager

  • Starting Search Service

  • Starting Clipboard Service

  • Starting checkin service

  • Starting Wallpaper service

  • Starting Audio Service

  • Starting HeadsetObserver

  • Starting AdbSettingsObserver

We have finally completed the booting process: the system services are up and running in memory. At this point the system will send a broadcast action called ACTION_BOOT_COMPLETED which informs all dependent processes that the boot process is completed.

After this device displays the Home screen and is ready to interact with the user.