Some questions arise when we think about the Android boot sequence. What is the Zygote, init.rc, what is the difference between the linux kernel and the android linux kernel?.
This document is intended to explain how the booting process runs.
Consider the following graph:
Step 1: Power On and System Startup
When we press the power button, the Boot ROM code starts executing from a pre-defined location which is hardwired in ROM. It loads the Bootloader into RAM and starts executing.
Step 2: Bootloader
The bootloader is a small program which runs before Android does. This is NOT part of the Android operating system. The bootloader is the place where manufacturer puts their locks and restrictions.
The bootloader executes in two stages. In the first stage it detects external RAM and loads a program which helps in the second stage.
In the second stage, the bootloader setups the network, memory, etc, which requires to run kernel. The bootloader is able to provide configuration parameters or inputs to the kernel for specific purposes.
The bootloader can be found at:
<android source>/bootable/bootloader/legacy/usbloader
This legacy loader contains 2 important files:
Step 3: Kernel
The Android kernel starts in a similar way as the linux kernel. As the kernel launches, is 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.
What is the difference between the linux and android kernels?, here's a list of changes/addons that the Android Project made to the Linux kernel:
Step 4: 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
Android has specific format and rules for init.rc files. More information about this rules can be found in: What is inside the init.rc and what is it used for.
At this stage, you can finally see the Android logo in your screen.
Step 5: Zygote and Dalvik
In Java, we know that a separate Virtual Machine instance will popup in memory for separate per app, but in the case of Android, the VM should run as quick as possible for an app. But what happens if you have several apps thus launching several instances of the Dalvik (VM)?, it would consume an immense amount of memory.
To overcome this problem, the Android OS has a system called “Zygote”. The Zygote enables code sharing across the Dalvik VM, achieving a lower memory footprint and minimal startup time. Zygote is a virtual machine process that starts at system boot. The Zygote preloads and initializes core library classes.
The Zygote loading process:
At this time, you can see the boot animation.
Step 6: System service
After the above steps are completed, Zygote launches the system services. The Zygote forks a new process to launch the system services.
Core services:
Other services:
Now we have finally completed the booting process (system service are up and running in memory).
Need to analyze the Android Bootup?
The logcat :: Use adb to get the booting process events from the logcat.
‘adb logcat –d –b events | grep “boot”
‘adb logcat –d | grep preload’
More information about ADB can be found here: Using ADB with your Sabre Board
This is really good document.
Thanks for posting.
Important to understand is the fact that "Android" alone is not entirely an Operating System, it is rather the User Space of Linux Kernel. Android is based on the Linux Operating System, the GNU Linux kernel.
Boot Process is Architecture dependent i.e. X86 and ARM (e.g A8 Cortex) have differences, ARM requires a signed first stage loader so there is a two stage boot process as the article says but does not clearly say its for ARM, Android now runs on x86 as well. If you are interested reading upon the x86 boot process see my white paper: "https://sites.google.com/site/weqaar/Home/files/bootSector_code.pdf?attredirects=0&d=1"
On ARM the boot process looks like:
1) X Loader (ARM specific)
2) Boot strapper (i.e. uBoot) - jumps to kernel entry point (head.s)
3) Kernel loads init (i.e. /sbin/init)
4) /sbin/init then reads /etc/inittab, then "si::sysinit:/etc/init.d/rcS" (systemV init)
5) rcS creates device files (i.e. using mtab, mounts important fs i.e. /sys), forks daemons or demons whatever
6) getty is then attached to virt terminals, bash is then executed on user login by getty
Dalvik is a Register VM, a user space process for most of the part, JAVA eh.
I forked an embedded Linux distro, that is not based on any other distro i.e. Debian, its a good starting point for anybody wanting to learn boot stuff (for ARM specially), runs in QEMU, here is the doc:
"https://sites.google.com/site/weqaar/Home/files/DaaS-Embedded-Linux-v1.03.pdf?attredirects=0&d=1"
I can make the sources with toolchain available if anybody wants, good stuff it is I can tell you that.
Books I wold recommend:
ISBN 10: 0-8493-4058-6
ISBN 10: 0-137-01783-9
The diagram shows daemons coming off the Kernel which is not entirely true, Kernel processes or Kernel Daemons e.g. kswapd are forked by the Kernel whereas Init forks user-space processes or daemons e.g. ssh
Good Document, I get answers for some of my questions. Really appreciate for the simplicity and the way you expressed.SergioSolis