34
ANDROID BOOTUP PROCESS SHIBIN GEORGE Date last updated: 1/1/2017

Android bootup

Embed Size (px)

Citation preview

Page 1: Android bootup

ANDROID BOOTUP PROCESS

SHIBIN GEORGE

Date last updated 112017

AGENDA

bull ANDROID BOOTLOADER

bull KERNEL BOOTUP PROCESS

bull INIT

bull SERVICEMANAGER

bull ZYGOTE

bull SYSTEM-SERVER

bull LAUNCHER

bull BOOTANIMATION

bull BOOT_COMPLETED

httpswwwlinkedincominsg1993 2georgeshibin1993gmailcom

BOOTUP OVERVIEW

ANDROID BOOTLOADERbull (L)ittle (K)ernel based Android bootloader

bull Android bootloader is developed on top of an open source project on kernelorg ndash named (L)ittle(K)ernel project

bull It does hardware initialization reading the Linux kernel amp ramdisk loading it up to RAM setting up initial registers and command line arguments for Linux kernel and jumps to the kernel

bull For normal bootup mode lk loads bootimg and for recovery mode it loads recoveryimg

bull UEFI-ABL is used as Bootloader for recent chipsets

httpswwwlinkedincominsg1993 4georgeshibin1993gmailcom

KERNEL BOOTUP PROCESS

bull Boot image is a raw partition ie there is no underlying filesystem like ext4FAT

bull Boot image(bootimg) = The kernel binary + ramdisk The bootloader loads kernel binary onto memory and then executes it

bull The first hardware independent piece of code that runs in kernel is start_kernel()

bull start_kernel() initializes various kernel subsystems and data structures These include the scheduler memory zones time keeping and so on

bull At the end of start_kernel() rest_init() is invoked

bull In rest_init() we start a kernel thread(kernel_init) that eventually becomes lsquoinitrsquo (with pid=1)

httpopengrokqualcommcomsourcexrefLAUM00kernelmsm-318initmainc396

static noinline void __init_refok rest_init(void)

int pid rcu_scheduler_starting()

smpboot_thread_init() s

We need to spawn init first so that it obtains pid 1 however

the init task will end up wanting to create kthreads which if

we schedule it before we create kthreadd will OOPS

kernel_thread(kernel_init NULL CLONE_FS)

httpswwwlinkedincominsg1993 5georgeshibin1993gmailcom

KERNEL BOOTUP PROCESS

bull Kernel_init at do_mountsc mounts ramdisk at lsquorsquo (root location) this is where init binary and other init scripts reside

bull This thread tries to execute init (thefirst user-mode process) in the following order init sbininit etcinit bininit and binsh If all fail kernel panics

bull But what happens to the thread that spawned init

bull That thread is known as the sched or swapper thread and has pid 0 (it does not appear in ps output but does appear as ppid of init) At the end of rest_init() this thread calls schedule() (to kickstart task scheduling) Then it enters idle loop here

httpopengrokqualcommcomsourcexrefLAUM00kernelmsm-318initmainc950

if (ramdisk_execute_command)

ret = run_init_process(ramdisk_execute_command)

We try each of these until one succeeds

The Bourne shell can be used instead of init if we are

trying to recover a really broken machine

if (try_to_run_init_process(sbininit) ||

try_to_run_init_process(etcinit) ||

try_to_run_init_process(bininit) ||

try_to_run_init_process(binsh))

return 0

panic(No working init found Try passing init= option to kernel

See Linux Documentationinittxt for guidance)

httpswwwlinkedincominsg1993 6georgeshibin1993gmailcom

bull The init processrsquos code resides here systemcoreinit

bull Basically all init does is the seemingly simple task of starting servicesdaemons and restarting some in case they are stopped It reads some configuration files ie rc files to figure out what to do when The rc files are written in initrsquos own language

bull The Android Init Language consists of five broad classes of statements - Actions Commands Services Options and Imports

INIT

httpswwwlinkedincominsg1993 7georgeshibin1993gmailcom

INIT RC FILE LINGObull Services are definitions of servicesdaemons etc that you want init to run

bull These are generally run when certain events are triggered

bull Options are modifiers to services Some important modifiers are-

bull critical ndash If it exits more than four times in four minutes the device will reboot into recovery mode (example critical)

bull disabled - This service will not automatically start with its class (ex bootanim)

bull socket ndash a socket at devsocketname will be created when the service starts (example devsocketzygote)

bull oneshot ndash Do not restart the service if it exits Most of important services will NOT have this modifier

bull class ndash 3 major classes of services ndash coremainlate-start

bull onrestart ndash execute the command following this when service restarts (example in zygotersquos rc onrestart restart cameraserver)

httpswwwlinkedincominsg1993 8georgeshibin1993gmailcom

INIT RC FILE LINGObull Triggers are strings which are used to match certain events

bull on ltpatterngt lthelliphellipgt - if the pattern is triggered by someone this is executed (ex on early-init)

bull on propertya=b ndash command is executed when property a is set to b

bull Commands are executed when predefined events are triggered (ie on lttriggergt)

bull trigger write chmod chown start stop restart setprop etc

bull Actions are of the form

bull For an action to be executed it is therefore necessary for an event to be triggered

bull Import statements are used to tell init to parse rc files present in different locations

on lttriggergt

ltcommandgt

ltcommandgt

ltcommandgt

httpswwwlinkedincominsg1993 9georgeshibin1993gmailcom

INIT

httpandroidxrefcom700_r1xrefsystemcorerootdirinitrc

on late-inittrigger early-fstrigger fstrigger post-fshelliptrigger early-boottrigger boot

on bootsetprop nettcpdefault_init_rwnd 60class_start core

httpswwwlinkedincominsg1993 10georgeshibin1993gmailcom

INITbull After some initial setup init first proceeds to parse initrc which is the primary rc file

bull All the other rc files are parsed using import statements in initrc

bull Once parsing is done to kickstart execution of servicesdaemons a few triggers have to be explicitly triggered by init itself

bull The first one of these is early-init

bull early-init is the cue to start ueventd for instance as defined in initrc

bull Init now has to start native daemonsservices like Surfaceflinger vold servicemanager healthd etc

httpandroidxrefcom700_r1xrefsystemcoreinitinitcpp688

parserParseConfig(initrc)

hellip

amQueueEventTrigger(early-init)

httpopengrokqualcommcomsourcexrefLAUM00systemcorerootdirinitrc13

on early-init

hellip

start ueventd

httpswwwlinkedincominsg1993 11georgeshibin1993gmailcom

INITbull Init also explicitly triggers event init and late-init When late-init is triggered it triggers event fs which is

when init parses fstab(qcom) entries to mount remaining partitions (system data misc) here

bull After that init basically runs in an infinite while loop on the lookout for services that might need restarting here

bull Among the services started by init one is particularly important for IPC to happen

bull Lets find out more about ServiceManager

httpopengrokqualcommcomsourcexrefLAUM00deviceqcommsm8937_64inittargetrc42

on fs

hellip

mount_all fstabqcom

httpswwwlinkedincominsg1993 12georgeshibin1993gmailcom

A LITTLE SOMETHING ABOUT SERVICEMANAGER

bull Binder is the core of Android and forms the foundation of the IPC mechanism

bull OpenBinder was developed by Be Inc (later Palm Inc) (Tidbit Palm Inc designed the worldrsquos first PDA and one of the first smartphones)

bull Google developed the Binder framework for Android on the basis of OpenBinder

bull OpenBinder allows processes to present interfaces which may be called by other threads Each process maintains a thread pool which may be used to service such requests

bull In OpenBinder an entity called context manager exists maintains all services handles and returns the service handle to client on request

httpswwwlinkedincominsg1993 13georgeshibin1993gmailcom

A LITTLE SOMETHING ABOUT SERVICEMANAGER

bull If a client wants to publishadd a service it has to invoke an entity called context manager If a client wants to get a reference to a service it again has to query the context manager

bull The Context Manager in Android is called the ServiceManager

bull Since ServiceManager is essential for IPC in android it is started as a ldquocriticalrdquo service

bull Source-code at - frameworksnativecmdsservicemanager

bull During initialization ServiceManager itself calls binder_become_context_manager() to inform the binder driver that it is the contextManager

httpswwwlinkedincominsg1993 14georgeshibin1993gmailcom

A LITTLE SOMETHING ABOUT SERVICEMANAGER

bull The kernel binder driver on receiving this ioctl creates a binder node 0

bull Once this is done clients can now query ServiceManager Internally this happens via ioctl(fd paramscmd=GET srv=ldquoSERVICE_NAMErdquo target=0 hellip)

httpopengrokqualcommcomsourcexrefLAUM00kernelmsm-

318driversstagingandroidbinderc2729

binder_context_mgr_node = binder_new_node(proc 0 0)

httpopengrokqualcommcomsourcexrefLAUM00frameworksnativecmdsservicemanagerbinder

c146

int binder_become_context_manager(struct binder_state bs)

return ioctl(bs-gtfd BINDER_SET_CONTEXT_MGR 0)

httpswwwlinkedincominsg1993 15georgeshibin1993gmailcom

A LITTLE SOMETHING ABOUT SERVICEMANAGER01-01 071603022 0 0 I init Starting service ueventd

01-01 071604958 0 0 I init Starting service logd

01-01 071606345 0 0 I init Starting service vold

01-01 071606871 0 0 I init Starting service exec 1 (systembintzdatacheck)

01-01 071608191 0 0 I init Starting service exec 2 (initqcomearly_bootsh)

01-01 071609225 0 0 I init Starting service healthd

01-01 071609290 0 0 I init Starting service cs-early-boot

01-01 071609296 0 0 I init Starting service esepmdaemon

01-01 071609302 0 0 I init Starting service qcom-usb-sh

01-01 071609309 0 0 I init Starting service qseecomd

01-01 071609315 0 0 I init Starting service per_mgr

01-01 071609321 0 0 I init Starting service lmkd

01-01 071609327 0 0 I init Starting service servicemanager01-01 071609335 0 0 I init Starting service surfaceflinger

01-01 071610101 0 0 I init Starting service bootanim

01-01 071612563 0 0 I init Starting service logd-reinit

01-01 071612777 0 0 I init Starting service exec 4 (systembintzdatacheck)

01-01 071612903 0 0 I init Starting service carrier_switcher

01-01 071612911 0 0 I init Starting service exec 5 (systembinbootstat)

01-01 071612977 0 0 I init Starting service qcomsysd

01-01 071612983 0 0 I init Starting service qcom-c_main-sh

01-01 071612990 0 0 I init Starting service cnd

01-01 071612996 0 0 I init Starting service ptt_socket_app

01-01 071613002 0 0 I init Starting service cnss_diag

01-01 071613028 0 0 I init Starting service thermal-engine

01-01 071613034 0 0 I init Starting service wcnss-service

01-01 071613041 0 0 I init Starting service imsstarter

01-01 071613048 0 0 I init Starting service adsprpcd

01-01 071613054 0 0 I init Starting service hvdcp_opti

01-01 071613062 0 0 I init Starting service zygote01-01 071613069 0 0 I init Starting service zygote_secondary

httpswwwlinkedincominsg1993 16georgeshibin1993gmailcom

INITZYGOTE - STARTUP

bull Just like init is parent of all init-services system-server amp every app is spawned by zygote An executable called app_process(3264) is executed which is then known to others as zygote

bull It belongs to main class of services ie if userdata-encryption is enabled once you enter password zygote is restarted

httpandroidxrefcom700_r1xrefsystemcorerootdirinitzygote64_32rc

service zygote systembinapp_process64 -Xzygote systembin --zygote --start-system-server --socket-name=zygote

class main

socket zygote stream 660 root system

onrestart write sysandroid_powerrequest_state wake

onrestart write syspowerstate on

onrestart restart audioserver

onrestart restart cameraserver

onrestart restart media

onrestart restart netd

writepid devcpusetforegroundtasks sysfscgroupstuneforegroundtasks

service zygote_secondary systembinapp_process32 -Xzygote systembin --zygote --socket-name=zygote_secondary

class main

socket zygote_secondary stream 660 root system

onrestart restart zygote

writepid devcpusetforegroundtasks devstuneforegroundtasks

httpswwwlinkedincominsg1993 17georgeshibin1993gmailcom

ZYGOTE

bull App_process is a native proc (written in C++) Source for app_process resides here

bull ndashzygote option passed is to rename the process name from app_process to zygote here

bull comandroidinternalosZygoteInitjava is called (through runtimestart()) which starts systemServer and then polls

bull ndashstart-system_server option passed makes the zygote spawn system_server

bull Zygote uses an entity called ldquoAndroidRuntimerdquo that starts a VM to run Java Runtimestart() starts a new virtual machine As you know all code written in Java runs in a VM

bull Interesting tidbit the main() of ZygoteInitjava is the first piece of Java code that runs since the device was turned on (Reason is that this is the first time VM was created and java bytecode runs in VM)

httpandroidxrefcom700_r1xrefframeworksbasecmdsapp_processapp_maincpp306

if (zygote)

runtimestart(comandroidinternalosZygoteInit args zygote)

httpandroidxrefcom700_r1xrefframeworksbasecorejavacomandroidinternalosZygoteInitjava746

if (startSystemServer)

startSystemServer(abiList socketName)

httpswwwlinkedincominsg1993 18georgeshibin1993gmailcom

ZYGOTE

bull The most important reason behind Zygotersquos existence can be summarized in this one line of code

bull Zygote preloads classes (as in java class files) resources some shared libraries (so files) etc

bull You can find the list of these classes to be preloaded here on your device at systemetcpreloaded-classes Zygote reads this file here

bull On my device running Android Nougat the total number of preloaded classes alone is 4165 to be exact

httpandroidxrefcom700_r1xrefframeworksbasecorejavacomandroidinternalosZygoteInitjava722

preload()

httpswwwlinkedincominsg1993 19georgeshibin1993gmailcom

ZYGOTE

bull So how exactly is preloading helping

bull To know this we come back to one of the important tasks of zygote ie spawning each and every single application process (remember it is the parent process of all application processes)

bull After starting system_server zygote runs in an infinite while loop here

bull It keeps on polling a socket ndash devsocketzygote When you launch an application the request to create a new process comes from system_server to Zygote on this socket The call reaches hereand then it executes a fork system call as shown below

httpandroidxrefcom700_r1xrefframeworksbasecorejavacomandroidinternalosZygoteConnectionjava225

pid = ZygoteforkAndSpecialize(parsedArgsuid parsedArgsgid parsedArgsgids

parsedArgsdebugFlags rlimits parsedArgsmountExternal parsedArgsseInfo

parsedArgsniceName fdsToClose parsedArgsinstructionSet

parsedArgsappDataDir)

httpswwwlinkedincominsg1993 20georgeshibin1993gmailcom

ZYGOTEbull Here is where you will appreciate the virtue of a great design

bull When a process forks it creates a clone of itself It replicates itself in another memory space When this happens to Zygote it creates a clean new Dalvik VM preloaded with all necessary classes and resources that any App will need (the same 4165 I mentioned earlier)

bull Except that it is never copied

bull You see the Linux Kernel implements a strategy called Copy On Write (COW) With COW Linux doesnrsquot actually copy anything Instead it maps the pages of the new process over to those of the parent process and makes copies only when the new process writes to a page But the classeslibrariesresources preloaded by Zygote are all read-only and not modified by any application This means that all processes forked from Zygote are using the exact same copy of the system classes and resources till EOL These preloaded objects live in the Zygote heap

bull This is what saves the time when apps are launched Also the memory saved is worth mentioning as no matter how many applications are started only one copy of the system classes and the resources is ever loaded in RAM

bull Personally I think the reason we still need Zygote (and cannot be replaced by system_server) is because we would like a process that does almost nothing other than fork() so that COW can do its magic Something like system_server would be counterproductive as its own heap and loaded classes would be huge

httpswwwlinkedincominsg1993 21georgeshibin1993gmailcom

ZYGOTEbull Thats pretty much what Zygote does during its lifetime Lets move onto system_server Notice the class name passed

as argument to Zygotersquos fork call for system_server

bull Just like in Zygotersquos case the AndroidRuntime knows how to execute the main() function in comandroidserverSystemServerjava

httpandroidxrefcom700_r1xrefframeworksbasecorejavacomandroidinternalosZygoteInitjava632

String args[] =

--setuid=1000

--setgid=1000

--setgroups=10011002100310041005100610071008100910101018102110323001300230033006300730093010

--capabilities= + capabilities + + capabilities

--nice-name=system_server

--runtime-args

comandroidserverSystemServer

httpandroidxrefcom700_r1xrefframeworksbaseservicesjavacomandroidserverSystemServerjava205

The main entry point from zygote

public static void main(String[] args)

new SystemServer()run()

httpswwwlinkedincominsg1993 22georgeshibin1993gmailcom

SYSTEM-SERVERbull The run() of system_server starts bootstrap-services core-services and some other services

bull Bootstrap-services are a small number of critical services

bull These are ActivityManagerService PowerManagerService DisplayManagerService PackageManagerService UserManagerService and sSensorService Bootstrap services are started almost together as they have internal dependencies with each other

bull Core services are some essential services that do not have dependencies on bootstrap services so can be started some time later One of these is the WindowManagerService

bull After that a couple of services which are not as critical as the above two classes Infact some of them even need not be started for device bootup

httpandroidxrefcom700_r1xrefframeworksbaseservicesjavacomandroidserverSystemServerjava320

try

TracetraceBegin(TraceTRACE_TAG_SYSTEM_SERVER StartServices)

startBootstrapServices()

startCoreServices()

startOtherServices()

httpswwwlinkedincominsg1993 23georgeshibin1993gmailcom

SYSTEM-SERVERbull Later down the line after starting almost all of the criticalcore services the system_server

(ie its main thread) proceeds to notify ActivityManagerService that the system is now ready to execute third-party code (read apps) The ActivityManagerService does some initializations before it can start applications

bull The callback reaches back to system_server main thread where it starts the first app comandroidsystemui here (specifically SystemUiService of systemui component)

bull We are now mostly done with this thread of system_server (the main thread mainly deals with handling messages from other components and redirecting them)

httpandroidxrefcom700_r1xrefframeworksbaseservicesjavacomandroidserverSystemServerjava1275

mActivityManagerServicesystemReady(new Runnable()

Override

public void run()

hellip

try

startSystemUi(context)

catch (Throwable e)

reportWtf(starting System UI e)

httpswwwlinkedincominsg1993 24georgeshibin1993gmailcom

BOOTANIMATION

bull Wondering what is being displayed on the screen during this entire process

bull After init starts what you see is bootanimation

bull The bootanim is a service that displays the bootanimation and is started by init

bull The rc file is parsed by init during startup But init does not start it right away (Notice the disabled)

bull This also means that someone has to explicitly start bootanim This is done by SurfaceFlinger in its init()

httpandroidxrefcom700_r1xrefframeworksbasecmdsbootanimationbootanimrc

service bootanim systembinbootanimation

class core

user graphics

group graphics audio

disabled

oneshot

httpandroidxrefcom700_r1xrefframeworksbaseservicesjavacomandroidserverSystemServerjava1275

start boot animation

startBootAnim()

httpandroidxrefcom700_r1xrefframeworksnativeservicessurfaceflingerSurfaceFlingercpp506

void SurfaceFlingerstartBootAnim()

start boot animation

property_set(servicebootanimexit 0)

property_set(ctlstart bootanim)

httpswwwlinkedincominsg1993 25georgeshibin1993gmailcom

BOOTANIMATION

bull Note that SF doesnrsquot directly spawnfork a process Rather it sets a property ctlstart to bootanim

bull ctl is special because there is no actual property named ctlstartstop (it wonrsquot appear in getprop output)

bull Note the special handling of a property if the property_name starts with ctl

httpandroidxrefcom700_r1xrefsystemcoreinitproperty_servicecpp280

case PROP_MSG_SETPROP

hellip

if(memcmp(msgnamectl4) == 0)

hellip

if (check_control_mac_perms(msgvalue source_ctx ampcr))

handle_control_message((char) msgname + 4 (char) msgvalue)

hellip

else

if (check_mac_perms(msgname source_ctx ampcr))

property_set((char) msgname (char) msgvalue)

hellip

httpswwwlinkedincominsg1993 26georgeshibin1993gmailcom

LAUNCHER

bull When the call reaches init it starts the service which is assigned to ctlstart

bull So when SF sets ctlstart to bootanim init starts the service bootanim

bull Bootanim gets the media files from systemmediabootanimationzip

bull But who stops bootanim Lets get back to system_server to find that out

bull Remember we informed ActivityManagerService that we are ready to executelaunch 3rd party codeapplications here

bull AMS on executing this calls startHomeActivityLocked() Internally this sends an Intent with category IntentCATEGORY_HOME This intent category is special because if an app registers for this intent it means that the application is a Launcher-appHome-screen replacement app

bull On receving this intent Launcher is started as it had registered for the same (see Manifest)

bull Ok Launcher has started but you are still not seeing it on the display

httpswwwlinkedincominsg1993 27georgeshibin1993gmailcom

LAUNCHERbull For Launcher to be displayed bootanimation has to be stopped There is only one entity that can tell SF to stop

bootanim via a binder transaction ie WindowManagerService WindowManagerServicersquosperformEnableScreen() API needs to be invoked

httpandroidxrefcom700_r1xrefframeworksbaseservicescorejavacomandroidserverwmWindowManagerServicejava5866

if (mBootAnimationStopped)

Do this one time

TraceasyncTraceBegin(TraceTRACE_TAG_WINDOW_MANAGER Stop bootanim 0)

try

IBinder surfaceFlinger = ServiceManagergetService(SurfaceFlinger)

if (surfaceFlinger = null)

Slogi(TAG_WM TELLING SURFACE FLINGER WE ARE BOOTED)

Parcel data = Parcelobtain()

datawriteInterfaceToken(androiduiISurfaceComposer)

surfaceFlingertransact(IBinderFIRST_CALL_TRANSACTION BOOT_FINISHED

data null 0)

datarecycle()

catch (RemoteException ex)

Sloge(TAG_WM Boot completed SurfaceFlinger is dead)

mBootAnimationStopped = true

httpswwwlinkedincominsg1993 28georgeshibin1993gmailcom

bull So SF receives a binder call from WindowManagerService with the code IBinderFIRST_CALL_TRANSACTION SurfaceFlinger Binder IPC interface has defined the following

bull The call ultimately reaches bootFinished()

httpandroidxrefcom700_r1xrefframeworksnativeincludeguiISurfaceComposerh177

Note BOOT_FINISHED must remain this value it is called from

Java by ActivityManagerService

BOOT_FINISHED = IBinderFIRST_CALL_TRANSACTION

httpandroidxrefcom700_r1xrefframeworksnativeservicessurfaceflingerSurfaceFlingercpp292

void SurfaceFlingerbootFinished()

hellip

ALOGI(Boot is finished (ld ms) long(ns2ms(duration)) )

mBootFinished = true

stop boot animation

formerly we would just kill the process but we now ask it to exit so it

can choose where to stop the animation

property_set(servicebootanimexit 1)

httpswwwlinkedincominsg1993 29georgeshibin1993gmailcom

BOOTANIMATION

bull SF sets the property serviebootanim to 1 How does this stop bootanim

bull All this while since the time it was started bootanim has been executing playAnimation()

bull While doing so it also periodically calls checkExit()

bull On detecting that this property is set to 1 bootanim gracefully exits

httpandroidxrefcom700_r1xrefframeworksbasecmdsbootanimationBootAnimationcpp387

Allow surface flinger to gracefully request shutdown

char value[PROPERTY_VALUE_MAX]

property_get(servicebootanimexit value 0)

int exitnow = atoi(value)

if (exitnow)

requestExit()

if (mAudioPlayer = NULL)

mAudioPlayer-gtrequestExit()

httpswwwlinkedincominsg1993 30georgeshibin1993gmailcom

BOOT_COMPLETEDbull WindowManager invoked binder transaction to tell SF to stop bootanim

bull After that it calls ActivityManagerrsquos bootAnimationComplete() function

bull In ActivityManagerService finishBooting() is invoked where the property sysboot_completed is set to 1 This property is important because it is the ldquoofficialrdquo way of letting native-servicesdaemons know that boot is now complete

bull After this AMS tells UserController (which is a helper class for handling multi-user functionality) to send the 2 criticalimportant intents

bull Before you unlockswipe the lock screen the intent IntentACTION_LOCKED_BOOT_COMPLETED is sent here

bull Once the user is unlocked (by entering PINswiping-the-lock screen) the intent IntentACTION_BOOT_COMPLETED is sent here This intent is important because it lets Java-services3rd-party apps know that system boot-up is now officially complete and that user is now in the home screen

httpandroidxrefcom700_r1xrefframeworksbaseservicescorejavacomandroidserverwmWindowManagerServicejav

a5899

try

mActivityManagerbootAnimationComplete()

catch (RemoteException e)

httpswwwlinkedincominsg1993 31georgeshibin1993gmailcom

Aaaaand you are now in Home screen

httpswwwlinkedincominsg1993 32georgeshibin1993gmailcom

REFERENCES

bull My highlights on Karim Yaghmourrsquos famous book (Embedded Android) httpswwwsafaribooksonlinecomu001o000000YZt6HAATembedded-android9781449327958

bull Kernel boot process

bull httpduartesorggustavoblogpostkernel-boot-process

bull https0xaxgitbooksiolinux-insidescontentInitializationlinux-initialization-4html

bull httposr507docxinuoscomenPERFORMprocess_stateshtml

bull httpstackoverflowcomquestions464483why-do-we-need-a-swapper-task-in-linux

bull httpunixstackexchangecomquestions83322which-process-has-pid-0

bull BinderServiceManager

bull httpwwwmacrobugcomblog20071215decoding-a-service-call-in-android

bull httpwwwcubridorgblogdev-platformbinder-communication-mechanism-of-android-processes

bull httpwwwprogrameringcomaMjMyMDMwATQhtml

And most importantly httpandroidxrefcom700_r1xref

httpswwwlinkedincominsg1993 33georgeshibin1993gmailcom

Thank You for reading this far

httpswwwlinkedincominsg1993 34

Disclaimer

Almost none (okay fine absolutely zilch) of the information that I put up is proprietary to Qualcomm Inc

Some of the source-code hyperlinks to Qualcommrsquos internal repository which is not accessible to others anyway

For all the other stuff I have provided Android-xref links and is openly accessible to all

However I wonrsquot vouch for the correctness of all information presented here Nope

You are welcome to correcteditpresent this material according to your needs

However it would be nice if you could shoot me a mail (at georgeshibin1993gmailcom) andor provide a

reference to the original material Just sayinghellip it would be nice

georgeshibin1993gmailcom

Page 2: Android bootup

AGENDA

bull ANDROID BOOTLOADER

bull KERNEL BOOTUP PROCESS

bull INIT

bull SERVICEMANAGER

bull ZYGOTE

bull SYSTEM-SERVER

bull LAUNCHER

bull BOOTANIMATION

bull BOOT_COMPLETED

httpswwwlinkedincominsg1993 2georgeshibin1993gmailcom

BOOTUP OVERVIEW

ANDROID BOOTLOADERbull (L)ittle (K)ernel based Android bootloader

bull Android bootloader is developed on top of an open source project on kernelorg ndash named (L)ittle(K)ernel project

bull It does hardware initialization reading the Linux kernel amp ramdisk loading it up to RAM setting up initial registers and command line arguments for Linux kernel and jumps to the kernel

bull For normal bootup mode lk loads bootimg and for recovery mode it loads recoveryimg

bull UEFI-ABL is used as Bootloader for recent chipsets

httpswwwlinkedincominsg1993 4georgeshibin1993gmailcom

KERNEL BOOTUP PROCESS

bull Boot image is a raw partition ie there is no underlying filesystem like ext4FAT

bull Boot image(bootimg) = The kernel binary + ramdisk The bootloader loads kernel binary onto memory and then executes it

bull The first hardware independent piece of code that runs in kernel is start_kernel()

bull start_kernel() initializes various kernel subsystems and data structures These include the scheduler memory zones time keeping and so on

bull At the end of start_kernel() rest_init() is invoked

bull In rest_init() we start a kernel thread(kernel_init) that eventually becomes lsquoinitrsquo (with pid=1)

httpopengrokqualcommcomsourcexrefLAUM00kernelmsm-318initmainc396

static noinline void __init_refok rest_init(void)

int pid rcu_scheduler_starting()

smpboot_thread_init() s

We need to spawn init first so that it obtains pid 1 however

the init task will end up wanting to create kthreads which if

we schedule it before we create kthreadd will OOPS

kernel_thread(kernel_init NULL CLONE_FS)

httpswwwlinkedincominsg1993 5georgeshibin1993gmailcom

KERNEL BOOTUP PROCESS

bull Kernel_init at do_mountsc mounts ramdisk at lsquorsquo (root location) this is where init binary and other init scripts reside

bull This thread tries to execute init (thefirst user-mode process) in the following order init sbininit etcinit bininit and binsh If all fail kernel panics

bull But what happens to the thread that spawned init

bull That thread is known as the sched or swapper thread and has pid 0 (it does not appear in ps output but does appear as ppid of init) At the end of rest_init() this thread calls schedule() (to kickstart task scheduling) Then it enters idle loop here

httpopengrokqualcommcomsourcexrefLAUM00kernelmsm-318initmainc950

if (ramdisk_execute_command)

ret = run_init_process(ramdisk_execute_command)

We try each of these until one succeeds

The Bourne shell can be used instead of init if we are

trying to recover a really broken machine

if (try_to_run_init_process(sbininit) ||

try_to_run_init_process(etcinit) ||

try_to_run_init_process(bininit) ||

try_to_run_init_process(binsh))

return 0

panic(No working init found Try passing init= option to kernel

See Linux Documentationinittxt for guidance)

httpswwwlinkedincominsg1993 6georgeshibin1993gmailcom

bull The init processrsquos code resides here systemcoreinit

bull Basically all init does is the seemingly simple task of starting servicesdaemons and restarting some in case they are stopped It reads some configuration files ie rc files to figure out what to do when The rc files are written in initrsquos own language

bull The Android Init Language consists of five broad classes of statements - Actions Commands Services Options and Imports

INIT

httpswwwlinkedincominsg1993 7georgeshibin1993gmailcom

INIT RC FILE LINGObull Services are definitions of servicesdaemons etc that you want init to run

bull These are generally run when certain events are triggered

bull Options are modifiers to services Some important modifiers are-

bull critical ndash If it exits more than four times in four minutes the device will reboot into recovery mode (example critical)

bull disabled - This service will not automatically start with its class (ex bootanim)

bull socket ndash a socket at devsocketname will be created when the service starts (example devsocketzygote)

bull oneshot ndash Do not restart the service if it exits Most of important services will NOT have this modifier

bull class ndash 3 major classes of services ndash coremainlate-start

bull onrestart ndash execute the command following this when service restarts (example in zygotersquos rc onrestart restart cameraserver)

httpswwwlinkedincominsg1993 8georgeshibin1993gmailcom

INIT RC FILE LINGObull Triggers are strings which are used to match certain events

bull on ltpatterngt lthelliphellipgt - if the pattern is triggered by someone this is executed (ex on early-init)

bull on propertya=b ndash command is executed when property a is set to b

bull Commands are executed when predefined events are triggered (ie on lttriggergt)

bull trigger write chmod chown start stop restart setprop etc

bull Actions are of the form

bull For an action to be executed it is therefore necessary for an event to be triggered

bull Import statements are used to tell init to parse rc files present in different locations

on lttriggergt

ltcommandgt

ltcommandgt

ltcommandgt

httpswwwlinkedincominsg1993 9georgeshibin1993gmailcom

INIT

httpandroidxrefcom700_r1xrefsystemcorerootdirinitrc

on late-inittrigger early-fstrigger fstrigger post-fshelliptrigger early-boottrigger boot

on bootsetprop nettcpdefault_init_rwnd 60class_start core

httpswwwlinkedincominsg1993 10georgeshibin1993gmailcom

INITbull After some initial setup init first proceeds to parse initrc which is the primary rc file

bull All the other rc files are parsed using import statements in initrc

bull Once parsing is done to kickstart execution of servicesdaemons a few triggers have to be explicitly triggered by init itself

bull The first one of these is early-init

bull early-init is the cue to start ueventd for instance as defined in initrc

bull Init now has to start native daemonsservices like Surfaceflinger vold servicemanager healthd etc

httpandroidxrefcom700_r1xrefsystemcoreinitinitcpp688

parserParseConfig(initrc)

hellip

amQueueEventTrigger(early-init)

httpopengrokqualcommcomsourcexrefLAUM00systemcorerootdirinitrc13

on early-init

hellip

start ueventd

httpswwwlinkedincominsg1993 11georgeshibin1993gmailcom

INITbull Init also explicitly triggers event init and late-init When late-init is triggered it triggers event fs which is

when init parses fstab(qcom) entries to mount remaining partitions (system data misc) here

bull After that init basically runs in an infinite while loop on the lookout for services that might need restarting here

bull Among the services started by init one is particularly important for IPC to happen

bull Lets find out more about ServiceManager

httpopengrokqualcommcomsourcexrefLAUM00deviceqcommsm8937_64inittargetrc42

on fs

hellip

mount_all fstabqcom

httpswwwlinkedincominsg1993 12georgeshibin1993gmailcom

A LITTLE SOMETHING ABOUT SERVICEMANAGER

bull Binder is the core of Android and forms the foundation of the IPC mechanism

bull OpenBinder was developed by Be Inc (later Palm Inc) (Tidbit Palm Inc designed the worldrsquos first PDA and one of the first smartphones)

bull Google developed the Binder framework for Android on the basis of OpenBinder

bull OpenBinder allows processes to present interfaces which may be called by other threads Each process maintains a thread pool which may be used to service such requests

bull In OpenBinder an entity called context manager exists maintains all services handles and returns the service handle to client on request

httpswwwlinkedincominsg1993 13georgeshibin1993gmailcom

A LITTLE SOMETHING ABOUT SERVICEMANAGER

bull If a client wants to publishadd a service it has to invoke an entity called context manager If a client wants to get a reference to a service it again has to query the context manager

bull The Context Manager in Android is called the ServiceManager

bull Since ServiceManager is essential for IPC in android it is started as a ldquocriticalrdquo service

bull Source-code at - frameworksnativecmdsservicemanager

bull During initialization ServiceManager itself calls binder_become_context_manager() to inform the binder driver that it is the contextManager

httpswwwlinkedincominsg1993 14georgeshibin1993gmailcom

A LITTLE SOMETHING ABOUT SERVICEMANAGER

bull The kernel binder driver on receiving this ioctl creates a binder node 0

bull Once this is done clients can now query ServiceManager Internally this happens via ioctl(fd paramscmd=GET srv=ldquoSERVICE_NAMErdquo target=0 hellip)

httpopengrokqualcommcomsourcexrefLAUM00kernelmsm-

318driversstagingandroidbinderc2729

binder_context_mgr_node = binder_new_node(proc 0 0)

httpopengrokqualcommcomsourcexrefLAUM00frameworksnativecmdsservicemanagerbinder

c146

int binder_become_context_manager(struct binder_state bs)

return ioctl(bs-gtfd BINDER_SET_CONTEXT_MGR 0)

httpswwwlinkedincominsg1993 15georgeshibin1993gmailcom

A LITTLE SOMETHING ABOUT SERVICEMANAGER01-01 071603022 0 0 I init Starting service ueventd

01-01 071604958 0 0 I init Starting service logd

01-01 071606345 0 0 I init Starting service vold

01-01 071606871 0 0 I init Starting service exec 1 (systembintzdatacheck)

01-01 071608191 0 0 I init Starting service exec 2 (initqcomearly_bootsh)

01-01 071609225 0 0 I init Starting service healthd

01-01 071609290 0 0 I init Starting service cs-early-boot

01-01 071609296 0 0 I init Starting service esepmdaemon

01-01 071609302 0 0 I init Starting service qcom-usb-sh

01-01 071609309 0 0 I init Starting service qseecomd

01-01 071609315 0 0 I init Starting service per_mgr

01-01 071609321 0 0 I init Starting service lmkd

01-01 071609327 0 0 I init Starting service servicemanager01-01 071609335 0 0 I init Starting service surfaceflinger

01-01 071610101 0 0 I init Starting service bootanim

01-01 071612563 0 0 I init Starting service logd-reinit

01-01 071612777 0 0 I init Starting service exec 4 (systembintzdatacheck)

01-01 071612903 0 0 I init Starting service carrier_switcher

01-01 071612911 0 0 I init Starting service exec 5 (systembinbootstat)

01-01 071612977 0 0 I init Starting service qcomsysd

01-01 071612983 0 0 I init Starting service qcom-c_main-sh

01-01 071612990 0 0 I init Starting service cnd

01-01 071612996 0 0 I init Starting service ptt_socket_app

01-01 071613002 0 0 I init Starting service cnss_diag

01-01 071613028 0 0 I init Starting service thermal-engine

01-01 071613034 0 0 I init Starting service wcnss-service

01-01 071613041 0 0 I init Starting service imsstarter

01-01 071613048 0 0 I init Starting service adsprpcd

01-01 071613054 0 0 I init Starting service hvdcp_opti

01-01 071613062 0 0 I init Starting service zygote01-01 071613069 0 0 I init Starting service zygote_secondary

httpswwwlinkedincominsg1993 16georgeshibin1993gmailcom

INITZYGOTE - STARTUP

bull Just like init is parent of all init-services system-server amp every app is spawned by zygote An executable called app_process(3264) is executed which is then known to others as zygote

bull It belongs to main class of services ie if userdata-encryption is enabled once you enter password zygote is restarted

httpandroidxrefcom700_r1xrefsystemcorerootdirinitzygote64_32rc

service zygote systembinapp_process64 -Xzygote systembin --zygote --start-system-server --socket-name=zygote

class main

socket zygote stream 660 root system

onrestart write sysandroid_powerrequest_state wake

onrestart write syspowerstate on

onrestart restart audioserver

onrestart restart cameraserver

onrestart restart media

onrestart restart netd

writepid devcpusetforegroundtasks sysfscgroupstuneforegroundtasks

service zygote_secondary systembinapp_process32 -Xzygote systembin --zygote --socket-name=zygote_secondary

class main

socket zygote_secondary stream 660 root system

onrestart restart zygote

writepid devcpusetforegroundtasks devstuneforegroundtasks

httpswwwlinkedincominsg1993 17georgeshibin1993gmailcom

ZYGOTE

bull App_process is a native proc (written in C++) Source for app_process resides here

bull ndashzygote option passed is to rename the process name from app_process to zygote here

bull comandroidinternalosZygoteInitjava is called (through runtimestart()) which starts systemServer and then polls

bull ndashstart-system_server option passed makes the zygote spawn system_server

bull Zygote uses an entity called ldquoAndroidRuntimerdquo that starts a VM to run Java Runtimestart() starts a new virtual machine As you know all code written in Java runs in a VM

bull Interesting tidbit the main() of ZygoteInitjava is the first piece of Java code that runs since the device was turned on (Reason is that this is the first time VM was created and java bytecode runs in VM)

httpandroidxrefcom700_r1xrefframeworksbasecmdsapp_processapp_maincpp306

if (zygote)

runtimestart(comandroidinternalosZygoteInit args zygote)

httpandroidxrefcom700_r1xrefframeworksbasecorejavacomandroidinternalosZygoteInitjava746

if (startSystemServer)

startSystemServer(abiList socketName)

httpswwwlinkedincominsg1993 18georgeshibin1993gmailcom

ZYGOTE

bull The most important reason behind Zygotersquos existence can be summarized in this one line of code

bull Zygote preloads classes (as in java class files) resources some shared libraries (so files) etc

bull You can find the list of these classes to be preloaded here on your device at systemetcpreloaded-classes Zygote reads this file here

bull On my device running Android Nougat the total number of preloaded classes alone is 4165 to be exact

httpandroidxrefcom700_r1xrefframeworksbasecorejavacomandroidinternalosZygoteInitjava722

preload()

httpswwwlinkedincominsg1993 19georgeshibin1993gmailcom

ZYGOTE

bull So how exactly is preloading helping

bull To know this we come back to one of the important tasks of zygote ie spawning each and every single application process (remember it is the parent process of all application processes)

bull After starting system_server zygote runs in an infinite while loop here

bull It keeps on polling a socket ndash devsocketzygote When you launch an application the request to create a new process comes from system_server to Zygote on this socket The call reaches hereand then it executes a fork system call as shown below

httpandroidxrefcom700_r1xrefframeworksbasecorejavacomandroidinternalosZygoteConnectionjava225

pid = ZygoteforkAndSpecialize(parsedArgsuid parsedArgsgid parsedArgsgids

parsedArgsdebugFlags rlimits parsedArgsmountExternal parsedArgsseInfo

parsedArgsniceName fdsToClose parsedArgsinstructionSet

parsedArgsappDataDir)

httpswwwlinkedincominsg1993 20georgeshibin1993gmailcom

ZYGOTEbull Here is where you will appreciate the virtue of a great design

bull When a process forks it creates a clone of itself It replicates itself in another memory space When this happens to Zygote it creates a clean new Dalvik VM preloaded with all necessary classes and resources that any App will need (the same 4165 I mentioned earlier)

bull Except that it is never copied

bull You see the Linux Kernel implements a strategy called Copy On Write (COW) With COW Linux doesnrsquot actually copy anything Instead it maps the pages of the new process over to those of the parent process and makes copies only when the new process writes to a page But the classeslibrariesresources preloaded by Zygote are all read-only and not modified by any application This means that all processes forked from Zygote are using the exact same copy of the system classes and resources till EOL These preloaded objects live in the Zygote heap

bull This is what saves the time when apps are launched Also the memory saved is worth mentioning as no matter how many applications are started only one copy of the system classes and the resources is ever loaded in RAM

bull Personally I think the reason we still need Zygote (and cannot be replaced by system_server) is because we would like a process that does almost nothing other than fork() so that COW can do its magic Something like system_server would be counterproductive as its own heap and loaded classes would be huge

httpswwwlinkedincominsg1993 21georgeshibin1993gmailcom

ZYGOTEbull Thats pretty much what Zygote does during its lifetime Lets move onto system_server Notice the class name passed

as argument to Zygotersquos fork call for system_server

bull Just like in Zygotersquos case the AndroidRuntime knows how to execute the main() function in comandroidserverSystemServerjava

httpandroidxrefcom700_r1xrefframeworksbasecorejavacomandroidinternalosZygoteInitjava632

String args[] =

--setuid=1000

--setgid=1000

--setgroups=10011002100310041005100610071008100910101018102110323001300230033006300730093010

--capabilities= + capabilities + + capabilities

--nice-name=system_server

--runtime-args

comandroidserverSystemServer

httpandroidxrefcom700_r1xrefframeworksbaseservicesjavacomandroidserverSystemServerjava205

The main entry point from zygote

public static void main(String[] args)

new SystemServer()run()

httpswwwlinkedincominsg1993 22georgeshibin1993gmailcom

SYSTEM-SERVERbull The run() of system_server starts bootstrap-services core-services and some other services

bull Bootstrap-services are a small number of critical services

bull These are ActivityManagerService PowerManagerService DisplayManagerService PackageManagerService UserManagerService and sSensorService Bootstrap services are started almost together as they have internal dependencies with each other

bull Core services are some essential services that do not have dependencies on bootstrap services so can be started some time later One of these is the WindowManagerService

bull After that a couple of services which are not as critical as the above two classes Infact some of them even need not be started for device bootup

httpandroidxrefcom700_r1xrefframeworksbaseservicesjavacomandroidserverSystemServerjava320

try

TracetraceBegin(TraceTRACE_TAG_SYSTEM_SERVER StartServices)

startBootstrapServices()

startCoreServices()

startOtherServices()

httpswwwlinkedincominsg1993 23georgeshibin1993gmailcom

SYSTEM-SERVERbull Later down the line after starting almost all of the criticalcore services the system_server

(ie its main thread) proceeds to notify ActivityManagerService that the system is now ready to execute third-party code (read apps) The ActivityManagerService does some initializations before it can start applications

bull The callback reaches back to system_server main thread where it starts the first app comandroidsystemui here (specifically SystemUiService of systemui component)

bull We are now mostly done with this thread of system_server (the main thread mainly deals with handling messages from other components and redirecting them)

httpandroidxrefcom700_r1xrefframeworksbaseservicesjavacomandroidserverSystemServerjava1275

mActivityManagerServicesystemReady(new Runnable()

Override

public void run()

hellip

try

startSystemUi(context)

catch (Throwable e)

reportWtf(starting System UI e)

httpswwwlinkedincominsg1993 24georgeshibin1993gmailcom

BOOTANIMATION

bull Wondering what is being displayed on the screen during this entire process

bull After init starts what you see is bootanimation

bull The bootanim is a service that displays the bootanimation and is started by init

bull The rc file is parsed by init during startup But init does not start it right away (Notice the disabled)

bull This also means that someone has to explicitly start bootanim This is done by SurfaceFlinger in its init()

httpandroidxrefcom700_r1xrefframeworksbasecmdsbootanimationbootanimrc

service bootanim systembinbootanimation

class core

user graphics

group graphics audio

disabled

oneshot

httpandroidxrefcom700_r1xrefframeworksbaseservicesjavacomandroidserverSystemServerjava1275

start boot animation

startBootAnim()

httpandroidxrefcom700_r1xrefframeworksnativeservicessurfaceflingerSurfaceFlingercpp506

void SurfaceFlingerstartBootAnim()

start boot animation

property_set(servicebootanimexit 0)

property_set(ctlstart bootanim)

httpswwwlinkedincominsg1993 25georgeshibin1993gmailcom

BOOTANIMATION

bull Note that SF doesnrsquot directly spawnfork a process Rather it sets a property ctlstart to bootanim

bull ctl is special because there is no actual property named ctlstartstop (it wonrsquot appear in getprop output)

bull Note the special handling of a property if the property_name starts with ctl

httpandroidxrefcom700_r1xrefsystemcoreinitproperty_servicecpp280

case PROP_MSG_SETPROP

hellip

if(memcmp(msgnamectl4) == 0)

hellip

if (check_control_mac_perms(msgvalue source_ctx ampcr))

handle_control_message((char) msgname + 4 (char) msgvalue)

hellip

else

if (check_mac_perms(msgname source_ctx ampcr))

property_set((char) msgname (char) msgvalue)

hellip

httpswwwlinkedincominsg1993 26georgeshibin1993gmailcom

LAUNCHER

bull When the call reaches init it starts the service which is assigned to ctlstart

bull So when SF sets ctlstart to bootanim init starts the service bootanim

bull Bootanim gets the media files from systemmediabootanimationzip

bull But who stops bootanim Lets get back to system_server to find that out

bull Remember we informed ActivityManagerService that we are ready to executelaunch 3rd party codeapplications here

bull AMS on executing this calls startHomeActivityLocked() Internally this sends an Intent with category IntentCATEGORY_HOME This intent category is special because if an app registers for this intent it means that the application is a Launcher-appHome-screen replacement app

bull On receving this intent Launcher is started as it had registered for the same (see Manifest)

bull Ok Launcher has started but you are still not seeing it on the display

httpswwwlinkedincominsg1993 27georgeshibin1993gmailcom

LAUNCHERbull For Launcher to be displayed bootanimation has to be stopped There is only one entity that can tell SF to stop

bootanim via a binder transaction ie WindowManagerService WindowManagerServicersquosperformEnableScreen() API needs to be invoked

httpandroidxrefcom700_r1xrefframeworksbaseservicescorejavacomandroidserverwmWindowManagerServicejava5866

if (mBootAnimationStopped)

Do this one time

TraceasyncTraceBegin(TraceTRACE_TAG_WINDOW_MANAGER Stop bootanim 0)

try

IBinder surfaceFlinger = ServiceManagergetService(SurfaceFlinger)

if (surfaceFlinger = null)

Slogi(TAG_WM TELLING SURFACE FLINGER WE ARE BOOTED)

Parcel data = Parcelobtain()

datawriteInterfaceToken(androiduiISurfaceComposer)

surfaceFlingertransact(IBinderFIRST_CALL_TRANSACTION BOOT_FINISHED

data null 0)

datarecycle()

catch (RemoteException ex)

Sloge(TAG_WM Boot completed SurfaceFlinger is dead)

mBootAnimationStopped = true

httpswwwlinkedincominsg1993 28georgeshibin1993gmailcom

bull So SF receives a binder call from WindowManagerService with the code IBinderFIRST_CALL_TRANSACTION SurfaceFlinger Binder IPC interface has defined the following

bull The call ultimately reaches bootFinished()

httpandroidxrefcom700_r1xrefframeworksnativeincludeguiISurfaceComposerh177

Note BOOT_FINISHED must remain this value it is called from

Java by ActivityManagerService

BOOT_FINISHED = IBinderFIRST_CALL_TRANSACTION

httpandroidxrefcom700_r1xrefframeworksnativeservicessurfaceflingerSurfaceFlingercpp292

void SurfaceFlingerbootFinished()

hellip

ALOGI(Boot is finished (ld ms) long(ns2ms(duration)) )

mBootFinished = true

stop boot animation

formerly we would just kill the process but we now ask it to exit so it

can choose where to stop the animation

property_set(servicebootanimexit 1)

httpswwwlinkedincominsg1993 29georgeshibin1993gmailcom

BOOTANIMATION

bull SF sets the property serviebootanim to 1 How does this stop bootanim

bull All this while since the time it was started bootanim has been executing playAnimation()

bull While doing so it also periodically calls checkExit()

bull On detecting that this property is set to 1 bootanim gracefully exits

httpandroidxrefcom700_r1xrefframeworksbasecmdsbootanimationBootAnimationcpp387

Allow surface flinger to gracefully request shutdown

char value[PROPERTY_VALUE_MAX]

property_get(servicebootanimexit value 0)

int exitnow = atoi(value)

if (exitnow)

requestExit()

if (mAudioPlayer = NULL)

mAudioPlayer-gtrequestExit()

httpswwwlinkedincominsg1993 30georgeshibin1993gmailcom

BOOT_COMPLETEDbull WindowManager invoked binder transaction to tell SF to stop bootanim

bull After that it calls ActivityManagerrsquos bootAnimationComplete() function

bull In ActivityManagerService finishBooting() is invoked where the property sysboot_completed is set to 1 This property is important because it is the ldquoofficialrdquo way of letting native-servicesdaemons know that boot is now complete

bull After this AMS tells UserController (which is a helper class for handling multi-user functionality) to send the 2 criticalimportant intents

bull Before you unlockswipe the lock screen the intent IntentACTION_LOCKED_BOOT_COMPLETED is sent here

bull Once the user is unlocked (by entering PINswiping-the-lock screen) the intent IntentACTION_BOOT_COMPLETED is sent here This intent is important because it lets Java-services3rd-party apps know that system boot-up is now officially complete and that user is now in the home screen

httpandroidxrefcom700_r1xrefframeworksbaseservicescorejavacomandroidserverwmWindowManagerServicejav

a5899

try

mActivityManagerbootAnimationComplete()

catch (RemoteException e)

httpswwwlinkedincominsg1993 31georgeshibin1993gmailcom

Aaaaand you are now in Home screen

httpswwwlinkedincominsg1993 32georgeshibin1993gmailcom

REFERENCES

bull My highlights on Karim Yaghmourrsquos famous book (Embedded Android) httpswwwsafaribooksonlinecomu001o000000YZt6HAATembedded-android9781449327958

bull Kernel boot process

bull httpduartesorggustavoblogpostkernel-boot-process

bull https0xaxgitbooksiolinux-insidescontentInitializationlinux-initialization-4html

bull httposr507docxinuoscomenPERFORMprocess_stateshtml

bull httpstackoverflowcomquestions464483why-do-we-need-a-swapper-task-in-linux

bull httpunixstackexchangecomquestions83322which-process-has-pid-0

bull BinderServiceManager

bull httpwwwmacrobugcomblog20071215decoding-a-service-call-in-android

bull httpwwwcubridorgblogdev-platformbinder-communication-mechanism-of-android-processes

bull httpwwwprogrameringcomaMjMyMDMwATQhtml

And most importantly httpandroidxrefcom700_r1xref

httpswwwlinkedincominsg1993 33georgeshibin1993gmailcom

Thank You for reading this far

httpswwwlinkedincominsg1993 34

Disclaimer

Almost none (okay fine absolutely zilch) of the information that I put up is proprietary to Qualcomm Inc

Some of the source-code hyperlinks to Qualcommrsquos internal repository which is not accessible to others anyway

For all the other stuff I have provided Android-xref links and is openly accessible to all

However I wonrsquot vouch for the correctness of all information presented here Nope

You are welcome to correcteditpresent this material according to your needs

However it would be nice if you could shoot me a mail (at georgeshibin1993gmailcom) andor provide a

reference to the original material Just sayinghellip it would be nice

georgeshibin1993gmailcom

Page 3: Android bootup

BOOTUP OVERVIEW

ANDROID BOOTLOADERbull (L)ittle (K)ernel based Android bootloader

bull Android bootloader is developed on top of an open source project on kernelorg ndash named (L)ittle(K)ernel project

bull It does hardware initialization reading the Linux kernel amp ramdisk loading it up to RAM setting up initial registers and command line arguments for Linux kernel and jumps to the kernel

bull For normal bootup mode lk loads bootimg and for recovery mode it loads recoveryimg

bull UEFI-ABL is used as Bootloader for recent chipsets

httpswwwlinkedincominsg1993 4georgeshibin1993gmailcom

KERNEL BOOTUP PROCESS

bull Boot image is a raw partition ie there is no underlying filesystem like ext4FAT

bull Boot image(bootimg) = The kernel binary + ramdisk The bootloader loads kernel binary onto memory and then executes it

bull The first hardware independent piece of code that runs in kernel is start_kernel()

bull start_kernel() initializes various kernel subsystems and data structures These include the scheduler memory zones time keeping and so on

bull At the end of start_kernel() rest_init() is invoked

bull In rest_init() we start a kernel thread(kernel_init) that eventually becomes lsquoinitrsquo (with pid=1)

httpopengrokqualcommcomsourcexrefLAUM00kernelmsm-318initmainc396

static noinline void __init_refok rest_init(void)

int pid rcu_scheduler_starting()

smpboot_thread_init() s

We need to spawn init first so that it obtains pid 1 however

the init task will end up wanting to create kthreads which if

we schedule it before we create kthreadd will OOPS

kernel_thread(kernel_init NULL CLONE_FS)

httpswwwlinkedincominsg1993 5georgeshibin1993gmailcom

KERNEL BOOTUP PROCESS

bull Kernel_init at do_mountsc mounts ramdisk at lsquorsquo (root location) this is where init binary and other init scripts reside

bull This thread tries to execute init (thefirst user-mode process) in the following order init sbininit etcinit bininit and binsh If all fail kernel panics

bull But what happens to the thread that spawned init

bull That thread is known as the sched or swapper thread and has pid 0 (it does not appear in ps output but does appear as ppid of init) At the end of rest_init() this thread calls schedule() (to kickstart task scheduling) Then it enters idle loop here

httpopengrokqualcommcomsourcexrefLAUM00kernelmsm-318initmainc950

if (ramdisk_execute_command)

ret = run_init_process(ramdisk_execute_command)

We try each of these until one succeeds

The Bourne shell can be used instead of init if we are

trying to recover a really broken machine

if (try_to_run_init_process(sbininit) ||

try_to_run_init_process(etcinit) ||

try_to_run_init_process(bininit) ||

try_to_run_init_process(binsh))

return 0

panic(No working init found Try passing init= option to kernel

See Linux Documentationinittxt for guidance)

httpswwwlinkedincominsg1993 6georgeshibin1993gmailcom

bull The init processrsquos code resides here systemcoreinit

bull Basically all init does is the seemingly simple task of starting servicesdaemons and restarting some in case they are stopped It reads some configuration files ie rc files to figure out what to do when The rc files are written in initrsquos own language

bull The Android Init Language consists of five broad classes of statements - Actions Commands Services Options and Imports

INIT

httpswwwlinkedincominsg1993 7georgeshibin1993gmailcom

INIT RC FILE LINGObull Services are definitions of servicesdaemons etc that you want init to run

bull These are generally run when certain events are triggered

bull Options are modifiers to services Some important modifiers are-

bull critical ndash If it exits more than four times in four minutes the device will reboot into recovery mode (example critical)

bull disabled - This service will not automatically start with its class (ex bootanim)

bull socket ndash a socket at devsocketname will be created when the service starts (example devsocketzygote)

bull oneshot ndash Do not restart the service if it exits Most of important services will NOT have this modifier

bull class ndash 3 major classes of services ndash coremainlate-start

bull onrestart ndash execute the command following this when service restarts (example in zygotersquos rc onrestart restart cameraserver)

httpswwwlinkedincominsg1993 8georgeshibin1993gmailcom

INIT RC FILE LINGObull Triggers are strings which are used to match certain events

bull on ltpatterngt lthelliphellipgt - if the pattern is triggered by someone this is executed (ex on early-init)

bull on propertya=b ndash command is executed when property a is set to b

bull Commands are executed when predefined events are triggered (ie on lttriggergt)

bull trigger write chmod chown start stop restart setprop etc

bull Actions are of the form

bull For an action to be executed it is therefore necessary for an event to be triggered

bull Import statements are used to tell init to parse rc files present in different locations

on lttriggergt

ltcommandgt

ltcommandgt

ltcommandgt

httpswwwlinkedincominsg1993 9georgeshibin1993gmailcom

INIT

httpandroidxrefcom700_r1xrefsystemcorerootdirinitrc

on late-inittrigger early-fstrigger fstrigger post-fshelliptrigger early-boottrigger boot

on bootsetprop nettcpdefault_init_rwnd 60class_start core

httpswwwlinkedincominsg1993 10georgeshibin1993gmailcom

INITbull After some initial setup init first proceeds to parse initrc which is the primary rc file

bull All the other rc files are parsed using import statements in initrc

bull Once parsing is done to kickstart execution of servicesdaemons a few triggers have to be explicitly triggered by init itself

bull The first one of these is early-init

bull early-init is the cue to start ueventd for instance as defined in initrc

bull Init now has to start native daemonsservices like Surfaceflinger vold servicemanager healthd etc

httpandroidxrefcom700_r1xrefsystemcoreinitinitcpp688

parserParseConfig(initrc)

hellip

amQueueEventTrigger(early-init)

httpopengrokqualcommcomsourcexrefLAUM00systemcorerootdirinitrc13

on early-init

hellip

start ueventd

httpswwwlinkedincominsg1993 11georgeshibin1993gmailcom

INITbull Init also explicitly triggers event init and late-init When late-init is triggered it triggers event fs which is

when init parses fstab(qcom) entries to mount remaining partitions (system data misc) here

bull After that init basically runs in an infinite while loop on the lookout for services that might need restarting here

bull Among the services started by init one is particularly important for IPC to happen

bull Lets find out more about ServiceManager

httpopengrokqualcommcomsourcexrefLAUM00deviceqcommsm8937_64inittargetrc42

on fs

hellip

mount_all fstabqcom

httpswwwlinkedincominsg1993 12georgeshibin1993gmailcom

A LITTLE SOMETHING ABOUT SERVICEMANAGER

bull Binder is the core of Android and forms the foundation of the IPC mechanism

bull OpenBinder was developed by Be Inc (later Palm Inc) (Tidbit Palm Inc designed the worldrsquos first PDA and one of the first smartphones)

bull Google developed the Binder framework for Android on the basis of OpenBinder

bull OpenBinder allows processes to present interfaces which may be called by other threads Each process maintains a thread pool which may be used to service such requests

bull In OpenBinder an entity called context manager exists maintains all services handles and returns the service handle to client on request

httpswwwlinkedincominsg1993 13georgeshibin1993gmailcom

A LITTLE SOMETHING ABOUT SERVICEMANAGER

bull If a client wants to publishadd a service it has to invoke an entity called context manager If a client wants to get a reference to a service it again has to query the context manager

bull The Context Manager in Android is called the ServiceManager

bull Since ServiceManager is essential for IPC in android it is started as a ldquocriticalrdquo service

bull Source-code at - frameworksnativecmdsservicemanager

bull During initialization ServiceManager itself calls binder_become_context_manager() to inform the binder driver that it is the contextManager

httpswwwlinkedincominsg1993 14georgeshibin1993gmailcom

A LITTLE SOMETHING ABOUT SERVICEMANAGER

bull The kernel binder driver on receiving this ioctl creates a binder node 0

bull Once this is done clients can now query ServiceManager Internally this happens via ioctl(fd paramscmd=GET srv=ldquoSERVICE_NAMErdquo target=0 hellip)

httpopengrokqualcommcomsourcexrefLAUM00kernelmsm-

318driversstagingandroidbinderc2729

binder_context_mgr_node = binder_new_node(proc 0 0)

httpopengrokqualcommcomsourcexrefLAUM00frameworksnativecmdsservicemanagerbinder

c146

int binder_become_context_manager(struct binder_state bs)

return ioctl(bs-gtfd BINDER_SET_CONTEXT_MGR 0)

httpswwwlinkedincominsg1993 15georgeshibin1993gmailcom

A LITTLE SOMETHING ABOUT SERVICEMANAGER01-01 071603022 0 0 I init Starting service ueventd

01-01 071604958 0 0 I init Starting service logd

01-01 071606345 0 0 I init Starting service vold

01-01 071606871 0 0 I init Starting service exec 1 (systembintzdatacheck)

01-01 071608191 0 0 I init Starting service exec 2 (initqcomearly_bootsh)

01-01 071609225 0 0 I init Starting service healthd

01-01 071609290 0 0 I init Starting service cs-early-boot

01-01 071609296 0 0 I init Starting service esepmdaemon

01-01 071609302 0 0 I init Starting service qcom-usb-sh

01-01 071609309 0 0 I init Starting service qseecomd

01-01 071609315 0 0 I init Starting service per_mgr

01-01 071609321 0 0 I init Starting service lmkd

01-01 071609327 0 0 I init Starting service servicemanager01-01 071609335 0 0 I init Starting service surfaceflinger

01-01 071610101 0 0 I init Starting service bootanim

01-01 071612563 0 0 I init Starting service logd-reinit

01-01 071612777 0 0 I init Starting service exec 4 (systembintzdatacheck)

01-01 071612903 0 0 I init Starting service carrier_switcher

01-01 071612911 0 0 I init Starting service exec 5 (systembinbootstat)

01-01 071612977 0 0 I init Starting service qcomsysd

01-01 071612983 0 0 I init Starting service qcom-c_main-sh

01-01 071612990 0 0 I init Starting service cnd

01-01 071612996 0 0 I init Starting service ptt_socket_app

01-01 071613002 0 0 I init Starting service cnss_diag

01-01 071613028 0 0 I init Starting service thermal-engine

01-01 071613034 0 0 I init Starting service wcnss-service

01-01 071613041 0 0 I init Starting service imsstarter

01-01 071613048 0 0 I init Starting service adsprpcd

01-01 071613054 0 0 I init Starting service hvdcp_opti

01-01 071613062 0 0 I init Starting service zygote01-01 071613069 0 0 I init Starting service zygote_secondary

httpswwwlinkedincominsg1993 16georgeshibin1993gmailcom

INITZYGOTE - STARTUP

bull Just like init is parent of all init-services system-server amp every app is spawned by zygote An executable called app_process(3264) is executed which is then known to others as zygote

bull It belongs to main class of services ie if userdata-encryption is enabled once you enter password zygote is restarted

httpandroidxrefcom700_r1xrefsystemcorerootdirinitzygote64_32rc

service zygote systembinapp_process64 -Xzygote systembin --zygote --start-system-server --socket-name=zygote

class main

socket zygote stream 660 root system

onrestart write sysandroid_powerrequest_state wake

onrestart write syspowerstate on

onrestart restart audioserver

onrestart restart cameraserver

onrestart restart media

onrestart restart netd

writepid devcpusetforegroundtasks sysfscgroupstuneforegroundtasks

service zygote_secondary systembinapp_process32 -Xzygote systembin --zygote --socket-name=zygote_secondary

class main

socket zygote_secondary stream 660 root system

onrestart restart zygote

writepid devcpusetforegroundtasks devstuneforegroundtasks

httpswwwlinkedincominsg1993 17georgeshibin1993gmailcom

ZYGOTE

bull App_process is a native proc (written in C++) Source for app_process resides here

bull ndashzygote option passed is to rename the process name from app_process to zygote here

bull comandroidinternalosZygoteInitjava is called (through runtimestart()) which starts systemServer and then polls

bull ndashstart-system_server option passed makes the zygote spawn system_server

bull Zygote uses an entity called ldquoAndroidRuntimerdquo that starts a VM to run Java Runtimestart() starts a new virtual machine As you know all code written in Java runs in a VM

bull Interesting tidbit the main() of ZygoteInitjava is the first piece of Java code that runs since the device was turned on (Reason is that this is the first time VM was created and java bytecode runs in VM)

httpandroidxrefcom700_r1xrefframeworksbasecmdsapp_processapp_maincpp306

if (zygote)

runtimestart(comandroidinternalosZygoteInit args zygote)

httpandroidxrefcom700_r1xrefframeworksbasecorejavacomandroidinternalosZygoteInitjava746

if (startSystemServer)

startSystemServer(abiList socketName)

httpswwwlinkedincominsg1993 18georgeshibin1993gmailcom

ZYGOTE

bull The most important reason behind Zygotersquos existence can be summarized in this one line of code

bull Zygote preloads classes (as in java class files) resources some shared libraries (so files) etc

bull You can find the list of these classes to be preloaded here on your device at systemetcpreloaded-classes Zygote reads this file here

bull On my device running Android Nougat the total number of preloaded classes alone is 4165 to be exact

httpandroidxrefcom700_r1xrefframeworksbasecorejavacomandroidinternalosZygoteInitjava722

preload()

httpswwwlinkedincominsg1993 19georgeshibin1993gmailcom

ZYGOTE

bull So how exactly is preloading helping

bull To know this we come back to one of the important tasks of zygote ie spawning each and every single application process (remember it is the parent process of all application processes)

bull After starting system_server zygote runs in an infinite while loop here

bull It keeps on polling a socket ndash devsocketzygote When you launch an application the request to create a new process comes from system_server to Zygote on this socket The call reaches hereand then it executes a fork system call as shown below

httpandroidxrefcom700_r1xrefframeworksbasecorejavacomandroidinternalosZygoteConnectionjava225

pid = ZygoteforkAndSpecialize(parsedArgsuid parsedArgsgid parsedArgsgids

parsedArgsdebugFlags rlimits parsedArgsmountExternal parsedArgsseInfo

parsedArgsniceName fdsToClose parsedArgsinstructionSet

parsedArgsappDataDir)

httpswwwlinkedincominsg1993 20georgeshibin1993gmailcom

ZYGOTEbull Here is where you will appreciate the virtue of a great design

bull When a process forks it creates a clone of itself It replicates itself in another memory space When this happens to Zygote it creates a clean new Dalvik VM preloaded with all necessary classes and resources that any App will need (the same 4165 I mentioned earlier)

bull Except that it is never copied

bull You see the Linux Kernel implements a strategy called Copy On Write (COW) With COW Linux doesnrsquot actually copy anything Instead it maps the pages of the new process over to those of the parent process and makes copies only when the new process writes to a page But the classeslibrariesresources preloaded by Zygote are all read-only and not modified by any application This means that all processes forked from Zygote are using the exact same copy of the system classes and resources till EOL These preloaded objects live in the Zygote heap

bull This is what saves the time when apps are launched Also the memory saved is worth mentioning as no matter how many applications are started only one copy of the system classes and the resources is ever loaded in RAM

bull Personally I think the reason we still need Zygote (and cannot be replaced by system_server) is because we would like a process that does almost nothing other than fork() so that COW can do its magic Something like system_server would be counterproductive as its own heap and loaded classes would be huge

httpswwwlinkedincominsg1993 21georgeshibin1993gmailcom

ZYGOTEbull Thats pretty much what Zygote does during its lifetime Lets move onto system_server Notice the class name passed

as argument to Zygotersquos fork call for system_server

bull Just like in Zygotersquos case the AndroidRuntime knows how to execute the main() function in comandroidserverSystemServerjava

httpandroidxrefcom700_r1xrefframeworksbasecorejavacomandroidinternalosZygoteInitjava632

String args[] =

--setuid=1000

--setgid=1000

--setgroups=10011002100310041005100610071008100910101018102110323001300230033006300730093010

--capabilities= + capabilities + + capabilities

--nice-name=system_server

--runtime-args

comandroidserverSystemServer

httpandroidxrefcom700_r1xrefframeworksbaseservicesjavacomandroidserverSystemServerjava205

The main entry point from zygote

public static void main(String[] args)

new SystemServer()run()

httpswwwlinkedincominsg1993 22georgeshibin1993gmailcom

SYSTEM-SERVERbull The run() of system_server starts bootstrap-services core-services and some other services

bull Bootstrap-services are a small number of critical services

bull These are ActivityManagerService PowerManagerService DisplayManagerService PackageManagerService UserManagerService and sSensorService Bootstrap services are started almost together as they have internal dependencies with each other

bull Core services are some essential services that do not have dependencies on bootstrap services so can be started some time later One of these is the WindowManagerService

bull After that a couple of services which are not as critical as the above two classes Infact some of them even need not be started for device bootup

httpandroidxrefcom700_r1xrefframeworksbaseservicesjavacomandroidserverSystemServerjava320

try

TracetraceBegin(TraceTRACE_TAG_SYSTEM_SERVER StartServices)

startBootstrapServices()

startCoreServices()

startOtherServices()

httpswwwlinkedincominsg1993 23georgeshibin1993gmailcom

SYSTEM-SERVERbull Later down the line after starting almost all of the criticalcore services the system_server

(ie its main thread) proceeds to notify ActivityManagerService that the system is now ready to execute third-party code (read apps) The ActivityManagerService does some initializations before it can start applications

bull The callback reaches back to system_server main thread where it starts the first app comandroidsystemui here (specifically SystemUiService of systemui component)

bull We are now mostly done with this thread of system_server (the main thread mainly deals with handling messages from other components and redirecting them)

httpandroidxrefcom700_r1xrefframeworksbaseservicesjavacomandroidserverSystemServerjava1275

mActivityManagerServicesystemReady(new Runnable()

Override

public void run()

hellip

try

startSystemUi(context)

catch (Throwable e)

reportWtf(starting System UI e)

httpswwwlinkedincominsg1993 24georgeshibin1993gmailcom

BOOTANIMATION

bull Wondering what is being displayed on the screen during this entire process

bull After init starts what you see is bootanimation

bull The bootanim is a service that displays the bootanimation and is started by init

bull The rc file is parsed by init during startup But init does not start it right away (Notice the disabled)

bull This also means that someone has to explicitly start bootanim This is done by SurfaceFlinger in its init()

httpandroidxrefcom700_r1xrefframeworksbasecmdsbootanimationbootanimrc

service bootanim systembinbootanimation

class core

user graphics

group graphics audio

disabled

oneshot

httpandroidxrefcom700_r1xrefframeworksbaseservicesjavacomandroidserverSystemServerjava1275

start boot animation

startBootAnim()

httpandroidxrefcom700_r1xrefframeworksnativeservicessurfaceflingerSurfaceFlingercpp506

void SurfaceFlingerstartBootAnim()

start boot animation

property_set(servicebootanimexit 0)

property_set(ctlstart bootanim)

httpswwwlinkedincominsg1993 25georgeshibin1993gmailcom

BOOTANIMATION

bull Note that SF doesnrsquot directly spawnfork a process Rather it sets a property ctlstart to bootanim

bull ctl is special because there is no actual property named ctlstartstop (it wonrsquot appear in getprop output)

bull Note the special handling of a property if the property_name starts with ctl

httpandroidxrefcom700_r1xrefsystemcoreinitproperty_servicecpp280

case PROP_MSG_SETPROP

hellip

if(memcmp(msgnamectl4) == 0)

hellip

if (check_control_mac_perms(msgvalue source_ctx ampcr))

handle_control_message((char) msgname + 4 (char) msgvalue)

hellip

else

if (check_mac_perms(msgname source_ctx ampcr))

property_set((char) msgname (char) msgvalue)

hellip

httpswwwlinkedincominsg1993 26georgeshibin1993gmailcom

LAUNCHER

bull When the call reaches init it starts the service which is assigned to ctlstart

bull So when SF sets ctlstart to bootanim init starts the service bootanim

bull Bootanim gets the media files from systemmediabootanimationzip

bull But who stops bootanim Lets get back to system_server to find that out

bull Remember we informed ActivityManagerService that we are ready to executelaunch 3rd party codeapplications here

bull AMS on executing this calls startHomeActivityLocked() Internally this sends an Intent with category IntentCATEGORY_HOME This intent category is special because if an app registers for this intent it means that the application is a Launcher-appHome-screen replacement app

bull On receving this intent Launcher is started as it had registered for the same (see Manifest)

bull Ok Launcher has started but you are still not seeing it on the display

httpswwwlinkedincominsg1993 27georgeshibin1993gmailcom

LAUNCHERbull For Launcher to be displayed bootanimation has to be stopped There is only one entity that can tell SF to stop

bootanim via a binder transaction ie WindowManagerService WindowManagerServicersquosperformEnableScreen() API needs to be invoked

httpandroidxrefcom700_r1xrefframeworksbaseservicescorejavacomandroidserverwmWindowManagerServicejava5866

if (mBootAnimationStopped)

Do this one time

TraceasyncTraceBegin(TraceTRACE_TAG_WINDOW_MANAGER Stop bootanim 0)

try

IBinder surfaceFlinger = ServiceManagergetService(SurfaceFlinger)

if (surfaceFlinger = null)

Slogi(TAG_WM TELLING SURFACE FLINGER WE ARE BOOTED)

Parcel data = Parcelobtain()

datawriteInterfaceToken(androiduiISurfaceComposer)

surfaceFlingertransact(IBinderFIRST_CALL_TRANSACTION BOOT_FINISHED

data null 0)

datarecycle()

catch (RemoteException ex)

Sloge(TAG_WM Boot completed SurfaceFlinger is dead)

mBootAnimationStopped = true

httpswwwlinkedincominsg1993 28georgeshibin1993gmailcom

bull So SF receives a binder call from WindowManagerService with the code IBinderFIRST_CALL_TRANSACTION SurfaceFlinger Binder IPC interface has defined the following

bull The call ultimately reaches bootFinished()

httpandroidxrefcom700_r1xrefframeworksnativeincludeguiISurfaceComposerh177

Note BOOT_FINISHED must remain this value it is called from

Java by ActivityManagerService

BOOT_FINISHED = IBinderFIRST_CALL_TRANSACTION

httpandroidxrefcom700_r1xrefframeworksnativeservicessurfaceflingerSurfaceFlingercpp292

void SurfaceFlingerbootFinished()

hellip

ALOGI(Boot is finished (ld ms) long(ns2ms(duration)) )

mBootFinished = true

stop boot animation

formerly we would just kill the process but we now ask it to exit so it

can choose where to stop the animation

property_set(servicebootanimexit 1)

httpswwwlinkedincominsg1993 29georgeshibin1993gmailcom

BOOTANIMATION

bull SF sets the property serviebootanim to 1 How does this stop bootanim

bull All this while since the time it was started bootanim has been executing playAnimation()

bull While doing so it also periodically calls checkExit()

bull On detecting that this property is set to 1 bootanim gracefully exits

httpandroidxrefcom700_r1xrefframeworksbasecmdsbootanimationBootAnimationcpp387

Allow surface flinger to gracefully request shutdown

char value[PROPERTY_VALUE_MAX]

property_get(servicebootanimexit value 0)

int exitnow = atoi(value)

if (exitnow)

requestExit()

if (mAudioPlayer = NULL)

mAudioPlayer-gtrequestExit()

httpswwwlinkedincominsg1993 30georgeshibin1993gmailcom

BOOT_COMPLETEDbull WindowManager invoked binder transaction to tell SF to stop bootanim

bull After that it calls ActivityManagerrsquos bootAnimationComplete() function

bull In ActivityManagerService finishBooting() is invoked where the property sysboot_completed is set to 1 This property is important because it is the ldquoofficialrdquo way of letting native-servicesdaemons know that boot is now complete

bull After this AMS tells UserController (which is a helper class for handling multi-user functionality) to send the 2 criticalimportant intents

bull Before you unlockswipe the lock screen the intent IntentACTION_LOCKED_BOOT_COMPLETED is sent here

bull Once the user is unlocked (by entering PINswiping-the-lock screen) the intent IntentACTION_BOOT_COMPLETED is sent here This intent is important because it lets Java-services3rd-party apps know that system boot-up is now officially complete and that user is now in the home screen

httpandroidxrefcom700_r1xrefframeworksbaseservicescorejavacomandroidserverwmWindowManagerServicejav

a5899

try

mActivityManagerbootAnimationComplete()

catch (RemoteException e)

httpswwwlinkedincominsg1993 31georgeshibin1993gmailcom

Aaaaand you are now in Home screen

httpswwwlinkedincominsg1993 32georgeshibin1993gmailcom

REFERENCES

bull My highlights on Karim Yaghmourrsquos famous book (Embedded Android) httpswwwsafaribooksonlinecomu001o000000YZt6HAATembedded-android9781449327958

bull Kernel boot process

bull httpduartesorggustavoblogpostkernel-boot-process

bull https0xaxgitbooksiolinux-insidescontentInitializationlinux-initialization-4html

bull httposr507docxinuoscomenPERFORMprocess_stateshtml

bull httpstackoverflowcomquestions464483why-do-we-need-a-swapper-task-in-linux

bull httpunixstackexchangecomquestions83322which-process-has-pid-0

bull BinderServiceManager

bull httpwwwmacrobugcomblog20071215decoding-a-service-call-in-android

bull httpwwwcubridorgblogdev-platformbinder-communication-mechanism-of-android-processes

bull httpwwwprogrameringcomaMjMyMDMwATQhtml

And most importantly httpandroidxrefcom700_r1xref

httpswwwlinkedincominsg1993 33georgeshibin1993gmailcom

Thank You for reading this far

httpswwwlinkedincominsg1993 34

Disclaimer

Almost none (okay fine absolutely zilch) of the information that I put up is proprietary to Qualcomm Inc

Some of the source-code hyperlinks to Qualcommrsquos internal repository which is not accessible to others anyway

For all the other stuff I have provided Android-xref links and is openly accessible to all

However I wonrsquot vouch for the correctness of all information presented here Nope

You are welcome to correcteditpresent this material according to your needs

However it would be nice if you could shoot me a mail (at georgeshibin1993gmailcom) andor provide a

reference to the original material Just sayinghellip it would be nice

georgeshibin1993gmailcom

Page 4: Android bootup

ANDROID BOOTLOADERbull (L)ittle (K)ernel based Android bootloader

bull Android bootloader is developed on top of an open source project on kernelorg ndash named (L)ittle(K)ernel project

bull It does hardware initialization reading the Linux kernel amp ramdisk loading it up to RAM setting up initial registers and command line arguments for Linux kernel and jumps to the kernel

bull For normal bootup mode lk loads bootimg and for recovery mode it loads recoveryimg

bull UEFI-ABL is used as Bootloader for recent chipsets

httpswwwlinkedincominsg1993 4georgeshibin1993gmailcom

KERNEL BOOTUP PROCESS

bull Boot image is a raw partition ie there is no underlying filesystem like ext4FAT

bull Boot image(bootimg) = The kernel binary + ramdisk The bootloader loads kernel binary onto memory and then executes it

bull The first hardware independent piece of code that runs in kernel is start_kernel()

bull start_kernel() initializes various kernel subsystems and data structures These include the scheduler memory zones time keeping and so on

bull At the end of start_kernel() rest_init() is invoked

bull In rest_init() we start a kernel thread(kernel_init) that eventually becomes lsquoinitrsquo (with pid=1)

httpopengrokqualcommcomsourcexrefLAUM00kernelmsm-318initmainc396

static noinline void __init_refok rest_init(void)

int pid rcu_scheduler_starting()

smpboot_thread_init() s

We need to spawn init first so that it obtains pid 1 however

the init task will end up wanting to create kthreads which if

we schedule it before we create kthreadd will OOPS

kernel_thread(kernel_init NULL CLONE_FS)

httpswwwlinkedincominsg1993 5georgeshibin1993gmailcom

KERNEL BOOTUP PROCESS

bull Kernel_init at do_mountsc mounts ramdisk at lsquorsquo (root location) this is where init binary and other init scripts reside

bull This thread tries to execute init (thefirst user-mode process) in the following order init sbininit etcinit bininit and binsh If all fail kernel panics

bull But what happens to the thread that spawned init

bull That thread is known as the sched or swapper thread and has pid 0 (it does not appear in ps output but does appear as ppid of init) At the end of rest_init() this thread calls schedule() (to kickstart task scheduling) Then it enters idle loop here

httpopengrokqualcommcomsourcexrefLAUM00kernelmsm-318initmainc950

if (ramdisk_execute_command)

ret = run_init_process(ramdisk_execute_command)

We try each of these until one succeeds

The Bourne shell can be used instead of init if we are

trying to recover a really broken machine

if (try_to_run_init_process(sbininit) ||

try_to_run_init_process(etcinit) ||

try_to_run_init_process(bininit) ||

try_to_run_init_process(binsh))

return 0

panic(No working init found Try passing init= option to kernel

See Linux Documentationinittxt for guidance)

httpswwwlinkedincominsg1993 6georgeshibin1993gmailcom

bull The init processrsquos code resides here systemcoreinit

bull Basically all init does is the seemingly simple task of starting servicesdaemons and restarting some in case they are stopped It reads some configuration files ie rc files to figure out what to do when The rc files are written in initrsquos own language

bull The Android Init Language consists of five broad classes of statements - Actions Commands Services Options and Imports

INIT

httpswwwlinkedincominsg1993 7georgeshibin1993gmailcom

INIT RC FILE LINGObull Services are definitions of servicesdaemons etc that you want init to run

bull These are generally run when certain events are triggered

bull Options are modifiers to services Some important modifiers are-

bull critical ndash If it exits more than four times in four minutes the device will reboot into recovery mode (example critical)

bull disabled - This service will not automatically start with its class (ex bootanim)

bull socket ndash a socket at devsocketname will be created when the service starts (example devsocketzygote)

bull oneshot ndash Do not restart the service if it exits Most of important services will NOT have this modifier

bull class ndash 3 major classes of services ndash coremainlate-start

bull onrestart ndash execute the command following this when service restarts (example in zygotersquos rc onrestart restart cameraserver)

httpswwwlinkedincominsg1993 8georgeshibin1993gmailcom

INIT RC FILE LINGObull Triggers are strings which are used to match certain events

bull on ltpatterngt lthelliphellipgt - if the pattern is triggered by someone this is executed (ex on early-init)

bull on propertya=b ndash command is executed when property a is set to b

bull Commands are executed when predefined events are triggered (ie on lttriggergt)

bull trigger write chmod chown start stop restart setprop etc

bull Actions are of the form

bull For an action to be executed it is therefore necessary for an event to be triggered

bull Import statements are used to tell init to parse rc files present in different locations

on lttriggergt

ltcommandgt

ltcommandgt

ltcommandgt

httpswwwlinkedincominsg1993 9georgeshibin1993gmailcom

INIT

httpandroidxrefcom700_r1xrefsystemcorerootdirinitrc

on late-inittrigger early-fstrigger fstrigger post-fshelliptrigger early-boottrigger boot

on bootsetprop nettcpdefault_init_rwnd 60class_start core

httpswwwlinkedincominsg1993 10georgeshibin1993gmailcom

INITbull After some initial setup init first proceeds to parse initrc which is the primary rc file

bull All the other rc files are parsed using import statements in initrc

bull Once parsing is done to kickstart execution of servicesdaemons a few triggers have to be explicitly triggered by init itself

bull The first one of these is early-init

bull early-init is the cue to start ueventd for instance as defined in initrc

bull Init now has to start native daemonsservices like Surfaceflinger vold servicemanager healthd etc

httpandroidxrefcom700_r1xrefsystemcoreinitinitcpp688

parserParseConfig(initrc)

hellip

amQueueEventTrigger(early-init)

httpopengrokqualcommcomsourcexrefLAUM00systemcorerootdirinitrc13

on early-init

hellip

start ueventd

httpswwwlinkedincominsg1993 11georgeshibin1993gmailcom

INITbull Init also explicitly triggers event init and late-init When late-init is triggered it triggers event fs which is

when init parses fstab(qcom) entries to mount remaining partitions (system data misc) here

bull After that init basically runs in an infinite while loop on the lookout for services that might need restarting here

bull Among the services started by init one is particularly important for IPC to happen

bull Lets find out more about ServiceManager

httpopengrokqualcommcomsourcexrefLAUM00deviceqcommsm8937_64inittargetrc42

on fs

hellip

mount_all fstabqcom

httpswwwlinkedincominsg1993 12georgeshibin1993gmailcom

A LITTLE SOMETHING ABOUT SERVICEMANAGER

bull Binder is the core of Android and forms the foundation of the IPC mechanism

bull OpenBinder was developed by Be Inc (later Palm Inc) (Tidbit Palm Inc designed the worldrsquos first PDA and one of the first smartphones)

bull Google developed the Binder framework for Android on the basis of OpenBinder

bull OpenBinder allows processes to present interfaces which may be called by other threads Each process maintains a thread pool which may be used to service such requests

bull In OpenBinder an entity called context manager exists maintains all services handles and returns the service handle to client on request

httpswwwlinkedincominsg1993 13georgeshibin1993gmailcom

A LITTLE SOMETHING ABOUT SERVICEMANAGER

bull If a client wants to publishadd a service it has to invoke an entity called context manager If a client wants to get a reference to a service it again has to query the context manager

bull The Context Manager in Android is called the ServiceManager

bull Since ServiceManager is essential for IPC in android it is started as a ldquocriticalrdquo service

bull Source-code at - frameworksnativecmdsservicemanager

bull During initialization ServiceManager itself calls binder_become_context_manager() to inform the binder driver that it is the contextManager

httpswwwlinkedincominsg1993 14georgeshibin1993gmailcom

A LITTLE SOMETHING ABOUT SERVICEMANAGER

bull The kernel binder driver on receiving this ioctl creates a binder node 0

bull Once this is done clients can now query ServiceManager Internally this happens via ioctl(fd paramscmd=GET srv=ldquoSERVICE_NAMErdquo target=0 hellip)

httpopengrokqualcommcomsourcexrefLAUM00kernelmsm-

318driversstagingandroidbinderc2729

binder_context_mgr_node = binder_new_node(proc 0 0)

httpopengrokqualcommcomsourcexrefLAUM00frameworksnativecmdsservicemanagerbinder

c146

int binder_become_context_manager(struct binder_state bs)

return ioctl(bs-gtfd BINDER_SET_CONTEXT_MGR 0)

httpswwwlinkedincominsg1993 15georgeshibin1993gmailcom

A LITTLE SOMETHING ABOUT SERVICEMANAGER01-01 071603022 0 0 I init Starting service ueventd

01-01 071604958 0 0 I init Starting service logd

01-01 071606345 0 0 I init Starting service vold

01-01 071606871 0 0 I init Starting service exec 1 (systembintzdatacheck)

01-01 071608191 0 0 I init Starting service exec 2 (initqcomearly_bootsh)

01-01 071609225 0 0 I init Starting service healthd

01-01 071609290 0 0 I init Starting service cs-early-boot

01-01 071609296 0 0 I init Starting service esepmdaemon

01-01 071609302 0 0 I init Starting service qcom-usb-sh

01-01 071609309 0 0 I init Starting service qseecomd

01-01 071609315 0 0 I init Starting service per_mgr

01-01 071609321 0 0 I init Starting service lmkd

01-01 071609327 0 0 I init Starting service servicemanager01-01 071609335 0 0 I init Starting service surfaceflinger

01-01 071610101 0 0 I init Starting service bootanim

01-01 071612563 0 0 I init Starting service logd-reinit

01-01 071612777 0 0 I init Starting service exec 4 (systembintzdatacheck)

01-01 071612903 0 0 I init Starting service carrier_switcher

01-01 071612911 0 0 I init Starting service exec 5 (systembinbootstat)

01-01 071612977 0 0 I init Starting service qcomsysd

01-01 071612983 0 0 I init Starting service qcom-c_main-sh

01-01 071612990 0 0 I init Starting service cnd

01-01 071612996 0 0 I init Starting service ptt_socket_app

01-01 071613002 0 0 I init Starting service cnss_diag

01-01 071613028 0 0 I init Starting service thermal-engine

01-01 071613034 0 0 I init Starting service wcnss-service

01-01 071613041 0 0 I init Starting service imsstarter

01-01 071613048 0 0 I init Starting service adsprpcd

01-01 071613054 0 0 I init Starting service hvdcp_opti

01-01 071613062 0 0 I init Starting service zygote01-01 071613069 0 0 I init Starting service zygote_secondary

httpswwwlinkedincominsg1993 16georgeshibin1993gmailcom

INITZYGOTE - STARTUP

bull Just like init is parent of all init-services system-server amp every app is spawned by zygote An executable called app_process(3264) is executed which is then known to others as zygote

bull It belongs to main class of services ie if userdata-encryption is enabled once you enter password zygote is restarted

httpandroidxrefcom700_r1xrefsystemcorerootdirinitzygote64_32rc

service zygote systembinapp_process64 -Xzygote systembin --zygote --start-system-server --socket-name=zygote

class main

socket zygote stream 660 root system

onrestart write sysandroid_powerrequest_state wake

onrestart write syspowerstate on

onrestart restart audioserver

onrestart restart cameraserver

onrestart restart media

onrestart restart netd

writepid devcpusetforegroundtasks sysfscgroupstuneforegroundtasks

service zygote_secondary systembinapp_process32 -Xzygote systembin --zygote --socket-name=zygote_secondary

class main

socket zygote_secondary stream 660 root system

onrestart restart zygote

writepid devcpusetforegroundtasks devstuneforegroundtasks

httpswwwlinkedincominsg1993 17georgeshibin1993gmailcom

ZYGOTE

bull App_process is a native proc (written in C++) Source for app_process resides here

bull ndashzygote option passed is to rename the process name from app_process to zygote here

bull comandroidinternalosZygoteInitjava is called (through runtimestart()) which starts systemServer and then polls

bull ndashstart-system_server option passed makes the zygote spawn system_server

bull Zygote uses an entity called ldquoAndroidRuntimerdquo that starts a VM to run Java Runtimestart() starts a new virtual machine As you know all code written in Java runs in a VM

bull Interesting tidbit the main() of ZygoteInitjava is the first piece of Java code that runs since the device was turned on (Reason is that this is the first time VM was created and java bytecode runs in VM)

httpandroidxrefcom700_r1xrefframeworksbasecmdsapp_processapp_maincpp306

if (zygote)

runtimestart(comandroidinternalosZygoteInit args zygote)

httpandroidxrefcom700_r1xrefframeworksbasecorejavacomandroidinternalosZygoteInitjava746

if (startSystemServer)

startSystemServer(abiList socketName)

httpswwwlinkedincominsg1993 18georgeshibin1993gmailcom

ZYGOTE

bull The most important reason behind Zygotersquos existence can be summarized in this one line of code

bull Zygote preloads classes (as in java class files) resources some shared libraries (so files) etc

bull You can find the list of these classes to be preloaded here on your device at systemetcpreloaded-classes Zygote reads this file here

bull On my device running Android Nougat the total number of preloaded classes alone is 4165 to be exact

httpandroidxrefcom700_r1xrefframeworksbasecorejavacomandroidinternalosZygoteInitjava722

preload()

httpswwwlinkedincominsg1993 19georgeshibin1993gmailcom

ZYGOTE

bull So how exactly is preloading helping

bull To know this we come back to one of the important tasks of zygote ie spawning each and every single application process (remember it is the parent process of all application processes)

bull After starting system_server zygote runs in an infinite while loop here

bull It keeps on polling a socket ndash devsocketzygote When you launch an application the request to create a new process comes from system_server to Zygote on this socket The call reaches hereand then it executes a fork system call as shown below

httpandroidxrefcom700_r1xrefframeworksbasecorejavacomandroidinternalosZygoteConnectionjava225

pid = ZygoteforkAndSpecialize(parsedArgsuid parsedArgsgid parsedArgsgids

parsedArgsdebugFlags rlimits parsedArgsmountExternal parsedArgsseInfo

parsedArgsniceName fdsToClose parsedArgsinstructionSet

parsedArgsappDataDir)

httpswwwlinkedincominsg1993 20georgeshibin1993gmailcom

ZYGOTEbull Here is where you will appreciate the virtue of a great design

bull When a process forks it creates a clone of itself It replicates itself in another memory space When this happens to Zygote it creates a clean new Dalvik VM preloaded with all necessary classes and resources that any App will need (the same 4165 I mentioned earlier)

bull Except that it is never copied

bull You see the Linux Kernel implements a strategy called Copy On Write (COW) With COW Linux doesnrsquot actually copy anything Instead it maps the pages of the new process over to those of the parent process and makes copies only when the new process writes to a page But the classeslibrariesresources preloaded by Zygote are all read-only and not modified by any application This means that all processes forked from Zygote are using the exact same copy of the system classes and resources till EOL These preloaded objects live in the Zygote heap

bull This is what saves the time when apps are launched Also the memory saved is worth mentioning as no matter how many applications are started only one copy of the system classes and the resources is ever loaded in RAM

bull Personally I think the reason we still need Zygote (and cannot be replaced by system_server) is because we would like a process that does almost nothing other than fork() so that COW can do its magic Something like system_server would be counterproductive as its own heap and loaded classes would be huge

httpswwwlinkedincominsg1993 21georgeshibin1993gmailcom

ZYGOTEbull Thats pretty much what Zygote does during its lifetime Lets move onto system_server Notice the class name passed

as argument to Zygotersquos fork call for system_server

bull Just like in Zygotersquos case the AndroidRuntime knows how to execute the main() function in comandroidserverSystemServerjava

httpandroidxrefcom700_r1xrefframeworksbasecorejavacomandroidinternalosZygoteInitjava632

String args[] =

--setuid=1000

--setgid=1000

--setgroups=10011002100310041005100610071008100910101018102110323001300230033006300730093010

--capabilities= + capabilities + + capabilities

--nice-name=system_server

--runtime-args

comandroidserverSystemServer

httpandroidxrefcom700_r1xrefframeworksbaseservicesjavacomandroidserverSystemServerjava205

The main entry point from zygote

public static void main(String[] args)

new SystemServer()run()

httpswwwlinkedincominsg1993 22georgeshibin1993gmailcom

SYSTEM-SERVERbull The run() of system_server starts bootstrap-services core-services and some other services

bull Bootstrap-services are a small number of critical services

bull These are ActivityManagerService PowerManagerService DisplayManagerService PackageManagerService UserManagerService and sSensorService Bootstrap services are started almost together as they have internal dependencies with each other

bull Core services are some essential services that do not have dependencies on bootstrap services so can be started some time later One of these is the WindowManagerService

bull After that a couple of services which are not as critical as the above two classes Infact some of them even need not be started for device bootup

httpandroidxrefcom700_r1xrefframeworksbaseservicesjavacomandroidserverSystemServerjava320

try

TracetraceBegin(TraceTRACE_TAG_SYSTEM_SERVER StartServices)

startBootstrapServices()

startCoreServices()

startOtherServices()

httpswwwlinkedincominsg1993 23georgeshibin1993gmailcom

SYSTEM-SERVERbull Later down the line after starting almost all of the criticalcore services the system_server

(ie its main thread) proceeds to notify ActivityManagerService that the system is now ready to execute third-party code (read apps) The ActivityManagerService does some initializations before it can start applications

bull The callback reaches back to system_server main thread where it starts the first app comandroidsystemui here (specifically SystemUiService of systemui component)

bull We are now mostly done with this thread of system_server (the main thread mainly deals with handling messages from other components and redirecting them)

httpandroidxrefcom700_r1xrefframeworksbaseservicesjavacomandroidserverSystemServerjava1275

mActivityManagerServicesystemReady(new Runnable()

Override

public void run()

hellip

try

startSystemUi(context)

catch (Throwable e)

reportWtf(starting System UI e)

httpswwwlinkedincominsg1993 24georgeshibin1993gmailcom

BOOTANIMATION

bull Wondering what is being displayed on the screen during this entire process

bull After init starts what you see is bootanimation

bull The bootanim is a service that displays the bootanimation and is started by init

bull The rc file is parsed by init during startup But init does not start it right away (Notice the disabled)

bull This also means that someone has to explicitly start bootanim This is done by SurfaceFlinger in its init()

httpandroidxrefcom700_r1xrefframeworksbasecmdsbootanimationbootanimrc

service bootanim systembinbootanimation

class core

user graphics

group graphics audio

disabled

oneshot

httpandroidxrefcom700_r1xrefframeworksbaseservicesjavacomandroidserverSystemServerjava1275

start boot animation

startBootAnim()

httpandroidxrefcom700_r1xrefframeworksnativeservicessurfaceflingerSurfaceFlingercpp506

void SurfaceFlingerstartBootAnim()

start boot animation

property_set(servicebootanimexit 0)

property_set(ctlstart bootanim)

httpswwwlinkedincominsg1993 25georgeshibin1993gmailcom

BOOTANIMATION

bull Note that SF doesnrsquot directly spawnfork a process Rather it sets a property ctlstart to bootanim

bull ctl is special because there is no actual property named ctlstartstop (it wonrsquot appear in getprop output)

bull Note the special handling of a property if the property_name starts with ctl

httpandroidxrefcom700_r1xrefsystemcoreinitproperty_servicecpp280

case PROP_MSG_SETPROP

hellip

if(memcmp(msgnamectl4) == 0)

hellip

if (check_control_mac_perms(msgvalue source_ctx ampcr))

handle_control_message((char) msgname + 4 (char) msgvalue)

hellip

else

if (check_mac_perms(msgname source_ctx ampcr))

property_set((char) msgname (char) msgvalue)

hellip

httpswwwlinkedincominsg1993 26georgeshibin1993gmailcom

LAUNCHER

bull When the call reaches init it starts the service which is assigned to ctlstart

bull So when SF sets ctlstart to bootanim init starts the service bootanim

bull Bootanim gets the media files from systemmediabootanimationzip

bull But who stops bootanim Lets get back to system_server to find that out

bull Remember we informed ActivityManagerService that we are ready to executelaunch 3rd party codeapplications here

bull AMS on executing this calls startHomeActivityLocked() Internally this sends an Intent with category IntentCATEGORY_HOME This intent category is special because if an app registers for this intent it means that the application is a Launcher-appHome-screen replacement app

bull On receving this intent Launcher is started as it had registered for the same (see Manifest)

bull Ok Launcher has started but you are still not seeing it on the display

httpswwwlinkedincominsg1993 27georgeshibin1993gmailcom

LAUNCHERbull For Launcher to be displayed bootanimation has to be stopped There is only one entity that can tell SF to stop

bootanim via a binder transaction ie WindowManagerService WindowManagerServicersquosperformEnableScreen() API needs to be invoked

httpandroidxrefcom700_r1xrefframeworksbaseservicescorejavacomandroidserverwmWindowManagerServicejava5866

if (mBootAnimationStopped)

Do this one time

TraceasyncTraceBegin(TraceTRACE_TAG_WINDOW_MANAGER Stop bootanim 0)

try

IBinder surfaceFlinger = ServiceManagergetService(SurfaceFlinger)

if (surfaceFlinger = null)

Slogi(TAG_WM TELLING SURFACE FLINGER WE ARE BOOTED)

Parcel data = Parcelobtain()

datawriteInterfaceToken(androiduiISurfaceComposer)

surfaceFlingertransact(IBinderFIRST_CALL_TRANSACTION BOOT_FINISHED

data null 0)

datarecycle()

catch (RemoteException ex)

Sloge(TAG_WM Boot completed SurfaceFlinger is dead)

mBootAnimationStopped = true

httpswwwlinkedincominsg1993 28georgeshibin1993gmailcom

bull So SF receives a binder call from WindowManagerService with the code IBinderFIRST_CALL_TRANSACTION SurfaceFlinger Binder IPC interface has defined the following

bull The call ultimately reaches bootFinished()

httpandroidxrefcom700_r1xrefframeworksnativeincludeguiISurfaceComposerh177

Note BOOT_FINISHED must remain this value it is called from

Java by ActivityManagerService

BOOT_FINISHED = IBinderFIRST_CALL_TRANSACTION

httpandroidxrefcom700_r1xrefframeworksnativeservicessurfaceflingerSurfaceFlingercpp292

void SurfaceFlingerbootFinished()

hellip

ALOGI(Boot is finished (ld ms) long(ns2ms(duration)) )

mBootFinished = true

stop boot animation

formerly we would just kill the process but we now ask it to exit so it

can choose where to stop the animation

property_set(servicebootanimexit 1)

httpswwwlinkedincominsg1993 29georgeshibin1993gmailcom

BOOTANIMATION

bull SF sets the property serviebootanim to 1 How does this stop bootanim

bull All this while since the time it was started bootanim has been executing playAnimation()

bull While doing so it also periodically calls checkExit()

bull On detecting that this property is set to 1 bootanim gracefully exits

httpandroidxrefcom700_r1xrefframeworksbasecmdsbootanimationBootAnimationcpp387

Allow surface flinger to gracefully request shutdown

char value[PROPERTY_VALUE_MAX]

property_get(servicebootanimexit value 0)

int exitnow = atoi(value)

if (exitnow)

requestExit()

if (mAudioPlayer = NULL)

mAudioPlayer-gtrequestExit()

httpswwwlinkedincominsg1993 30georgeshibin1993gmailcom

BOOT_COMPLETEDbull WindowManager invoked binder transaction to tell SF to stop bootanim

bull After that it calls ActivityManagerrsquos bootAnimationComplete() function

bull In ActivityManagerService finishBooting() is invoked where the property sysboot_completed is set to 1 This property is important because it is the ldquoofficialrdquo way of letting native-servicesdaemons know that boot is now complete

bull After this AMS tells UserController (which is a helper class for handling multi-user functionality) to send the 2 criticalimportant intents

bull Before you unlockswipe the lock screen the intent IntentACTION_LOCKED_BOOT_COMPLETED is sent here

bull Once the user is unlocked (by entering PINswiping-the-lock screen) the intent IntentACTION_BOOT_COMPLETED is sent here This intent is important because it lets Java-services3rd-party apps know that system boot-up is now officially complete and that user is now in the home screen

httpandroidxrefcom700_r1xrefframeworksbaseservicescorejavacomandroidserverwmWindowManagerServicejav

a5899

try

mActivityManagerbootAnimationComplete()

catch (RemoteException e)

httpswwwlinkedincominsg1993 31georgeshibin1993gmailcom

Aaaaand you are now in Home screen

httpswwwlinkedincominsg1993 32georgeshibin1993gmailcom

REFERENCES

bull My highlights on Karim Yaghmourrsquos famous book (Embedded Android) httpswwwsafaribooksonlinecomu001o000000YZt6HAATembedded-android9781449327958

bull Kernel boot process

bull httpduartesorggustavoblogpostkernel-boot-process

bull https0xaxgitbooksiolinux-insidescontentInitializationlinux-initialization-4html

bull httposr507docxinuoscomenPERFORMprocess_stateshtml

bull httpstackoverflowcomquestions464483why-do-we-need-a-swapper-task-in-linux

bull httpunixstackexchangecomquestions83322which-process-has-pid-0

bull BinderServiceManager

bull httpwwwmacrobugcomblog20071215decoding-a-service-call-in-android

bull httpwwwcubridorgblogdev-platformbinder-communication-mechanism-of-android-processes

bull httpwwwprogrameringcomaMjMyMDMwATQhtml

And most importantly httpandroidxrefcom700_r1xref

httpswwwlinkedincominsg1993 33georgeshibin1993gmailcom

Thank You for reading this far

httpswwwlinkedincominsg1993 34

Disclaimer

Almost none (okay fine absolutely zilch) of the information that I put up is proprietary to Qualcomm Inc

Some of the source-code hyperlinks to Qualcommrsquos internal repository which is not accessible to others anyway

For all the other stuff I have provided Android-xref links and is openly accessible to all

However I wonrsquot vouch for the correctness of all information presented here Nope

You are welcome to correcteditpresent this material according to your needs

However it would be nice if you could shoot me a mail (at georgeshibin1993gmailcom) andor provide a

reference to the original material Just sayinghellip it would be nice

georgeshibin1993gmailcom

Page 5: Android bootup

KERNEL BOOTUP PROCESS

bull Boot image is a raw partition ie there is no underlying filesystem like ext4FAT

bull Boot image(bootimg) = The kernel binary + ramdisk The bootloader loads kernel binary onto memory and then executes it

bull The first hardware independent piece of code that runs in kernel is start_kernel()

bull start_kernel() initializes various kernel subsystems and data structures These include the scheduler memory zones time keeping and so on

bull At the end of start_kernel() rest_init() is invoked

bull In rest_init() we start a kernel thread(kernel_init) that eventually becomes lsquoinitrsquo (with pid=1)

httpopengrokqualcommcomsourcexrefLAUM00kernelmsm-318initmainc396

static noinline void __init_refok rest_init(void)

int pid rcu_scheduler_starting()

smpboot_thread_init() s

We need to spawn init first so that it obtains pid 1 however

the init task will end up wanting to create kthreads which if

we schedule it before we create kthreadd will OOPS

kernel_thread(kernel_init NULL CLONE_FS)

httpswwwlinkedincominsg1993 5georgeshibin1993gmailcom

KERNEL BOOTUP PROCESS

bull Kernel_init at do_mountsc mounts ramdisk at lsquorsquo (root location) this is where init binary and other init scripts reside

bull This thread tries to execute init (thefirst user-mode process) in the following order init sbininit etcinit bininit and binsh If all fail kernel panics

bull But what happens to the thread that spawned init

bull That thread is known as the sched or swapper thread and has pid 0 (it does not appear in ps output but does appear as ppid of init) At the end of rest_init() this thread calls schedule() (to kickstart task scheduling) Then it enters idle loop here

httpopengrokqualcommcomsourcexrefLAUM00kernelmsm-318initmainc950

if (ramdisk_execute_command)

ret = run_init_process(ramdisk_execute_command)

We try each of these until one succeeds

The Bourne shell can be used instead of init if we are

trying to recover a really broken machine

if (try_to_run_init_process(sbininit) ||

try_to_run_init_process(etcinit) ||

try_to_run_init_process(bininit) ||

try_to_run_init_process(binsh))

return 0

panic(No working init found Try passing init= option to kernel

See Linux Documentationinittxt for guidance)

httpswwwlinkedincominsg1993 6georgeshibin1993gmailcom

bull The init processrsquos code resides here systemcoreinit

bull Basically all init does is the seemingly simple task of starting servicesdaemons and restarting some in case they are stopped It reads some configuration files ie rc files to figure out what to do when The rc files are written in initrsquos own language

bull The Android Init Language consists of five broad classes of statements - Actions Commands Services Options and Imports

INIT

httpswwwlinkedincominsg1993 7georgeshibin1993gmailcom

INIT RC FILE LINGObull Services are definitions of servicesdaemons etc that you want init to run

bull These are generally run when certain events are triggered

bull Options are modifiers to services Some important modifiers are-

bull critical ndash If it exits more than four times in four minutes the device will reboot into recovery mode (example critical)

bull disabled - This service will not automatically start with its class (ex bootanim)

bull socket ndash a socket at devsocketname will be created when the service starts (example devsocketzygote)

bull oneshot ndash Do not restart the service if it exits Most of important services will NOT have this modifier

bull class ndash 3 major classes of services ndash coremainlate-start

bull onrestart ndash execute the command following this when service restarts (example in zygotersquos rc onrestart restart cameraserver)

httpswwwlinkedincominsg1993 8georgeshibin1993gmailcom

INIT RC FILE LINGObull Triggers are strings which are used to match certain events

bull on ltpatterngt lthelliphellipgt - if the pattern is triggered by someone this is executed (ex on early-init)

bull on propertya=b ndash command is executed when property a is set to b

bull Commands are executed when predefined events are triggered (ie on lttriggergt)

bull trigger write chmod chown start stop restart setprop etc

bull Actions are of the form

bull For an action to be executed it is therefore necessary for an event to be triggered

bull Import statements are used to tell init to parse rc files present in different locations

on lttriggergt

ltcommandgt

ltcommandgt

ltcommandgt

httpswwwlinkedincominsg1993 9georgeshibin1993gmailcom

INIT

httpandroidxrefcom700_r1xrefsystemcorerootdirinitrc

on late-inittrigger early-fstrigger fstrigger post-fshelliptrigger early-boottrigger boot

on bootsetprop nettcpdefault_init_rwnd 60class_start core

httpswwwlinkedincominsg1993 10georgeshibin1993gmailcom

INITbull After some initial setup init first proceeds to parse initrc which is the primary rc file

bull All the other rc files are parsed using import statements in initrc

bull Once parsing is done to kickstart execution of servicesdaemons a few triggers have to be explicitly triggered by init itself

bull The first one of these is early-init

bull early-init is the cue to start ueventd for instance as defined in initrc

bull Init now has to start native daemonsservices like Surfaceflinger vold servicemanager healthd etc

httpandroidxrefcom700_r1xrefsystemcoreinitinitcpp688

parserParseConfig(initrc)

hellip

amQueueEventTrigger(early-init)

httpopengrokqualcommcomsourcexrefLAUM00systemcorerootdirinitrc13

on early-init

hellip

start ueventd

httpswwwlinkedincominsg1993 11georgeshibin1993gmailcom

INITbull Init also explicitly triggers event init and late-init When late-init is triggered it triggers event fs which is

when init parses fstab(qcom) entries to mount remaining partitions (system data misc) here

bull After that init basically runs in an infinite while loop on the lookout for services that might need restarting here

bull Among the services started by init one is particularly important for IPC to happen

bull Lets find out more about ServiceManager

httpopengrokqualcommcomsourcexrefLAUM00deviceqcommsm8937_64inittargetrc42

on fs

hellip

mount_all fstabqcom

httpswwwlinkedincominsg1993 12georgeshibin1993gmailcom

A LITTLE SOMETHING ABOUT SERVICEMANAGER

bull Binder is the core of Android and forms the foundation of the IPC mechanism

bull OpenBinder was developed by Be Inc (later Palm Inc) (Tidbit Palm Inc designed the worldrsquos first PDA and one of the first smartphones)

bull Google developed the Binder framework for Android on the basis of OpenBinder

bull OpenBinder allows processes to present interfaces which may be called by other threads Each process maintains a thread pool which may be used to service such requests

bull In OpenBinder an entity called context manager exists maintains all services handles and returns the service handle to client on request

httpswwwlinkedincominsg1993 13georgeshibin1993gmailcom

A LITTLE SOMETHING ABOUT SERVICEMANAGER

bull If a client wants to publishadd a service it has to invoke an entity called context manager If a client wants to get a reference to a service it again has to query the context manager

bull The Context Manager in Android is called the ServiceManager

bull Since ServiceManager is essential for IPC in android it is started as a ldquocriticalrdquo service

bull Source-code at - frameworksnativecmdsservicemanager

bull During initialization ServiceManager itself calls binder_become_context_manager() to inform the binder driver that it is the contextManager

httpswwwlinkedincominsg1993 14georgeshibin1993gmailcom

A LITTLE SOMETHING ABOUT SERVICEMANAGER

bull The kernel binder driver on receiving this ioctl creates a binder node 0

bull Once this is done clients can now query ServiceManager Internally this happens via ioctl(fd paramscmd=GET srv=ldquoSERVICE_NAMErdquo target=0 hellip)

httpopengrokqualcommcomsourcexrefLAUM00kernelmsm-

318driversstagingandroidbinderc2729

binder_context_mgr_node = binder_new_node(proc 0 0)

httpopengrokqualcommcomsourcexrefLAUM00frameworksnativecmdsservicemanagerbinder

c146

int binder_become_context_manager(struct binder_state bs)

return ioctl(bs-gtfd BINDER_SET_CONTEXT_MGR 0)

httpswwwlinkedincominsg1993 15georgeshibin1993gmailcom

A LITTLE SOMETHING ABOUT SERVICEMANAGER01-01 071603022 0 0 I init Starting service ueventd

01-01 071604958 0 0 I init Starting service logd

01-01 071606345 0 0 I init Starting service vold

01-01 071606871 0 0 I init Starting service exec 1 (systembintzdatacheck)

01-01 071608191 0 0 I init Starting service exec 2 (initqcomearly_bootsh)

01-01 071609225 0 0 I init Starting service healthd

01-01 071609290 0 0 I init Starting service cs-early-boot

01-01 071609296 0 0 I init Starting service esepmdaemon

01-01 071609302 0 0 I init Starting service qcom-usb-sh

01-01 071609309 0 0 I init Starting service qseecomd

01-01 071609315 0 0 I init Starting service per_mgr

01-01 071609321 0 0 I init Starting service lmkd

01-01 071609327 0 0 I init Starting service servicemanager01-01 071609335 0 0 I init Starting service surfaceflinger

01-01 071610101 0 0 I init Starting service bootanim

01-01 071612563 0 0 I init Starting service logd-reinit

01-01 071612777 0 0 I init Starting service exec 4 (systembintzdatacheck)

01-01 071612903 0 0 I init Starting service carrier_switcher

01-01 071612911 0 0 I init Starting service exec 5 (systembinbootstat)

01-01 071612977 0 0 I init Starting service qcomsysd

01-01 071612983 0 0 I init Starting service qcom-c_main-sh

01-01 071612990 0 0 I init Starting service cnd

01-01 071612996 0 0 I init Starting service ptt_socket_app

01-01 071613002 0 0 I init Starting service cnss_diag

01-01 071613028 0 0 I init Starting service thermal-engine

01-01 071613034 0 0 I init Starting service wcnss-service

01-01 071613041 0 0 I init Starting service imsstarter

01-01 071613048 0 0 I init Starting service adsprpcd

01-01 071613054 0 0 I init Starting service hvdcp_opti

01-01 071613062 0 0 I init Starting service zygote01-01 071613069 0 0 I init Starting service zygote_secondary

httpswwwlinkedincominsg1993 16georgeshibin1993gmailcom

INITZYGOTE - STARTUP

bull Just like init is parent of all init-services system-server amp every app is spawned by zygote An executable called app_process(3264) is executed which is then known to others as zygote

bull It belongs to main class of services ie if userdata-encryption is enabled once you enter password zygote is restarted

httpandroidxrefcom700_r1xrefsystemcorerootdirinitzygote64_32rc

service zygote systembinapp_process64 -Xzygote systembin --zygote --start-system-server --socket-name=zygote

class main

socket zygote stream 660 root system

onrestart write sysandroid_powerrequest_state wake

onrestart write syspowerstate on

onrestart restart audioserver

onrestart restart cameraserver

onrestart restart media

onrestart restart netd

writepid devcpusetforegroundtasks sysfscgroupstuneforegroundtasks

service zygote_secondary systembinapp_process32 -Xzygote systembin --zygote --socket-name=zygote_secondary

class main

socket zygote_secondary stream 660 root system

onrestart restart zygote

writepid devcpusetforegroundtasks devstuneforegroundtasks

httpswwwlinkedincominsg1993 17georgeshibin1993gmailcom

ZYGOTE

bull App_process is a native proc (written in C++) Source for app_process resides here

bull ndashzygote option passed is to rename the process name from app_process to zygote here

bull comandroidinternalosZygoteInitjava is called (through runtimestart()) which starts systemServer and then polls

bull ndashstart-system_server option passed makes the zygote spawn system_server

bull Zygote uses an entity called ldquoAndroidRuntimerdquo that starts a VM to run Java Runtimestart() starts a new virtual machine As you know all code written in Java runs in a VM

bull Interesting tidbit the main() of ZygoteInitjava is the first piece of Java code that runs since the device was turned on (Reason is that this is the first time VM was created and java bytecode runs in VM)

httpandroidxrefcom700_r1xrefframeworksbasecmdsapp_processapp_maincpp306

if (zygote)

runtimestart(comandroidinternalosZygoteInit args zygote)

httpandroidxrefcom700_r1xrefframeworksbasecorejavacomandroidinternalosZygoteInitjava746

if (startSystemServer)

startSystemServer(abiList socketName)

httpswwwlinkedincominsg1993 18georgeshibin1993gmailcom

ZYGOTE

bull The most important reason behind Zygotersquos existence can be summarized in this one line of code

bull Zygote preloads classes (as in java class files) resources some shared libraries (so files) etc

bull You can find the list of these classes to be preloaded here on your device at systemetcpreloaded-classes Zygote reads this file here

bull On my device running Android Nougat the total number of preloaded classes alone is 4165 to be exact

httpandroidxrefcom700_r1xrefframeworksbasecorejavacomandroidinternalosZygoteInitjava722

preload()

httpswwwlinkedincominsg1993 19georgeshibin1993gmailcom

ZYGOTE

bull So how exactly is preloading helping

bull To know this we come back to one of the important tasks of zygote ie spawning each and every single application process (remember it is the parent process of all application processes)

bull After starting system_server zygote runs in an infinite while loop here

bull It keeps on polling a socket ndash devsocketzygote When you launch an application the request to create a new process comes from system_server to Zygote on this socket The call reaches hereand then it executes a fork system call as shown below

httpandroidxrefcom700_r1xrefframeworksbasecorejavacomandroidinternalosZygoteConnectionjava225

pid = ZygoteforkAndSpecialize(parsedArgsuid parsedArgsgid parsedArgsgids

parsedArgsdebugFlags rlimits parsedArgsmountExternal parsedArgsseInfo

parsedArgsniceName fdsToClose parsedArgsinstructionSet

parsedArgsappDataDir)

httpswwwlinkedincominsg1993 20georgeshibin1993gmailcom

ZYGOTEbull Here is where you will appreciate the virtue of a great design

bull When a process forks it creates a clone of itself It replicates itself in another memory space When this happens to Zygote it creates a clean new Dalvik VM preloaded with all necessary classes and resources that any App will need (the same 4165 I mentioned earlier)

bull Except that it is never copied

bull You see the Linux Kernel implements a strategy called Copy On Write (COW) With COW Linux doesnrsquot actually copy anything Instead it maps the pages of the new process over to those of the parent process and makes copies only when the new process writes to a page But the classeslibrariesresources preloaded by Zygote are all read-only and not modified by any application This means that all processes forked from Zygote are using the exact same copy of the system classes and resources till EOL These preloaded objects live in the Zygote heap

bull This is what saves the time when apps are launched Also the memory saved is worth mentioning as no matter how many applications are started only one copy of the system classes and the resources is ever loaded in RAM

bull Personally I think the reason we still need Zygote (and cannot be replaced by system_server) is because we would like a process that does almost nothing other than fork() so that COW can do its magic Something like system_server would be counterproductive as its own heap and loaded classes would be huge

httpswwwlinkedincominsg1993 21georgeshibin1993gmailcom

ZYGOTEbull Thats pretty much what Zygote does during its lifetime Lets move onto system_server Notice the class name passed

as argument to Zygotersquos fork call for system_server

bull Just like in Zygotersquos case the AndroidRuntime knows how to execute the main() function in comandroidserverSystemServerjava

httpandroidxrefcom700_r1xrefframeworksbasecorejavacomandroidinternalosZygoteInitjava632

String args[] =

--setuid=1000

--setgid=1000

--setgroups=10011002100310041005100610071008100910101018102110323001300230033006300730093010

--capabilities= + capabilities + + capabilities

--nice-name=system_server

--runtime-args

comandroidserverSystemServer

httpandroidxrefcom700_r1xrefframeworksbaseservicesjavacomandroidserverSystemServerjava205

The main entry point from zygote

public static void main(String[] args)

new SystemServer()run()

httpswwwlinkedincominsg1993 22georgeshibin1993gmailcom

SYSTEM-SERVERbull The run() of system_server starts bootstrap-services core-services and some other services

bull Bootstrap-services are a small number of critical services

bull These are ActivityManagerService PowerManagerService DisplayManagerService PackageManagerService UserManagerService and sSensorService Bootstrap services are started almost together as they have internal dependencies with each other

bull Core services are some essential services that do not have dependencies on bootstrap services so can be started some time later One of these is the WindowManagerService

bull After that a couple of services which are not as critical as the above two classes Infact some of them even need not be started for device bootup

httpandroidxrefcom700_r1xrefframeworksbaseservicesjavacomandroidserverSystemServerjava320

try

TracetraceBegin(TraceTRACE_TAG_SYSTEM_SERVER StartServices)

startBootstrapServices()

startCoreServices()

startOtherServices()

httpswwwlinkedincominsg1993 23georgeshibin1993gmailcom

SYSTEM-SERVERbull Later down the line after starting almost all of the criticalcore services the system_server

(ie its main thread) proceeds to notify ActivityManagerService that the system is now ready to execute third-party code (read apps) The ActivityManagerService does some initializations before it can start applications

bull The callback reaches back to system_server main thread where it starts the first app comandroidsystemui here (specifically SystemUiService of systemui component)

bull We are now mostly done with this thread of system_server (the main thread mainly deals with handling messages from other components and redirecting them)

httpandroidxrefcom700_r1xrefframeworksbaseservicesjavacomandroidserverSystemServerjava1275

mActivityManagerServicesystemReady(new Runnable()

Override

public void run()

hellip

try

startSystemUi(context)

catch (Throwable e)

reportWtf(starting System UI e)

httpswwwlinkedincominsg1993 24georgeshibin1993gmailcom

BOOTANIMATION

bull Wondering what is being displayed on the screen during this entire process

bull After init starts what you see is bootanimation

bull The bootanim is a service that displays the bootanimation and is started by init

bull The rc file is parsed by init during startup But init does not start it right away (Notice the disabled)

bull This also means that someone has to explicitly start bootanim This is done by SurfaceFlinger in its init()

httpandroidxrefcom700_r1xrefframeworksbasecmdsbootanimationbootanimrc

service bootanim systembinbootanimation

class core

user graphics

group graphics audio

disabled

oneshot

httpandroidxrefcom700_r1xrefframeworksbaseservicesjavacomandroidserverSystemServerjava1275

start boot animation

startBootAnim()

httpandroidxrefcom700_r1xrefframeworksnativeservicessurfaceflingerSurfaceFlingercpp506

void SurfaceFlingerstartBootAnim()

start boot animation

property_set(servicebootanimexit 0)

property_set(ctlstart bootanim)

httpswwwlinkedincominsg1993 25georgeshibin1993gmailcom

BOOTANIMATION

bull Note that SF doesnrsquot directly spawnfork a process Rather it sets a property ctlstart to bootanim

bull ctl is special because there is no actual property named ctlstartstop (it wonrsquot appear in getprop output)

bull Note the special handling of a property if the property_name starts with ctl

httpandroidxrefcom700_r1xrefsystemcoreinitproperty_servicecpp280

case PROP_MSG_SETPROP

hellip

if(memcmp(msgnamectl4) == 0)

hellip

if (check_control_mac_perms(msgvalue source_ctx ampcr))

handle_control_message((char) msgname + 4 (char) msgvalue)

hellip

else

if (check_mac_perms(msgname source_ctx ampcr))

property_set((char) msgname (char) msgvalue)

hellip

httpswwwlinkedincominsg1993 26georgeshibin1993gmailcom

LAUNCHER

bull When the call reaches init it starts the service which is assigned to ctlstart

bull So when SF sets ctlstart to bootanim init starts the service bootanim

bull Bootanim gets the media files from systemmediabootanimationzip

bull But who stops bootanim Lets get back to system_server to find that out

bull Remember we informed ActivityManagerService that we are ready to executelaunch 3rd party codeapplications here

bull AMS on executing this calls startHomeActivityLocked() Internally this sends an Intent with category IntentCATEGORY_HOME This intent category is special because if an app registers for this intent it means that the application is a Launcher-appHome-screen replacement app

bull On receving this intent Launcher is started as it had registered for the same (see Manifest)

bull Ok Launcher has started but you are still not seeing it on the display

httpswwwlinkedincominsg1993 27georgeshibin1993gmailcom

LAUNCHERbull For Launcher to be displayed bootanimation has to be stopped There is only one entity that can tell SF to stop

bootanim via a binder transaction ie WindowManagerService WindowManagerServicersquosperformEnableScreen() API needs to be invoked

httpandroidxrefcom700_r1xrefframeworksbaseservicescorejavacomandroidserverwmWindowManagerServicejava5866

if (mBootAnimationStopped)

Do this one time

TraceasyncTraceBegin(TraceTRACE_TAG_WINDOW_MANAGER Stop bootanim 0)

try

IBinder surfaceFlinger = ServiceManagergetService(SurfaceFlinger)

if (surfaceFlinger = null)

Slogi(TAG_WM TELLING SURFACE FLINGER WE ARE BOOTED)

Parcel data = Parcelobtain()

datawriteInterfaceToken(androiduiISurfaceComposer)

surfaceFlingertransact(IBinderFIRST_CALL_TRANSACTION BOOT_FINISHED

data null 0)

datarecycle()

catch (RemoteException ex)

Sloge(TAG_WM Boot completed SurfaceFlinger is dead)

mBootAnimationStopped = true

httpswwwlinkedincominsg1993 28georgeshibin1993gmailcom

bull So SF receives a binder call from WindowManagerService with the code IBinderFIRST_CALL_TRANSACTION SurfaceFlinger Binder IPC interface has defined the following

bull The call ultimately reaches bootFinished()

httpandroidxrefcom700_r1xrefframeworksnativeincludeguiISurfaceComposerh177

Note BOOT_FINISHED must remain this value it is called from

Java by ActivityManagerService

BOOT_FINISHED = IBinderFIRST_CALL_TRANSACTION

httpandroidxrefcom700_r1xrefframeworksnativeservicessurfaceflingerSurfaceFlingercpp292

void SurfaceFlingerbootFinished()

hellip

ALOGI(Boot is finished (ld ms) long(ns2ms(duration)) )

mBootFinished = true

stop boot animation

formerly we would just kill the process but we now ask it to exit so it

can choose where to stop the animation

property_set(servicebootanimexit 1)

httpswwwlinkedincominsg1993 29georgeshibin1993gmailcom

BOOTANIMATION

bull SF sets the property serviebootanim to 1 How does this stop bootanim

bull All this while since the time it was started bootanim has been executing playAnimation()

bull While doing so it also periodically calls checkExit()

bull On detecting that this property is set to 1 bootanim gracefully exits

httpandroidxrefcom700_r1xrefframeworksbasecmdsbootanimationBootAnimationcpp387

Allow surface flinger to gracefully request shutdown

char value[PROPERTY_VALUE_MAX]

property_get(servicebootanimexit value 0)

int exitnow = atoi(value)

if (exitnow)

requestExit()

if (mAudioPlayer = NULL)

mAudioPlayer-gtrequestExit()

httpswwwlinkedincominsg1993 30georgeshibin1993gmailcom

BOOT_COMPLETEDbull WindowManager invoked binder transaction to tell SF to stop bootanim

bull After that it calls ActivityManagerrsquos bootAnimationComplete() function

bull In ActivityManagerService finishBooting() is invoked where the property sysboot_completed is set to 1 This property is important because it is the ldquoofficialrdquo way of letting native-servicesdaemons know that boot is now complete

bull After this AMS tells UserController (which is a helper class for handling multi-user functionality) to send the 2 criticalimportant intents

bull Before you unlockswipe the lock screen the intent IntentACTION_LOCKED_BOOT_COMPLETED is sent here

bull Once the user is unlocked (by entering PINswiping-the-lock screen) the intent IntentACTION_BOOT_COMPLETED is sent here This intent is important because it lets Java-services3rd-party apps know that system boot-up is now officially complete and that user is now in the home screen

httpandroidxrefcom700_r1xrefframeworksbaseservicescorejavacomandroidserverwmWindowManagerServicejav

a5899

try

mActivityManagerbootAnimationComplete()

catch (RemoteException e)

httpswwwlinkedincominsg1993 31georgeshibin1993gmailcom

Aaaaand you are now in Home screen

httpswwwlinkedincominsg1993 32georgeshibin1993gmailcom

REFERENCES

bull My highlights on Karim Yaghmourrsquos famous book (Embedded Android) httpswwwsafaribooksonlinecomu001o000000YZt6HAATembedded-android9781449327958

bull Kernel boot process

bull httpduartesorggustavoblogpostkernel-boot-process

bull https0xaxgitbooksiolinux-insidescontentInitializationlinux-initialization-4html

bull httposr507docxinuoscomenPERFORMprocess_stateshtml

bull httpstackoverflowcomquestions464483why-do-we-need-a-swapper-task-in-linux

bull httpunixstackexchangecomquestions83322which-process-has-pid-0

bull BinderServiceManager

bull httpwwwmacrobugcomblog20071215decoding-a-service-call-in-android

bull httpwwwcubridorgblogdev-platformbinder-communication-mechanism-of-android-processes

bull httpwwwprogrameringcomaMjMyMDMwATQhtml

And most importantly httpandroidxrefcom700_r1xref

httpswwwlinkedincominsg1993 33georgeshibin1993gmailcom

Thank You for reading this far

httpswwwlinkedincominsg1993 34

Disclaimer

Almost none (okay fine absolutely zilch) of the information that I put up is proprietary to Qualcomm Inc

Some of the source-code hyperlinks to Qualcommrsquos internal repository which is not accessible to others anyway

For all the other stuff I have provided Android-xref links and is openly accessible to all

However I wonrsquot vouch for the correctness of all information presented here Nope

You are welcome to correcteditpresent this material according to your needs

However it would be nice if you could shoot me a mail (at georgeshibin1993gmailcom) andor provide a

reference to the original material Just sayinghellip it would be nice

georgeshibin1993gmailcom

Page 6: Android bootup

KERNEL BOOTUP PROCESS

bull Kernel_init at do_mountsc mounts ramdisk at lsquorsquo (root location) this is where init binary and other init scripts reside

bull This thread tries to execute init (thefirst user-mode process) in the following order init sbininit etcinit bininit and binsh If all fail kernel panics

bull But what happens to the thread that spawned init

bull That thread is known as the sched or swapper thread and has pid 0 (it does not appear in ps output but does appear as ppid of init) At the end of rest_init() this thread calls schedule() (to kickstart task scheduling) Then it enters idle loop here

httpopengrokqualcommcomsourcexrefLAUM00kernelmsm-318initmainc950

if (ramdisk_execute_command)

ret = run_init_process(ramdisk_execute_command)

We try each of these until one succeeds

The Bourne shell can be used instead of init if we are

trying to recover a really broken machine

if (try_to_run_init_process(sbininit) ||

try_to_run_init_process(etcinit) ||

try_to_run_init_process(bininit) ||

try_to_run_init_process(binsh))

return 0

panic(No working init found Try passing init= option to kernel

See Linux Documentationinittxt for guidance)

httpswwwlinkedincominsg1993 6georgeshibin1993gmailcom

bull The init processrsquos code resides here systemcoreinit

bull Basically all init does is the seemingly simple task of starting servicesdaemons and restarting some in case they are stopped It reads some configuration files ie rc files to figure out what to do when The rc files are written in initrsquos own language

bull The Android Init Language consists of five broad classes of statements - Actions Commands Services Options and Imports

INIT

httpswwwlinkedincominsg1993 7georgeshibin1993gmailcom

INIT RC FILE LINGObull Services are definitions of servicesdaemons etc that you want init to run

bull These are generally run when certain events are triggered

bull Options are modifiers to services Some important modifiers are-

bull critical ndash If it exits more than four times in four minutes the device will reboot into recovery mode (example critical)

bull disabled - This service will not automatically start with its class (ex bootanim)

bull socket ndash a socket at devsocketname will be created when the service starts (example devsocketzygote)

bull oneshot ndash Do not restart the service if it exits Most of important services will NOT have this modifier

bull class ndash 3 major classes of services ndash coremainlate-start

bull onrestart ndash execute the command following this when service restarts (example in zygotersquos rc onrestart restart cameraserver)

httpswwwlinkedincominsg1993 8georgeshibin1993gmailcom

INIT RC FILE LINGObull Triggers are strings which are used to match certain events

bull on ltpatterngt lthelliphellipgt - if the pattern is triggered by someone this is executed (ex on early-init)

bull on propertya=b ndash command is executed when property a is set to b

bull Commands are executed when predefined events are triggered (ie on lttriggergt)

bull trigger write chmod chown start stop restart setprop etc

bull Actions are of the form

bull For an action to be executed it is therefore necessary for an event to be triggered

bull Import statements are used to tell init to parse rc files present in different locations

on lttriggergt

ltcommandgt

ltcommandgt

ltcommandgt

httpswwwlinkedincominsg1993 9georgeshibin1993gmailcom

INIT

httpandroidxrefcom700_r1xrefsystemcorerootdirinitrc

on late-inittrigger early-fstrigger fstrigger post-fshelliptrigger early-boottrigger boot

on bootsetprop nettcpdefault_init_rwnd 60class_start core

httpswwwlinkedincominsg1993 10georgeshibin1993gmailcom

INITbull After some initial setup init first proceeds to parse initrc which is the primary rc file

bull All the other rc files are parsed using import statements in initrc

bull Once parsing is done to kickstart execution of servicesdaemons a few triggers have to be explicitly triggered by init itself

bull The first one of these is early-init

bull early-init is the cue to start ueventd for instance as defined in initrc

bull Init now has to start native daemonsservices like Surfaceflinger vold servicemanager healthd etc

httpandroidxrefcom700_r1xrefsystemcoreinitinitcpp688

parserParseConfig(initrc)

hellip

amQueueEventTrigger(early-init)

httpopengrokqualcommcomsourcexrefLAUM00systemcorerootdirinitrc13

on early-init

hellip

start ueventd

httpswwwlinkedincominsg1993 11georgeshibin1993gmailcom

INITbull Init also explicitly triggers event init and late-init When late-init is triggered it triggers event fs which is

when init parses fstab(qcom) entries to mount remaining partitions (system data misc) here

bull After that init basically runs in an infinite while loop on the lookout for services that might need restarting here

bull Among the services started by init one is particularly important for IPC to happen

bull Lets find out more about ServiceManager

httpopengrokqualcommcomsourcexrefLAUM00deviceqcommsm8937_64inittargetrc42

on fs

hellip

mount_all fstabqcom

httpswwwlinkedincominsg1993 12georgeshibin1993gmailcom

A LITTLE SOMETHING ABOUT SERVICEMANAGER

bull Binder is the core of Android and forms the foundation of the IPC mechanism

bull OpenBinder was developed by Be Inc (later Palm Inc) (Tidbit Palm Inc designed the worldrsquos first PDA and one of the first smartphones)

bull Google developed the Binder framework for Android on the basis of OpenBinder

bull OpenBinder allows processes to present interfaces which may be called by other threads Each process maintains a thread pool which may be used to service such requests

bull In OpenBinder an entity called context manager exists maintains all services handles and returns the service handle to client on request

httpswwwlinkedincominsg1993 13georgeshibin1993gmailcom

A LITTLE SOMETHING ABOUT SERVICEMANAGER

bull If a client wants to publishadd a service it has to invoke an entity called context manager If a client wants to get a reference to a service it again has to query the context manager

bull The Context Manager in Android is called the ServiceManager

bull Since ServiceManager is essential for IPC in android it is started as a ldquocriticalrdquo service

bull Source-code at - frameworksnativecmdsservicemanager

bull During initialization ServiceManager itself calls binder_become_context_manager() to inform the binder driver that it is the contextManager

httpswwwlinkedincominsg1993 14georgeshibin1993gmailcom

A LITTLE SOMETHING ABOUT SERVICEMANAGER

bull The kernel binder driver on receiving this ioctl creates a binder node 0

bull Once this is done clients can now query ServiceManager Internally this happens via ioctl(fd paramscmd=GET srv=ldquoSERVICE_NAMErdquo target=0 hellip)

httpopengrokqualcommcomsourcexrefLAUM00kernelmsm-

318driversstagingandroidbinderc2729

binder_context_mgr_node = binder_new_node(proc 0 0)

httpopengrokqualcommcomsourcexrefLAUM00frameworksnativecmdsservicemanagerbinder

c146

int binder_become_context_manager(struct binder_state bs)

return ioctl(bs-gtfd BINDER_SET_CONTEXT_MGR 0)

httpswwwlinkedincominsg1993 15georgeshibin1993gmailcom

A LITTLE SOMETHING ABOUT SERVICEMANAGER01-01 071603022 0 0 I init Starting service ueventd

01-01 071604958 0 0 I init Starting service logd

01-01 071606345 0 0 I init Starting service vold

01-01 071606871 0 0 I init Starting service exec 1 (systembintzdatacheck)

01-01 071608191 0 0 I init Starting service exec 2 (initqcomearly_bootsh)

01-01 071609225 0 0 I init Starting service healthd

01-01 071609290 0 0 I init Starting service cs-early-boot

01-01 071609296 0 0 I init Starting service esepmdaemon

01-01 071609302 0 0 I init Starting service qcom-usb-sh

01-01 071609309 0 0 I init Starting service qseecomd

01-01 071609315 0 0 I init Starting service per_mgr

01-01 071609321 0 0 I init Starting service lmkd

01-01 071609327 0 0 I init Starting service servicemanager01-01 071609335 0 0 I init Starting service surfaceflinger

01-01 071610101 0 0 I init Starting service bootanim

01-01 071612563 0 0 I init Starting service logd-reinit

01-01 071612777 0 0 I init Starting service exec 4 (systembintzdatacheck)

01-01 071612903 0 0 I init Starting service carrier_switcher

01-01 071612911 0 0 I init Starting service exec 5 (systembinbootstat)

01-01 071612977 0 0 I init Starting service qcomsysd

01-01 071612983 0 0 I init Starting service qcom-c_main-sh

01-01 071612990 0 0 I init Starting service cnd

01-01 071612996 0 0 I init Starting service ptt_socket_app

01-01 071613002 0 0 I init Starting service cnss_diag

01-01 071613028 0 0 I init Starting service thermal-engine

01-01 071613034 0 0 I init Starting service wcnss-service

01-01 071613041 0 0 I init Starting service imsstarter

01-01 071613048 0 0 I init Starting service adsprpcd

01-01 071613054 0 0 I init Starting service hvdcp_opti

01-01 071613062 0 0 I init Starting service zygote01-01 071613069 0 0 I init Starting service zygote_secondary

httpswwwlinkedincominsg1993 16georgeshibin1993gmailcom

INITZYGOTE - STARTUP

bull Just like init is parent of all init-services system-server amp every app is spawned by zygote An executable called app_process(3264) is executed which is then known to others as zygote

bull It belongs to main class of services ie if userdata-encryption is enabled once you enter password zygote is restarted

httpandroidxrefcom700_r1xrefsystemcorerootdirinitzygote64_32rc

service zygote systembinapp_process64 -Xzygote systembin --zygote --start-system-server --socket-name=zygote

class main

socket zygote stream 660 root system

onrestart write sysandroid_powerrequest_state wake

onrestart write syspowerstate on

onrestart restart audioserver

onrestart restart cameraserver

onrestart restart media

onrestart restart netd

writepid devcpusetforegroundtasks sysfscgroupstuneforegroundtasks

service zygote_secondary systembinapp_process32 -Xzygote systembin --zygote --socket-name=zygote_secondary

class main

socket zygote_secondary stream 660 root system

onrestart restart zygote

writepid devcpusetforegroundtasks devstuneforegroundtasks

httpswwwlinkedincominsg1993 17georgeshibin1993gmailcom

ZYGOTE

bull App_process is a native proc (written in C++) Source for app_process resides here

bull ndashzygote option passed is to rename the process name from app_process to zygote here

bull comandroidinternalosZygoteInitjava is called (through runtimestart()) which starts systemServer and then polls

bull ndashstart-system_server option passed makes the zygote spawn system_server

bull Zygote uses an entity called ldquoAndroidRuntimerdquo that starts a VM to run Java Runtimestart() starts a new virtual machine As you know all code written in Java runs in a VM

bull Interesting tidbit the main() of ZygoteInitjava is the first piece of Java code that runs since the device was turned on (Reason is that this is the first time VM was created and java bytecode runs in VM)

httpandroidxrefcom700_r1xrefframeworksbasecmdsapp_processapp_maincpp306

if (zygote)

runtimestart(comandroidinternalosZygoteInit args zygote)

httpandroidxrefcom700_r1xrefframeworksbasecorejavacomandroidinternalosZygoteInitjava746

if (startSystemServer)

startSystemServer(abiList socketName)

httpswwwlinkedincominsg1993 18georgeshibin1993gmailcom

ZYGOTE

bull The most important reason behind Zygotersquos existence can be summarized in this one line of code

bull Zygote preloads classes (as in java class files) resources some shared libraries (so files) etc

bull You can find the list of these classes to be preloaded here on your device at systemetcpreloaded-classes Zygote reads this file here

bull On my device running Android Nougat the total number of preloaded classes alone is 4165 to be exact

httpandroidxrefcom700_r1xrefframeworksbasecorejavacomandroidinternalosZygoteInitjava722

preload()

httpswwwlinkedincominsg1993 19georgeshibin1993gmailcom

ZYGOTE

bull So how exactly is preloading helping

bull To know this we come back to one of the important tasks of zygote ie spawning each and every single application process (remember it is the parent process of all application processes)

bull After starting system_server zygote runs in an infinite while loop here

bull It keeps on polling a socket ndash devsocketzygote When you launch an application the request to create a new process comes from system_server to Zygote on this socket The call reaches hereand then it executes a fork system call as shown below

httpandroidxrefcom700_r1xrefframeworksbasecorejavacomandroidinternalosZygoteConnectionjava225

pid = ZygoteforkAndSpecialize(parsedArgsuid parsedArgsgid parsedArgsgids

parsedArgsdebugFlags rlimits parsedArgsmountExternal parsedArgsseInfo

parsedArgsniceName fdsToClose parsedArgsinstructionSet

parsedArgsappDataDir)

httpswwwlinkedincominsg1993 20georgeshibin1993gmailcom

ZYGOTEbull Here is where you will appreciate the virtue of a great design

bull When a process forks it creates a clone of itself It replicates itself in another memory space When this happens to Zygote it creates a clean new Dalvik VM preloaded with all necessary classes and resources that any App will need (the same 4165 I mentioned earlier)

bull Except that it is never copied

bull You see the Linux Kernel implements a strategy called Copy On Write (COW) With COW Linux doesnrsquot actually copy anything Instead it maps the pages of the new process over to those of the parent process and makes copies only when the new process writes to a page But the classeslibrariesresources preloaded by Zygote are all read-only and not modified by any application This means that all processes forked from Zygote are using the exact same copy of the system classes and resources till EOL These preloaded objects live in the Zygote heap

bull This is what saves the time when apps are launched Also the memory saved is worth mentioning as no matter how many applications are started only one copy of the system classes and the resources is ever loaded in RAM

bull Personally I think the reason we still need Zygote (and cannot be replaced by system_server) is because we would like a process that does almost nothing other than fork() so that COW can do its magic Something like system_server would be counterproductive as its own heap and loaded classes would be huge

httpswwwlinkedincominsg1993 21georgeshibin1993gmailcom

ZYGOTEbull Thats pretty much what Zygote does during its lifetime Lets move onto system_server Notice the class name passed

as argument to Zygotersquos fork call for system_server

bull Just like in Zygotersquos case the AndroidRuntime knows how to execute the main() function in comandroidserverSystemServerjava

httpandroidxrefcom700_r1xrefframeworksbasecorejavacomandroidinternalosZygoteInitjava632

String args[] =

--setuid=1000

--setgid=1000

--setgroups=10011002100310041005100610071008100910101018102110323001300230033006300730093010

--capabilities= + capabilities + + capabilities

--nice-name=system_server

--runtime-args

comandroidserverSystemServer

httpandroidxrefcom700_r1xrefframeworksbaseservicesjavacomandroidserverSystemServerjava205

The main entry point from zygote

public static void main(String[] args)

new SystemServer()run()

httpswwwlinkedincominsg1993 22georgeshibin1993gmailcom

SYSTEM-SERVERbull The run() of system_server starts bootstrap-services core-services and some other services

bull Bootstrap-services are a small number of critical services

bull These are ActivityManagerService PowerManagerService DisplayManagerService PackageManagerService UserManagerService and sSensorService Bootstrap services are started almost together as they have internal dependencies with each other

bull Core services are some essential services that do not have dependencies on bootstrap services so can be started some time later One of these is the WindowManagerService

bull After that a couple of services which are not as critical as the above two classes Infact some of them even need not be started for device bootup

httpandroidxrefcom700_r1xrefframeworksbaseservicesjavacomandroidserverSystemServerjava320

try

TracetraceBegin(TraceTRACE_TAG_SYSTEM_SERVER StartServices)

startBootstrapServices()

startCoreServices()

startOtherServices()

httpswwwlinkedincominsg1993 23georgeshibin1993gmailcom

SYSTEM-SERVERbull Later down the line after starting almost all of the criticalcore services the system_server

(ie its main thread) proceeds to notify ActivityManagerService that the system is now ready to execute third-party code (read apps) The ActivityManagerService does some initializations before it can start applications

bull The callback reaches back to system_server main thread where it starts the first app comandroidsystemui here (specifically SystemUiService of systemui component)

bull We are now mostly done with this thread of system_server (the main thread mainly deals with handling messages from other components and redirecting them)

httpandroidxrefcom700_r1xrefframeworksbaseservicesjavacomandroidserverSystemServerjava1275

mActivityManagerServicesystemReady(new Runnable()

Override

public void run()

hellip

try

startSystemUi(context)

catch (Throwable e)

reportWtf(starting System UI e)

httpswwwlinkedincominsg1993 24georgeshibin1993gmailcom

BOOTANIMATION

bull Wondering what is being displayed on the screen during this entire process

bull After init starts what you see is bootanimation

bull The bootanim is a service that displays the bootanimation and is started by init

bull The rc file is parsed by init during startup But init does not start it right away (Notice the disabled)

bull This also means that someone has to explicitly start bootanim This is done by SurfaceFlinger in its init()

httpandroidxrefcom700_r1xrefframeworksbasecmdsbootanimationbootanimrc

service bootanim systembinbootanimation

class core

user graphics

group graphics audio

disabled

oneshot

httpandroidxrefcom700_r1xrefframeworksbaseservicesjavacomandroidserverSystemServerjava1275

start boot animation

startBootAnim()

httpandroidxrefcom700_r1xrefframeworksnativeservicessurfaceflingerSurfaceFlingercpp506

void SurfaceFlingerstartBootAnim()

start boot animation

property_set(servicebootanimexit 0)

property_set(ctlstart bootanim)

httpswwwlinkedincominsg1993 25georgeshibin1993gmailcom

BOOTANIMATION

bull Note that SF doesnrsquot directly spawnfork a process Rather it sets a property ctlstart to bootanim

bull ctl is special because there is no actual property named ctlstartstop (it wonrsquot appear in getprop output)

bull Note the special handling of a property if the property_name starts with ctl

httpandroidxrefcom700_r1xrefsystemcoreinitproperty_servicecpp280

case PROP_MSG_SETPROP

hellip

if(memcmp(msgnamectl4) == 0)

hellip

if (check_control_mac_perms(msgvalue source_ctx ampcr))

handle_control_message((char) msgname + 4 (char) msgvalue)

hellip

else

if (check_mac_perms(msgname source_ctx ampcr))

property_set((char) msgname (char) msgvalue)

hellip

httpswwwlinkedincominsg1993 26georgeshibin1993gmailcom

LAUNCHER

bull When the call reaches init it starts the service which is assigned to ctlstart

bull So when SF sets ctlstart to bootanim init starts the service bootanim

bull Bootanim gets the media files from systemmediabootanimationzip

bull But who stops bootanim Lets get back to system_server to find that out

bull Remember we informed ActivityManagerService that we are ready to executelaunch 3rd party codeapplications here

bull AMS on executing this calls startHomeActivityLocked() Internally this sends an Intent with category IntentCATEGORY_HOME This intent category is special because if an app registers for this intent it means that the application is a Launcher-appHome-screen replacement app

bull On receving this intent Launcher is started as it had registered for the same (see Manifest)

bull Ok Launcher has started but you are still not seeing it on the display

httpswwwlinkedincominsg1993 27georgeshibin1993gmailcom

LAUNCHERbull For Launcher to be displayed bootanimation has to be stopped There is only one entity that can tell SF to stop

bootanim via a binder transaction ie WindowManagerService WindowManagerServicersquosperformEnableScreen() API needs to be invoked

httpandroidxrefcom700_r1xrefframeworksbaseservicescorejavacomandroidserverwmWindowManagerServicejava5866

if (mBootAnimationStopped)

Do this one time

TraceasyncTraceBegin(TraceTRACE_TAG_WINDOW_MANAGER Stop bootanim 0)

try

IBinder surfaceFlinger = ServiceManagergetService(SurfaceFlinger)

if (surfaceFlinger = null)

Slogi(TAG_WM TELLING SURFACE FLINGER WE ARE BOOTED)

Parcel data = Parcelobtain()

datawriteInterfaceToken(androiduiISurfaceComposer)

surfaceFlingertransact(IBinderFIRST_CALL_TRANSACTION BOOT_FINISHED

data null 0)

datarecycle()

catch (RemoteException ex)

Sloge(TAG_WM Boot completed SurfaceFlinger is dead)

mBootAnimationStopped = true

httpswwwlinkedincominsg1993 28georgeshibin1993gmailcom

bull So SF receives a binder call from WindowManagerService with the code IBinderFIRST_CALL_TRANSACTION SurfaceFlinger Binder IPC interface has defined the following

bull The call ultimately reaches bootFinished()

httpandroidxrefcom700_r1xrefframeworksnativeincludeguiISurfaceComposerh177

Note BOOT_FINISHED must remain this value it is called from

Java by ActivityManagerService

BOOT_FINISHED = IBinderFIRST_CALL_TRANSACTION

httpandroidxrefcom700_r1xrefframeworksnativeservicessurfaceflingerSurfaceFlingercpp292

void SurfaceFlingerbootFinished()

hellip

ALOGI(Boot is finished (ld ms) long(ns2ms(duration)) )

mBootFinished = true

stop boot animation

formerly we would just kill the process but we now ask it to exit so it

can choose where to stop the animation

property_set(servicebootanimexit 1)

httpswwwlinkedincominsg1993 29georgeshibin1993gmailcom

BOOTANIMATION

bull SF sets the property serviebootanim to 1 How does this stop bootanim

bull All this while since the time it was started bootanim has been executing playAnimation()

bull While doing so it also periodically calls checkExit()

bull On detecting that this property is set to 1 bootanim gracefully exits

httpandroidxrefcom700_r1xrefframeworksbasecmdsbootanimationBootAnimationcpp387

Allow surface flinger to gracefully request shutdown

char value[PROPERTY_VALUE_MAX]

property_get(servicebootanimexit value 0)

int exitnow = atoi(value)

if (exitnow)

requestExit()

if (mAudioPlayer = NULL)

mAudioPlayer-gtrequestExit()

httpswwwlinkedincominsg1993 30georgeshibin1993gmailcom

BOOT_COMPLETEDbull WindowManager invoked binder transaction to tell SF to stop bootanim

bull After that it calls ActivityManagerrsquos bootAnimationComplete() function

bull In ActivityManagerService finishBooting() is invoked where the property sysboot_completed is set to 1 This property is important because it is the ldquoofficialrdquo way of letting native-servicesdaemons know that boot is now complete

bull After this AMS tells UserController (which is a helper class for handling multi-user functionality) to send the 2 criticalimportant intents

bull Before you unlockswipe the lock screen the intent IntentACTION_LOCKED_BOOT_COMPLETED is sent here

bull Once the user is unlocked (by entering PINswiping-the-lock screen) the intent IntentACTION_BOOT_COMPLETED is sent here This intent is important because it lets Java-services3rd-party apps know that system boot-up is now officially complete and that user is now in the home screen

httpandroidxrefcom700_r1xrefframeworksbaseservicescorejavacomandroidserverwmWindowManagerServicejav

a5899

try

mActivityManagerbootAnimationComplete()

catch (RemoteException e)

httpswwwlinkedincominsg1993 31georgeshibin1993gmailcom

Aaaaand you are now in Home screen

httpswwwlinkedincominsg1993 32georgeshibin1993gmailcom

REFERENCES

bull My highlights on Karim Yaghmourrsquos famous book (Embedded Android) httpswwwsafaribooksonlinecomu001o000000YZt6HAATembedded-android9781449327958

bull Kernel boot process

bull httpduartesorggustavoblogpostkernel-boot-process

bull https0xaxgitbooksiolinux-insidescontentInitializationlinux-initialization-4html

bull httposr507docxinuoscomenPERFORMprocess_stateshtml

bull httpstackoverflowcomquestions464483why-do-we-need-a-swapper-task-in-linux

bull httpunixstackexchangecomquestions83322which-process-has-pid-0

bull BinderServiceManager

bull httpwwwmacrobugcomblog20071215decoding-a-service-call-in-android

bull httpwwwcubridorgblogdev-platformbinder-communication-mechanism-of-android-processes

bull httpwwwprogrameringcomaMjMyMDMwATQhtml

And most importantly httpandroidxrefcom700_r1xref

httpswwwlinkedincominsg1993 33georgeshibin1993gmailcom

Thank You for reading this far

httpswwwlinkedincominsg1993 34

Disclaimer

Almost none (okay fine absolutely zilch) of the information that I put up is proprietary to Qualcomm Inc

Some of the source-code hyperlinks to Qualcommrsquos internal repository which is not accessible to others anyway

For all the other stuff I have provided Android-xref links and is openly accessible to all

However I wonrsquot vouch for the correctness of all information presented here Nope

You are welcome to correcteditpresent this material according to your needs

However it would be nice if you could shoot me a mail (at georgeshibin1993gmailcom) andor provide a

reference to the original material Just sayinghellip it would be nice

georgeshibin1993gmailcom

Page 7: Android bootup

bull The init processrsquos code resides here systemcoreinit

bull Basically all init does is the seemingly simple task of starting servicesdaemons and restarting some in case they are stopped It reads some configuration files ie rc files to figure out what to do when The rc files are written in initrsquos own language

bull The Android Init Language consists of five broad classes of statements - Actions Commands Services Options and Imports

INIT

httpswwwlinkedincominsg1993 7georgeshibin1993gmailcom

INIT RC FILE LINGObull Services are definitions of servicesdaemons etc that you want init to run

bull These are generally run when certain events are triggered

bull Options are modifiers to services Some important modifiers are-

bull critical ndash If it exits more than four times in four minutes the device will reboot into recovery mode (example critical)

bull disabled - This service will not automatically start with its class (ex bootanim)

bull socket ndash a socket at devsocketname will be created when the service starts (example devsocketzygote)

bull oneshot ndash Do not restart the service if it exits Most of important services will NOT have this modifier

bull class ndash 3 major classes of services ndash coremainlate-start

bull onrestart ndash execute the command following this when service restarts (example in zygotersquos rc onrestart restart cameraserver)

httpswwwlinkedincominsg1993 8georgeshibin1993gmailcom

INIT RC FILE LINGObull Triggers are strings which are used to match certain events

bull on ltpatterngt lthelliphellipgt - if the pattern is triggered by someone this is executed (ex on early-init)

bull on propertya=b ndash command is executed when property a is set to b

bull Commands are executed when predefined events are triggered (ie on lttriggergt)

bull trigger write chmod chown start stop restart setprop etc

bull Actions are of the form

bull For an action to be executed it is therefore necessary for an event to be triggered

bull Import statements are used to tell init to parse rc files present in different locations

on lttriggergt

ltcommandgt

ltcommandgt

ltcommandgt

httpswwwlinkedincominsg1993 9georgeshibin1993gmailcom

INIT

httpandroidxrefcom700_r1xrefsystemcorerootdirinitrc

on late-inittrigger early-fstrigger fstrigger post-fshelliptrigger early-boottrigger boot

on bootsetprop nettcpdefault_init_rwnd 60class_start core

httpswwwlinkedincominsg1993 10georgeshibin1993gmailcom

INITbull After some initial setup init first proceeds to parse initrc which is the primary rc file

bull All the other rc files are parsed using import statements in initrc

bull Once parsing is done to kickstart execution of servicesdaemons a few triggers have to be explicitly triggered by init itself

bull The first one of these is early-init

bull early-init is the cue to start ueventd for instance as defined in initrc

bull Init now has to start native daemonsservices like Surfaceflinger vold servicemanager healthd etc

httpandroidxrefcom700_r1xrefsystemcoreinitinitcpp688

parserParseConfig(initrc)

hellip

amQueueEventTrigger(early-init)

httpopengrokqualcommcomsourcexrefLAUM00systemcorerootdirinitrc13

on early-init

hellip

start ueventd

httpswwwlinkedincominsg1993 11georgeshibin1993gmailcom

INITbull Init also explicitly triggers event init and late-init When late-init is triggered it triggers event fs which is

when init parses fstab(qcom) entries to mount remaining partitions (system data misc) here

bull After that init basically runs in an infinite while loop on the lookout for services that might need restarting here

bull Among the services started by init one is particularly important for IPC to happen

bull Lets find out more about ServiceManager

httpopengrokqualcommcomsourcexrefLAUM00deviceqcommsm8937_64inittargetrc42

on fs

hellip

mount_all fstabqcom

httpswwwlinkedincominsg1993 12georgeshibin1993gmailcom

A LITTLE SOMETHING ABOUT SERVICEMANAGER

bull Binder is the core of Android and forms the foundation of the IPC mechanism

bull OpenBinder was developed by Be Inc (later Palm Inc) (Tidbit Palm Inc designed the worldrsquos first PDA and one of the first smartphones)

bull Google developed the Binder framework for Android on the basis of OpenBinder

bull OpenBinder allows processes to present interfaces which may be called by other threads Each process maintains a thread pool which may be used to service such requests

bull In OpenBinder an entity called context manager exists maintains all services handles and returns the service handle to client on request

httpswwwlinkedincominsg1993 13georgeshibin1993gmailcom

A LITTLE SOMETHING ABOUT SERVICEMANAGER

bull If a client wants to publishadd a service it has to invoke an entity called context manager If a client wants to get a reference to a service it again has to query the context manager

bull The Context Manager in Android is called the ServiceManager

bull Since ServiceManager is essential for IPC in android it is started as a ldquocriticalrdquo service

bull Source-code at - frameworksnativecmdsservicemanager

bull During initialization ServiceManager itself calls binder_become_context_manager() to inform the binder driver that it is the contextManager

httpswwwlinkedincominsg1993 14georgeshibin1993gmailcom

A LITTLE SOMETHING ABOUT SERVICEMANAGER

bull The kernel binder driver on receiving this ioctl creates a binder node 0

bull Once this is done clients can now query ServiceManager Internally this happens via ioctl(fd paramscmd=GET srv=ldquoSERVICE_NAMErdquo target=0 hellip)

httpopengrokqualcommcomsourcexrefLAUM00kernelmsm-

318driversstagingandroidbinderc2729

binder_context_mgr_node = binder_new_node(proc 0 0)

httpopengrokqualcommcomsourcexrefLAUM00frameworksnativecmdsservicemanagerbinder

c146

int binder_become_context_manager(struct binder_state bs)

return ioctl(bs-gtfd BINDER_SET_CONTEXT_MGR 0)

httpswwwlinkedincominsg1993 15georgeshibin1993gmailcom

A LITTLE SOMETHING ABOUT SERVICEMANAGER01-01 071603022 0 0 I init Starting service ueventd

01-01 071604958 0 0 I init Starting service logd

01-01 071606345 0 0 I init Starting service vold

01-01 071606871 0 0 I init Starting service exec 1 (systembintzdatacheck)

01-01 071608191 0 0 I init Starting service exec 2 (initqcomearly_bootsh)

01-01 071609225 0 0 I init Starting service healthd

01-01 071609290 0 0 I init Starting service cs-early-boot

01-01 071609296 0 0 I init Starting service esepmdaemon

01-01 071609302 0 0 I init Starting service qcom-usb-sh

01-01 071609309 0 0 I init Starting service qseecomd

01-01 071609315 0 0 I init Starting service per_mgr

01-01 071609321 0 0 I init Starting service lmkd

01-01 071609327 0 0 I init Starting service servicemanager01-01 071609335 0 0 I init Starting service surfaceflinger

01-01 071610101 0 0 I init Starting service bootanim

01-01 071612563 0 0 I init Starting service logd-reinit

01-01 071612777 0 0 I init Starting service exec 4 (systembintzdatacheck)

01-01 071612903 0 0 I init Starting service carrier_switcher

01-01 071612911 0 0 I init Starting service exec 5 (systembinbootstat)

01-01 071612977 0 0 I init Starting service qcomsysd

01-01 071612983 0 0 I init Starting service qcom-c_main-sh

01-01 071612990 0 0 I init Starting service cnd

01-01 071612996 0 0 I init Starting service ptt_socket_app

01-01 071613002 0 0 I init Starting service cnss_diag

01-01 071613028 0 0 I init Starting service thermal-engine

01-01 071613034 0 0 I init Starting service wcnss-service

01-01 071613041 0 0 I init Starting service imsstarter

01-01 071613048 0 0 I init Starting service adsprpcd

01-01 071613054 0 0 I init Starting service hvdcp_opti

01-01 071613062 0 0 I init Starting service zygote01-01 071613069 0 0 I init Starting service zygote_secondary

httpswwwlinkedincominsg1993 16georgeshibin1993gmailcom

INITZYGOTE - STARTUP

bull Just like init is parent of all init-services system-server amp every app is spawned by zygote An executable called app_process(3264) is executed which is then known to others as zygote

bull It belongs to main class of services ie if userdata-encryption is enabled once you enter password zygote is restarted

httpandroidxrefcom700_r1xrefsystemcorerootdirinitzygote64_32rc

service zygote systembinapp_process64 -Xzygote systembin --zygote --start-system-server --socket-name=zygote

class main

socket zygote stream 660 root system

onrestart write sysandroid_powerrequest_state wake

onrestart write syspowerstate on

onrestart restart audioserver

onrestart restart cameraserver

onrestart restart media

onrestart restart netd

writepid devcpusetforegroundtasks sysfscgroupstuneforegroundtasks

service zygote_secondary systembinapp_process32 -Xzygote systembin --zygote --socket-name=zygote_secondary

class main

socket zygote_secondary stream 660 root system

onrestart restart zygote

writepid devcpusetforegroundtasks devstuneforegroundtasks

httpswwwlinkedincominsg1993 17georgeshibin1993gmailcom

ZYGOTE

bull App_process is a native proc (written in C++) Source for app_process resides here

bull ndashzygote option passed is to rename the process name from app_process to zygote here

bull comandroidinternalosZygoteInitjava is called (through runtimestart()) which starts systemServer and then polls

bull ndashstart-system_server option passed makes the zygote spawn system_server

bull Zygote uses an entity called ldquoAndroidRuntimerdquo that starts a VM to run Java Runtimestart() starts a new virtual machine As you know all code written in Java runs in a VM

bull Interesting tidbit the main() of ZygoteInitjava is the first piece of Java code that runs since the device was turned on (Reason is that this is the first time VM was created and java bytecode runs in VM)

httpandroidxrefcom700_r1xrefframeworksbasecmdsapp_processapp_maincpp306

if (zygote)

runtimestart(comandroidinternalosZygoteInit args zygote)

httpandroidxrefcom700_r1xrefframeworksbasecorejavacomandroidinternalosZygoteInitjava746

if (startSystemServer)

startSystemServer(abiList socketName)

httpswwwlinkedincominsg1993 18georgeshibin1993gmailcom

ZYGOTE

bull The most important reason behind Zygotersquos existence can be summarized in this one line of code

bull Zygote preloads classes (as in java class files) resources some shared libraries (so files) etc

bull You can find the list of these classes to be preloaded here on your device at systemetcpreloaded-classes Zygote reads this file here

bull On my device running Android Nougat the total number of preloaded classes alone is 4165 to be exact

httpandroidxrefcom700_r1xrefframeworksbasecorejavacomandroidinternalosZygoteInitjava722

preload()

httpswwwlinkedincominsg1993 19georgeshibin1993gmailcom

ZYGOTE

bull So how exactly is preloading helping

bull To know this we come back to one of the important tasks of zygote ie spawning each and every single application process (remember it is the parent process of all application processes)

bull After starting system_server zygote runs in an infinite while loop here

bull It keeps on polling a socket ndash devsocketzygote When you launch an application the request to create a new process comes from system_server to Zygote on this socket The call reaches hereand then it executes a fork system call as shown below

httpandroidxrefcom700_r1xrefframeworksbasecorejavacomandroidinternalosZygoteConnectionjava225

pid = ZygoteforkAndSpecialize(parsedArgsuid parsedArgsgid parsedArgsgids

parsedArgsdebugFlags rlimits parsedArgsmountExternal parsedArgsseInfo

parsedArgsniceName fdsToClose parsedArgsinstructionSet

parsedArgsappDataDir)

httpswwwlinkedincominsg1993 20georgeshibin1993gmailcom

ZYGOTEbull Here is where you will appreciate the virtue of a great design

bull When a process forks it creates a clone of itself It replicates itself in another memory space When this happens to Zygote it creates a clean new Dalvik VM preloaded with all necessary classes and resources that any App will need (the same 4165 I mentioned earlier)

bull Except that it is never copied

bull You see the Linux Kernel implements a strategy called Copy On Write (COW) With COW Linux doesnrsquot actually copy anything Instead it maps the pages of the new process over to those of the parent process and makes copies only when the new process writes to a page But the classeslibrariesresources preloaded by Zygote are all read-only and not modified by any application This means that all processes forked from Zygote are using the exact same copy of the system classes and resources till EOL These preloaded objects live in the Zygote heap

bull This is what saves the time when apps are launched Also the memory saved is worth mentioning as no matter how many applications are started only one copy of the system classes and the resources is ever loaded in RAM

bull Personally I think the reason we still need Zygote (and cannot be replaced by system_server) is because we would like a process that does almost nothing other than fork() so that COW can do its magic Something like system_server would be counterproductive as its own heap and loaded classes would be huge

httpswwwlinkedincominsg1993 21georgeshibin1993gmailcom

ZYGOTEbull Thats pretty much what Zygote does during its lifetime Lets move onto system_server Notice the class name passed

as argument to Zygotersquos fork call for system_server

bull Just like in Zygotersquos case the AndroidRuntime knows how to execute the main() function in comandroidserverSystemServerjava

httpandroidxrefcom700_r1xrefframeworksbasecorejavacomandroidinternalosZygoteInitjava632

String args[] =

--setuid=1000

--setgid=1000

--setgroups=10011002100310041005100610071008100910101018102110323001300230033006300730093010

--capabilities= + capabilities + + capabilities

--nice-name=system_server

--runtime-args

comandroidserverSystemServer

httpandroidxrefcom700_r1xrefframeworksbaseservicesjavacomandroidserverSystemServerjava205

The main entry point from zygote

public static void main(String[] args)

new SystemServer()run()

httpswwwlinkedincominsg1993 22georgeshibin1993gmailcom

SYSTEM-SERVERbull The run() of system_server starts bootstrap-services core-services and some other services

bull Bootstrap-services are a small number of critical services

bull These are ActivityManagerService PowerManagerService DisplayManagerService PackageManagerService UserManagerService and sSensorService Bootstrap services are started almost together as they have internal dependencies with each other

bull Core services are some essential services that do not have dependencies on bootstrap services so can be started some time later One of these is the WindowManagerService

bull After that a couple of services which are not as critical as the above two classes Infact some of them even need not be started for device bootup

httpandroidxrefcom700_r1xrefframeworksbaseservicesjavacomandroidserverSystemServerjava320

try

TracetraceBegin(TraceTRACE_TAG_SYSTEM_SERVER StartServices)

startBootstrapServices()

startCoreServices()

startOtherServices()

httpswwwlinkedincominsg1993 23georgeshibin1993gmailcom

SYSTEM-SERVERbull Later down the line after starting almost all of the criticalcore services the system_server

(ie its main thread) proceeds to notify ActivityManagerService that the system is now ready to execute third-party code (read apps) The ActivityManagerService does some initializations before it can start applications

bull The callback reaches back to system_server main thread where it starts the first app comandroidsystemui here (specifically SystemUiService of systemui component)

bull We are now mostly done with this thread of system_server (the main thread mainly deals with handling messages from other components and redirecting them)

httpandroidxrefcom700_r1xrefframeworksbaseservicesjavacomandroidserverSystemServerjava1275

mActivityManagerServicesystemReady(new Runnable()

Override

public void run()

hellip

try

startSystemUi(context)

catch (Throwable e)

reportWtf(starting System UI e)

httpswwwlinkedincominsg1993 24georgeshibin1993gmailcom

BOOTANIMATION

bull Wondering what is being displayed on the screen during this entire process

bull After init starts what you see is bootanimation

bull The bootanim is a service that displays the bootanimation and is started by init

bull The rc file is parsed by init during startup But init does not start it right away (Notice the disabled)

bull This also means that someone has to explicitly start bootanim This is done by SurfaceFlinger in its init()

httpandroidxrefcom700_r1xrefframeworksbasecmdsbootanimationbootanimrc

service bootanim systembinbootanimation

class core

user graphics

group graphics audio

disabled

oneshot

httpandroidxrefcom700_r1xrefframeworksbaseservicesjavacomandroidserverSystemServerjava1275

start boot animation

startBootAnim()

httpandroidxrefcom700_r1xrefframeworksnativeservicessurfaceflingerSurfaceFlingercpp506

void SurfaceFlingerstartBootAnim()

start boot animation

property_set(servicebootanimexit 0)

property_set(ctlstart bootanim)

httpswwwlinkedincominsg1993 25georgeshibin1993gmailcom

BOOTANIMATION

bull Note that SF doesnrsquot directly spawnfork a process Rather it sets a property ctlstart to bootanim

bull ctl is special because there is no actual property named ctlstartstop (it wonrsquot appear in getprop output)

bull Note the special handling of a property if the property_name starts with ctl

httpandroidxrefcom700_r1xrefsystemcoreinitproperty_servicecpp280

case PROP_MSG_SETPROP

hellip

if(memcmp(msgnamectl4) == 0)

hellip

if (check_control_mac_perms(msgvalue source_ctx ampcr))

handle_control_message((char) msgname + 4 (char) msgvalue)

hellip

else

if (check_mac_perms(msgname source_ctx ampcr))

property_set((char) msgname (char) msgvalue)

hellip

httpswwwlinkedincominsg1993 26georgeshibin1993gmailcom

LAUNCHER

bull When the call reaches init it starts the service which is assigned to ctlstart

bull So when SF sets ctlstart to bootanim init starts the service bootanim

bull Bootanim gets the media files from systemmediabootanimationzip

bull But who stops bootanim Lets get back to system_server to find that out

bull Remember we informed ActivityManagerService that we are ready to executelaunch 3rd party codeapplications here

bull AMS on executing this calls startHomeActivityLocked() Internally this sends an Intent with category IntentCATEGORY_HOME This intent category is special because if an app registers for this intent it means that the application is a Launcher-appHome-screen replacement app

bull On receving this intent Launcher is started as it had registered for the same (see Manifest)

bull Ok Launcher has started but you are still not seeing it on the display

httpswwwlinkedincominsg1993 27georgeshibin1993gmailcom

LAUNCHERbull For Launcher to be displayed bootanimation has to be stopped There is only one entity that can tell SF to stop

bootanim via a binder transaction ie WindowManagerService WindowManagerServicersquosperformEnableScreen() API needs to be invoked

httpandroidxrefcom700_r1xrefframeworksbaseservicescorejavacomandroidserverwmWindowManagerServicejava5866

if (mBootAnimationStopped)

Do this one time

TraceasyncTraceBegin(TraceTRACE_TAG_WINDOW_MANAGER Stop bootanim 0)

try

IBinder surfaceFlinger = ServiceManagergetService(SurfaceFlinger)

if (surfaceFlinger = null)

Slogi(TAG_WM TELLING SURFACE FLINGER WE ARE BOOTED)

Parcel data = Parcelobtain()

datawriteInterfaceToken(androiduiISurfaceComposer)

surfaceFlingertransact(IBinderFIRST_CALL_TRANSACTION BOOT_FINISHED

data null 0)

datarecycle()

catch (RemoteException ex)

Sloge(TAG_WM Boot completed SurfaceFlinger is dead)

mBootAnimationStopped = true

httpswwwlinkedincominsg1993 28georgeshibin1993gmailcom

bull So SF receives a binder call from WindowManagerService with the code IBinderFIRST_CALL_TRANSACTION SurfaceFlinger Binder IPC interface has defined the following

bull The call ultimately reaches bootFinished()

httpandroidxrefcom700_r1xrefframeworksnativeincludeguiISurfaceComposerh177

Note BOOT_FINISHED must remain this value it is called from

Java by ActivityManagerService

BOOT_FINISHED = IBinderFIRST_CALL_TRANSACTION

httpandroidxrefcom700_r1xrefframeworksnativeservicessurfaceflingerSurfaceFlingercpp292

void SurfaceFlingerbootFinished()

hellip

ALOGI(Boot is finished (ld ms) long(ns2ms(duration)) )

mBootFinished = true

stop boot animation

formerly we would just kill the process but we now ask it to exit so it

can choose where to stop the animation

property_set(servicebootanimexit 1)

httpswwwlinkedincominsg1993 29georgeshibin1993gmailcom

BOOTANIMATION

bull SF sets the property serviebootanim to 1 How does this stop bootanim

bull All this while since the time it was started bootanim has been executing playAnimation()

bull While doing so it also periodically calls checkExit()

bull On detecting that this property is set to 1 bootanim gracefully exits

httpandroidxrefcom700_r1xrefframeworksbasecmdsbootanimationBootAnimationcpp387

Allow surface flinger to gracefully request shutdown

char value[PROPERTY_VALUE_MAX]

property_get(servicebootanimexit value 0)

int exitnow = atoi(value)

if (exitnow)

requestExit()

if (mAudioPlayer = NULL)

mAudioPlayer-gtrequestExit()

httpswwwlinkedincominsg1993 30georgeshibin1993gmailcom

BOOT_COMPLETEDbull WindowManager invoked binder transaction to tell SF to stop bootanim

bull After that it calls ActivityManagerrsquos bootAnimationComplete() function

bull In ActivityManagerService finishBooting() is invoked where the property sysboot_completed is set to 1 This property is important because it is the ldquoofficialrdquo way of letting native-servicesdaemons know that boot is now complete

bull After this AMS tells UserController (which is a helper class for handling multi-user functionality) to send the 2 criticalimportant intents

bull Before you unlockswipe the lock screen the intent IntentACTION_LOCKED_BOOT_COMPLETED is sent here

bull Once the user is unlocked (by entering PINswiping-the-lock screen) the intent IntentACTION_BOOT_COMPLETED is sent here This intent is important because it lets Java-services3rd-party apps know that system boot-up is now officially complete and that user is now in the home screen

httpandroidxrefcom700_r1xrefframeworksbaseservicescorejavacomandroidserverwmWindowManagerServicejav

a5899

try

mActivityManagerbootAnimationComplete()

catch (RemoteException e)

httpswwwlinkedincominsg1993 31georgeshibin1993gmailcom

Aaaaand you are now in Home screen

httpswwwlinkedincominsg1993 32georgeshibin1993gmailcom

REFERENCES

bull My highlights on Karim Yaghmourrsquos famous book (Embedded Android) httpswwwsafaribooksonlinecomu001o000000YZt6HAATembedded-android9781449327958

bull Kernel boot process

bull httpduartesorggustavoblogpostkernel-boot-process

bull https0xaxgitbooksiolinux-insidescontentInitializationlinux-initialization-4html

bull httposr507docxinuoscomenPERFORMprocess_stateshtml

bull httpstackoverflowcomquestions464483why-do-we-need-a-swapper-task-in-linux

bull httpunixstackexchangecomquestions83322which-process-has-pid-0

bull BinderServiceManager

bull httpwwwmacrobugcomblog20071215decoding-a-service-call-in-android

bull httpwwwcubridorgblogdev-platformbinder-communication-mechanism-of-android-processes

bull httpwwwprogrameringcomaMjMyMDMwATQhtml

And most importantly httpandroidxrefcom700_r1xref

httpswwwlinkedincominsg1993 33georgeshibin1993gmailcom

Thank You for reading this far

httpswwwlinkedincominsg1993 34

Disclaimer

Almost none (okay fine absolutely zilch) of the information that I put up is proprietary to Qualcomm Inc

Some of the source-code hyperlinks to Qualcommrsquos internal repository which is not accessible to others anyway

For all the other stuff I have provided Android-xref links and is openly accessible to all

However I wonrsquot vouch for the correctness of all information presented here Nope

You are welcome to correcteditpresent this material according to your needs

However it would be nice if you could shoot me a mail (at georgeshibin1993gmailcom) andor provide a

reference to the original material Just sayinghellip it would be nice

georgeshibin1993gmailcom

Page 8: Android bootup

INIT RC FILE LINGObull Services are definitions of servicesdaemons etc that you want init to run

bull These are generally run when certain events are triggered

bull Options are modifiers to services Some important modifiers are-

bull critical ndash If it exits more than four times in four minutes the device will reboot into recovery mode (example critical)

bull disabled - This service will not automatically start with its class (ex bootanim)

bull socket ndash a socket at devsocketname will be created when the service starts (example devsocketzygote)

bull oneshot ndash Do not restart the service if it exits Most of important services will NOT have this modifier

bull class ndash 3 major classes of services ndash coremainlate-start

bull onrestart ndash execute the command following this when service restarts (example in zygotersquos rc onrestart restart cameraserver)

httpswwwlinkedincominsg1993 8georgeshibin1993gmailcom

INIT RC FILE LINGObull Triggers are strings which are used to match certain events

bull on ltpatterngt lthelliphellipgt - if the pattern is triggered by someone this is executed (ex on early-init)

bull on propertya=b ndash command is executed when property a is set to b

bull Commands are executed when predefined events are triggered (ie on lttriggergt)

bull trigger write chmod chown start stop restart setprop etc

bull Actions are of the form

bull For an action to be executed it is therefore necessary for an event to be triggered

bull Import statements are used to tell init to parse rc files present in different locations

on lttriggergt

ltcommandgt

ltcommandgt

ltcommandgt

httpswwwlinkedincominsg1993 9georgeshibin1993gmailcom

INIT

httpandroidxrefcom700_r1xrefsystemcorerootdirinitrc

on late-inittrigger early-fstrigger fstrigger post-fshelliptrigger early-boottrigger boot

on bootsetprop nettcpdefault_init_rwnd 60class_start core

httpswwwlinkedincominsg1993 10georgeshibin1993gmailcom

INITbull After some initial setup init first proceeds to parse initrc which is the primary rc file

bull All the other rc files are parsed using import statements in initrc

bull Once parsing is done to kickstart execution of servicesdaemons a few triggers have to be explicitly triggered by init itself

bull The first one of these is early-init

bull early-init is the cue to start ueventd for instance as defined in initrc

bull Init now has to start native daemonsservices like Surfaceflinger vold servicemanager healthd etc

httpandroidxrefcom700_r1xrefsystemcoreinitinitcpp688

parserParseConfig(initrc)

hellip

amQueueEventTrigger(early-init)

httpopengrokqualcommcomsourcexrefLAUM00systemcorerootdirinitrc13

on early-init

hellip

start ueventd

httpswwwlinkedincominsg1993 11georgeshibin1993gmailcom

INITbull Init also explicitly triggers event init and late-init When late-init is triggered it triggers event fs which is

when init parses fstab(qcom) entries to mount remaining partitions (system data misc) here

bull After that init basically runs in an infinite while loop on the lookout for services that might need restarting here

bull Among the services started by init one is particularly important for IPC to happen

bull Lets find out more about ServiceManager

httpopengrokqualcommcomsourcexrefLAUM00deviceqcommsm8937_64inittargetrc42

on fs

hellip

mount_all fstabqcom

httpswwwlinkedincominsg1993 12georgeshibin1993gmailcom

A LITTLE SOMETHING ABOUT SERVICEMANAGER

bull Binder is the core of Android and forms the foundation of the IPC mechanism

bull OpenBinder was developed by Be Inc (later Palm Inc) (Tidbit Palm Inc designed the worldrsquos first PDA and one of the first smartphones)

bull Google developed the Binder framework for Android on the basis of OpenBinder

bull OpenBinder allows processes to present interfaces which may be called by other threads Each process maintains a thread pool which may be used to service such requests

bull In OpenBinder an entity called context manager exists maintains all services handles and returns the service handle to client on request

httpswwwlinkedincominsg1993 13georgeshibin1993gmailcom

A LITTLE SOMETHING ABOUT SERVICEMANAGER

bull If a client wants to publishadd a service it has to invoke an entity called context manager If a client wants to get a reference to a service it again has to query the context manager

bull The Context Manager in Android is called the ServiceManager

bull Since ServiceManager is essential for IPC in android it is started as a ldquocriticalrdquo service

bull Source-code at - frameworksnativecmdsservicemanager

bull During initialization ServiceManager itself calls binder_become_context_manager() to inform the binder driver that it is the contextManager

httpswwwlinkedincominsg1993 14georgeshibin1993gmailcom

A LITTLE SOMETHING ABOUT SERVICEMANAGER

bull The kernel binder driver on receiving this ioctl creates a binder node 0

bull Once this is done clients can now query ServiceManager Internally this happens via ioctl(fd paramscmd=GET srv=ldquoSERVICE_NAMErdquo target=0 hellip)

httpopengrokqualcommcomsourcexrefLAUM00kernelmsm-

318driversstagingandroidbinderc2729

binder_context_mgr_node = binder_new_node(proc 0 0)

httpopengrokqualcommcomsourcexrefLAUM00frameworksnativecmdsservicemanagerbinder

c146

int binder_become_context_manager(struct binder_state bs)

return ioctl(bs-gtfd BINDER_SET_CONTEXT_MGR 0)

httpswwwlinkedincominsg1993 15georgeshibin1993gmailcom

A LITTLE SOMETHING ABOUT SERVICEMANAGER01-01 071603022 0 0 I init Starting service ueventd

01-01 071604958 0 0 I init Starting service logd

01-01 071606345 0 0 I init Starting service vold

01-01 071606871 0 0 I init Starting service exec 1 (systembintzdatacheck)

01-01 071608191 0 0 I init Starting service exec 2 (initqcomearly_bootsh)

01-01 071609225 0 0 I init Starting service healthd

01-01 071609290 0 0 I init Starting service cs-early-boot

01-01 071609296 0 0 I init Starting service esepmdaemon

01-01 071609302 0 0 I init Starting service qcom-usb-sh

01-01 071609309 0 0 I init Starting service qseecomd

01-01 071609315 0 0 I init Starting service per_mgr

01-01 071609321 0 0 I init Starting service lmkd

01-01 071609327 0 0 I init Starting service servicemanager01-01 071609335 0 0 I init Starting service surfaceflinger

01-01 071610101 0 0 I init Starting service bootanim

01-01 071612563 0 0 I init Starting service logd-reinit

01-01 071612777 0 0 I init Starting service exec 4 (systembintzdatacheck)

01-01 071612903 0 0 I init Starting service carrier_switcher

01-01 071612911 0 0 I init Starting service exec 5 (systembinbootstat)

01-01 071612977 0 0 I init Starting service qcomsysd

01-01 071612983 0 0 I init Starting service qcom-c_main-sh

01-01 071612990 0 0 I init Starting service cnd

01-01 071612996 0 0 I init Starting service ptt_socket_app

01-01 071613002 0 0 I init Starting service cnss_diag

01-01 071613028 0 0 I init Starting service thermal-engine

01-01 071613034 0 0 I init Starting service wcnss-service

01-01 071613041 0 0 I init Starting service imsstarter

01-01 071613048 0 0 I init Starting service adsprpcd

01-01 071613054 0 0 I init Starting service hvdcp_opti

01-01 071613062 0 0 I init Starting service zygote01-01 071613069 0 0 I init Starting service zygote_secondary

httpswwwlinkedincominsg1993 16georgeshibin1993gmailcom

INITZYGOTE - STARTUP

bull Just like init is parent of all init-services system-server amp every app is spawned by zygote An executable called app_process(3264) is executed which is then known to others as zygote

bull It belongs to main class of services ie if userdata-encryption is enabled once you enter password zygote is restarted

httpandroidxrefcom700_r1xrefsystemcorerootdirinitzygote64_32rc

service zygote systembinapp_process64 -Xzygote systembin --zygote --start-system-server --socket-name=zygote

class main

socket zygote stream 660 root system

onrestart write sysandroid_powerrequest_state wake

onrestart write syspowerstate on

onrestart restart audioserver

onrestart restart cameraserver

onrestart restart media

onrestart restart netd

writepid devcpusetforegroundtasks sysfscgroupstuneforegroundtasks

service zygote_secondary systembinapp_process32 -Xzygote systembin --zygote --socket-name=zygote_secondary

class main

socket zygote_secondary stream 660 root system

onrestart restart zygote

writepid devcpusetforegroundtasks devstuneforegroundtasks

httpswwwlinkedincominsg1993 17georgeshibin1993gmailcom

ZYGOTE

bull App_process is a native proc (written in C++) Source for app_process resides here

bull ndashzygote option passed is to rename the process name from app_process to zygote here

bull comandroidinternalosZygoteInitjava is called (through runtimestart()) which starts systemServer and then polls

bull ndashstart-system_server option passed makes the zygote spawn system_server

bull Zygote uses an entity called ldquoAndroidRuntimerdquo that starts a VM to run Java Runtimestart() starts a new virtual machine As you know all code written in Java runs in a VM

bull Interesting tidbit the main() of ZygoteInitjava is the first piece of Java code that runs since the device was turned on (Reason is that this is the first time VM was created and java bytecode runs in VM)

httpandroidxrefcom700_r1xrefframeworksbasecmdsapp_processapp_maincpp306

if (zygote)

runtimestart(comandroidinternalosZygoteInit args zygote)

httpandroidxrefcom700_r1xrefframeworksbasecorejavacomandroidinternalosZygoteInitjava746

if (startSystemServer)

startSystemServer(abiList socketName)

httpswwwlinkedincominsg1993 18georgeshibin1993gmailcom

ZYGOTE

bull The most important reason behind Zygotersquos existence can be summarized in this one line of code

bull Zygote preloads classes (as in java class files) resources some shared libraries (so files) etc

bull You can find the list of these classes to be preloaded here on your device at systemetcpreloaded-classes Zygote reads this file here

bull On my device running Android Nougat the total number of preloaded classes alone is 4165 to be exact

httpandroidxrefcom700_r1xrefframeworksbasecorejavacomandroidinternalosZygoteInitjava722

preload()

httpswwwlinkedincominsg1993 19georgeshibin1993gmailcom

ZYGOTE

bull So how exactly is preloading helping

bull To know this we come back to one of the important tasks of zygote ie spawning each and every single application process (remember it is the parent process of all application processes)

bull After starting system_server zygote runs in an infinite while loop here

bull It keeps on polling a socket ndash devsocketzygote When you launch an application the request to create a new process comes from system_server to Zygote on this socket The call reaches hereand then it executes a fork system call as shown below

httpandroidxrefcom700_r1xrefframeworksbasecorejavacomandroidinternalosZygoteConnectionjava225

pid = ZygoteforkAndSpecialize(parsedArgsuid parsedArgsgid parsedArgsgids

parsedArgsdebugFlags rlimits parsedArgsmountExternal parsedArgsseInfo

parsedArgsniceName fdsToClose parsedArgsinstructionSet

parsedArgsappDataDir)

httpswwwlinkedincominsg1993 20georgeshibin1993gmailcom

ZYGOTEbull Here is where you will appreciate the virtue of a great design

bull When a process forks it creates a clone of itself It replicates itself in another memory space When this happens to Zygote it creates a clean new Dalvik VM preloaded with all necessary classes and resources that any App will need (the same 4165 I mentioned earlier)

bull Except that it is never copied

bull You see the Linux Kernel implements a strategy called Copy On Write (COW) With COW Linux doesnrsquot actually copy anything Instead it maps the pages of the new process over to those of the parent process and makes copies only when the new process writes to a page But the classeslibrariesresources preloaded by Zygote are all read-only and not modified by any application This means that all processes forked from Zygote are using the exact same copy of the system classes and resources till EOL These preloaded objects live in the Zygote heap

bull This is what saves the time when apps are launched Also the memory saved is worth mentioning as no matter how many applications are started only one copy of the system classes and the resources is ever loaded in RAM

bull Personally I think the reason we still need Zygote (and cannot be replaced by system_server) is because we would like a process that does almost nothing other than fork() so that COW can do its magic Something like system_server would be counterproductive as its own heap and loaded classes would be huge

httpswwwlinkedincominsg1993 21georgeshibin1993gmailcom

ZYGOTEbull Thats pretty much what Zygote does during its lifetime Lets move onto system_server Notice the class name passed

as argument to Zygotersquos fork call for system_server

bull Just like in Zygotersquos case the AndroidRuntime knows how to execute the main() function in comandroidserverSystemServerjava

httpandroidxrefcom700_r1xrefframeworksbasecorejavacomandroidinternalosZygoteInitjava632

String args[] =

--setuid=1000

--setgid=1000

--setgroups=10011002100310041005100610071008100910101018102110323001300230033006300730093010

--capabilities= + capabilities + + capabilities

--nice-name=system_server

--runtime-args

comandroidserverSystemServer

httpandroidxrefcom700_r1xrefframeworksbaseservicesjavacomandroidserverSystemServerjava205

The main entry point from zygote

public static void main(String[] args)

new SystemServer()run()

httpswwwlinkedincominsg1993 22georgeshibin1993gmailcom

SYSTEM-SERVERbull The run() of system_server starts bootstrap-services core-services and some other services

bull Bootstrap-services are a small number of critical services

bull These are ActivityManagerService PowerManagerService DisplayManagerService PackageManagerService UserManagerService and sSensorService Bootstrap services are started almost together as they have internal dependencies with each other

bull Core services are some essential services that do not have dependencies on bootstrap services so can be started some time later One of these is the WindowManagerService

bull After that a couple of services which are not as critical as the above two classes Infact some of them even need not be started for device bootup

httpandroidxrefcom700_r1xrefframeworksbaseservicesjavacomandroidserverSystemServerjava320

try

TracetraceBegin(TraceTRACE_TAG_SYSTEM_SERVER StartServices)

startBootstrapServices()

startCoreServices()

startOtherServices()

httpswwwlinkedincominsg1993 23georgeshibin1993gmailcom

SYSTEM-SERVERbull Later down the line after starting almost all of the criticalcore services the system_server

(ie its main thread) proceeds to notify ActivityManagerService that the system is now ready to execute third-party code (read apps) The ActivityManagerService does some initializations before it can start applications

bull The callback reaches back to system_server main thread where it starts the first app comandroidsystemui here (specifically SystemUiService of systemui component)

bull We are now mostly done with this thread of system_server (the main thread mainly deals with handling messages from other components and redirecting them)

httpandroidxrefcom700_r1xrefframeworksbaseservicesjavacomandroidserverSystemServerjava1275

mActivityManagerServicesystemReady(new Runnable()

Override

public void run()

hellip

try

startSystemUi(context)

catch (Throwable e)

reportWtf(starting System UI e)

httpswwwlinkedincominsg1993 24georgeshibin1993gmailcom

BOOTANIMATION

bull Wondering what is being displayed on the screen during this entire process

bull After init starts what you see is bootanimation

bull The bootanim is a service that displays the bootanimation and is started by init

bull The rc file is parsed by init during startup But init does not start it right away (Notice the disabled)

bull This also means that someone has to explicitly start bootanim This is done by SurfaceFlinger in its init()

httpandroidxrefcom700_r1xrefframeworksbasecmdsbootanimationbootanimrc

service bootanim systembinbootanimation

class core

user graphics

group graphics audio

disabled

oneshot

httpandroidxrefcom700_r1xrefframeworksbaseservicesjavacomandroidserverSystemServerjava1275

start boot animation

startBootAnim()

httpandroidxrefcom700_r1xrefframeworksnativeservicessurfaceflingerSurfaceFlingercpp506

void SurfaceFlingerstartBootAnim()

start boot animation

property_set(servicebootanimexit 0)

property_set(ctlstart bootanim)

httpswwwlinkedincominsg1993 25georgeshibin1993gmailcom

BOOTANIMATION

bull Note that SF doesnrsquot directly spawnfork a process Rather it sets a property ctlstart to bootanim

bull ctl is special because there is no actual property named ctlstartstop (it wonrsquot appear in getprop output)

bull Note the special handling of a property if the property_name starts with ctl

httpandroidxrefcom700_r1xrefsystemcoreinitproperty_servicecpp280

case PROP_MSG_SETPROP

hellip

if(memcmp(msgnamectl4) == 0)

hellip

if (check_control_mac_perms(msgvalue source_ctx ampcr))

handle_control_message((char) msgname + 4 (char) msgvalue)

hellip

else

if (check_mac_perms(msgname source_ctx ampcr))

property_set((char) msgname (char) msgvalue)

hellip

httpswwwlinkedincominsg1993 26georgeshibin1993gmailcom

LAUNCHER

bull When the call reaches init it starts the service which is assigned to ctlstart

bull So when SF sets ctlstart to bootanim init starts the service bootanim

bull Bootanim gets the media files from systemmediabootanimationzip

bull But who stops bootanim Lets get back to system_server to find that out

bull Remember we informed ActivityManagerService that we are ready to executelaunch 3rd party codeapplications here

bull AMS on executing this calls startHomeActivityLocked() Internally this sends an Intent with category IntentCATEGORY_HOME This intent category is special because if an app registers for this intent it means that the application is a Launcher-appHome-screen replacement app

bull On receving this intent Launcher is started as it had registered for the same (see Manifest)

bull Ok Launcher has started but you are still not seeing it on the display

httpswwwlinkedincominsg1993 27georgeshibin1993gmailcom

LAUNCHERbull For Launcher to be displayed bootanimation has to be stopped There is only one entity that can tell SF to stop

bootanim via a binder transaction ie WindowManagerService WindowManagerServicersquosperformEnableScreen() API needs to be invoked

httpandroidxrefcom700_r1xrefframeworksbaseservicescorejavacomandroidserverwmWindowManagerServicejava5866

if (mBootAnimationStopped)

Do this one time

TraceasyncTraceBegin(TraceTRACE_TAG_WINDOW_MANAGER Stop bootanim 0)

try

IBinder surfaceFlinger = ServiceManagergetService(SurfaceFlinger)

if (surfaceFlinger = null)

Slogi(TAG_WM TELLING SURFACE FLINGER WE ARE BOOTED)

Parcel data = Parcelobtain()

datawriteInterfaceToken(androiduiISurfaceComposer)

surfaceFlingertransact(IBinderFIRST_CALL_TRANSACTION BOOT_FINISHED

data null 0)

datarecycle()

catch (RemoteException ex)

Sloge(TAG_WM Boot completed SurfaceFlinger is dead)

mBootAnimationStopped = true

httpswwwlinkedincominsg1993 28georgeshibin1993gmailcom

bull So SF receives a binder call from WindowManagerService with the code IBinderFIRST_CALL_TRANSACTION SurfaceFlinger Binder IPC interface has defined the following

bull The call ultimately reaches bootFinished()

httpandroidxrefcom700_r1xrefframeworksnativeincludeguiISurfaceComposerh177

Note BOOT_FINISHED must remain this value it is called from

Java by ActivityManagerService

BOOT_FINISHED = IBinderFIRST_CALL_TRANSACTION

httpandroidxrefcom700_r1xrefframeworksnativeservicessurfaceflingerSurfaceFlingercpp292

void SurfaceFlingerbootFinished()

hellip

ALOGI(Boot is finished (ld ms) long(ns2ms(duration)) )

mBootFinished = true

stop boot animation

formerly we would just kill the process but we now ask it to exit so it

can choose where to stop the animation

property_set(servicebootanimexit 1)

httpswwwlinkedincominsg1993 29georgeshibin1993gmailcom

BOOTANIMATION

bull SF sets the property serviebootanim to 1 How does this stop bootanim

bull All this while since the time it was started bootanim has been executing playAnimation()

bull While doing so it also periodically calls checkExit()

bull On detecting that this property is set to 1 bootanim gracefully exits

httpandroidxrefcom700_r1xrefframeworksbasecmdsbootanimationBootAnimationcpp387

Allow surface flinger to gracefully request shutdown

char value[PROPERTY_VALUE_MAX]

property_get(servicebootanimexit value 0)

int exitnow = atoi(value)

if (exitnow)

requestExit()

if (mAudioPlayer = NULL)

mAudioPlayer-gtrequestExit()

httpswwwlinkedincominsg1993 30georgeshibin1993gmailcom

BOOT_COMPLETEDbull WindowManager invoked binder transaction to tell SF to stop bootanim

bull After that it calls ActivityManagerrsquos bootAnimationComplete() function

bull In ActivityManagerService finishBooting() is invoked where the property sysboot_completed is set to 1 This property is important because it is the ldquoofficialrdquo way of letting native-servicesdaemons know that boot is now complete

bull After this AMS tells UserController (which is a helper class for handling multi-user functionality) to send the 2 criticalimportant intents

bull Before you unlockswipe the lock screen the intent IntentACTION_LOCKED_BOOT_COMPLETED is sent here

bull Once the user is unlocked (by entering PINswiping-the-lock screen) the intent IntentACTION_BOOT_COMPLETED is sent here This intent is important because it lets Java-services3rd-party apps know that system boot-up is now officially complete and that user is now in the home screen

httpandroidxrefcom700_r1xrefframeworksbaseservicescorejavacomandroidserverwmWindowManagerServicejav

a5899

try

mActivityManagerbootAnimationComplete()

catch (RemoteException e)

httpswwwlinkedincominsg1993 31georgeshibin1993gmailcom

Aaaaand you are now in Home screen

httpswwwlinkedincominsg1993 32georgeshibin1993gmailcom

REFERENCES

bull My highlights on Karim Yaghmourrsquos famous book (Embedded Android) httpswwwsafaribooksonlinecomu001o000000YZt6HAATembedded-android9781449327958

bull Kernel boot process

bull httpduartesorggustavoblogpostkernel-boot-process

bull https0xaxgitbooksiolinux-insidescontentInitializationlinux-initialization-4html

bull httposr507docxinuoscomenPERFORMprocess_stateshtml

bull httpstackoverflowcomquestions464483why-do-we-need-a-swapper-task-in-linux

bull httpunixstackexchangecomquestions83322which-process-has-pid-0

bull BinderServiceManager

bull httpwwwmacrobugcomblog20071215decoding-a-service-call-in-android

bull httpwwwcubridorgblogdev-platformbinder-communication-mechanism-of-android-processes

bull httpwwwprogrameringcomaMjMyMDMwATQhtml

And most importantly httpandroidxrefcom700_r1xref

httpswwwlinkedincominsg1993 33georgeshibin1993gmailcom

Thank You for reading this far

httpswwwlinkedincominsg1993 34

Disclaimer

Almost none (okay fine absolutely zilch) of the information that I put up is proprietary to Qualcomm Inc

Some of the source-code hyperlinks to Qualcommrsquos internal repository which is not accessible to others anyway

For all the other stuff I have provided Android-xref links and is openly accessible to all

However I wonrsquot vouch for the correctness of all information presented here Nope

You are welcome to correcteditpresent this material according to your needs

However it would be nice if you could shoot me a mail (at georgeshibin1993gmailcom) andor provide a

reference to the original material Just sayinghellip it would be nice

georgeshibin1993gmailcom

Page 9: Android bootup

INIT RC FILE LINGObull Triggers are strings which are used to match certain events

bull on ltpatterngt lthelliphellipgt - if the pattern is triggered by someone this is executed (ex on early-init)

bull on propertya=b ndash command is executed when property a is set to b

bull Commands are executed when predefined events are triggered (ie on lttriggergt)

bull trigger write chmod chown start stop restart setprop etc

bull Actions are of the form

bull For an action to be executed it is therefore necessary for an event to be triggered

bull Import statements are used to tell init to parse rc files present in different locations

on lttriggergt

ltcommandgt

ltcommandgt

ltcommandgt

httpswwwlinkedincominsg1993 9georgeshibin1993gmailcom

INIT

httpandroidxrefcom700_r1xrefsystemcorerootdirinitrc

on late-inittrigger early-fstrigger fstrigger post-fshelliptrigger early-boottrigger boot

on bootsetprop nettcpdefault_init_rwnd 60class_start core

httpswwwlinkedincominsg1993 10georgeshibin1993gmailcom

INITbull After some initial setup init first proceeds to parse initrc which is the primary rc file

bull All the other rc files are parsed using import statements in initrc

bull Once parsing is done to kickstart execution of servicesdaemons a few triggers have to be explicitly triggered by init itself

bull The first one of these is early-init

bull early-init is the cue to start ueventd for instance as defined in initrc

bull Init now has to start native daemonsservices like Surfaceflinger vold servicemanager healthd etc

httpandroidxrefcom700_r1xrefsystemcoreinitinitcpp688

parserParseConfig(initrc)

hellip

amQueueEventTrigger(early-init)

httpopengrokqualcommcomsourcexrefLAUM00systemcorerootdirinitrc13

on early-init

hellip

start ueventd

httpswwwlinkedincominsg1993 11georgeshibin1993gmailcom

INITbull Init also explicitly triggers event init and late-init When late-init is triggered it triggers event fs which is

when init parses fstab(qcom) entries to mount remaining partitions (system data misc) here

bull After that init basically runs in an infinite while loop on the lookout for services that might need restarting here

bull Among the services started by init one is particularly important for IPC to happen

bull Lets find out more about ServiceManager

httpopengrokqualcommcomsourcexrefLAUM00deviceqcommsm8937_64inittargetrc42

on fs

hellip

mount_all fstabqcom

httpswwwlinkedincominsg1993 12georgeshibin1993gmailcom

A LITTLE SOMETHING ABOUT SERVICEMANAGER

bull Binder is the core of Android and forms the foundation of the IPC mechanism

bull OpenBinder was developed by Be Inc (later Palm Inc) (Tidbit Palm Inc designed the worldrsquos first PDA and one of the first smartphones)

bull Google developed the Binder framework for Android on the basis of OpenBinder

bull OpenBinder allows processes to present interfaces which may be called by other threads Each process maintains a thread pool which may be used to service such requests

bull In OpenBinder an entity called context manager exists maintains all services handles and returns the service handle to client on request

httpswwwlinkedincominsg1993 13georgeshibin1993gmailcom

A LITTLE SOMETHING ABOUT SERVICEMANAGER

bull If a client wants to publishadd a service it has to invoke an entity called context manager If a client wants to get a reference to a service it again has to query the context manager

bull The Context Manager in Android is called the ServiceManager

bull Since ServiceManager is essential for IPC in android it is started as a ldquocriticalrdquo service

bull Source-code at - frameworksnativecmdsservicemanager

bull During initialization ServiceManager itself calls binder_become_context_manager() to inform the binder driver that it is the contextManager

httpswwwlinkedincominsg1993 14georgeshibin1993gmailcom

A LITTLE SOMETHING ABOUT SERVICEMANAGER

bull The kernel binder driver on receiving this ioctl creates a binder node 0

bull Once this is done clients can now query ServiceManager Internally this happens via ioctl(fd paramscmd=GET srv=ldquoSERVICE_NAMErdquo target=0 hellip)

httpopengrokqualcommcomsourcexrefLAUM00kernelmsm-

318driversstagingandroidbinderc2729

binder_context_mgr_node = binder_new_node(proc 0 0)

httpopengrokqualcommcomsourcexrefLAUM00frameworksnativecmdsservicemanagerbinder

c146

int binder_become_context_manager(struct binder_state bs)

return ioctl(bs-gtfd BINDER_SET_CONTEXT_MGR 0)

httpswwwlinkedincominsg1993 15georgeshibin1993gmailcom

A LITTLE SOMETHING ABOUT SERVICEMANAGER01-01 071603022 0 0 I init Starting service ueventd

01-01 071604958 0 0 I init Starting service logd

01-01 071606345 0 0 I init Starting service vold

01-01 071606871 0 0 I init Starting service exec 1 (systembintzdatacheck)

01-01 071608191 0 0 I init Starting service exec 2 (initqcomearly_bootsh)

01-01 071609225 0 0 I init Starting service healthd

01-01 071609290 0 0 I init Starting service cs-early-boot

01-01 071609296 0 0 I init Starting service esepmdaemon

01-01 071609302 0 0 I init Starting service qcom-usb-sh

01-01 071609309 0 0 I init Starting service qseecomd

01-01 071609315 0 0 I init Starting service per_mgr

01-01 071609321 0 0 I init Starting service lmkd

01-01 071609327 0 0 I init Starting service servicemanager01-01 071609335 0 0 I init Starting service surfaceflinger

01-01 071610101 0 0 I init Starting service bootanim

01-01 071612563 0 0 I init Starting service logd-reinit

01-01 071612777 0 0 I init Starting service exec 4 (systembintzdatacheck)

01-01 071612903 0 0 I init Starting service carrier_switcher

01-01 071612911 0 0 I init Starting service exec 5 (systembinbootstat)

01-01 071612977 0 0 I init Starting service qcomsysd

01-01 071612983 0 0 I init Starting service qcom-c_main-sh

01-01 071612990 0 0 I init Starting service cnd

01-01 071612996 0 0 I init Starting service ptt_socket_app

01-01 071613002 0 0 I init Starting service cnss_diag

01-01 071613028 0 0 I init Starting service thermal-engine

01-01 071613034 0 0 I init Starting service wcnss-service

01-01 071613041 0 0 I init Starting service imsstarter

01-01 071613048 0 0 I init Starting service adsprpcd

01-01 071613054 0 0 I init Starting service hvdcp_opti

01-01 071613062 0 0 I init Starting service zygote01-01 071613069 0 0 I init Starting service zygote_secondary

httpswwwlinkedincominsg1993 16georgeshibin1993gmailcom

INITZYGOTE - STARTUP

bull Just like init is parent of all init-services system-server amp every app is spawned by zygote An executable called app_process(3264) is executed which is then known to others as zygote

bull It belongs to main class of services ie if userdata-encryption is enabled once you enter password zygote is restarted

httpandroidxrefcom700_r1xrefsystemcorerootdirinitzygote64_32rc

service zygote systembinapp_process64 -Xzygote systembin --zygote --start-system-server --socket-name=zygote

class main

socket zygote stream 660 root system

onrestart write sysandroid_powerrequest_state wake

onrestart write syspowerstate on

onrestart restart audioserver

onrestart restart cameraserver

onrestart restart media

onrestart restart netd

writepid devcpusetforegroundtasks sysfscgroupstuneforegroundtasks

service zygote_secondary systembinapp_process32 -Xzygote systembin --zygote --socket-name=zygote_secondary

class main

socket zygote_secondary stream 660 root system

onrestart restart zygote

writepid devcpusetforegroundtasks devstuneforegroundtasks

httpswwwlinkedincominsg1993 17georgeshibin1993gmailcom

ZYGOTE

bull App_process is a native proc (written in C++) Source for app_process resides here

bull ndashzygote option passed is to rename the process name from app_process to zygote here

bull comandroidinternalosZygoteInitjava is called (through runtimestart()) which starts systemServer and then polls

bull ndashstart-system_server option passed makes the zygote spawn system_server

bull Zygote uses an entity called ldquoAndroidRuntimerdquo that starts a VM to run Java Runtimestart() starts a new virtual machine As you know all code written in Java runs in a VM

bull Interesting tidbit the main() of ZygoteInitjava is the first piece of Java code that runs since the device was turned on (Reason is that this is the first time VM was created and java bytecode runs in VM)

httpandroidxrefcom700_r1xrefframeworksbasecmdsapp_processapp_maincpp306

if (zygote)

runtimestart(comandroidinternalosZygoteInit args zygote)

httpandroidxrefcom700_r1xrefframeworksbasecorejavacomandroidinternalosZygoteInitjava746

if (startSystemServer)

startSystemServer(abiList socketName)

httpswwwlinkedincominsg1993 18georgeshibin1993gmailcom

ZYGOTE

bull The most important reason behind Zygotersquos existence can be summarized in this one line of code

bull Zygote preloads classes (as in java class files) resources some shared libraries (so files) etc

bull You can find the list of these classes to be preloaded here on your device at systemetcpreloaded-classes Zygote reads this file here

bull On my device running Android Nougat the total number of preloaded classes alone is 4165 to be exact

httpandroidxrefcom700_r1xrefframeworksbasecorejavacomandroidinternalosZygoteInitjava722

preload()

httpswwwlinkedincominsg1993 19georgeshibin1993gmailcom

ZYGOTE

bull So how exactly is preloading helping

bull To know this we come back to one of the important tasks of zygote ie spawning each and every single application process (remember it is the parent process of all application processes)

bull After starting system_server zygote runs in an infinite while loop here

bull It keeps on polling a socket ndash devsocketzygote When you launch an application the request to create a new process comes from system_server to Zygote on this socket The call reaches hereand then it executes a fork system call as shown below

httpandroidxrefcom700_r1xrefframeworksbasecorejavacomandroidinternalosZygoteConnectionjava225

pid = ZygoteforkAndSpecialize(parsedArgsuid parsedArgsgid parsedArgsgids

parsedArgsdebugFlags rlimits parsedArgsmountExternal parsedArgsseInfo

parsedArgsniceName fdsToClose parsedArgsinstructionSet

parsedArgsappDataDir)

httpswwwlinkedincominsg1993 20georgeshibin1993gmailcom

ZYGOTEbull Here is where you will appreciate the virtue of a great design

bull When a process forks it creates a clone of itself It replicates itself in another memory space When this happens to Zygote it creates a clean new Dalvik VM preloaded with all necessary classes and resources that any App will need (the same 4165 I mentioned earlier)

bull Except that it is never copied

bull You see the Linux Kernel implements a strategy called Copy On Write (COW) With COW Linux doesnrsquot actually copy anything Instead it maps the pages of the new process over to those of the parent process and makes copies only when the new process writes to a page But the classeslibrariesresources preloaded by Zygote are all read-only and not modified by any application This means that all processes forked from Zygote are using the exact same copy of the system classes and resources till EOL These preloaded objects live in the Zygote heap

bull This is what saves the time when apps are launched Also the memory saved is worth mentioning as no matter how many applications are started only one copy of the system classes and the resources is ever loaded in RAM

bull Personally I think the reason we still need Zygote (and cannot be replaced by system_server) is because we would like a process that does almost nothing other than fork() so that COW can do its magic Something like system_server would be counterproductive as its own heap and loaded classes would be huge

httpswwwlinkedincominsg1993 21georgeshibin1993gmailcom

ZYGOTEbull Thats pretty much what Zygote does during its lifetime Lets move onto system_server Notice the class name passed

as argument to Zygotersquos fork call for system_server

bull Just like in Zygotersquos case the AndroidRuntime knows how to execute the main() function in comandroidserverSystemServerjava

httpandroidxrefcom700_r1xrefframeworksbasecorejavacomandroidinternalosZygoteInitjava632

String args[] =

--setuid=1000

--setgid=1000

--setgroups=10011002100310041005100610071008100910101018102110323001300230033006300730093010

--capabilities= + capabilities + + capabilities

--nice-name=system_server

--runtime-args

comandroidserverSystemServer

httpandroidxrefcom700_r1xrefframeworksbaseservicesjavacomandroidserverSystemServerjava205

The main entry point from zygote

public static void main(String[] args)

new SystemServer()run()

httpswwwlinkedincominsg1993 22georgeshibin1993gmailcom

SYSTEM-SERVERbull The run() of system_server starts bootstrap-services core-services and some other services

bull Bootstrap-services are a small number of critical services

bull These are ActivityManagerService PowerManagerService DisplayManagerService PackageManagerService UserManagerService and sSensorService Bootstrap services are started almost together as they have internal dependencies with each other

bull Core services are some essential services that do not have dependencies on bootstrap services so can be started some time later One of these is the WindowManagerService

bull After that a couple of services which are not as critical as the above two classes Infact some of them even need not be started for device bootup

httpandroidxrefcom700_r1xrefframeworksbaseservicesjavacomandroidserverSystemServerjava320

try

TracetraceBegin(TraceTRACE_TAG_SYSTEM_SERVER StartServices)

startBootstrapServices()

startCoreServices()

startOtherServices()

httpswwwlinkedincominsg1993 23georgeshibin1993gmailcom

SYSTEM-SERVERbull Later down the line after starting almost all of the criticalcore services the system_server

(ie its main thread) proceeds to notify ActivityManagerService that the system is now ready to execute third-party code (read apps) The ActivityManagerService does some initializations before it can start applications

bull The callback reaches back to system_server main thread where it starts the first app comandroidsystemui here (specifically SystemUiService of systemui component)

bull We are now mostly done with this thread of system_server (the main thread mainly deals with handling messages from other components and redirecting them)

httpandroidxrefcom700_r1xrefframeworksbaseservicesjavacomandroidserverSystemServerjava1275

mActivityManagerServicesystemReady(new Runnable()

Override

public void run()

hellip

try

startSystemUi(context)

catch (Throwable e)

reportWtf(starting System UI e)

httpswwwlinkedincominsg1993 24georgeshibin1993gmailcom

BOOTANIMATION

bull Wondering what is being displayed on the screen during this entire process

bull After init starts what you see is bootanimation

bull The bootanim is a service that displays the bootanimation and is started by init

bull The rc file is parsed by init during startup But init does not start it right away (Notice the disabled)

bull This also means that someone has to explicitly start bootanim This is done by SurfaceFlinger in its init()

httpandroidxrefcom700_r1xrefframeworksbasecmdsbootanimationbootanimrc

service bootanim systembinbootanimation

class core

user graphics

group graphics audio

disabled

oneshot

httpandroidxrefcom700_r1xrefframeworksbaseservicesjavacomandroidserverSystemServerjava1275

start boot animation

startBootAnim()

httpandroidxrefcom700_r1xrefframeworksnativeservicessurfaceflingerSurfaceFlingercpp506

void SurfaceFlingerstartBootAnim()

start boot animation

property_set(servicebootanimexit 0)

property_set(ctlstart bootanim)

httpswwwlinkedincominsg1993 25georgeshibin1993gmailcom

BOOTANIMATION

bull Note that SF doesnrsquot directly spawnfork a process Rather it sets a property ctlstart to bootanim

bull ctl is special because there is no actual property named ctlstartstop (it wonrsquot appear in getprop output)

bull Note the special handling of a property if the property_name starts with ctl

httpandroidxrefcom700_r1xrefsystemcoreinitproperty_servicecpp280

case PROP_MSG_SETPROP

hellip

if(memcmp(msgnamectl4) == 0)

hellip

if (check_control_mac_perms(msgvalue source_ctx ampcr))

handle_control_message((char) msgname + 4 (char) msgvalue)

hellip

else

if (check_mac_perms(msgname source_ctx ampcr))

property_set((char) msgname (char) msgvalue)

hellip

httpswwwlinkedincominsg1993 26georgeshibin1993gmailcom

LAUNCHER

bull When the call reaches init it starts the service which is assigned to ctlstart

bull So when SF sets ctlstart to bootanim init starts the service bootanim

bull Bootanim gets the media files from systemmediabootanimationzip

bull But who stops bootanim Lets get back to system_server to find that out

bull Remember we informed ActivityManagerService that we are ready to executelaunch 3rd party codeapplications here

bull AMS on executing this calls startHomeActivityLocked() Internally this sends an Intent with category IntentCATEGORY_HOME This intent category is special because if an app registers for this intent it means that the application is a Launcher-appHome-screen replacement app

bull On receving this intent Launcher is started as it had registered for the same (see Manifest)

bull Ok Launcher has started but you are still not seeing it on the display

httpswwwlinkedincominsg1993 27georgeshibin1993gmailcom

LAUNCHERbull For Launcher to be displayed bootanimation has to be stopped There is only one entity that can tell SF to stop

bootanim via a binder transaction ie WindowManagerService WindowManagerServicersquosperformEnableScreen() API needs to be invoked

httpandroidxrefcom700_r1xrefframeworksbaseservicescorejavacomandroidserverwmWindowManagerServicejava5866

if (mBootAnimationStopped)

Do this one time

TraceasyncTraceBegin(TraceTRACE_TAG_WINDOW_MANAGER Stop bootanim 0)

try

IBinder surfaceFlinger = ServiceManagergetService(SurfaceFlinger)

if (surfaceFlinger = null)

Slogi(TAG_WM TELLING SURFACE FLINGER WE ARE BOOTED)

Parcel data = Parcelobtain()

datawriteInterfaceToken(androiduiISurfaceComposer)

surfaceFlingertransact(IBinderFIRST_CALL_TRANSACTION BOOT_FINISHED

data null 0)

datarecycle()

catch (RemoteException ex)

Sloge(TAG_WM Boot completed SurfaceFlinger is dead)

mBootAnimationStopped = true

httpswwwlinkedincominsg1993 28georgeshibin1993gmailcom

bull So SF receives a binder call from WindowManagerService with the code IBinderFIRST_CALL_TRANSACTION SurfaceFlinger Binder IPC interface has defined the following

bull The call ultimately reaches bootFinished()

httpandroidxrefcom700_r1xrefframeworksnativeincludeguiISurfaceComposerh177

Note BOOT_FINISHED must remain this value it is called from

Java by ActivityManagerService

BOOT_FINISHED = IBinderFIRST_CALL_TRANSACTION

httpandroidxrefcom700_r1xrefframeworksnativeservicessurfaceflingerSurfaceFlingercpp292

void SurfaceFlingerbootFinished()

hellip

ALOGI(Boot is finished (ld ms) long(ns2ms(duration)) )

mBootFinished = true

stop boot animation

formerly we would just kill the process but we now ask it to exit so it

can choose where to stop the animation

property_set(servicebootanimexit 1)

httpswwwlinkedincominsg1993 29georgeshibin1993gmailcom

BOOTANIMATION

bull SF sets the property serviebootanim to 1 How does this stop bootanim

bull All this while since the time it was started bootanim has been executing playAnimation()

bull While doing so it also periodically calls checkExit()

bull On detecting that this property is set to 1 bootanim gracefully exits

httpandroidxrefcom700_r1xrefframeworksbasecmdsbootanimationBootAnimationcpp387

Allow surface flinger to gracefully request shutdown

char value[PROPERTY_VALUE_MAX]

property_get(servicebootanimexit value 0)

int exitnow = atoi(value)

if (exitnow)

requestExit()

if (mAudioPlayer = NULL)

mAudioPlayer-gtrequestExit()

httpswwwlinkedincominsg1993 30georgeshibin1993gmailcom

BOOT_COMPLETEDbull WindowManager invoked binder transaction to tell SF to stop bootanim

bull After that it calls ActivityManagerrsquos bootAnimationComplete() function

bull In ActivityManagerService finishBooting() is invoked where the property sysboot_completed is set to 1 This property is important because it is the ldquoofficialrdquo way of letting native-servicesdaemons know that boot is now complete

bull After this AMS tells UserController (which is a helper class for handling multi-user functionality) to send the 2 criticalimportant intents

bull Before you unlockswipe the lock screen the intent IntentACTION_LOCKED_BOOT_COMPLETED is sent here

bull Once the user is unlocked (by entering PINswiping-the-lock screen) the intent IntentACTION_BOOT_COMPLETED is sent here This intent is important because it lets Java-services3rd-party apps know that system boot-up is now officially complete and that user is now in the home screen

httpandroidxrefcom700_r1xrefframeworksbaseservicescorejavacomandroidserverwmWindowManagerServicejav

a5899

try

mActivityManagerbootAnimationComplete()

catch (RemoteException e)

httpswwwlinkedincominsg1993 31georgeshibin1993gmailcom

Aaaaand you are now in Home screen

httpswwwlinkedincominsg1993 32georgeshibin1993gmailcom

REFERENCES

bull My highlights on Karim Yaghmourrsquos famous book (Embedded Android) httpswwwsafaribooksonlinecomu001o000000YZt6HAATembedded-android9781449327958

bull Kernel boot process

bull httpduartesorggustavoblogpostkernel-boot-process

bull https0xaxgitbooksiolinux-insidescontentInitializationlinux-initialization-4html

bull httposr507docxinuoscomenPERFORMprocess_stateshtml

bull httpstackoverflowcomquestions464483why-do-we-need-a-swapper-task-in-linux

bull httpunixstackexchangecomquestions83322which-process-has-pid-0

bull BinderServiceManager

bull httpwwwmacrobugcomblog20071215decoding-a-service-call-in-android

bull httpwwwcubridorgblogdev-platformbinder-communication-mechanism-of-android-processes

bull httpwwwprogrameringcomaMjMyMDMwATQhtml

And most importantly httpandroidxrefcom700_r1xref

httpswwwlinkedincominsg1993 33georgeshibin1993gmailcom

Thank You for reading this far

httpswwwlinkedincominsg1993 34

Disclaimer

Almost none (okay fine absolutely zilch) of the information that I put up is proprietary to Qualcomm Inc

Some of the source-code hyperlinks to Qualcommrsquos internal repository which is not accessible to others anyway

For all the other stuff I have provided Android-xref links and is openly accessible to all

However I wonrsquot vouch for the correctness of all information presented here Nope

You are welcome to correcteditpresent this material according to your needs

However it would be nice if you could shoot me a mail (at georgeshibin1993gmailcom) andor provide a

reference to the original material Just sayinghellip it would be nice

georgeshibin1993gmailcom

Page 10: Android bootup

INIT

httpandroidxrefcom700_r1xrefsystemcorerootdirinitrc

on late-inittrigger early-fstrigger fstrigger post-fshelliptrigger early-boottrigger boot

on bootsetprop nettcpdefault_init_rwnd 60class_start core

httpswwwlinkedincominsg1993 10georgeshibin1993gmailcom

INITbull After some initial setup init first proceeds to parse initrc which is the primary rc file

bull All the other rc files are parsed using import statements in initrc

bull Once parsing is done to kickstart execution of servicesdaemons a few triggers have to be explicitly triggered by init itself

bull The first one of these is early-init

bull early-init is the cue to start ueventd for instance as defined in initrc

bull Init now has to start native daemonsservices like Surfaceflinger vold servicemanager healthd etc

httpandroidxrefcom700_r1xrefsystemcoreinitinitcpp688

parserParseConfig(initrc)

hellip

amQueueEventTrigger(early-init)

httpopengrokqualcommcomsourcexrefLAUM00systemcorerootdirinitrc13

on early-init

hellip

start ueventd

httpswwwlinkedincominsg1993 11georgeshibin1993gmailcom

INITbull Init also explicitly triggers event init and late-init When late-init is triggered it triggers event fs which is

when init parses fstab(qcom) entries to mount remaining partitions (system data misc) here

bull After that init basically runs in an infinite while loop on the lookout for services that might need restarting here

bull Among the services started by init one is particularly important for IPC to happen

bull Lets find out more about ServiceManager

httpopengrokqualcommcomsourcexrefLAUM00deviceqcommsm8937_64inittargetrc42

on fs

hellip

mount_all fstabqcom

httpswwwlinkedincominsg1993 12georgeshibin1993gmailcom

A LITTLE SOMETHING ABOUT SERVICEMANAGER

bull Binder is the core of Android and forms the foundation of the IPC mechanism

bull OpenBinder was developed by Be Inc (later Palm Inc) (Tidbit Palm Inc designed the worldrsquos first PDA and one of the first smartphones)

bull Google developed the Binder framework for Android on the basis of OpenBinder

bull OpenBinder allows processes to present interfaces which may be called by other threads Each process maintains a thread pool which may be used to service such requests

bull In OpenBinder an entity called context manager exists maintains all services handles and returns the service handle to client on request

httpswwwlinkedincominsg1993 13georgeshibin1993gmailcom

A LITTLE SOMETHING ABOUT SERVICEMANAGER

bull If a client wants to publishadd a service it has to invoke an entity called context manager If a client wants to get a reference to a service it again has to query the context manager

bull The Context Manager in Android is called the ServiceManager

bull Since ServiceManager is essential for IPC in android it is started as a ldquocriticalrdquo service

bull Source-code at - frameworksnativecmdsservicemanager

bull During initialization ServiceManager itself calls binder_become_context_manager() to inform the binder driver that it is the contextManager

httpswwwlinkedincominsg1993 14georgeshibin1993gmailcom

A LITTLE SOMETHING ABOUT SERVICEMANAGER

bull The kernel binder driver on receiving this ioctl creates a binder node 0

bull Once this is done clients can now query ServiceManager Internally this happens via ioctl(fd paramscmd=GET srv=ldquoSERVICE_NAMErdquo target=0 hellip)

httpopengrokqualcommcomsourcexrefLAUM00kernelmsm-

318driversstagingandroidbinderc2729

binder_context_mgr_node = binder_new_node(proc 0 0)

httpopengrokqualcommcomsourcexrefLAUM00frameworksnativecmdsservicemanagerbinder

c146

int binder_become_context_manager(struct binder_state bs)

return ioctl(bs-gtfd BINDER_SET_CONTEXT_MGR 0)

httpswwwlinkedincominsg1993 15georgeshibin1993gmailcom

A LITTLE SOMETHING ABOUT SERVICEMANAGER01-01 071603022 0 0 I init Starting service ueventd

01-01 071604958 0 0 I init Starting service logd

01-01 071606345 0 0 I init Starting service vold

01-01 071606871 0 0 I init Starting service exec 1 (systembintzdatacheck)

01-01 071608191 0 0 I init Starting service exec 2 (initqcomearly_bootsh)

01-01 071609225 0 0 I init Starting service healthd

01-01 071609290 0 0 I init Starting service cs-early-boot

01-01 071609296 0 0 I init Starting service esepmdaemon

01-01 071609302 0 0 I init Starting service qcom-usb-sh

01-01 071609309 0 0 I init Starting service qseecomd

01-01 071609315 0 0 I init Starting service per_mgr

01-01 071609321 0 0 I init Starting service lmkd

01-01 071609327 0 0 I init Starting service servicemanager01-01 071609335 0 0 I init Starting service surfaceflinger

01-01 071610101 0 0 I init Starting service bootanim

01-01 071612563 0 0 I init Starting service logd-reinit

01-01 071612777 0 0 I init Starting service exec 4 (systembintzdatacheck)

01-01 071612903 0 0 I init Starting service carrier_switcher

01-01 071612911 0 0 I init Starting service exec 5 (systembinbootstat)

01-01 071612977 0 0 I init Starting service qcomsysd

01-01 071612983 0 0 I init Starting service qcom-c_main-sh

01-01 071612990 0 0 I init Starting service cnd

01-01 071612996 0 0 I init Starting service ptt_socket_app

01-01 071613002 0 0 I init Starting service cnss_diag

01-01 071613028 0 0 I init Starting service thermal-engine

01-01 071613034 0 0 I init Starting service wcnss-service

01-01 071613041 0 0 I init Starting service imsstarter

01-01 071613048 0 0 I init Starting service adsprpcd

01-01 071613054 0 0 I init Starting service hvdcp_opti

01-01 071613062 0 0 I init Starting service zygote01-01 071613069 0 0 I init Starting service zygote_secondary

httpswwwlinkedincominsg1993 16georgeshibin1993gmailcom

INITZYGOTE - STARTUP

bull Just like init is parent of all init-services system-server amp every app is spawned by zygote An executable called app_process(3264) is executed which is then known to others as zygote

bull It belongs to main class of services ie if userdata-encryption is enabled once you enter password zygote is restarted

httpandroidxrefcom700_r1xrefsystemcorerootdirinitzygote64_32rc

service zygote systembinapp_process64 -Xzygote systembin --zygote --start-system-server --socket-name=zygote

class main

socket zygote stream 660 root system

onrestart write sysandroid_powerrequest_state wake

onrestart write syspowerstate on

onrestart restart audioserver

onrestart restart cameraserver

onrestart restart media

onrestart restart netd

writepid devcpusetforegroundtasks sysfscgroupstuneforegroundtasks

service zygote_secondary systembinapp_process32 -Xzygote systembin --zygote --socket-name=zygote_secondary

class main

socket zygote_secondary stream 660 root system

onrestart restart zygote

writepid devcpusetforegroundtasks devstuneforegroundtasks

httpswwwlinkedincominsg1993 17georgeshibin1993gmailcom

ZYGOTE

bull App_process is a native proc (written in C++) Source for app_process resides here

bull ndashzygote option passed is to rename the process name from app_process to zygote here

bull comandroidinternalosZygoteInitjava is called (through runtimestart()) which starts systemServer and then polls

bull ndashstart-system_server option passed makes the zygote spawn system_server

bull Zygote uses an entity called ldquoAndroidRuntimerdquo that starts a VM to run Java Runtimestart() starts a new virtual machine As you know all code written in Java runs in a VM

bull Interesting tidbit the main() of ZygoteInitjava is the first piece of Java code that runs since the device was turned on (Reason is that this is the first time VM was created and java bytecode runs in VM)

httpandroidxrefcom700_r1xrefframeworksbasecmdsapp_processapp_maincpp306

if (zygote)

runtimestart(comandroidinternalosZygoteInit args zygote)

httpandroidxrefcom700_r1xrefframeworksbasecorejavacomandroidinternalosZygoteInitjava746

if (startSystemServer)

startSystemServer(abiList socketName)

httpswwwlinkedincominsg1993 18georgeshibin1993gmailcom

ZYGOTE

bull The most important reason behind Zygotersquos existence can be summarized in this one line of code

bull Zygote preloads classes (as in java class files) resources some shared libraries (so files) etc

bull You can find the list of these classes to be preloaded here on your device at systemetcpreloaded-classes Zygote reads this file here

bull On my device running Android Nougat the total number of preloaded classes alone is 4165 to be exact

httpandroidxrefcom700_r1xrefframeworksbasecorejavacomandroidinternalosZygoteInitjava722

preload()

httpswwwlinkedincominsg1993 19georgeshibin1993gmailcom

ZYGOTE

bull So how exactly is preloading helping

bull To know this we come back to one of the important tasks of zygote ie spawning each and every single application process (remember it is the parent process of all application processes)

bull After starting system_server zygote runs in an infinite while loop here

bull It keeps on polling a socket ndash devsocketzygote When you launch an application the request to create a new process comes from system_server to Zygote on this socket The call reaches hereand then it executes a fork system call as shown below

httpandroidxrefcom700_r1xrefframeworksbasecorejavacomandroidinternalosZygoteConnectionjava225

pid = ZygoteforkAndSpecialize(parsedArgsuid parsedArgsgid parsedArgsgids

parsedArgsdebugFlags rlimits parsedArgsmountExternal parsedArgsseInfo

parsedArgsniceName fdsToClose parsedArgsinstructionSet

parsedArgsappDataDir)

httpswwwlinkedincominsg1993 20georgeshibin1993gmailcom

ZYGOTEbull Here is where you will appreciate the virtue of a great design

bull When a process forks it creates a clone of itself It replicates itself in another memory space When this happens to Zygote it creates a clean new Dalvik VM preloaded with all necessary classes and resources that any App will need (the same 4165 I mentioned earlier)

bull Except that it is never copied

bull You see the Linux Kernel implements a strategy called Copy On Write (COW) With COW Linux doesnrsquot actually copy anything Instead it maps the pages of the new process over to those of the parent process and makes copies only when the new process writes to a page But the classeslibrariesresources preloaded by Zygote are all read-only and not modified by any application This means that all processes forked from Zygote are using the exact same copy of the system classes and resources till EOL These preloaded objects live in the Zygote heap

bull This is what saves the time when apps are launched Also the memory saved is worth mentioning as no matter how many applications are started only one copy of the system classes and the resources is ever loaded in RAM

bull Personally I think the reason we still need Zygote (and cannot be replaced by system_server) is because we would like a process that does almost nothing other than fork() so that COW can do its magic Something like system_server would be counterproductive as its own heap and loaded classes would be huge

httpswwwlinkedincominsg1993 21georgeshibin1993gmailcom

ZYGOTEbull Thats pretty much what Zygote does during its lifetime Lets move onto system_server Notice the class name passed

as argument to Zygotersquos fork call for system_server

bull Just like in Zygotersquos case the AndroidRuntime knows how to execute the main() function in comandroidserverSystemServerjava

httpandroidxrefcom700_r1xrefframeworksbasecorejavacomandroidinternalosZygoteInitjava632

String args[] =

--setuid=1000

--setgid=1000

--setgroups=10011002100310041005100610071008100910101018102110323001300230033006300730093010

--capabilities= + capabilities + + capabilities

--nice-name=system_server

--runtime-args

comandroidserverSystemServer

httpandroidxrefcom700_r1xrefframeworksbaseservicesjavacomandroidserverSystemServerjava205

The main entry point from zygote

public static void main(String[] args)

new SystemServer()run()

httpswwwlinkedincominsg1993 22georgeshibin1993gmailcom

SYSTEM-SERVERbull The run() of system_server starts bootstrap-services core-services and some other services

bull Bootstrap-services are a small number of critical services

bull These are ActivityManagerService PowerManagerService DisplayManagerService PackageManagerService UserManagerService and sSensorService Bootstrap services are started almost together as they have internal dependencies with each other

bull Core services are some essential services that do not have dependencies on bootstrap services so can be started some time later One of these is the WindowManagerService

bull After that a couple of services which are not as critical as the above two classes Infact some of them even need not be started for device bootup

httpandroidxrefcom700_r1xrefframeworksbaseservicesjavacomandroidserverSystemServerjava320

try

TracetraceBegin(TraceTRACE_TAG_SYSTEM_SERVER StartServices)

startBootstrapServices()

startCoreServices()

startOtherServices()

httpswwwlinkedincominsg1993 23georgeshibin1993gmailcom

SYSTEM-SERVERbull Later down the line after starting almost all of the criticalcore services the system_server

(ie its main thread) proceeds to notify ActivityManagerService that the system is now ready to execute third-party code (read apps) The ActivityManagerService does some initializations before it can start applications

bull The callback reaches back to system_server main thread where it starts the first app comandroidsystemui here (specifically SystemUiService of systemui component)

bull We are now mostly done with this thread of system_server (the main thread mainly deals with handling messages from other components and redirecting them)

httpandroidxrefcom700_r1xrefframeworksbaseservicesjavacomandroidserverSystemServerjava1275

mActivityManagerServicesystemReady(new Runnable()

Override

public void run()

hellip

try

startSystemUi(context)

catch (Throwable e)

reportWtf(starting System UI e)

httpswwwlinkedincominsg1993 24georgeshibin1993gmailcom

BOOTANIMATION

bull Wondering what is being displayed on the screen during this entire process

bull After init starts what you see is bootanimation

bull The bootanim is a service that displays the bootanimation and is started by init

bull The rc file is parsed by init during startup But init does not start it right away (Notice the disabled)

bull This also means that someone has to explicitly start bootanim This is done by SurfaceFlinger in its init()

httpandroidxrefcom700_r1xrefframeworksbasecmdsbootanimationbootanimrc

service bootanim systembinbootanimation

class core

user graphics

group graphics audio

disabled

oneshot

httpandroidxrefcom700_r1xrefframeworksbaseservicesjavacomandroidserverSystemServerjava1275

start boot animation

startBootAnim()

httpandroidxrefcom700_r1xrefframeworksnativeservicessurfaceflingerSurfaceFlingercpp506

void SurfaceFlingerstartBootAnim()

start boot animation

property_set(servicebootanimexit 0)

property_set(ctlstart bootanim)

httpswwwlinkedincominsg1993 25georgeshibin1993gmailcom

BOOTANIMATION

bull Note that SF doesnrsquot directly spawnfork a process Rather it sets a property ctlstart to bootanim

bull ctl is special because there is no actual property named ctlstartstop (it wonrsquot appear in getprop output)

bull Note the special handling of a property if the property_name starts with ctl

httpandroidxrefcom700_r1xrefsystemcoreinitproperty_servicecpp280

case PROP_MSG_SETPROP

hellip

if(memcmp(msgnamectl4) == 0)

hellip

if (check_control_mac_perms(msgvalue source_ctx ampcr))

handle_control_message((char) msgname + 4 (char) msgvalue)

hellip

else

if (check_mac_perms(msgname source_ctx ampcr))

property_set((char) msgname (char) msgvalue)

hellip

httpswwwlinkedincominsg1993 26georgeshibin1993gmailcom

LAUNCHER

bull When the call reaches init it starts the service which is assigned to ctlstart

bull So when SF sets ctlstart to bootanim init starts the service bootanim

bull Bootanim gets the media files from systemmediabootanimationzip

bull But who stops bootanim Lets get back to system_server to find that out

bull Remember we informed ActivityManagerService that we are ready to executelaunch 3rd party codeapplications here

bull AMS on executing this calls startHomeActivityLocked() Internally this sends an Intent with category IntentCATEGORY_HOME This intent category is special because if an app registers for this intent it means that the application is a Launcher-appHome-screen replacement app

bull On receving this intent Launcher is started as it had registered for the same (see Manifest)

bull Ok Launcher has started but you are still not seeing it on the display

httpswwwlinkedincominsg1993 27georgeshibin1993gmailcom

LAUNCHERbull For Launcher to be displayed bootanimation has to be stopped There is only one entity that can tell SF to stop

bootanim via a binder transaction ie WindowManagerService WindowManagerServicersquosperformEnableScreen() API needs to be invoked

httpandroidxrefcom700_r1xrefframeworksbaseservicescorejavacomandroidserverwmWindowManagerServicejava5866

if (mBootAnimationStopped)

Do this one time

TraceasyncTraceBegin(TraceTRACE_TAG_WINDOW_MANAGER Stop bootanim 0)

try

IBinder surfaceFlinger = ServiceManagergetService(SurfaceFlinger)

if (surfaceFlinger = null)

Slogi(TAG_WM TELLING SURFACE FLINGER WE ARE BOOTED)

Parcel data = Parcelobtain()

datawriteInterfaceToken(androiduiISurfaceComposer)

surfaceFlingertransact(IBinderFIRST_CALL_TRANSACTION BOOT_FINISHED

data null 0)

datarecycle()

catch (RemoteException ex)

Sloge(TAG_WM Boot completed SurfaceFlinger is dead)

mBootAnimationStopped = true

httpswwwlinkedincominsg1993 28georgeshibin1993gmailcom

bull So SF receives a binder call from WindowManagerService with the code IBinderFIRST_CALL_TRANSACTION SurfaceFlinger Binder IPC interface has defined the following

bull The call ultimately reaches bootFinished()

httpandroidxrefcom700_r1xrefframeworksnativeincludeguiISurfaceComposerh177

Note BOOT_FINISHED must remain this value it is called from

Java by ActivityManagerService

BOOT_FINISHED = IBinderFIRST_CALL_TRANSACTION

httpandroidxrefcom700_r1xrefframeworksnativeservicessurfaceflingerSurfaceFlingercpp292

void SurfaceFlingerbootFinished()

hellip

ALOGI(Boot is finished (ld ms) long(ns2ms(duration)) )

mBootFinished = true

stop boot animation

formerly we would just kill the process but we now ask it to exit so it

can choose where to stop the animation

property_set(servicebootanimexit 1)

httpswwwlinkedincominsg1993 29georgeshibin1993gmailcom

BOOTANIMATION

bull SF sets the property serviebootanim to 1 How does this stop bootanim

bull All this while since the time it was started bootanim has been executing playAnimation()

bull While doing so it also periodically calls checkExit()

bull On detecting that this property is set to 1 bootanim gracefully exits

httpandroidxrefcom700_r1xrefframeworksbasecmdsbootanimationBootAnimationcpp387

Allow surface flinger to gracefully request shutdown

char value[PROPERTY_VALUE_MAX]

property_get(servicebootanimexit value 0)

int exitnow = atoi(value)

if (exitnow)

requestExit()

if (mAudioPlayer = NULL)

mAudioPlayer-gtrequestExit()

httpswwwlinkedincominsg1993 30georgeshibin1993gmailcom

BOOT_COMPLETEDbull WindowManager invoked binder transaction to tell SF to stop bootanim

bull After that it calls ActivityManagerrsquos bootAnimationComplete() function

bull In ActivityManagerService finishBooting() is invoked where the property sysboot_completed is set to 1 This property is important because it is the ldquoofficialrdquo way of letting native-servicesdaemons know that boot is now complete

bull After this AMS tells UserController (which is a helper class for handling multi-user functionality) to send the 2 criticalimportant intents

bull Before you unlockswipe the lock screen the intent IntentACTION_LOCKED_BOOT_COMPLETED is sent here

bull Once the user is unlocked (by entering PINswiping-the-lock screen) the intent IntentACTION_BOOT_COMPLETED is sent here This intent is important because it lets Java-services3rd-party apps know that system boot-up is now officially complete and that user is now in the home screen

httpandroidxrefcom700_r1xrefframeworksbaseservicescorejavacomandroidserverwmWindowManagerServicejav

a5899

try

mActivityManagerbootAnimationComplete()

catch (RemoteException e)

httpswwwlinkedincominsg1993 31georgeshibin1993gmailcom

Aaaaand you are now in Home screen

httpswwwlinkedincominsg1993 32georgeshibin1993gmailcom

REFERENCES

bull My highlights on Karim Yaghmourrsquos famous book (Embedded Android) httpswwwsafaribooksonlinecomu001o000000YZt6HAATembedded-android9781449327958

bull Kernel boot process

bull httpduartesorggustavoblogpostkernel-boot-process

bull https0xaxgitbooksiolinux-insidescontentInitializationlinux-initialization-4html

bull httposr507docxinuoscomenPERFORMprocess_stateshtml

bull httpstackoverflowcomquestions464483why-do-we-need-a-swapper-task-in-linux

bull httpunixstackexchangecomquestions83322which-process-has-pid-0

bull BinderServiceManager

bull httpwwwmacrobugcomblog20071215decoding-a-service-call-in-android

bull httpwwwcubridorgblogdev-platformbinder-communication-mechanism-of-android-processes

bull httpwwwprogrameringcomaMjMyMDMwATQhtml

And most importantly httpandroidxrefcom700_r1xref

httpswwwlinkedincominsg1993 33georgeshibin1993gmailcom

Thank You for reading this far

httpswwwlinkedincominsg1993 34

Disclaimer

Almost none (okay fine absolutely zilch) of the information that I put up is proprietary to Qualcomm Inc

Some of the source-code hyperlinks to Qualcommrsquos internal repository which is not accessible to others anyway

For all the other stuff I have provided Android-xref links and is openly accessible to all

However I wonrsquot vouch for the correctness of all information presented here Nope

You are welcome to correcteditpresent this material according to your needs

However it would be nice if you could shoot me a mail (at georgeshibin1993gmailcom) andor provide a

reference to the original material Just sayinghellip it would be nice

georgeshibin1993gmailcom

Page 11: Android bootup

INITbull After some initial setup init first proceeds to parse initrc which is the primary rc file

bull All the other rc files are parsed using import statements in initrc

bull Once parsing is done to kickstart execution of servicesdaemons a few triggers have to be explicitly triggered by init itself

bull The first one of these is early-init

bull early-init is the cue to start ueventd for instance as defined in initrc

bull Init now has to start native daemonsservices like Surfaceflinger vold servicemanager healthd etc

httpandroidxrefcom700_r1xrefsystemcoreinitinitcpp688

parserParseConfig(initrc)

hellip

amQueueEventTrigger(early-init)

httpopengrokqualcommcomsourcexrefLAUM00systemcorerootdirinitrc13

on early-init

hellip

start ueventd

httpswwwlinkedincominsg1993 11georgeshibin1993gmailcom

INITbull Init also explicitly triggers event init and late-init When late-init is triggered it triggers event fs which is

when init parses fstab(qcom) entries to mount remaining partitions (system data misc) here

bull After that init basically runs in an infinite while loop on the lookout for services that might need restarting here

bull Among the services started by init one is particularly important for IPC to happen

bull Lets find out more about ServiceManager

httpopengrokqualcommcomsourcexrefLAUM00deviceqcommsm8937_64inittargetrc42

on fs

hellip

mount_all fstabqcom

httpswwwlinkedincominsg1993 12georgeshibin1993gmailcom

A LITTLE SOMETHING ABOUT SERVICEMANAGER

bull Binder is the core of Android and forms the foundation of the IPC mechanism

bull OpenBinder was developed by Be Inc (later Palm Inc) (Tidbit Palm Inc designed the worldrsquos first PDA and one of the first smartphones)

bull Google developed the Binder framework for Android on the basis of OpenBinder

bull OpenBinder allows processes to present interfaces which may be called by other threads Each process maintains a thread pool which may be used to service such requests

bull In OpenBinder an entity called context manager exists maintains all services handles and returns the service handle to client on request

httpswwwlinkedincominsg1993 13georgeshibin1993gmailcom

A LITTLE SOMETHING ABOUT SERVICEMANAGER

bull If a client wants to publishadd a service it has to invoke an entity called context manager If a client wants to get a reference to a service it again has to query the context manager

bull The Context Manager in Android is called the ServiceManager

bull Since ServiceManager is essential for IPC in android it is started as a ldquocriticalrdquo service

bull Source-code at - frameworksnativecmdsservicemanager

bull During initialization ServiceManager itself calls binder_become_context_manager() to inform the binder driver that it is the contextManager

httpswwwlinkedincominsg1993 14georgeshibin1993gmailcom

A LITTLE SOMETHING ABOUT SERVICEMANAGER

bull The kernel binder driver on receiving this ioctl creates a binder node 0

bull Once this is done clients can now query ServiceManager Internally this happens via ioctl(fd paramscmd=GET srv=ldquoSERVICE_NAMErdquo target=0 hellip)

httpopengrokqualcommcomsourcexrefLAUM00kernelmsm-

318driversstagingandroidbinderc2729

binder_context_mgr_node = binder_new_node(proc 0 0)

httpopengrokqualcommcomsourcexrefLAUM00frameworksnativecmdsservicemanagerbinder

c146

int binder_become_context_manager(struct binder_state bs)

return ioctl(bs-gtfd BINDER_SET_CONTEXT_MGR 0)

httpswwwlinkedincominsg1993 15georgeshibin1993gmailcom

A LITTLE SOMETHING ABOUT SERVICEMANAGER01-01 071603022 0 0 I init Starting service ueventd

01-01 071604958 0 0 I init Starting service logd

01-01 071606345 0 0 I init Starting service vold

01-01 071606871 0 0 I init Starting service exec 1 (systembintzdatacheck)

01-01 071608191 0 0 I init Starting service exec 2 (initqcomearly_bootsh)

01-01 071609225 0 0 I init Starting service healthd

01-01 071609290 0 0 I init Starting service cs-early-boot

01-01 071609296 0 0 I init Starting service esepmdaemon

01-01 071609302 0 0 I init Starting service qcom-usb-sh

01-01 071609309 0 0 I init Starting service qseecomd

01-01 071609315 0 0 I init Starting service per_mgr

01-01 071609321 0 0 I init Starting service lmkd

01-01 071609327 0 0 I init Starting service servicemanager01-01 071609335 0 0 I init Starting service surfaceflinger

01-01 071610101 0 0 I init Starting service bootanim

01-01 071612563 0 0 I init Starting service logd-reinit

01-01 071612777 0 0 I init Starting service exec 4 (systembintzdatacheck)

01-01 071612903 0 0 I init Starting service carrier_switcher

01-01 071612911 0 0 I init Starting service exec 5 (systembinbootstat)

01-01 071612977 0 0 I init Starting service qcomsysd

01-01 071612983 0 0 I init Starting service qcom-c_main-sh

01-01 071612990 0 0 I init Starting service cnd

01-01 071612996 0 0 I init Starting service ptt_socket_app

01-01 071613002 0 0 I init Starting service cnss_diag

01-01 071613028 0 0 I init Starting service thermal-engine

01-01 071613034 0 0 I init Starting service wcnss-service

01-01 071613041 0 0 I init Starting service imsstarter

01-01 071613048 0 0 I init Starting service adsprpcd

01-01 071613054 0 0 I init Starting service hvdcp_opti

01-01 071613062 0 0 I init Starting service zygote01-01 071613069 0 0 I init Starting service zygote_secondary

httpswwwlinkedincominsg1993 16georgeshibin1993gmailcom

INITZYGOTE - STARTUP

bull Just like init is parent of all init-services system-server amp every app is spawned by zygote An executable called app_process(3264) is executed which is then known to others as zygote

bull It belongs to main class of services ie if userdata-encryption is enabled once you enter password zygote is restarted

httpandroidxrefcom700_r1xrefsystemcorerootdirinitzygote64_32rc

service zygote systembinapp_process64 -Xzygote systembin --zygote --start-system-server --socket-name=zygote

class main

socket zygote stream 660 root system

onrestart write sysandroid_powerrequest_state wake

onrestart write syspowerstate on

onrestart restart audioserver

onrestart restart cameraserver

onrestart restart media

onrestart restart netd

writepid devcpusetforegroundtasks sysfscgroupstuneforegroundtasks

service zygote_secondary systembinapp_process32 -Xzygote systembin --zygote --socket-name=zygote_secondary

class main

socket zygote_secondary stream 660 root system

onrestart restart zygote

writepid devcpusetforegroundtasks devstuneforegroundtasks

httpswwwlinkedincominsg1993 17georgeshibin1993gmailcom

ZYGOTE

bull App_process is a native proc (written in C++) Source for app_process resides here

bull ndashzygote option passed is to rename the process name from app_process to zygote here

bull comandroidinternalosZygoteInitjava is called (through runtimestart()) which starts systemServer and then polls

bull ndashstart-system_server option passed makes the zygote spawn system_server

bull Zygote uses an entity called ldquoAndroidRuntimerdquo that starts a VM to run Java Runtimestart() starts a new virtual machine As you know all code written in Java runs in a VM

bull Interesting tidbit the main() of ZygoteInitjava is the first piece of Java code that runs since the device was turned on (Reason is that this is the first time VM was created and java bytecode runs in VM)

httpandroidxrefcom700_r1xrefframeworksbasecmdsapp_processapp_maincpp306

if (zygote)

runtimestart(comandroidinternalosZygoteInit args zygote)

httpandroidxrefcom700_r1xrefframeworksbasecorejavacomandroidinternalosZygoteInitjava746

if (startSystemServer)

startSystemServer(abiList socketName)

httpswwwlinkedincominsg1993 18georgeshibin1993gmailcom

ZYGOTE

bull The most important reason behind Zygotersquos existence can be summarized in this one line of code

bull Zygote preloads classes (as in java class files) resources some shared libraries (so files) etc

bull You can find the list of these classes to be preloaded here on your device at systemetcpreloaded-classes Zygote reads this file here

bull On my device running Android Nougat the total number of preloaded classes alone is 4165 to be exact

httpandroidxrefcom700_r1xrefframeworksbasecorejavacomandroidinternalosZygoteInitjava722

preload()

httpswwwlinkedincominsg1993 19georgeshibin1993gmailcom

ZYGOTE

bull So how exactly is preloading helping

bull To know this we come back to one of the important tasks of zygote ie spawning each and every single application process (remember it is the parent process of all application processes)

bull After starting system_server zygote runs in an infinite while loop here

bull It keeps on polling a socket ndash devsocketzygote When you launch an application the request to create a new process comes from system_server to Zygote on this socket The call reaches hereand then it executes a fork system call as shown below

httpandroidxrefcom700_r1xrefframeworksbasecorejavacomandroidinternalosZygoteConnectionjava225

pid = ZygoteforkAndSpecialize(parsedArgsuid parsedArgsgid parsedArgsgids

parsedArgsdebugFlags rlimits parsedArgsmountExternal parsedArgsseInfo

parsedArgsniceName fdsToClose parsedArgsinstructionSet

parsedArgsappDataDir)

httpswwwlinkedincominsg1993 20georgeshibin1993gmailcom

ZYGOTEbull Here is where you will appreciate the virtue of a great design

bull When a process forks it creates a clone of itself It replicates itself in another memory space When this happens to Zygote it creates a clean new Dalvik VM preloaded with all necessary classes and resources that any App will need (the same 4165 I mentioned earlier)

bull Except that it is never copied

bull You see the Linux Kernel implements a strategy called Copy On Write (COW) With COW Linux doesnrsquot actually copy anything Instead it maps the pages of the new process over to those of the parent process and makes copies only when the new process writes to a page But the classeslibrariesresources preloaded by Zygote are all read-only and not modified by any application This means that all processes forked from Zygote are using the exact same copy of the system classes and resources till EOL These preloaded objects live in the Zygote heap

bull This is what saves the time when apps are launched Also the memory saved is worth mentioning as no matter how many applications are started only one copy of the system classes and the resources is ever loaded in RAM

bull Personally I think the reason we still need Zygote (and cannot be replaced by system_server) is because we would like a process that does almost nothing other than fork() so that COW can do its magic Something like system_server would be counterproductive as its own heap and loaded classes would be huge

httpswwwlinkedincominsg1993 21georgeshibin1993gmailcom

ZYGOTEbull Thats pretty much what Zygote does during its lifetime Lets move onto system_server Notice the class name passed

as argument to Zygotersquos fork call for system_server

bull Just like in Zygotersquos case the AndroidRuntime knows how to execute the main() function in comandroidserverSystemServerjava

httpandroidxrefcom700_r1xrefframeworksbasecorejavacomandroidinternalosZygoteInitjava632

String args[] =

--setuid=1000

--setgid=1000

--setgroups=10011002100310041005100610071008100910101018102110323001300230033006300730093010

--capabilities= + capabilities + + capabilities

--nice-name=system_server

--runtime-args

comandroidserverSystemServer

httpandroidxrefcom700_r1xrefframeworksbaseservicesjavacomandroidserverSystemServerjava205

The main entry point from zygote

public static void main(String[] args)

new SystemServer()run()

httpswwwlinkedincominsg1993 22georgeshibin1993gmailcom

SYSTEM-SERVERbull The run() of system_server starts bootstrap-services core-services and some other services

bull Bootstrap-services are a small number of critical services

bull These are ActivityManagerService PowerManagerService DisplayManagerService PackageManagerService UserManagerService and sSensorService Bootstrap services are started almost together as they have internal dependencies with each other

bull Core services are some essential services that do not have dependencies on bootstrap services so can be started some time later One of these is the WindowManagerService

bull After that a couple of services which are not as critical as the above two classes Infact some of them even need not be started for device bootup

httpandroidxrefcom700_r1xrefframeworksbaseservicesjavacomandroidserverSystemServerjava320

try

TracetraceBegin(TraceTRACE_TAG_SYSTEM_SERVER StartServices)

startBootstrapServices()

startCoreServices()

startOtherServices()

httpswwwlinkedincominsg1993 23georgeshibin1993gmailcom

SYSTEM-SERVERbull Later down the line after starting almost all of the criticalcore services the system_server

(ie its main thread) proceeds to notify ActivityManagerService that the system is now ready to execute third-party code (read apps) The ActivityManagerService does some initializations before it can start applications

bull The callback reaches back to system_server main thread where it starts the first app comandroidsystemui here (specifically SystemUiService of systemui component)

bull We are now mostly done with this thread of system_server (the main thread mainly deals with handling messages from other components and redirecting them)

httpandroidxrefcom700_r1xrefframeworksbaseservicesjavacomandroidserverSystemServerjava1275

mActivityManagerServicesystemReady(new Runnable()

Override

public void run()

hellip

try

startSystemUi(context)

catch (Throwable e)

reportWtf(starting System UI e)

httpswwwlinkedincominsg1993 24georgeshibin1993gmailcom

BOOTANIMATION

bull Wondering what is being displayed on the screen during this entire process

bull After init starts what you see is bootanimation

bull The bootanim is a service that displays the bootanimation and is started by init

bull The rc file is parsed by init during startup But init does not start it right away (Notice the disabled)

bull This also means that someone has to explicitly start bootanim This is done by SurfaceFlinger in its init()

httpandroidxrefcom700_r1xrefframeworksbasecmdsbootanimationbootanimrc

service bootanim systembinbootanimation

class core

user graphics

group graphics audio

disabled

oneshot

httpandroidxrefcom700_r1xrefframeworksbaseservicesjavacomandroidserverSystemServerjava1275

start boot animation

startBootAnim()

httpandroidxrefcom700_r1xrefframeworksnativeservicessurfaceflingerSurfaceFlingercpp506

void SurfaceFlingerstartBootAnim()

start boot animation

property_set(servicebootanimexit 0)

property_set(ctlstart bootanim)

httpswwwlinkedincominsg1993 25georgeshibin1993gmailcom

BOOTANIMATION

bull Note that SF doesnrsquot directly spawnfork a process Rather it sets a property ctlstart to bootanim

bull ctl is special because there is no actual property named ctlstartstop (it wonrsquot appear in getprop output)

bull Note the special handling of a property if the property_name starts with ctl

httpandroidxrefcom700_r1xrefsystemcoreinitproperty_servicecpp280

case PROP_MSG_SETPROP

hellip

if(memcmp(msgnamectl4) == 0)

hellip

if (check_control_mac_perms(msgvalue source_ctx ampcr))

handle_control_message((char) msgname + 4 (char) msgvalue)

hellip

else

if (check_mac_perms(msgname source_ctx ampcr))

property_set((char) msgname (char) msgvalue)

hellip

httpswwwlinkedincominsg1993 26georgeshibin1993gmailcom

LAUNCHER

bull When the call reaches init it starts the service which is assigned to ctlstart

bull So when SF sets ctlstart to bootanim init starts the service bootanim

bull Bootanim gets the media files from systemmediabootanimationzip

bull But who stops bootanim Lets get back to system_server to find that out

bull Remember we informed ActivityManagerService that we are ready to executelaunch 3rd party codeapplications here

bull AMS on executing this calls startHomeActivityLocked() Internally this sends an Intent with category IntentCATEGORY_HOME This intent category is special because if an app registers for this intent it means that the application is a Launcher-appHome-screen replacement app

bull On receving this intent Launcher is started as it had registered for the same (see Manifest)

bull Ok Launcher has started but you are still not seeing it on the display

httpswwwlinkedincominsg1993 27georgeshibin1993gmailcom

LAUNCHERbull For Launcher to be displayed bootanimation has to be stopped There is only one entity that can tell SF to stop

bootanim via a binder transaction ie WindowManagerService WindowManagerServicersquosperformEnableScreen() API needs to be invoked

httpandroidxrefcom700_r1xrefframeworksbaseservicescorejavacomandroidserverwmWindowManagerServicejava5866

if (mBootAnimationStopped)

Do this one time

TraceasyncTraceBegin(TraceTRACE_TAG_WINDOW_MANAGER Stop bootanim 0)

try

IBinder surfaceFlinger = ServiceManagergetService(SurfaceFlinger)

if (surfaceFlinger = null)

Slogi(TAG_WM TELLING SURFACE FLINGER WE ARE BOOTED)

Parcel data = Parcelobtain()

datawriteInterfaceToken(androiduiISurfaceComposer)

surfaceFlingertransact(IBinderFIRST_CALL_TRANSACTION BOOT_FINISHED

data null 0)

datarecycle()

catch (RemoteException ex)

Sloge(TAG_WM Boot completed SurfaceFlinger is dead)

mBootAnimationStopped = true

httpswwwlinkedincominsg1993 28georgeshibin1993gmailcom

bull So SF receives a binder call from WindowManagerService with the code IBinderFIRST_CALL_TRANSACTION SurfaceFlinger Binder IPC interface has defined the following

bull The call ultimately reaches bootFinished()

httpandroidxrefcom700_r1xrefframeworksnativeincludeguiISurfaceComposerh177

Note BOOT_FINISHED must remain this value it is called from

Java by ActivityManagerService

BOOT_FINISHED = IBinderFIRST_CALL_TRANSACTION

httpandroidxrefcom700_r1xrefframeworksnativeservicessurfaceflingerSurfaceFlingercpp292

void SurfaceFlingerbootFinished()

hellip

ALOGI(Boot is finished (ld ms) long(ns2ms(duration)) )

mBootFinished = true

stop boot animation

formerly we would just kill the process but we now ask it to exit so it

can choose where to stop the animation

property_set(servicebootanimexit 1)

httpswwwlinkedincominsg1993 29georgeshibin1993gmailcom

BOOTANIMATION

bull SF sets the property serviebootanim to 1 How does this stop bootanim

bull All this while since the time it was started bootanim has been executing playAnimation()

bull While doing so it also periodically calls checkExit()

bull On detecting that this property is set to 1 bootanim gracefully exits

httpandroidxrefcom700_r1xrefframeworksbasecmdsbootanimationBootAnimationcpp387

Allow surface flinger to gracefully request shutdown

char value[PROPERTY_VALUE_MAX]

property_get(servicebootanimexit value 0)

int exitnow = atoi(value)

if (exitnow)

requestExit()

if (mAudioPlayer = NULL)

mAudioPlayer-gtrequestExit()

httpswwwlinkedincominsg1993 30georgeshibin1993gmailcom

BOOT_COMPLETEDbull WindowManager invoked binder transaction to tell SF to stop bootanim

bull After that it calls ActivityManagerrsquos bootAnimationComplete() function

bull In ActivityManagerService finishBooting() is invoked where the property sysboot_completed is set to 1 This property is important because it is the ldquoofficialrdquo way of letting native-servicesdaemons know that boot is now complete

bull After this AMS tells UserController (which is a helper class for handling multi-user functionality) to send the 2 criticalimportant intents

bull Before you unlockswipe the lock screen the intent IntentACTION_LOCKED_BOOT_COMPLETED is sent here

bull Once the user is unlocked (by entering PINswiping-the-lock screen) the intent IntentACTION_BOOT_COMPLETED is sent here This intent is important because it lets Java-services3rd-party apps know that system boot-up is now officially complete and that user is now in the home screen

httpandroidxrefcom700_r1xrefframeworksbaseservicescorejavacomandroidserverwmWindowManagerServicejav

a5899

try

mActivityManagerbootAnimationComplete()

catch (RemoteException e)

httpswwwlinkedincominsg1993 31georgeshibin1993gmailcom

Aaaaand you are now in Home screen

httpswwwlinkedincominsg1993 32georgeshibin1993gmailcom

REFERENCES

bull My highlights on Karim Yaghmourrsquos famous book (Embedded Android) httpswwwsafaribooksonlinecomu001o000000YZt6HAATembedded-android9781449327958

bull Kernel boot process

bull httpduartesorggustavoblogpostkernel-boot-process

bull https0xaxgitbooksiolinux-insidescontentInitializationlinux-initialization-4html

bull httposr507docxinuoscomenPERFORMprocess_stateshtml

bull httpstackoverflowcomquestions464483why-do-we-need-a-swapper-task-in-linux

bull httpunixstackexchangecomquestions83322which-process-has-pid-0

bull BinderServiceManager

bull httpwwwmacrobugcomblog20071215decoding-a-service-call-in-android

bull httpwwwcubridorgblogdev-platformbinder-communication-mechanism-of-android-processes

bull httpwwwprogrameringcomaMjMyMDMwATQhtml

And most importantly httpandroidxrefcom700_r1xref

httpswwwlinkedincominsg1993 33georgeshibin1993gmailcom

Thank You for reading this far

httpswwwlinkedincominsg1993 34

Disclaimer

Almost none (okay fine absolutely zilch) of the information that I put up is proprietary to Qualcomm Inc

Some of the source-code hyperlinks to Qualcommrsquos internal repository which is not accessible to others anyway

For all the other stuff I have provided Android-xref links and is openly accessible to all

However I wonrsquot vouch for the correctness of all information presented here Nope

You are welcome to correcteditpresent this material according to your needs

However it would be nice if you could shoot me a mail (at georgeshibin1993gmailcom) andor provide a

reference to the original material Just sayinghellip it would be nice

georgeshibin1993gmailcom

Page 12: Android bootup

INITbull Init also explicitly triggers event init and late-init When late-init is triggered it triggers event fs which is

when init parses fstab(qcom) entries to mount remaining partitions (system data misc) here

bull After that init basically runs in an infinite while loop on the lookout for services that might need restarting here

bull Among the services started by init one is particularly important for IPC to happen

bull Lets find out more about ServiceManager

httpopengrokqualcommcomsourcexrefLAUM00deviceqcommsm8937_64inittargetrc42

on fs

hellip

mount_all fstabqcom

httpswwwlinkedincominsg1993 12georgeshibin1993gmailcom

A LITTLE SOMETHING ABOUT SERVICEMANAGER

bull Binder is the core of Android and forms the foundation of the IPC mechanism

bull OpenBinder was developed by Be Inc (later Palm Inc) (Tidbit Palm Inc designed the worldrsquos first PDA and one of the first smartphones)

bull Google developed the Binder framework for Android on the basis of OpenBinder

bull OpenBinder allows processes to present interfaces which may be called by other threads Each process maintains a thread pool which may be used to service such requests

bull In OpenBinder an entity called context manager exists maintains all services handles and returns the service handle to client on request

httpswwwlinkedincominsg1993 13georgeshibin1993gmailcom

A LITTLE SOMETHING ABOUT SERVICEMANAGER

bull If a client wants to publishadd a service it has to invoke an entity called context manager If a client wants to get a reference to a service it again has to query the context manager

bull The Context Manager in Android is called the ServiceManager

bull Since ServiceManager is essential for IPC in android it is started as a ldquocriticalrdquo service

bull Source-code at - frameworksnativecmdsservicemanager

bull During initialization ServiceManager itself calls binder_become_context_manager() to inform the binder driver that it is the contextManager

httpswwwlinkedincominsg1993 14georgeshibin1993gmailcom

A LITTLE SOMETHING ABOUT SERVICEMANAGER

bull The kernel binder driver on receiving this ioctl creates a binder node 0

bull Once this is done clients can now query ServiceManager Internally this happens via ioctl(fd paramscmd=GET srv=ldquoSERVICE_NAMErdquo target=0 hellip)

httpopengrokqualcommcomsourcexrefLAUM00kernelmsm-

318driversstagingandroidbinderc2729

binder_context_mgr_node = binder_new_node(proc 0 0)

httpopengrokqualcommcomsourcexrefLAUM00frameworksnativecmdsservicemanagerbinder

c146

int binder_become_context_manager(struct binder_state bs)

return ioctl(bs-gtfd BINDER_SET_CONTEXT_MGR 0)

httpswwwlinkedincominsg1993 15georgeshibin1993gmailcom

A LITTLE SOMETHING ABOUT SERVICEMANAGER01-01 071603022 0 0 I init Starting service ueventd

01-01 071604958 0 0 I init Starting service logd

01-01 071606345 0 0 I init Starting service vold

01-01 071606871 0 0 I init Starting service exec 1 (systembintzdatacheck)

01-01 071608191 0 0 I init Starting service exec 2 (initqcomearly_bootsh)

01-01 071609225 0 0 I init Starting service healthd

01-01 071609290 0 0 I init Starting service cs-early-boot

01-01 071609296 0 0 I init Starting service esepmdaemon

01-01 071609302 0 0 I init Starting service qcom-usb-sh

01-01 071609309 0 0 I init Starting service qseecomd

01-01 071609315 0 0 I init Starting service per_mgr

01-01 071609321 0 0 I init Starting service lmkd

01-01 071609327 0 0 I init Starting service servicemanager01-01 071609335 0 0 I init Starting service surfaceflinger

01-01 071610101 0 0 I init Starting service bootanim

01-01 071612563 0 0 I init Starting service logd-reinit

01-01 071612777 0 0 I init Starting service exec 4 (systembintzdatacheck)

01-01 071612903 0 0 I init Starting service carrier_switcher

01-01 071612911 0 0 I init Starting service exec 5 (systembinbootstat)

01-01 071612977 0 0 I init Starting service qcomsysd

01-01 071612983 0 0 I init Starting service qcom-c_main-sh

01-01 071612990 0 0 I init Starting service cnd

01-01 071612996 0 0 I init Starting service ptt_socket_app

01-01 071613002 0 0 I init Starting service cnss_diag

01-01 071613028 0 0 I init Starting service thermal-engine

01-01 071613034 0 0 I init Starting service wcnss-service

01-01 071613041 0 0 I init Starting service imsstarter

01-01 071613048 0 0 I init Starting service adsprpcd

01-01 071613054 0 0 I init Starting service hvdcp_opti

01-01 071613062 0 0 I init Starting service zygote01-01 071613069 0 0 I init Starting service zygote_secondary

httpswwwlinkedincominsg1993 16georgeshibin1993gmailcom

INITZYGOTE - STARTUP

bull Just like init is parent of all init-services system-server amp every app is spawned by zygote An executable called app_process(3264) is executed which is then known to others as zygote

bull It belongs to main class of services ie if userdata-encryption is enabled once you enter password zygote is restarted

httpandroidxrefcom700_r1xrefsystemcorerootdirinitzygote64_32rc

service zygote systembinapp_process64 -Xzygote systembin --zygote --start-system-server --socket-name=zygote

class main

socket zygote stream 660 root system

onrestart write sysandroid_powerrequest_state wake

onrestart write syspowerstate on

onrestart restart audioserver

onrestart restart cameraserver

onrestart restart media

onrestart restart netd

writepid devcpusetforegroundtasks sysfscgroupstuneforegroundtasks

service zygote_secondary systembinapp_process32 -Xzygote systembin --zygote --socket-name=zygote_secondary

class main

socket zygote_secondary stream 660 root system

onrestart restart zygote

writepid devcpusetforegroundtasks devstuneforegroundtasks

httpswwwlinkedincominsg1993 17georgeshibin1993gmailcom

ZYGOTE

bull App_process is a native proc (written in C++) Source for app_process resides here

bull ndashzygote option passed is to rename the process name from app_process to zygote here

bull comandroidinternalosZygoteInitjava is called (through runtimestart()) which starts systemServer and then polls

bull ndashstart-system_server option passed makes the zygote spawn system_server

bull Zygote uses an entity called ldquoAndroidRuntimerdquo that starts a VM to run Java Runtimestart() starts a new virtual machine As you know all code written in Java runs in a VM

bull Interesting tidbit the main() of ZygoteInitjava is the first piece of Java code that runs since the device was turned on (Reason is that this is the first time VM was created and java bytecode runs in VM)

httpandroidxrefcom700_r1xrefframeworksbasecmdsapp_processapp_maincpp306

if (zygote)

runtimestart(comandroidinternalosZygoteInit args zygote)

httpandroidxrefcom700_r1xrefframeworksbasecorejavacomandroidinternalosZygoteInitjava746

if (startSystemServer)

startSystemServer(abiList socketName)

httpswwwlinkedincominsg1993 18georgeshibin1993gmailcom

ZYGOTE

bull The most important reason behind Zygotersquos existence can be summarized in this one line of code

bull Zygote preloads classes (as in java class files) resources some shared libraries (so files) etc

bull You can find the list of these classes to be preloaded here on your device at systemetcpreloaded-classes Zygote reads this file here

bull On my device running Android Nougat the total number of preloaded classes alone is 4165 to be exact

httpandroidxrefcom700_r1xrefframeworksbasecorejavacomandroidinternalosZygoteInitjava722

preload()

httpswwwlinkedincominsg1993 19georgeshibin1993gmailcom

ZYGOTE

bull So how exactly is preloading helping

bull To know this we come back to one of the important tasks of zygote ie spawning each and every single application process (remember it is the parent process of all application processes)

bull After starting system_server zygote runs in an infinite while loop here

bull It keeps on polling a socket ndash devsocketzygote When you launch an application the request to create a new process comes from system_server to Zygote on this socket The call reaches hereand then it executes a fork system call as shown below

httpandroidxrefcom700_r1xrefframeworksbasecorejavacomandroidinternalosZygoteConnectionjava225

pid = ZygoteforkAndSpecialize(parsedArgsuid parsedArgsgid parsedArgsgids

parsedArgsdebugFlags rlimits parsedArgsmountExternal parsedArgsseInfo

parsedArgsniceName fdsToClose parsedArgsinstructionSet

parsedArgsappDataDir)

httpswwwlinkedincominsg1993 20georgeshibin1993gmailcom

ZYGOTEbull Here is where you will appreciate the virtue of a great design

bull When a process forks it creates a clone of itself It replicates itself in another memory space When this happens to Zygote it creates a clean new Dalvik VM preloaded with all necessary classes and resources that any App will need (the same 4165 I mentioned earlier)

bull Except that it is never copied

bull You see the Linux Kernel implements a strategy called Copy On Write (COW) With COW Linux doesnrsquot actually copy anything Instead it maps the pages of the new process over to those of the parent process and makes copies only when the new process writes to a page But the classeslibrariesresources preloaded by Zygote are all read-only and not modified by any application This means that all processes forked from Zygote are using the exact same copy of the system classes and resources till EOL These preloaded objects live in the Zygote heap

bull This is what saves the time when apps are launched Also the memory saved is worth mentioning as no matter how many applications are started only one copy of the system classes and the resources is ever loaded in RAM

bull Personally I think the reason we still need Zygote (and cannot be replaced by system_server) is because we would like a process that does almost nothing other than fork() so that COW can do its magic Something like system_server would be counterproductive as its own heap and loaded classes would be huge

httpswwwlinkedincominsg1993 21georgeshibin1993gmailcom

ZYGOTEbull Thats pretty much what Zygote does during its lifetime Lets move onto system_server Notice the class name passed

as argument to Zygotersquos fork call for system_server

bull Just like in Zygotersquos case the AndroidRuntime knows how to execute the main() function in comandroidserverSystemServerjava

httpandroidxrefcom700_r1xrefframeworksbasecorejavacomandroidinternalosZygoteInitjava632

String args[] =

--setuid=1000

--setgid=1000

--setgroups=10011002100310041005100610071008100910101018102110323001300230033006300730093010

--capabilities= + capabilities + + capabilities

--nice-name=system_server

--runtime-args

comandroidserverSystemServer

httpandroidxrefcom700_r1xrefframeworksbaseservicesjavacomandroidserverSystemServerjava205

The main entry point from zygote

public static void main(String[] args)

new SystemServer()run()

httpswwwlinkedincominsg1993 22georgeshibin1993gmailcom

SYSTEM-SERVERbull The run() of system_server starts bootstrap-services core-services and some other services

bull Bootstrap-services are a small number of critical services

bull These are ActivityManagerService PowerManagerService DisplayManagerService PackageManagerService UserManagerService and sSensorService Bootstrap services are started almost together as they have internal dependencies with each other

bull Core services are some essential services that do not have dependencies on bootstrap services so can be started some time later One of these is the WindowManagerService

bull After that a couple of services which are not as critical as the above two classes Infact some of them even need not be started for device bootup

httpandroidxrefcom700_r1xrefframeworksbaseservicesjavacomandroidserverSystemServerjava320

try

TracetraceBegin(TraceTRACE_TAG_SYSTEM_SERVER StartServices)

startBootstrapServices()

startCoreServices()

startOtherServices()

httpswwwlinkedincominsg1993 23georgeshibin1993gmailcom

SYSTEM-SERVERbull Later down the line after starting almost all of the criticalcore services the system_server

(ie its main thread) proceeds to notify ActivityManagerService that the system is now ready to execute third-party code (read apps) The ActivityManagerService does some initializations before it can start applications

bull The callback reaches back to system_server main thread where it starts the first app comandroidsystemui here (specifically SystemUiService of systemui component)

bull We are now mostly done with this thread of system_server (the main thread mainly deals with handling messages from other components and redirecting them)

httpandroidxrefcom700_r1xrefframeworksbaseservicesjavacomandroidserverSystemServerjava1275

mActivityManagerServicesystemReady(new Runnable()

Override

public void run()

hellip

try

startSystemUi(context)

catch (Throwable e)

reportWtf(starting System UI e)

httpswwwlinkedincominsg1993 24georgeshibin1993gmailcom

BOOTANIMATION

bull Wondering what is being displayed on the screen during this entire process

bull After init starts what you see is bootanimation

bull The bootanim is a service that displays the bootanimation and is started by init

bull The rc file is parsed by init during startup But init does not start it right away (Notice the disabled)

bull This also means that someone has to explicitly start bootanim This is done by SurfaceFlinger in its init()

httpandroidxrefcom700_r1xrefframeworksbasecmdsbootanimationbootanimrc

service bootanim systembinbootanimation

class core

user graphics

group graphics audio

disabled

oneshot

httpandroidxrefcom700_r1xrefframeworksbaseservicesjavacomandroidserverSystemServerjava1275

start boot animation

startBootAnim()

httpandroidxrefcom700_r1xrefframeworksnativeservicessurfaceflingerSurfaceFlingercpp506

void SurfaceFlingerstartBootAnim()

start boot animation

property_set(servicebootanimexit 0)

property_set(ctlstart bootanim)

httpswwwlinkedincominsg1993 25georgeshibin1993gmailcom

BOOTANIMATION

bull Note that SF doesnrsquot directly spawnfork a process Rather it sets a property ctlstart to bootanim

bull ctl is special because there is no actual property named ctlstartstop (it wonrsquot appear in getprop output)

bull Note the special handling of a property if the property_name starts with ctl

httpandroidxrefcom700_r1xrefsystemcoreinitproperty_servicecpp280

case PROP_MSG_SETPROP

hellip

if(memcmp(msgnamectl4) == 0)

hellip

if (check_control_mac_perms(msgvalue source_ctx ampcr))

handle_control_message((char) msgname + 4 (char) msgvalue)

hellip

else

if (check_mac_perms(msgname source_ctx ampcr))

property_set((char) msgname (char) msgvalue)

hellip

httpswwwlinkedincominsg1993 26georgeshibin1993gmailcom

LAUNCHER

bull When the call reaches init it starts the service which is assigned to ctlstart

bull So when SF sets ctlstart to bootanim init starts the service bootanim

bull Bootanim gets the media files from systemmediabootanimationzip

bull But who stops bootanim Lets get back to system_server to find that out

bull Remember we informed ActivityManagerService that we are ready to executelaunch 3rd party codeapplications here

bull AMS on executing this calls startHomeActivityLocked() Internally this sends an Intent with category IntentCATEGORY_HOME This intent category is special because if an app registers for this intent it means that the application is a Launcher-appHome-screen replacement app

bull On receving this intent Launcher is started as it had registered for the same (see Manifest)

bull Ok Launcher has started but you are still not seeing it on the display

httpswwwlinkedincominsg1993 27georgeshibin1993gmailcom

LAUNCHERbull For Launcher to be displayed bootanimation has to be stopped There is only one entity that can tell SF to stop

bootanim via a binder transaction ie WindowManagerService WindowManagerServicersquosperformEnableScreen() API needs to be invoked

httpandroidxrefcom700_r1xrefframeworksbaseservicescorejavacomandroidserverwmWindowManagerServicejava5866

if (mBootAnimationStopped)

Do this one time

TraceasyncTraceBegin(TraceTRACE_TAG_WINDOW_MANAGER Stop bootanim 0)

try

IBinder surfaceFlinger = ServiceManagergetService(SurfaceFlinger)

if (surfaceFlinger = null)

Slogi(TAG_WM TELLING SURFACE FLINGER WE ARE BOOTED)

Parcel data = Parcelobtain()

datawriteInterfaceToken(androiduiISurfaceComposer)

surfaceFlingertransact(IBinderFIRST_CALL_TRANSACTION BOOT_FINISHED

data null 0)

datarecycle()

catch (RemoteException ex)

Sloge(TAG_WM Boot completed SurfaceFlinger is dead)

mBootAnimationStopped = true

httpswwwlinkedincominsg1993 28georgeshibin1993gmailcom

bull So SF receives a binder call from WindowManagerService with the code IBinderFIRST_CALL_TRANSACTION SurfaceFlinger Binder IPC interface has defined the following

bull The call ultimately reaches bootFinished()

httpandroidxrefcom700_r1xrefframeworksnativeincludeguiISurfaceComposerh177

Note BOOT_FINISHED must remain this value it is called from

Java by ActivityManagerService

BOOT_FINISHED = IBinderFIRST_CALL_TRANSACTION

httpandroidxrefcom700_r1xrefframeworksnativeservicessurfaceflingerSurfaceFlingercpp292

void SurfaceFlingerbootFinished()

hellip

ALOGI(Boot is finished (ld ms) long(ns2ms(duration)) )

mBootFinished = true

stop boot animation

formerly we would just kill the process but we now ask it to exit so it

can choose where to stop the animation

property_set(servicebootanimexit 1)

httpswwwlinkedincominsg1993 29georgeshibin1993gmailcom

BOOTANIMATION

bull SF sets the property serviebootanim to 1 How does this stop bootanim

bull All this while since the time it was started bootanim has been executing playAnimation()

bull While doing so it also periodically calls checkExit()

bull On detecting that this property is set to 1 bootanim gracefully exits

httpandroidxrefcom700_r1xrefframeworksbasecmdsbootanimationBootAnimationcpp387

Allow surface flinger to gracefully request shutdown

char value[PROPERTY_VALUE_MAX]

property_get(servicebootanimexit value 0)

int exitnow = atoi(value)

if (exitnow)

requestExit()

if (mAudioPlayer = NULL)

mAudioPlayer-gtrequestExit()

httpswwwlinkedincominsg1993 30georgeshibin1993gmailcom

BOOT_COMPLETEDbull WindowManager invoked binder transaction to tell SF to stop bootanim

bull After that it calls ActivityManagerrsquos bootAnimationComplete() function

bull In ActivityManagerService finishBooting() is invoked where the property sysboot_completed is set to 1 This property is important because it is the ldquoofficialrdquo way of letting native-servicesdaemons know that boot is now complete

bull After this AMS tells UserController (which is a helper class for handling multi-user functionality) to send the 2 criticalimportant intents

bull Before you unlockswipe the lock screen the intent IntentACTION_LOCKED_BOOT_COMPLETED is sent here

bull Once the user is unlocked (by entering PINswiping-the-lock screen) the intent IntentACTION_BOOT_COMPLETED is sent here This intent is important because it lets Java-services3rd-party apps know that system boot-up is now officially complete and that user is now in the home screen

httpandroidxrefcom700_r1xrefframeworksbaseservicescorejavacomandroidserverwmWindowManagerServicejav

a5899

try

mActivityManagerbootAnimationComplete()

catch (RemoteException e)

httpswwwlinkedincominsg1993 31georgeshibin1993gmailcom

Aaaaand you are now in Home screen

httpswwwlinkedincominsg1993 32georgeshibin1993gmailcom

REFERENCES

bull My highlights on Karim Yaghmourrsquos famous book (Embedded Android) httpswwwsafaribooksonlinecomu001o000000YZt6HAATembedded-android9781449327958

bull Kernel boot process

bull httpduartesorggustavoblogpostkernel-boot-process

bull https0xaxgitbooksiolinux-insidescontentInitializationlinux-initialization-4html

bull httposr507docxinuoscomenPERFORMprocess_stateshtml

bull httpstackoverflowcomquestions464483why-do-we-need-a-swapper-task-in-linux

bull httpunixstackexchangecomquestions83322which-process-has-pid-0

bull BinderServiceManager

bull httpwwwmacrobugcomblog20071215decoding-a-service-call-in-android

bull httpwwwcubridorgblogdev-platformbinder-communication-mechanism-of-android-processes

bull httpwwwprogrameringcomaMjMyMDMwATQhtml

And most importantly httpandroidxrefcom700_r1xref

httpswwwlinkedincominsg1993 33georgeshibin1993gmailcom

Thank You for reading this far

httpswwwlinkedincominsg1993 34

Disclaimer

Almost none (okay fine absolutely zilch) of the information that I put up is proprietary to Qualcomm Inc

Some of the source-code hyperlinks to Qualcommrsquos internal repository which is not accessible to others anyway

For all the other stuff I have provided Android-xref links and is openly accessible to all

However I wonrsquot vouch for the correctness of all information presented here Nope

You are welcome to correcteditpresent this material according to your needs

However it would be nice if you could shoot me a mail (at georgeshibin1993gmailcom) andor provide a

reference to the original material Just sayinghellip it would be nice

georgeshibin1993gmailcom

Page 13: Android bootup

A LITTLE SOMETHING ABOUT SERVICEMANAGER

bull Binder is the core of Android and forms the foundation of the IPC mechanism

bull OpenBinder was developed by Be Inc (later Palm Inc) (Tidbit Palm Inc designed the worldrsquos first PDA and one of the first smartphones)

bull Google developed the Binder framework for Android on the basis of OpenBinder

bull OpenBinder allows processes to present interfaces which may be called by other threads Each process maintains a thread pool which may be used to service such requests

bull In OpenBinder an entity called context manager exists maintains all services handles and returns the service handle to client on request

httpswwwlinkedincominsg1993 13georgeshibin1993gmailcom

A LITTLE SOMETHING ABOUT SERVICEMANAGER

bull If a client wants to publishadd a service it has to invoke an entity called context manager If a client wants to get a reference to a service it again has to query the context manager

bull The Context Manager in Android is called the ServiceManager

bull Since ServiceManager is essential for IPC in android it is started as a ldquocriticalrdquo service

bull Source-code at - frameworksnativecmdsservicemanager

bull During initialization ServiceManager itself calls binder_become_context_manager() to inform the binder driver that it is the contextManager

httpswwwlinkedincominsg1993 14georgeshibin1993gmailcom

A LITTLE SOMETHING ABOUT SERVICEMANAGER

bull The kernel binder driver on receiving this ioctl creates a binder node 0

bull Once this is done clients can now query ServiceManager Internally this happens via ioctl(fd paramscmd=GET srv=ldquoSERVICE_NAMErdquo target=0 hellip)

httpopengrokqualcommcomsourcexrefLAUM00kernelmsm-

318driversstagingandroidbinderc2729

binder_context_mgr_node = binder_new_node(proc 0 0)

httpopengrokqualcommcomsourcexrefLAUM00frameworksnativecmdsservicemanagerbinder

c146

int binder_become_context_manager(struct binder_state bs)

return ioctl(bs-gtfd BINDER_SET_CONTEXT_MGR 0)

httpswwwlinkedincominsg1993 15georgeshibin1993gmailcom

A LITTLE SOMETHING ABOUT SERVICEMANAGER01-01 071603022 0 0 I init Starting service ueventd

01-01 071604958 0 0 I init Starting service logd

01-01 071606345 0 0 I init Starting service vold

01-01 071606871 0 0 I init Starting service exec 1 (systembintzdatacheck)

01-01 071608191 0 0 I init Starting service exec 2 (initqcomearly_bootsh)

01-01 071609225 0 0 I init Starting service healthd

01-01 071609290 0 0 I init Starting service cs-early-boot

01-01 071609296 0 0 I init Starting service esepmdaemon

01-01 071609302 0 0 I init Starting service qcom-usb-sh

01-01 071609309 0 0 I init Starting service qseecomd

01-01 071609315 0 0 I init Starting service per_mgr

01-01 071609321 0 0 I init Starting service lmkd

01-01 071609327 0 0 I init Starting service servicemanager01-01 071609335 0 0 I init Starting service surfaceflinger

01-01 071610101 0 0 I init Starting service bootanim

01-01 071612563 0 0 I init Starting service logd-reinit

01-01 071612777 0 0 I init Starting service exec 4 (systembintzdatacheck)

01-01 071612903 0 0 I init Starting service carrier_switcher

01-01 071612911 0 0 I init Starting service exec 5 (systembinbootstat)

01-01 071612977 0 0 I init Starting service qcomsysd

01-01 071612983 0 0 I init Starting service qcom-c_main-sh

01-01 071612990 0 0 I init Starting service cnd

01-01 071612996 0 0 I init Starting service ptt_socket_app

01-01 071613002 0 0 I init Starting service cnss_diag

01-01 071613028 0 0 I init Starting service thermal-engine

01-01 071613034 0 0 I init Starting service wcnss-service

01-01 071613041 0 0 I init Starting service imsstarter

01-01 071613048 0 0 I init Starting service adsprpcd

01-01 071613054 0 0 I init Starting service hvdcp_opti

01-01 071613062 0 0 I init Starting service zygote01-01 071613069 0 0 I init Starting service zygote_secondary

httpswwwlinkedincominsg1993 16georgeshibin1993gmailcom

INITZYGOTE - STARTUP

bull Just like init is parent of all init-services system-server amp every app is spawned by zygote An executable called app_process(3264) is executed which is then known to others as zygote

bull It belongs to main class of services ie if userdata-encryption is enabled once you enter password zygote is restarted

httpandroidxrefcom700_r1xrefsystemcorerootdirinitzygote64_32rc

service zygote systembinapp_process64 -Xzygote systembin --zygote --start-system-server --socket-name=zygote

class main

socket zygote stream 660 root system

onrestart write sysandroid_powerrequest_state wake

onrestart write syspowerstate on

onrestart restart audioserver

onrestart restart cameraserver

onrestart restart media

onrestart restart netd

writepid devcpusetforegroundtasks sysfscgroupstuneforegroundtasks

service zygote_secondary systembinapp_process32 -Xzygote systembin --zygote --socket-name=zygote_secondary

class main

socket zygote_secondary stream 660 root system

onrestart restart zygote

writepid devcpusetforegroundtasks devstuneforegroundtasks

httpswwwlinkedincominsg1993 17georgeshibin1993gmailcom

ZYGOTE

bull App_process is a native proc (written in C++) Source for app_process resides here

bull ndashzygote option passed is to rename the process name from app_process to zygote here

bull comandroidinternalosZygoteInitjava is called (through runtimestart()) which starts systemServer and then polls

bull ndashstart-system_server option passed makes the zygote spawn system_server

bull Zygote uses an entity called ldquoAndroidRuntimerdquo that starts a VM to run Java Runtimestart() starts a new virtual machine As you know all code written in Java runs in a VM

bull Interesting tidbit the main() of ZygoteInitjava is the first piece of Java code that runs since the device was turned on (Reason is that this is the first time VM was created and java bytecode runs in VM)

httpandroidxrefcom700_r1xrefframeworksbasecmdsapp_processapp_maincpp306

if (zygote)

runtimestart(comandroidinternalosZygoteInit args zygote)

httpandroidxrefcom700_r1xrefframeworksbasecorejavacomandroidinternalosZygoteInitjava746

if (startSystemServer)

startSystemServer(abiList socketName)

httpswwwlinkedincominsg1993 18georgeshibin1993gmailcom

ZYGOTE

bull The most important reason behind Zygotersquos existence can be summarized in this one line of code

bull Zygote preloads classes (as in java class files) resources some shared libraries (so files) etc

bull You can find the list of these classes to be preloaded here on your device at systemetcpreloaded-classes Zygote reads this file here

bull On my device running Android Nougat the total number of preloaded classes alone is 4165 to be exact

httpandroidxrefcom700_r1xrefframeworksbasecorejavacomandroidinternalosZygoteInitjava722

preload()

httpswwwlinkedincominsg1993 19georgeshibin1993gmailcom

ZYGOTE

bull So how exactly is preloading helping

bull To know this we come back to one of the important tasks of zygote ie spawning each and every single application process (remember it is the parent process of all application processes)

bull After starting system_server zygote runs in an infinite while loop here

bull It keeps on polling a socket ndash devsocketzygote When you launch an application the request to create a new process comes from system_server to Zygote on this socket The call reaches hereand then it executes a fork system call as shown below

httpandroidxrefcom700_r1xrefframeworksbasecorejavacomandroidinternalosZygoteConnectionjava225

pid = ZygoteforkAndSpecialize(parsedArgsuid parsedArgsgid parsedArgsgids

parsedArgsdebugFlags rlimits parsedArgsmountExternal parsedArgsseInfo

parsedArgsniceName fdsToClose parsedArgsinstructionSet

parsedArgsappDataDir)

httpswwwlinkedincominsg1993 20georgeshibin1993gmailcom

ZYGOTEbull Here is where you will appreciate the virtue of a great design

bull When a process forks it creates a clone of itself It replicates itself in another memory space When this happens to Zygote it creates a clean new Dalvik VM preloaded with all necessary classes and resources that any App will need (the same 4165 I mentioned earlier)

bull Except that it is never copied

bull You see the Linux Kernel implements a strategy called Copy On Write (COW) With COW Linux doesnrsquot actually copy anything Instead it maps the pages of the new process over to those of the parent process and makes copies only when the new process writes to a page But the classeslibrariesresources preloaded by Zygote are all read-only and not modified by any application This means that all processes forked from Zygote are using the exact same copy of the system classes and resources till EOL These preloaded objects live in the Zygote heap

bull This is what saves the time when apps are launched Also the memory saved is worth mentioning as no matter how many applications are started only one copy of the system classes and the resources is ever loaded in RAM

bull Personally I think the reason we still need Zygote (and cannot be replaced by system_server) is because we would like a process that does almost nothing other than fork() so that COW can do its magic Something like system_server would be counterproductive as its own heap and loaded classes would be huge

httpswwwlinkedincominsg1993 21georgeshibin1993gmailcom

ZYGOTEbull Thats pretty much what Zygote does during its lifetime Lets move onto system_server Notice the class name passed

as argument to Zygotersquos fork call for system_server

bull Just like in Zygotersquos case the AndroidRuntime knows how to execute the main() function in comandroidserverSystemServerjava

httpandroidxrefcom700_r1xrefframeworksbasecorejavacomandroidinternalosZygoteInitjava632

String args[] =

--setuid=1000

--setgid=1000

--setgroups=10011002100310041005100610071008100910101018102110323001300230033006300730093010

--capabilities= + capabilities + + capabilities

--nice-name=system_server

--runtime-args

comandroidserverSystemServer

httpandroidxrefcom700_r1xrefframeworksbaseservicesjavacomandroidserverSystemServerjava205

The main entry point from zygote

public static void main(String[] args)

new SystemServer()run()

httpswwwlinkedincominsg1993 22georgeshibin1993gmailcom

SYSTEM-SERVERbull The run() of system_server starts bootstrap-services core-services and some other services

bull Bootstrap-services are a small number of critical services

bull These are ActivityManagerService PowerManagerService DisplayManagerService PackageManagerService UserManagerService and sSensorService Bootstrap services are started almost together as they have internal dependencies with each other

bull Core services are some essential services that do not have dependencies on bootstrap services so can be started some time later One of these is the WindowManagerService

bull After that a couple of services which are not as critical as the above two classes Infact some of them even need not be started for device bootup

httpandroidxrefcom700_r1xrefframeworksbaseservicesjavacomandroidserverSystemServerjava320

try

TracetraceBegin(TraceTRACE_TAG_SYSTEM_SERVER StartServices)

startBootstrapServices()

startCoreServices()

startOtherServices()

httpswwwlinkedincominsg1993 23georgeshibin1993gmailcom

SYSTEM-SERVERbull Later down the line after starting almost all of the criticalcore services the system_server

(ie its main thread) proceeds to notify ActivityManagerService that the system is now ready to execute third-party code (read apps) The ActivityManagerService does some initializations before it can start applications

bull The callback reaches back to system_server main thread where it starts the first app comandroidsystemui here (specifically SystemUiService of systemui component)

bull We are now mostly done with this thread of system_server (the main thread mainly deals with handling messages from other components and redirecting them)

httpandroidxrefcom700_r1xrefframeworksbaseservicesjavacomandroidserverSystemServerjava1275

mActivityManagerServicesystemReady(new Runnable()

Override

public void run()

hellip

try

startSystemUi(context)

catch (Throwable e)

reportWtf(starting System UI e)

httpswwwlinkedincominsg1993 24georgeshibin1993gmailcom

BOOTANIMATION

bull Wondering what is being displayed on the screen during this entire process

bull After init starts what you see is bootanimation

bull The bootanim is a service that displays the bootanimation and is started by init

bull The rc file is parsed by init during startup But init does not start it right away (Notice the disabled)

bull This also means that someone has to explicitly start bootanim This is done by SurfaceFlinger in its init()

httpandroidxrefcom700_r1xrefframeworksbasecmdsbootanimationbootanimrc

service bootanim systembinbootanimation

class core

user graphics

group graphics audio

disabled

oneshot

httpandroidxrefcom700_r1xrefframeworksbaseservicesjavacomandroidserverSystemServerjava1275

start boot animation

startBootAnim()

httpandroidxrefcom700_r1xrefframeworksnativeservicessurfaceflingerSurfaceFlingercpp506

void SurfaceFlingerstartBootAnim()

start boot animation

property_set(servicebootanimexit 0)

property_set(ctlstart bootanim)

httpswwwlinkedincominsg1993 25georgeshibin1993gmailcom

BOOTANIMATION

bull Note that SF doesnrsquot directly spawnfork a process Rather it sets a property ctlstart to bootanim

bull ctl is special because there is no actual property named ctlstartstop (it wonrsquot appear in getprop output)

bull Note the special handling of a property if the property_name starts with ctl

httpandroidxrefcom700_r1xrefsystemcoreinitproperty_servicecpp280

case PROP_MSG_SETPROP

hellip

if(memcmp(msgnamectl4) == 0)

hellip

if (check_control_mac_perms(msgvalue source_ctx ampcr))

handle_control_message((char) msgname + 4 (char) msgvalue)

hellip

else

if (check_mac_perms(msgname source_ctx ampcr))

property_set((char) msgname (char) msgvalue)

hellip

httpswwwlinkedincominsg1993 26georgeshibin1993gmailcom

LAUNCHER

bull When the call reaches init it starts the service which is assigned to ctlstart

bull So when SF sets ctlstart to bootanim init starts the service bootanim

bull Bootanim gets the media files from systemmediabootanimationzip

bull But who stops bootanim Lets get back to system_server to find that out

bull Remember we informed ActivityManagerService that we are ready to executelaunch 3rd party codeapplications here

bull AMS on executing this calls startHomeActivityLocked() Internally this sends an Intent with category IntentCATEGORY_HOME This intent category is special because if an app registers for this intent it means that the application is a Launcher-appHome-screen replacement app

bull On receving this intent Launcher is started as it had registered for the same (see Manifest)

bull Ok Launcher has started but you are still not seeing it on the display

httpswwwlinkedincominsg1993 27georgeshibin1993gmailcom

LAUNCHERbull For Launcher to be displayed bootanimation has to be stopped There is only one entity that can tell SF to stop

bootanim via a binder transaction ie WindowManagerService WindowManagerServicersquosperformEnableScreen() API needs to be invoked

httpandroidxrefcom700_r1xrefframeworksbaseservicescorejavacomandroidserverwmWindowManagerServicejava5866

if (mBootAnimationStopped)

Do this one time

TraceasyncTraceBegin(TraceTRACE_TAG_WINDOW_MANAGER Stop bootanim 0)

try

IBinder surfaceFlinger = ServiceManagergetService(SurfaceFlinger)

if (surfaceFlinger = null)

Slogi(TAG_WM TELLING SURFACE FLINGER WE ARE BOOTED)

Parcel data = Parcelobtain()

datawriteInterfaceToken(androiduiISurfaceComposer)

surfaceFlingertransact(IBinderFIRST_CALL_TRANSACTION BOOT_FINISHED

data null 0)

datarecycle()

catch (RemoteException ex)

Sloge(TAG_WM Boot completed SurfaceFlinger is dead)

mBootAnimationStopped = true

httpswwwlinkedincominsg1993 28georgeshibin1993gmailcom

bull So SF receives a binder call from WindowManagerService with the code IBinderFIRST_CALL_TRANSACTION SurfaceFlinger Binder IPC interface has defined the following

bull The call ultimately reaches bootFinished()

httpandroidxrefcom700_r1xrefframeworksnativeincludeguiISurfaceComposerh177

Note BOOT_FINISHED must remain this value it is called from

Java by ActivityManagerService

BOOT_FINISHED = IBinderFIRST_CALL_TRANSACTION

httpandroidxrefcom700_r1xrefframeworksnativeservicessurfaceflingerSurfaceFlingercpp292

void SurfaceFlingerbootFinished()

hellip

ALOGI(Boot is finished (ld ms) long(ns2ms(duration)) )

mBootFinished = true

stop boot animation

formerly we would just kill the process but we now ask it to exit so it

can choose where to stop the animation

property_set(servicebootanimexit 1)

httpswwwlinkedincominsg1993 29georgeshibin1993gmailcom

BOOTANIMATION

bull SF sets the property serviebootanim to 1 How does this stop bootanim

bull All this while since the time it was started bootanim has been executing playAnimation()

bull While doing so it also periodically calls checkExit()

bull On detecting that this property is set to 1 bootanim gracefully exits

httpandroidxrefcom700_r1xrefframeworksbasecmdsbootanimationBootAnimationcpp387

Allow surface flinger to gracefully request shutdown

char value[PROPERTY_VALUE_MAX]

property_get(servicebootanimexit value 0)

int exitnow = atoi(value)

if (exitnow)

requestExit()

if (mAudioPlayer = NULL)

mAudioPlayer-gtrequestExit()

httpswwwlinkedincominsg1993 30georgeshibin1993gmailcom

BOOT_COMPLETEDbull WindowManager invoked binder transaction to tell SF to stop bootanim

bull After that it calls ActivityManagerrsquos bootAnimationComplete() function

bull In ActivityManagerService finishBooting() is invoked where the property sysboot_completed is set to 1 This property is important because it is the ldquoofficialrdquo way of letting native-servicesdaemons know that boot is now complete

bull After this AMS tells UserController (which is a helper class for handling multi-user functionality) to send the 2 criticalimportant intents

bull Before you unlockswipe the lock screen the intent IntentACTION_LOCKED_BOOT_COMPLETED is sent here

bull Once the user is unlocked (by entering PINswiping-the-lock screen) the intent IntentACTION_BOOT_COMPLETED is sent here This intent is important because it lets Java-services3rd-party apps know that system boot-up is now officially complete and that user is now in the home screen

httpandroidxrefcom700_r1xrefframeworksbaseservicescorejavacomandroidserverwmWindowManagerServicejav

a5899

try

mActivityManagerbootAnimationComplete()

catch (RemoteException e)

httpswwwlinkedincominsg1993 31georgeshibin1993gmailcom

Aaaaand you are now in Home screen

httpswwwlinkedincominsg1993 32georgeshibin1993gmailcom

REFERENCES

bull My highlights on Karim Yaghmourrsquos famous book (Embedded Android) httpswwwsafaribooksonlinecomu001o000000YZt6HAATembedded-android9781449327958

bull Kernel boot process

bull httpduartesorggustavoblogpostkernel-boot-process

bull https0xaxgitbooksiolinux-insidescontentInitializationlinux-initialization-4html

bull httposr507docxinuoscomenPERFORMprocess_stateshtml

bull httpstackoverflowcomquestions464483why-do-we-need-a-swapper-task-in-linux

bull httpunixstackexchangecomquestions83322which-process-has-pid-0

bull BinderServiceManager

bull httpwwwmacrobugcomblog20071215decoding-a-service-call-in-android

bull httpwwwcubridorgblogdev-platformbinder-communication-mechanism-of-android-processes

bull httpwwwprogrameringcomaMjMyMDMwATQhtml

And most importantly httpandroidxrefcom700_r1xref

httpswwwlinkedincominsg1993 33georgeshibin1993gmailcom

Thank You for reading this far

httpswwwlinkedincominsg1993 34

Disclaimer

Almost none (okay fine absolutely zilch) of the information that I put up is proprietary to Qualcomm Inc

Some of the source-code hyperlinks to Qualcommrsquos internal repository which is not accessible to others anyway

For all the other stuff I have provided Android-xref links and is openly accessible to all

However I wonrsquot vouch for the correctness of all information presented here Nope

You are welcome to correcteditpresent this material according to your needs

However it would be nice if you could shoot me a mail (at georgeshibin1993gmailcom) andor provide a

reference to the original material Just sayinghellip it would be nice

georgeshibin1993gmailcom

Page 14: Android bootup

A LITTLE SOMETHING ABOUT SERVICEMANAGER

bull If a client wants to publishadd a service it has to invoke an entity called context manager If a client wants to get a reference to a service it again has to query the context manager

bull The Context Manager in Android is called the ServiceManager

bull Since ServiceManager is essential for IPC in android it is started as a ldquocriticalrdquo service

bull Source-code at - frameworksnativecmdsservicemanager

bull During initialization ServiceManager itself calls binder_become_context_manager() to inform the binder driver that it is the contextManager

httpswwwlinkedincominsg1993 14georgeshibin1993gmailcom

A LITTLE SOMETHING ABOUT SERVICEMANAGER

bull The kernel binder driver on receiving this ioctl creates a binder node 0

bull Once this is done clients can now query ServiceManager Internally this happens via ioctl(fd paramscmd=GET srv=ldquoSERVICE_NAMErdquo target=0 hellip)

httpopengrokqualcommcomsourcexrefLAUM00kernelmsm-

318driversstagingandroidbinderc2729

binder_context_mgr_node = binder_new_node(proc 0 0)

httpopengrokqualcommcomsourcexrefLAUM00frameworksnativecmdsservicemanagerbinder

c146

int binder_become_context_manager(struct binder_state bs)

return ioctl(bs-gtfd BINDER_SET_CONTEXT_MGR 0)

httpswwwlinkedincominsg1993 15georgeshibin1993gmailcom

A LITTLE SOMETHING ABOUT SERVICEMANAGER01-01 071603022 0 0 I init Starting service ueventd

01-01 071604958 0 0 I init Starting service logd

01-01 071606345 0 0 I init Starting service vold

01-01 071606871 0 0 I init Starting service exec 1 (systembintzdatacheck)

01-01 071608191 0 0 I init Starting service exec 2 (initqcomearly_bootsh)

01-01 071609225 0 0 I init Starting service healthd

01-01 071609290 0 0 I init Starting service cs-early-boot

01-01 071609296 0 0 I init Starting service esepmdaemon

01-01 071609302 0 0 I init Starting service qcom-usb-sh

01-01 071609309 0 0 I init Starting service qseecomd

01-01 071609315 0 0 I init Starting service per_mgr

01-01 071609321 0 0 I init Starting service lmkd

01-01 071609327 0 0 I init Starting service servicemanager01-01 071609335 0 0 I init Starting service surfaceflinger

01-01 071610101 0 0 I init Starting service bootanim

01-01 071612563 0 0 I init Starting service logd-reinit

01-01 071612777 0 0 I init Starting service exec 4 (systembintzdatacheck)

01-01 071612903 0 0 I init Starting service carrier_switcher

01-01 071612911 0 0 I init Starting service exec 5 (systembinbootstat)

01-01 071612977 0 0 I init Starting service qcomsysd

01-01 071612983 0 0 I init Starting service qcom-c_main-sh

01-01 071612990 0 0 I init Starting service cnd

01-01 071612996 0 0 I init Starting service ptt_socket_app

01-01 071613002 0 0 I init Starting service cnss_diag

01-01 071613028 0 0 I init Starting service thermal-engine

01-01 071613034 0 0 I init Starting service wcnss-service

01-01 071613041 0 0 I init Starting service imsstarter

01-01 071613048 0 0 I init Starting service adsprpcd

01-01 071613054 0 0 I init Starting service hvdcp_opti

01-01 071613062 0 0 I init Starting service zygote01-01 071613069 0 0 I init Starting service zygote_secondary

httpswwwlinkedincominsg1993 16georgeshibin1993gmailcom

INITZYGOTE - STARTUP

bull Just like init is parent of all init-services system-server amp every app is spawned by zygote An executable called app_process(3264) is executed which is then known to others as zygote

bull It belongs to main class of services ie if userdata-encryption is enabled once you enter password zygote is restarted

httpandroidxrefcom700_r1xrefsystemcorerootdirinitzygote64_32rc

service zygote systembinapp_process64 -Xzygote systembin --zygote --start-system-server --socket-name=zygote

class main

socket zygote stream 660 root system

onrestart write sysandroid_powerrequest_state wake

onrestart write syspowerstate on

onrestart restart audioserver

onrestart restart cameraserver

onrestart restart media

onrestart restart netd

writepid devcpusetforegroundtasks sysfscgroupstuneforegroundtasks

service zygote_secondary systembinapp_process32 -Xzygote systembin --zygote --socket-name=zygote_secondary

class main

socket zygote_secondary stream 660 root system

onrestart restart zygote

writepid devcpusetforegroundtasks devstuneforegroundtasks

httpswwwlinkedincominsg1993 17georgeshibin1993gmailcom

ZYGOTE

bull App_process is a native proc (written in C++) Source for app_process resides here

bull ndashzygote option passed is to rename the process name from app_process to zygote here

bull comandroidinternalosZygoteInitjava is called (through runtimestart()) which starts systemServer and then polls

bull ndashstart-system_server option passed makes the zygote spawn system_server

bull Zygote uses an entity called ldquoAndroidRuntimerdquo that starts a VM to run Java Runtimestart() starts a new virtual machine As you know all code written in Java runs in a VM

bull Interesting tidbit the main() of ZygoteInitjava is the first piece of Java code that runs since the device was turned on (Reason is that this is the first time VM was created and java bytecode runs in VM)

httpandroidxrefcom700_r1xrefframeworksbasecmdsapp_processapp_maincpp306

if (zygote)

runtimestart(comandroidinternalosZygoteInit args zygote)

httpandroidxrefcom700_r1xrefframeworksbasecorejavacomandroidinternalosZygoteInitjava746

if (startSystemServer)

startSystemServer(abiList socketName)

httpswwwlinkedincominsg1993 18georgeshibin1993gmailcom

ZYGOTE

bull The most important reason behind Zygotersquos existence can be summarized in this one line of code

bull Zygote preloads classes (as in java class files) resources some shared libraries (so files) etc

bull You can find the list of these classes to be preloaded here on your device at systemetcpreloaded-classes Zygote reads this file here

bull On my device running Android Nougat the total number of preloaded classes alone is 4165 to be exact

httpandroidxrefcom700_r1xrefframeworksbasecorejavacomandroidinternalosZygoteInitjava722

preload()

httpswwwlinkedincominsg1993 19georgeshibin1993gmailcom

ZYGOTE

bull So how exactly is preloading helping

bull To know this we come back to one of the important tasks of zygote ie spawning each and every single application process (remember it is the parent process of all application processes)

bull After starting system_server zygote runs in an infinite while loop here

bull It keeps on polling a socket ndash devsocketzygote When you launch an application the request to create a new process comes from system_server to Zygote on this socket The call reaches hereand then it executes a fork system call as shown below

httpandroidxrefcom700_r1xrefframeworksbasecorejavacomandroidinternalosZygoteConnectionjava225

pid = ZygoteforkAndSpecialize(parsedArgsuid parsedArgsgid parsedArgsgids

parsedArgsdebugFlags rlimits parsedArgsmountExternal parsedArgsseInfo

parsedArgsniceName fdsToClose parsedArgsinstructionSet

parsedArgsappDataDir)

httpswwwlinkedincominsg1993 20georgeshibin1993gmailcom

ZYGOTEbull Here is where you will appreciate the virtue of a great design

bull When a process forks it creates a clone of itself It replicates itself in another memory space When this happens to Zygote it creates a clean new Dalvik VM preloaded with all necessary classes and resources that any App will need (the same 4165 I mentioned earlier)

bull Except that it is never copied

bull You see the Linux Kernel implements a strategy called Copy On Write (COW) With COW Linux doesnrsquot actually copy anything Instead it maps the pages of the new process over to those of the parent process and makes copies only when the new process writes to a page But the classeslibrariesresources preloaded by Zygote are all read-only and not modified by any application This means that all processes forked from Zygote are using the exact same copy of the system classes and resources till EOL These preloaded objects live in the Zygote heap

bull This is what saves the time when apps are launched Also the memory saved is worth mentioning as no matter how many applications are started only one copy of the system classes and the resources is ever loaded in RAM

bull Personally I think the reason we still need Zygote (and cannot be replaced by system_server) is because we would like a process that does almost nothing other than fork() so that COW can do its magic Something like system_server would be counterproductive as its own heap and loaded classes would be huge

httpswwwlinkedincominsg1993 21georgeshibin1993gmailcom

ZYGOTEbull Thats pretty much what Zygote does during its lifetime Lets move onto system_server Notice the class name passed

as argument to Zygotersquos fork call for system_server

bull Just like in Zygotersquos case the AndroidRuntime knows how to execute the main() function in comandroidserverSystemServerjava

httpandroidxrefcom700_r1xrefframeworksbasecorejavacomandroidinternalosZygoteInitjava632

String args[] =

--setuid=1000

--setgid=1000

--setgroups=10011002100310041005100610071008100910101018102110323001300230033006300730093010

--capabilities= + capabilities + + capabilities

--nice-name=system_server

--runtime-args

comandroidserverSystemServer

httpandroidxrefcom700_r1xrefframeworksbaseservicesjavacomandroidserverSystemServerjava205

The main entry point from zygote

public static void main(String[] args)

new SystemServer()run()

httpswwwlinkedincominsg1993 22georgeshibin1993gmailcom

SYSTEM-SERVERbull The run() of system_server starts bootstrap-services core-services and some other services

bull Bootstrap-services are a small number of critical services

bull These are ActivityManagerService PowerManagerService DisplayManagerService PackageManagerService UserManagerService and sSensorService Bootstrap services are started almost together as they have internal dependencies with each other

bull Core services are some essential services that do not have dependencies on bootstrap services so can be started some time later One of these is the WindowManagerService

bull After that a couple of services which are not as critical as the above two classes Infact some of them even need not be started for device bootup

httpandroidxrefcom700_r1xrefframeworksbaseservicesjavacomandroidserverSystemServerjava320

try

TracetraceBegin(TraceTRACE_TAG_SYSTEM_SERVER StartServices)

startBootstrapServices()

startCoreServices()

startOtherServices()

httpswwwlinkedincominsg1993 23georgeshibin1993gmailcom

SYSTEM-SERVERbull Later down the line after starting almost all of the criticalcore services the system_server

(ie its main thread) proceeds to notify ActivityManagerService that the system is now ready to execute third-party code (read apps) The ActivityManagerService does some initializations before it can start applications

bull The callback reaches back to system_server main thread where it starts the first app comandroidsystemui here (specifically SystemUiService of systemui component)

bull We are now mostly done with this thread of system_server (the main thread mainly deals with handling messages from other components and redirecting them)

httpandroidxrefcom700_r1xrefframeworksbaseservicesjavacomandroidserverSystemServerjava1275

mActivityManagerServicesystemReady(new Runnable()

Override

public void run()

hellip

try

startSystemUi(context)

catch (Throwable e)

reportWtf(starting System UI e)

httpswwwlinkedincominsg1993 24georgeshibin1993gmailcom

BOOTANIMATION

bull Wondering what is being displayed on the screen during this entire process

bull After init starts what you see is bootanimation

bull The bootanim is a service that displays the bootanimation and is started by init

bull The rc file is parsed by init during startup But init does not start it right away (Notice the disabled)

bull This also means that someone has to explicitly start bootanim This is done by SurfaceFlinger in its init()

httpandroidxrefcom700_r1xrefframeworksbasecmdsbootanimationbootanimrc

service bootanim systembinbootanimation

class core

user graphics

group graphics audio

disabled

oneshot

httpandroidxrefcom700_r1xrefframeworksbaseservicesjavacomandroidserverSystemServerjava1275

start boot animation

startBootAnim()

httpandroidxrefcom700_r1xrefframeworksnativeservicessurfaceflingerSurfaceFlingercpp506

void SurfaceFlingerstartBootAnim()

start boot animation

property_set(servicebootanimexit 0)

property_set(ctlstart bootanim)

httpswwwlinkedincominsg1993 25georgeshibin1993gmailcom

BOOTANIMATION

bull Note that SF doesnrsquot directly spawnfork a process Rather it sets a property ctlstart to bootanim

bull ctl is special because there is no actual property named ctlstartstop (it wonrsquot appear in getprop output)

bull Note the special handling of a property if the property_name starts with ctl

httpandroidxrefcom700_r1xrefsystemcoreinitproperty_servicecpp280

case PROP_MSG_SETPROP

hellip

if(memcmp(msgnamectl4) == 0)

hellip

if (check_control_mac_perms(msgvalue source_ctx ampcr))

handle_control_message((char) msgname + 4 (char) msgvalue)

hellip

else

if (check_mac_perms(msgname source_ctx ampcr))

property_set((char) msgname (char) msgvalue)

hellip

httpswwwlinkedincominsg1993 26georgeshibin1993gmailcom

LAUNCHER

bull When the call reaches init it starts the service which is assigned to ctlstart

bull So when SF sets ctlstart to bootanim init starts the service bootanim

bull Bootanim gets the media files from systemmediabootanimationzip

bull But who stops bootanim Lets get back to system_server to find that out

bull Remember we informed ActivityManagerService that we are ready to executelaunch 3rd party codeapplications here

bull AMS on executing this calls startHomeActivityLocked() Internally this sends an Intent with category IntentCATEGORY_HOME This intent category is special because if an app registers for this intent it means that the application is a Launcher-appHome-screen replacement app

bull On receving this intent Launcher is started as it had registered for the same (see Manifest)

bull Ok Launcher has started but you are still not seeing it on the display

httpswwwlinkedincominsg1993 27georgeshibin1993gmailcom

LAUNCHERbull For Launcher to be displayed bootanimation has to be stopped There is only one entity that can tell SF to stop

bootanim via a binder transaction ie WindowManagerService WindowManagerServicersquosperformEnableScreen() API needs to be invoked

httpandroidxrefcom700_r1xrefframeworksbaseservicescorejavacomandroidserverwmWindowManagerServicejava5866

if (mBootAnimationStopped)

Do this one time

TraceasyncTraceBegin(TraceTRACE_TAG_WINDOW_MANAGER Stop bootanim 0)

try

IBinder surfaceFlinger = ServiceManagergetService(SurfaceFlinger)

if (surfaceFlinger = null)

Slogi(TAG_WM TELLING SURFACE FLINGER WE ARE BOOTED)

Parcel data = Parcelobtain()

datawriteInterfaceToken(androiduiISurfaceComposer)

surfaceFlingertransact(IBinderFIRST_CALL_TRANSACTION BOOT_FINISHED

data null 0)

datarecycle()

catch (RemoteException ex)

Sloge(TAG_WM Boot completed SurfaceFlinger is dead)

mBootAnimationStopped = true

httpswwwlinkedincominsg1993 28georgeshibin1993gmailcom

bull So SF receives a binder call from WindowManagerService with the code IBinderFIRST_CALL_TRANSACTION SurfaceFlinger Binder IPC interface has defined the following

bull The call ultimately reaches bootFinished()

httpandroidxrefcom700_r1xrefframeworksnativeincludeguiISurfaceComposerh177

Note BOOT_FINISHED must remain this value it is called from

Java by ActivityManagerService

BOOT_FINISHED = IBinderFIRST_CALL_TRANSACTION

httpandroidxrefcom700_r1xrefframeworksnativeservicessurfaceflingerSurfaceFlingercpp292

void SurfaceFlingerbootFinished()

hellip

ALOGI(Boot is finished (ld ms) long(ns2ms(duration)) )

mBootFinished = true

stop boot animation

formerly we would just kill the process but we now ask it to exit so it

can choose where to stop the animation

property_set(servicebootanimexit 1)

httpswwwlinkedincominsg1993 29georgeshibin1993gmailcom

BOOTANIMATION

bull SF sets the property serviebootanim to 1 How does this stop bootanim

bull All this while since the time it was started bootanim has been executing playAnimation()

bull While doing so it also periodically calls checkExit()

bull On detecting that this property is set to 1 bootanim gracefully exits

httpandroidxrefcom700_r1xrefframeworksbasecmdsbootanimationBootAnimationcpp387

Allow surface flinger to gracefully request shutdown

char value[PROPERTY_VALUE_MAX]

property_get(servicebootanimexit value 0)

int exitnow = atoi(value)

if (exitnow)

requestExit()

if (mAudioPlayer = NULL)

mAudioPlayer-gtrequestExit()

httpswwwlinkedincominsg1993 30georgeshibin1993gmailcom

BOOT_COMPLETEDbull WindowManager invoked binder transaction to tell SF to stop bootanim

bull After that it calls ActivityManagerrsquos bootAnimationComplete() function

bull In ActivityManagerService finishBooting() is invoked where the property sysboot_completed is set to 1 This property is important because it is the ldquoofficialrdquo way of letting native-servicesdaemons know that boot is now complete

bull After this AMS tells UserController (which is a helper class for handling multi-user functionality) to send the 2 criticalimportant intents

bull Before you unlockswipe the lock screen the intent IntentACTION_LOCKED_BOOT_COMPLETED is sent here

bull Once the user is unlocked (by entering PINswiping-the-lock screen) the intent IntentACTION_BOOT_COMPLETED is sent here This intent is important because it lets Java-services3rd-party apps know that system boot-up is now officially complete and that user is now in the home screen

httpandroidxrefcom700_r1xrefframeworksbaseservicescorejavacomandroidserverwmWindowManagerServicejav

a5899

try

mActivityManagerbootAnimationComplete()

catch (RemoteException e)

httpswwwlinkedincominsg1993 31georgeshibin1993gmailcom

Aaaaand you are now in Home screen

httpswwwlinkedincominsg1993 32georgeshibin1993gmailcom

REFERENCES

bull My highlights on Karim Yaghmourrsquos famous book (Embedded Android) httpswwwsafaribooksonlinecomu001o000000YZt6HAATembedded-android9781449327958

bull Kernel boot process

bull httpduartesorggustavoblogpostkernel-boot-process

bull https0xaxgitbooksiolinux-insidescontentInitializationlinux-initialization-4html

bull httposr507docxinuoscomenPERFORMprocess_stateshtml

bull httpstackoverflowcomquestions464483why-do-we-need-a-swapper-task-in-linux

bull httpunixstackexchangecomquestions83322which-process-has-pid-0

bull BinderServiceManager

bull httpwwwmacrobugcomblog20071215decoding-a-service-call-in-android

bull httpwwwcubridorgblogdev-platformbinder-communication-mechanism-of-android-processes

bull httpwwwprogrameringcomaMjMyMDMwATQhtml

And most importantly httpandroidxrefcom700_r1xref

httpswwwlinkedincominsg1993 33georgeshibin1993gmailcom

Thank You for reading this far

httpswwwlinkedincominsg1993 34

Disclaimer

Almost none (okay fine absolutely zilch) of the information that I put up is proprietary to Qualcomm Inc

Some of the source-code hyperlinks to Qualcommrsquos internal repository which is not accessible to others anyway

For all the other stuff I have provided Android-xref links and is openly accessible to all

However I wonrsquot vouch for the correctness of all information presented here Nope

You are welcome to correcteditpresent this material according to your needs

However it would be nice if you could shoot me a mail (at georgeshibin1993gmailcom) andor provide a

reference to the original material Just sayinghellip it would be nice

georgeshibin1993gmailcom

Page 15: Android bootup

A LITTLE SOMETHING ABOUT SERVICEMANAGER

bull The kernel binder driver on receiving this ioctl creates a binder node 0

bull Once this is done clients can now query ServiceManager Internally this happens via ioctl(fd paramscmd=GET srv=ldquoSERVICE_NAMErdquo target=0 hellip)

httpopengrokqualcommcomsourcexrefLAUM00kernelmsm-

318driversstagingandroidbinderc2729

binder_context_mgr_node = binder_new_node(proc 0 0)

httpopengrokqualcommcomsourcexrefLAUM00frameworksnativecmdsservicemanagerbinder

c146

int binder_become_context_manager(struct binder_state bs)

return ioctl(bs-gtfd BINDER_SET_CONTEXT_MGR 0)

httpswwwlinkedincominsg1993 15georgeshibin1993gmailcom

A LITTLE SOMETHING ABOUT SERVICEMANAGER01-01 071603022 0 0 I init Starting service ueventd

01-01 071604958 0 0 I init Starting service logd

01-01 071606345 0 0 I init Starting service vold

01-01 071606871 0 0 I init Starting service exec 1 (systembintzdatacheck)

01-01 071608191 0 0 I init Starting service exec 2 (initqcomearly_bootsh)

01-01 071609225 0 0 I init Starting service healthd

01-01 071609290 0 0 I init Starting service cs-early-boot

01-01 071609296 0 0 I init Starting service esepmdaemon

01-01 071609302 0 0 I init Starting service qcom-usb-sh

01-01 071609309 0 0 I init Starting service qseecomd

01-01 071609315 0 0 I init Starting service per_mgr

01-01 071609321 0 0 I init Starting service lmkd

01-01 071609327 0 0 I init Starting service servicemanager01-01 071609335 0 0 I init Starting service surfaceflinger

01-01 071610101 0 0 I init Starting service bootanim

01-01 071612563 0 0 I init Starting service logd-reinit

01-01 071612777 0 0 I init Starting service exec 4 (systembintzdatacheck)

01-01 071612903 0 0 I init Starting service carrier_switcher

01-01 071612911 0 0 I init Starting service exec 5 (systembinbootstat)

01-01 071612977 0 0 I init Starting service qcomsysd

01-01 071612983 0 0 I init Starting service qcom-c_main-sh

01-01 071612990 0 0 I init Starting service cnd

01-01 071612996 0 0 I init Starting service ptt_socket_app

01-01 071613002 0 0 I init Starting service cnss_diag

01-01 071613028 0 0 I init Starting service thermal-engine

01-01 071613034 0 0 I init Starting service wcnss-service

01-01 071613041 0 0 I init Starting service imsstarter

01-01 071613048 0 0 I init Starting service adsprpcd

01-01 071613054 0 0 I init Starting service hvdcp_opti

01-01 071613062 0 0 I init Starting service zygote01-01 071613069 0 0 I init Starting service zygote_secondary

httpswwwlinkedincominsg1993 16georgeshibin1993gmailcom

INITZYGOTE - STARTUP

bull Just like init is parent of all init-services system-server amp every app is spawned by zygote An executable called app_process(3264) is executed which is then known to others as zygote

bull It belongs to main class of services ie if userdata-encryption is enabled once you enter password zygote is restarted

httpandroidxrefcom700_r1xrefsystemcorerootdirinitzygote64_32rc

service zygote systembinapp_process64 -Xzygote systembin --zygote --start-system-server --socket-name=zygote

class main

socket zygote stream 660 root system

onrestart write sysandroid_powerrequest_state wake

onrestart write syspowerstate on

onrestart restart audioserver

onrestart restart cameraserver

onrestart restart media

onrestart restart netd

writepid devcpusetforegroundtasks sysfscgroupstuneforegroundtasks

service zygote_secondary systembinapp_process32 -Xzygote systembin --zygote --socket-name=zygote_secondary

class main

socket zygote_secondary stream 660 root system

onrestart restart zygote

writepid devcpusetforegroundtasks devstuneforegroundtasks

httpswwwlinkedincominsg1993 17georgeshibin1993gmailcom

ZYGOTE

bull App_process is a native proc (written in C++) Source for app_process resides here

bull ndashzygote option passed is to rename the process name from app_process to zygote here

bull comandroidinternalosZygoteInitjava is called (through runtimestart()) which starts systemServer and then polls

bull ndashstart-system_server option passed makes the zygote spawn system_server

bull Zygote uses an entity called ldquoAndroidRuntimerdquo that starts a VM to run Java Runtimestart() starts a new virtual machine As you know all code written in Java runs in a VM

bull Interesting tidbit the main() of ZygoteInitjava is the first piece of Java code that runs since the device was turned on (Reason is that this is the first time VM was created and java bytecode runs in VM)

httpandroidxrefcom700_r1xrefframeworksbasecmdsapp_processapp_maincpp306

if (zygote)

runtimestart(comandroidinternalosZygoteInit args zygote)

httpandroidxrefcom700_r1xrefframeworksbasecorejavacomandroidinternalosZygoteInitjava746

if (startSystemServer)

startSystemServer(abiList socketName)

httpswwwlinkedincominsg1993 18georgeshibin1993gmailcom

ZYGOTE

bull The most important reason behind Zygotersquos existence can be summarized in this one line of code

bull Zygote preloads classes (as in java class files) resources some shared libraries (so files) etc

bull You can find the list of these classes to be preloaded here on your device at systemetcpreloaded-classes Zygote reads this file here

bull On my device running Android Nougat the total number of preloaded classes alone is 4165 to be exact

httpandroidxrefcom700_r1xrefframeworksbasecorejavacomandroidinternalosZygoteInitjava722

preload()

httpswwwlinkedincominsg1993 19georgeshibin1993gmailcom

ZYGOTE

bull So how exactly is preloading helping

bull To know this we come back to one of the important tasks of zygote ie spawning each and every single application process (remember it is the parent process of all application processes)

bull After starting system_server zygote runs in an infinite while loop here

bull It keeps on polling a socket ndash devsocketzygote When you launch an application the request to create a new process comes from system_server to Zygote on this socket The call reaches hereand then it executes a fork system call as shown below

httpandroidxrefcom700_r1xrefframeworksbasecorejavacomandroidinternalosZygoteConnectionjava225

pid = ZygoteforkAndSpecialize(parsedArgsuid parsedArgsgid parsedArgsgids

parsedArgsdebugFlags rlimits parsedArgsmountExternal parsedArgsseInfo

parsedArgsniceName fdsToClose parsedArgsinstructionSet

parsedArgsappDataDir)

httpswwwlinkedincominsg1993 20georgeshibin1993gmailcom

ZYGOTEbull Here is where you will appreciate the virtue of a great design

bull When a process forks it creates a clone of itself It replicates itself in another memory space When this happens to Zygote it creates a clean new Dalvik VM preloaded with all necessary classes and resources that any App will need (the same 4165 I mentioned earlier)

bull Except that it is never copied

bull You see the Linux Kernel implements a strategy called Copy On Write (COW) With COW Linux doesnrsquot actually copy anything Instead it maps the pages of the new process over to those of the parent process and makes copies only when the new process writes to a page But the classeslibrariesresources preloaded by Zygote are all read-only and not modified by any application This means that all processes forked from Zygote are using the exact same copy of the system classes and resources till EOL These preloaded objects live in the Zygote heap

bull This is what saves the time when apps are launched Also the memory saved is worth mentioning as no matter how many applications are started only one copy of the system classes and the resources is ever loaded in RAM

bull Personally I think the reason we still need Zygote (and cannot be replaced by system_server) is because we would like a process that does almost nothing other than fork() so that COW can do its magic Something like system_server would be counterproductive as its own heap and loaded classes would be huge

httpswwwlinkedincominsg1993 21georgeshibin1993gmailcom

ZYGOTEbull Thats pretty much what Zygote does during its lifetime Lets move onto system_server Notice the class name passed

as argument to Zygotersquos fork call for system_server

bull Just like in Zygotersquos case the AndroidRuntime knows how to execute the main() function in comandroidserverSystemServerjava

httpandroidxrefcom700_r1xrefframeworksbasecorejavacomandroidinternalosZygoteInitjava632

String args[] =

--setuid=1000

--setgid=1000

--setgroups=10011002100310041005100610071008100910101018102110323001300230033006300730093010

--capabilities= + capabilities + + capabilities

--nice-name=system_server

--runtime-args

comandroidserverSystemServer

httpandroidxrefcom700_r1xrefframeworksbaseservicesjavacomandroidserverSystemServerjava205

The main entry point from zygote

public static void main(String[] args)

new SystemServer()run()

httpswwwlinkedincominsg1993 22georgeshibin1993gmailcom

SYSTEM-SERVERbull The run() of system_server starts bootstrap-services core-services and some other services

bull Bootstrap-services are a small number of critical services

bull These are ActivityManagerService PowerManagerService DisplayManagerService PackageManagerService UserManagerService and sSensorService Bootstrap services are started almost together as they have internal dependencies with each other

bull Core services are some essential services that do not have dependencies on bootstrap services so can be started some time later One of these is the WindowManagerService

bull After that a couple of services which are not as critical as the above two classes Infact some of them even need not be started for device bootup

httpandroidxrefcom700_r1xrefframeworksbaseservicesjavacomandroidserverSystemServerjava320

try

TracetraceBegin(TraceTRACE_TAG_SYSTEM_SERVER StartServices)

startBootstrapServices()

startCoreServices()

startOtherServices()

httpswwwlinkedincominsg1993 23georgeshibin1993gmailcom

SYSTEM-SERVERbull Later down the line after starting almost all of the criticalcore services the system_server

(ie its main thread) proceeds to notify ActivityManagerService that the system is now ready to execute third-party code (read apps) The ActivityManagerService does some initializations before it can start applications

bull The callback reaches back to system_server main thread where it starts the first app comandroidsystemui here (specifically SystemUiService of systemui component)

bull We are now mostly done with this thread of system_server (the main thread mainly deals with handling messages from other components and redirecting them)

httpandroidxrefcom700_r1xrefframeworksbaseservicesjavacomandroidserverSystemServerjava1275

mActivityManagerServicesystemReady(new Runnable()

Override

public void run()

hellip

try

startSystemUi(context)

catch (Throwable e)

reportWtf(starting System UI e)

httpswwwlinkedincominsg1993 24georgeshibin1993gmailcom

BOOTANIMATION

bull Wondering what is being displayed on the screen during this entire process

bull After init starts what you see is bootanimation

bull The bootanim is a service that displays the bootanimation and is started by init

bull The rc file is parsed by init during startup But init does not start it right away (Notice the disabled)

bull This also means that someone has to explicitly start bootanim This is done by SurfaceFlinger in its init()

httpandroidxrefcom700_r1xrefframeworksbasecmdsbootanimationbootanimrc

service bootanim systembinbootanimation

class core

user graphics

group graphics audio

disabled

oneshot

httpandroidxrefcom700_r1xrefframeworksbaseservicesjavacomandroidserverSystemServerjava1275

start boot animation

startBootAnim()

httpandroidxrefcom700_r1xrefframeworksnativeservicessurfaceflingerSurfaceFlingercpp506

void SurfaceFlingerstartBootAnim()

start boot animation

property_set(servicebootanimexit 0)

property_set(ctlstart bootanim)

httpswwwlinkedincominsg1993 25georgeshibin1993gmailcom

BOOTANIMATION

bull Note that SF doesnrsquot directly spawnfork a process Rather it sets a property ctlstart to bootanim

bull ctl is special because there is no actual property named ctlstartstop (it wonrsquot appear in getprop output)

bull Note the special handling of a property if the property_name starts with ctl

httpandroidxrefcom700_r1xrefsystemcoreinitproperty_servicecpp280

case PROP_MSG_SETPROP

hellip

if(memcmp(msgnamectl4) == 0)

hellip

if (check_control_mac_perms(msgvalue source_ctx ampcr))

handle_control_message((char) msgname + 4 (char) msgvalue)

hellip

else

if (check_mac_perms(msgname source_ctx ampcr))

property_set((char) msgname (char) msgvalue)

hellip

httpswwwlinkedincominsg1993 26georgeshibin1993gmailcom

LAUNCHER

bull When the call reaches init it starts the service which is assigned to ctlstart

bull So when SF sets ctlstart to bootanim init starts the service bootanim

bull Bootanim gets the media files from systemmediabootanimationzip

bull But who stops bootanim Lets get back to system_server to find that out

bull Remember we informed ActivityManagerService that we are ready to executelaunch 3rd party codeapplications here

bull AMS on executing this calls startHomeActivityLocked() Internally this sends an Intent with category IntentCATEGORY_HOME This intent category is special because if an app registers for this intent it means that the application is a Launcher-appHome-screen replacement app

bull On receving this intent Launcher is started as it had registered for the same (see Manifest)

bull Ok Launcher has started but you are still not seeing it on the display

httpswwwlinkedincominsg1993 27georgeshibin1993gmailcom

LAUNCHERbull For Launcher to be displayed bootanimation has to be stopped There is only one entity that can tell SF to stop

bootanim via a binder transaction ie WindowManagerService WindowManagerServicersquosperformEnableScreen() API needs to be invoked

httpandroidxrefcom700_r1xrefframeworksbaseservicescorejavacomandroidserverwmWindowManagerServicejava5866

if (mBootAnimationStopped)

Do this one time

TraceasyncTraceBegin(TraceTRACE_TAG_WINDOW_MANAGER Stop bootanim 0)

try

IBinder surfaceFlinger = ServiceManagergetService(SurfaceFlinger)

if (surfaceFlinger = null)

Slogi(TAG_WM TELLING SURFACE FLINGER WE ARE BOOTED)

Parcel data = Parcelobtain()

datawriteInterfaceToken(androiduiISurfaceComposer)

surfaceFlingertransact(IBinderFIRST_CALL_TRANSACTION BOOT_FINISHED

data null 0)

datarecycle()

catch (RemoteException ex)

Sloge(TAG_WM Boot completed SurfaceFlinger is dead)

mBootAnimationStopped = true

httpswwwlinkedincominsg1993 28georgeshibin1993gmailcom

bull So SF receives a binder call from WindowManagerService with the code IBinderFIRST_CALL_TRANSACTION SurfaceFlinger Binder IPC interface has defined the following

bull The call ultimately reaches bootFinished()

httpandroidxrefcom700_r1xrefframeworksnativeincludeguiISurfaceComposerh177

Note BOOT_FINISHED must remain this value it is called from

Java by ActivityManagerService

BOOT_FINISHED = IBinderFIRST_CALL_TRANSACTION

httpandroidxrefcom700_r1xrefframeworksnativeservicessurfaceflingerSurfaceFlingercpp292

void SurfaceFlingerbootFinished()

hellip

ALOGI(Boot is finished (ld ms) long(ns2ms(duration)) )

mBootFinished = true

stop boot animation

formerly we would just kill the process but we now ask it to exit so it

can choose where to stop the animation

property_set(servicebootanimexit 1)

httpswwwlinkedincominsg1993 29georgeshibin1993gmailcom

BOOTANIMATION

bull SF sets the property serviebootanim to 1 How does this stop bootanim

bull All this while since the time it was started bootanim has been executing playAnimation()

bull While doing so it also periodically calls checkExit()

bull On detecting that this property is set to 1 bootanim gracefully exits

httpandroidxrefcom700_r1xrefframeworksbasecmdsbootanimationBootAnimationcpp387

Allow surface flinger to gracefully request shutdown

char value[PROPERTY_VALUE_MAX]

property_get(servicebootanimexit value 0)

int exitnow = atoi(value)

if (exitnow)

requestExit()

if (mAudioPlayer = NULL)

mAudioPlayer-gtrequestExit()

httpswwwlinkedincominsg1993 30georgeshibin1993gmailcom

BOOT_COMPLETEDbull WindowManager invoked binder transaction to tell SF to stop bootanim

bull After that it calls ActivityManagerrsquos bootAnimationComplete() function

bull In ActivityManagerService finishBooting() is invoked where the property sysboot_completed is set to 1 This property is important because it is the ldquoofficialrdquo way of letting native-servicesdaemons know that boot is now complete

bull After this AMS tells UserController (which is a helper class for handling multi-user functionality) to send the 2 criticalimportant intents

bull Before you unlockswipe the lock screen the intent IntentACTION_LOCKED_BOOT_COMPLETED is sent here

bull Once the user is unlocked (by entering PINswiping-the-lock screen) the intent IntentACTION_BOOT_COMPLETED is sent here This intent is important because it lets Java-services3rd-party apps know that system boot-up is now officially complete and that user is now in the home screen

httpandroidxrefcom700_r1xrefframeworksbaseservicescorejavacomandroidserverwmWindowManagerServicejav

a5899

try

mActivityManagerbootAnimationComplete()

catch (RemoteException e)

httpswwwlinkedincominsg1993 31georgeshibin1993gmailcom

Aaaaand you are now in Home screen

httpswwwlinkedincominsg1993 32georgeshibin1993gmailcom

REFERENCES

bull My highlights on Karim Yaghmourrsquos famous book (Embedded Android) httpswwwsafaribooksonlinecomu001o000000YZt6HAATembedded-android9781449327958

bull Kernel boot process

bull httpduartesorggustavoblogpostkernel-boot-process

bull https0xaxgitbooksiolinux-insidescontentInitializationlinux-initialization-4html

bull httposr507docxinuoscomenPERFORMprocess_stateshtml

bull httpstackoverflowcomquestions464483why-do-we-need-a-swapper-task-in-linux

bull httpunixstackexchangecomquestions83322which-process-has-pid-0

bull BinderServiceManager

bull httpwwwmacrobugcomblog20071215decoding-a-service-call-in-android

bull httpwwwcubridorgblogdev-platformbinder-communication-mechanism-of-android-processes

bull httpwwwprogrameringcomaMjMyMDMwATQhtml

And most importantly httpandroidxrefcom700_r1xref

httpswwwlinkedincominsg1993 33georgeshibin1993gmailcom

Thank You for reading this far

httpswwwlinkedincominsg1993 34

Disclaimer

Almost none (okay fine absolutely zilch) of the information that I put up is proprietary to Qualcomm Inc

Some of the source-code hyperlinks to Qualcommrsquos internal repository which is not accessible to others anyway

For all the other stuff I have provided Android-xref links and is openly accessible to all

However I wonrsquot vouch for the correctness of all information presented here Nope

You are welcome to correcteditpresent this material according to your needs

However it would be nice if you could shoot me a mail (at georgeshibin1993gmailcom) andor provide a

reference to the original material Just sayinghellip it would be nice

georgeshibin1993gmailcom

Page 16: Android bootup

A LITTLE SOMETHING ABOUT SERVICEMANAGER01-01 071603022 0 0 I init Starting service ueventd

01-01 071604958 0 0 I init Starting service logd

01-01 071606345 0 0 I init Starting service vold

01-01 071606871 0 0 I init Starting service exec 1 (systembintzdatacheck)

01-01 071608191 0 0 I init Starting service exec 2 (initqcomearly_bootsh)

01-01 071609225 0 0 I init Starting service healthd

01-01 071609290 0 0 I init Starting service cs-early-boot

01-01 071609296 0 0 I init Starting service esepmdaemon

01-01 071609302 0 0 I init Starting service qcom-usb-sh

01-01 071609309 0 0 I init Starting service qseecomd

01-01 071609315 0 0 I init Starting service per_mgr

01-01 071609321 0 0 I init Starting service lmkd

01-01 071609327 0 0 I init Starting service servicemanager01-01 071609335 0 0 I init Starting service surfaceflinger

01-01 071610101 0 0 I init Starting service bootanim

01-01 071612563 0 0 I init Starting service logd-reinit

01-01 071612777 0 0 I init Starting service exec 4 (systembintzdatacheck)

01-01 071612903 0 0 I init Starting service carrier_switcher

01-01 071612911 0 0 I init Starting service exec 5 (systembinbootstat)

01-01 071612977 0 0 I init Starting service qcomsysd

01-01 071612983 0 0 I init Starting service qcom-c_main-sh

01-01 071612990 0 0 I init Starting service cnd

01-01 071612996 0 0 I init Starting service ptt_socket_app

01-01 071613002 0 0 I init Starting service cnss_diag

01-01 071613028 0 0 I init Starting service thermal-engine

01-01 071613034 0 0 I init Starting service wcnss-service

01-01 071613041 0 0 I init Starting service imsstarter

01-01 071613048 0 0 I init Starting service adsprpcd

01-01 071613054 0 0 I init Starting service hvdcp_opti

01-01 071613062 0 0 I init Starting service zygote01-01 071613069 0 0 I init Starting service zygote_secondary

httpswwwlinkedincominsg1993 16georgeshibin1993gmailcom

INITZYGOTE - STARTUP

bull Just like init is parent of all init-services system-server amp every app is spawned by zygote An executable called app_process(3264) is executed which is then known to others as zygote

bull It belongs to main class of services ie if userdata-encryption is enabled once you enter password zygote is restarted

httpandroidxrefcom700_r1xrefsystemcorerootdirinitzygote64_32rc

service zygote systembinapp_process64 -Xzygote systembin --zygote --start-system-server --socket-name=zygote

class main

socket zygote stream 660 root system

onrestart write sysandroid_powerrequest_state wake

onrestart write syspowerstate on

onrestart restart audioserver

onrestart restart cameraserver

onrestart restart media

onrestart restart netd

writepid devcpusetforegroundtasks sysfscgroupstuneforegroundtasks

service zygote_secondary systembinapp_process32 -Xzygote systembin --zygote --socket-name=zygote_secondary

class main

socket zygote_secondary stream 660 root system

onrestart restart zygote

writepid devcpusetforegroundtasks devstuneforegroundtasks

httpswwwlinkedincominsg1993 17georgeshibin1993gmailcom

ZYGOTE

bull App_process is a native proc (written in C++) Source for app_process resides here

bull ndashzygote option passed is to rename the process name from app_process to zygote here

bull comandroidinternalosZygoteInitjava is called (through runtimestart()) which starts systemServer and then polls

bull ndashstart-system_server option passed makes the zygote spawn system_server

bull Zygote uses an entity called ldquoAndroidRuntimerdquo that starts a VM to run Java Runtimestart() starts a new virtual machine As you know all code written in Java runs in a VM

bull Interesting tidbit the main() of ZygoteInitjava is the first piece of Java code that runs since the device was turned on (Reason is that this is the first time VM was created and java bytecode runs in VM)

httpandroidxrefcom700_r1xrefframeworksbasecmdsapp_processapp_maincpp306

if (zygote)

runtimestart(comandroidinternalosZygoteInit args zygote)

httpandroidxrefcom700_r1xrefframeworksbasecorejavacomandroidinternalosZygoteInitjava746

if (startSystemServer)

startSystemServer(abiList socketName)

httpswwwlinkedincominsg1993 18georgeshibin1993gmailcom

ZYGOTE

bull The most important reason behind Zygotersquos existence can be summarized in this one line of code

bull Zygote preloads classes (as in java class files) resources some shared libraries (so files) etc

bull You can find the list of these classes to be preloaded here on your device at systemetcpreloaded-classes Zygote reads this file here

bull On my device running Android Nougat the total number of preloaded classes alone is 4165 to be exact

httpandroidxrefcom700_r1xrefframeworksbasecorejavacomandroidinternalosZygoteInitjava722

preload()

httpswwwlinkedincominsg1993 19georgeshibin1993gmailcom

ZYGOTE

bull So how exactly is preloading helping

bull To know this we come back to one of the important tasks of zygote ie spawning each and every single application process (remember it is the parent process of all application processes)

bull After starting system_server zygote runs in an infinite while loop here

bull It keeps on polling a socket ndash devsocketzygote When you launch an application the request to create a new process comes from system_server to Zygote on this socket The call reaches hereand then it executes a fork system call as shown below

httpandroidxrefcom700_r1xrefframeworksbasecorejavacomandroidinternalosZygoteConnectionjava225

pid = ZygoteforkAndSpecialize(parsedArgsuid parsedArgsgid parsedArgsgids

parsedArgsdebugFlags rlimits parsedArgsmountExternal parsedArgsseInfo

parsedArgsniceName fdsToClose parsedArgsinstructionSet

parsedArgsappDataDir)

httpswwwlinkedincominsg1993 20georgeshibin1993gmailcom

ZYGOTEbull Here is where you will appreciate the virtue of a great design

bull When a process forks it creates a clone of itself It replicates itself in another memory space When this happens to Zygote it creates a clean new Dalvik VM preloaded with all necessary classes and resources that any App will need (the same 4165 I mentioned earlier)

bull Except that it is never copied

bull You see the Linux Kernel implements a strategy called Copy On Write (COW) With COW Linux doesnrsquot actually copy anything Instead it maps the pages of the new process over to those of the parent process and makes copies only when the new process writes to a page But the classeslibrariesresources preloaded by Zygote are all read-only and not modified by any application This means that all processes forked from Zygote are using the exact same copy of the system classes and resources till EOL These preloaded objects live in the Zygote heap

bull This is what saves the time when apps are launched Also the memory saved is worth mentioning as no matter how many applications are started only one copy of the system classes and the resources is ever loaded in RAM

bull Personally I think the reason we still need Zygote (and cannot be replaced by system_server) is because we would like a process that does almost nothing other than fork() so that COW can do its magic Something like system_server would be counterproductive as its own heap and loaded classes would be huge

httpswwwlinkedincominsg1993 21georgeshibin1993gmailcom

ZYGOTEbull Thats pretty much what Zygote does during its lifetime Lets move onto system_server Notice the class name passed

as argument to Zygotersquos fork call for system_server

bull Just like in Zygotersquos case the AndroidRuntime knows how to execute the main() function in comandroidserverSystemServerjava

httpandroidxrefcom700_r1xrefframeworksbasecorejavacomandroidinternalosZygoteInitjava632

String args[] =

--setuid=1000

--setgid=1000

--setgroups=10011002100310041005100610071008100910101018102110323001300230033006300730093010

--capabilities= + capabilities + + capabilities

--nice-name=system_server

--runtime-args

comandroidserverSystemServer

httpandroidxrefcom700_r1xrefframeworksbaseservicesjavacomandroidserverSystemServerjava205

The main entry point from zygote

public static void main(String[] args)

new SystemServer()run()

httpswwwlinkedincominsg1993 22georgeshibin1993gmailcom

SYSTEM-SERVERbull The run() of system_server starts bootstrap-services core-services and some other services

bull Bootstrap-services are a small number of critical services

bull These are ActivityManagerService PowerManagerService DisplayManagerService PackageManagerService UserManagerService and sSensorService Bootstrap services are started almost together as they have internal dependencies with each other

bull Core services are some essential services that do not have dependencies on bootstrap services so can be started some time later One of these is the WindowManagerService

bull After that a couple of services which are not as critical as the above two classes Infact some of them even need not be started for device bootup

httpandroidxrefcom700_r1xrefframeworksbaseservicesjavacomandroidserverSystemServerjava320

try

TracetraceBegin(TraceTRACE_TAG_SYSTEM_SERVER StartServices)

startBootstrapServices()

startCoreServices()

startOtherServices()

httpswwwlinkedincominsg1993 23georgeshibin1993gmailcom

SYSTEM-SERVERbull Later down the line after starting almost all of the criticalcore services the system_server

(ie its main thread) proceeds to notify ActivityManagerService that the system is now ready to execute third-party code (read apps) The ActivityManagerService does some initializations before it can start applications

bull The callback reaches back to system_server main thread where it starts the first app comandroidsystemui here (specifically SystemUiService of systemui component)

bull We are now mostly done with this thread of system_server (the main thread mainly deals with handling messages from other components and redirecting them)

httpandroidxrefcom700_r1xrefframeworksbaseservicesjavacomandroidserverSystemServerjava1275

mActivityManagerServicesystemReady(new Runnable()

Override

public void run()

hellip

try

startSystemUi(context)

catch (Throwable e)

reportWtf(starting System UI e)

httpswwwlinkedincominsg1993 24georgeshibin1993gmailcom

BOOTANIMATION

bull Wondering what is being displayed on the screen during this entire process

bull After init starts what you see is bootanimation

bull The bootanim is a service that displays the bootanimation and is started by init

bull The rc file is parsed by init during startup But init does not start it right away (Notice the disabled)

bull This also means that someone has to explicitly start bootanim This is done by SurfaceFlinger in its init()

httpandroidxrefcom700_r1xrefframeworksbasecmdsbootanimationbootanimrc

service bootanim systembinbootanimation

class core

user graphics

group graphics audio

disabled

oneshot

httpandroidxrefcom700_r1xrefframeworksbaseservicesjavacomandroidserverSystemServerjava1275

start boot animation

startBootAnim()

httpandroidxrefcom700_r1xrefframeworksnativeservicessurfaceflingerSurfaceFlingercpp506

void SurfaceFlingerstartBootAnim()

start boot animation

property_set(servicebootanimexit 0)

property_set(ctlstart bootanim)

httpswwwlinkedincominsg1993 25georgeshibin1993gmailcom

BOOTANIMATION

bull Note that SF doesnrsquot directly spawnfork a process Rather it sets a property ctlstart to bootanim

bull ctl is special because there is no actual property named ctlstartstop (it wonrsquot appear in getprop output)

bull Note the special handling of a property if the property_name starts with ctl

httpandroidxrefcom700_r1xrefsystemcoreinitproperty_servicecpp280

case PROP_MSG_SETPROP

hellip

if(memcmp(msgnamectl4) == 0)

hellip

if (check_control_mac_perms(msgvalue source_ctx ampcr))

handle_control_message((char) msgname + 4 (char) msgvalue)

hellip

else

if (check_mac_perms(msgname source_ctx ampcr))

property_set((char) msgname (char) msgvalue)

hellip

httpswwwlinkedincominsg1993 26georgeshibin1993gmailcom

LAUNCHER

bull When the call reaches init it starts the service which is assigned to ctlstart

bull So when SF sets ctlstart to bootanim init starts the service bootanim

bull Bootanim gets the media files from systemmediabootanimationzip

bull But who stops bootanim Lets get back to system_server to find that out

bull Remember we informed ActivityManagerService that we are ready to executelaunch 3rd party codeapplications here

bull AMS on executing this calls startHomeActivityLocked() Internally this sends an Intent with category IntentCATEGORY_HOME This intent category is special because if an app registers for this intent it means that the application is a Launcher-appHome-screen replacement app

bull On receving this intent Launcher is started as it had registered for the same (see Manifest)

bull Ok Launcher has started but you are still not seeing it on the display

httpswwwlinkedincominsg1993 27georgeshibin1993gmailcom

LAUNCHERbull For Launcher to be displayed bootanimation has to be stopped There is only one entity that can tell SF to stop

bootanim via a binder transaction ie WindowManagerService WindowManagerServicersquosperformEnableScreen() API needs to be invoked

httpandroidxrefcom700_r1xrefframeworksbaseservicescorejavacomandroidserverwmWindowManagerServicejava5866

if (mBootAnimationStopped)

Do this one time

TraceasyncTraceBegin(TraceTRACE_TAG_WINDOW_MANAGER Stop bootanim 0)

try

IBinder surfaceFlinger = ServiceManagergetService(SurfaceFlinger)

if (surfaceFlinger = null)

Slogi(TAG_WM TELLING SURFACE FLINGER WE ARE BOOTED)

Parcel data = Parcelobtain()

datawriteInterfaceToken(androiduiISurfaceComposer)

surfaceFlingertransact(IBinderFIRST_CALL_TRANSACTION BOOT_FINISHED

data null 0)

datarecycle()

catch (RemoteException ex)

Sloge(TAG_WM Boot completed SurfaceFlinger is dead)

mBootAnimationStopped = true

httpswwwlinkedincominsg1993 28georgeshibin1993gmailcom

bull So SF receives a binder call from WindowManagerService with the code IBinderFIRST_CALL_TRANSACTION SurfaceFlinger Binder IPC interface has defined the following

bull The call ultimately reaches bootFinished()

httpandroidxrefcom700_r1xrefframeworksnativeincludeguiISurfaceComposerh177

Note BOOT_FINISHED must remain this value it is called from

Java by ActivityManagerService

BOOT_FINISHED = IBinderFIRST_CALL_TRANSACTION

httpandroidxrefcom700_r1xrefframeworksnativeservicessurfaceflingerSurfaceFlingercpp292

void SurfaceFlingerbootFinished()

hellip

ALOGI(Boot is finished (ld ms) long(ns2ms(duration)) )

mBootFinished = true

stop boot animation

formerly we would just kill the process but we now ask it to exit so it

can choose where to stop the animation

property_set(servicebootanimexit 1)

httpswwwlinkedincominsg1993 29georgeshibin1993gmailcom

BOOTANIMATION

bull SF sets the property serviebootanim to 1 How does this stop bootanim

bull All this while since the time it was started bootanim has been executing playAnimation()

bull While doing so it also periodically calls checkExit()

bull On detecting that this property is set to 1 bootanim gracefully exits

httpandroidxrefcom700_r1xrefframeworksbasecmdsbootanimationBootAnimationcpp387

Allow surface flinger to gracefully request shutdown

char value[PROPERTY_VALUE_MAX]

property_get(servicebootanimexit value 0)

int exitnow = atoi(value)

if (exitnow)

requestExit()

if (mAudioPlayer = NULL)

mAudioPlayer-gtrequestExit()

httpswwwlinkedincominsg1993 30georgeshibin1993gmailcom

BOOT_COMPLETEDbull WindowManager invoked binder transaction to tell SF to stop bootanim

bull After that it calls ActivityManagerrsquos bootAnimationComplete() function

bull In ActivityManagerService finishBooting() is invoked where the property sysboot_completed is set to 1 This property is important because it is the ldquoofficialrdquo way of letting native-servicesdaemons know that boot is now complete

bull After this AMS tells UserController (which is a helper class for handling multi-user functionality) to send the 2 criticalimportant intents

bull Before you unlockswipe the lock screen the intent IntentACTION_LOCKED_BOOT_COMPLETED is sent here

bull Once the user is unlocked (by entering PINswiping-the-lock screen) the intent IntentACTION_BOOT_COMPLETED is sent here This intent is important because it lets Java-services3rd-party apps know that system boot-up is now officially complete and that user is now in the home screen

httpandroidxrefcom700_r1xrefframeworksbaseservicescorejavacomandroidserverwmWindowManagerServicejav

a5899

try

mActivityManagerbootAnimationComplete()

catch (RemoteException e)

httpswwwlinkedincominsg1993 31georgeshibin1993gmailcom

Aaaaand you are now in Home screen

httpswwwlinkedincominsg1993 32georgeshibin1993gmailcom

REFERENCES

bull My highlights on Karim Yaghmourrsquos famous book (Embedded Android) httpswwwsafaribooksonlinecomu001o000000YZt6HAATembedded-android9781449327958

bull Kernel boot process

bull httpduartesorggustavoblogpostkernel-boot-process

bull https0xaxgitbooksiolinux-insidescontentInitializationlinux-initialization-4html

bull httposr507docxinuoscomenPERFORMprocess_stateshtml

bull httpstackoverflowcomquestions464483why-do-we-need-a-swapper-task-in-linux

bull httpunixstackexchangecomquestions83322which-process-has-pid-0

bull BinderServiceManager

bull httpwwwmacrobugcomblog20071215decoding-a-service-call-in-android

bull httpwwwcubridorgblogdev-platformbinder-communication-mechanism-of-android-processes

bull httpwwwprogrameringcomaMjMyMDMwATQhtml

And most importantly httpandroidxrefcom700_r1xref

httpswwwlinkedincominsg1993 33georgeshibin1993gmailcom

Thank You for reading this far

httpswwwlinkedincominsg1993 34

Disclaimer

Almost none (okay fine absolutely zilch) of the information that I put up is proprietary to Qualcomm Inc

Some of the source-code hyperlinks to Qualcommrsquos internal repository which is not accessible to others anyway

For all the other stuff I have provided Android-xref links and is openly accessible to all

However I wonrsquot vouch for the correctness of all information presented here Nope

You are welcome to correcteditpresent this material according to your needs

However it would be nice if you could shoot me a mail (at georgeshibin1993gmailcom) andor provide a

reference to the original material Just sayinghellip it would be nice

georgeshibin1993gmailcom

Page 17: Android bootup

INITZYGOTE - STARTUP

bull Just like init is parent of all init-services system-server amp every app is spawned by zygote An executable called app_process(3264) is executed which is then known to others as zygote

bull It belongs to main class of services ie if userdata-encryption is enabled once you enter password zygote is restarted

httpandroidxrefcom700_r1xrefsystemcorerootdirinitzygote64_32rc

service zygote systembinapp_process64 -Xzygote systembin --zygote --start-system-server --socket-name=zygote

class main

socket zygote stream 660 root system

onrestart write sysandroid_powerrequest_state wake

onrestart write syspowerstate on

onrestart restart audioserver

onrestart restart cameraserver

onrestart restart media

onrestart restart netd

writepid devcpusetforegroundtasks sysfscgroupstuneforegroundtasks

service zygote_secondary systembinapp_process32 -Xzygote systembin --zygote --socket-name=zygote_secondary

class main

socket zygote_secondary stream 660 root system

onrestart restart zygote

writepid devcpusetforegroundtasks devstuneforegroundtasks

httpswwwlinkedincominsg1993 17georgeshibin1993gmailcom

ZYGOTE

bull App_process is a native proc (written in C++) Source for app_process resides here

bull ndashzygote option passed is to rename the process name from app_process to zygote here

bull comandroidinternalosZygoteInitjava is called (through runtimestart()) which starts systemServer and then polls

bull ndashstart-system_server option passed makes the zygote spawn system_server

bull Zygote uses an entity called ldquoAndroidRuntimerdquo that starts a VM to run Java Runtimestart() starts a new virtual machine As you know all code written in Java runs in a VM

bull Interesting tidbit the main() of ZygoteInitjava is the first piece of Java code that runs since the device was turned on (Reason is that this is the first time VM was created and java bytecode runs in VM)

httpandroidxrefcom700_r1xrefframeworksbasecmdsapp_processapp_maincpp306

if (zygote)

runtimestart(comandroidinternalosZygoteInit args zygote)

httpandroidxrefcom700_r1xrefframeworksbasecorejavacomandroidinternalosZygoteInitjava746

if (startSystemServer)

startSystemServer(abiList socketName)

httpswwwlinkedincominsg1993 18georgeshibin1993gmailcom

ZYGOTE

bull The most important reason behind Zygotersquos existence can be summarized in this one line of code

bull Zygote preloads classes (as in java class files) resources some shared libraries (so files) etc

bull You can find the list of these classes to be preloaded here on your device at systemetcpreloaded-classes Zygote reads this file here

bull On my device running Android Nougat the total number of preloaded classes alone is 4165 to be exact

httpandroidxrefcom700_r1xrefframeworksbasecorejavacomandroidinternalosZygoteInitjava722

preload()

httpswwwlinkedincominsg1993 19georgeshibin1993gmailcom

ZYGOTE

bull So how exactly is preloading helping

bull To know this we come back to one of the important tasks of zygote ie spawning each and every single application process (remember it is the parent process of all application processes)

bull After starting system_server zygote runs in an infinite while loop here

bull It keeps on polling a socket ndash devsocketzygote When you launch an application the request to create a new process comes from system_server to Zygote on this socket The call reaches hereand then it executes a fork system call as shown below

httpandroidxrefcom700_r1xrefframeworksbasecorejavacomandroidinternalosZygoteConnectionjava225

pid = ZygoteforkAndSpecialize(parsedArgsuid parsedArgsgid parsedArgsgids

parsedArgsdebugFlags rlimits parsedArgsmountExternal parsedArgsseInfo

parsedArgsniceName fdsToClose parsedArgsinstructionSet

parsedArgsappDataDir)

httpswwwlinkedincominsg1993 20georgeshibin1993gmailcom

ZYGOTEbull Here is where you will appreciate the virtue of a great design

bull When a process forks it creates a clone of itself It replicates itself in another memory space When this happens to Zygote it creates a clean new Dalvik VM preloaded with all necessary classes and resources that any App will need (the same 4165 I mentioned earlier)

bull Except that it is never copied

bull You see the Linux Kernel implements a strategy called Copy On Write (COW) With COW Linux doesnrsquot actually copy anything Instead it maps the pages of the new process over to those of the parent process and makes copies only when the new process writes to a page But the classeslibrariesresources preloaded by Zygote are all read-only and not modified by any application This means that all processes forked from Zygote are using the exact same copy of the system classes and resources till EOL These preloaded objects live in the Zygote heap

bull This is what saves the time when apps are launched Also the memory saved is worth mentioning as no matter how many applications are started only one copy of the system classes and the resources is ever loaded in RAM

bull Personally I think the reason we still need Zygote (and cannot be replaced by system_server) is because we would like a process that does almost nothing other than fork() so that COW can do its magic Something like system_server would be counterproductive as its own heap and loaded classes would be huge

httpswwwlinkedincominsg1993 21georgeshibin1993gmailcom

ZYGOTEbull Thats pretty much what Zygote does during its lifetime Lets move onto system_server Notice the class name passed

as argument to Zygotersquos fork call for system_server

bull Just like in Zygotersquos case the AndroidRuntime knows how to execute the main() function in comandroidserverSystemServerjava

httpandroidxrefcom700_r1xrefframeworksbasecorejavacomandroidinternalosZygoteInitjava632

String args[] =

--setuid=1000

--setgid=1000

--setgroups=10011002100310041005100610071008100910101018102110323001300230033006300730093010

--capabilities= + capabilities + + capabilities

--nice-name=system_server

--runtime-args

comandroidserverSystemServer

httpandroidxrefcom700_r1xrefframeworksbaseservicesjavacomandroidserverSystemServerjava205

The main entry point from zygote

public static void main(String[] args)

new SystemServer()run()

httpswwwlinkedincominsg1993 22georgeshibin1993gmailcom

SYSTEM-SERVERbull The run() of system_server starts bootstrap-services core-services and some other services

bull Bootstrap-services are a small number of critical services

bull These are ActivityManagerService PowerManagerService DisplayManagerService PackageManagerService UserManagerService and sSensorService Bootstrap services are started almost together as they have internal dependencies with each other

bull Core services are some essential services that do not have dependencies on bootstrap services so can be started some time later One of these is the WindowManagerService

bull After that a couple of services which are not as critical as the above two classes Infact some of them even need not be started for device bootup

httpandroidxrefcom700_r1xrefframeworksbaseservicesjavacomandroidserverSystemServerjava320

try

TracetraceBegin(TraceTRACE_TAG_SYSTEM_SERVER StartServices)

startBootstrapServices()

startCoreServices()

startOtherServices()

httpswwwlinkedincominsg1993 23georgeshibin1993gmailcom

SYSTEM-SERVERbull Later down the line after starting almost all of the criticalcore services the system_server

(ie its main thread) proceeds to notify ActivityManagerService that the system is now ready to execute third-party code (read apps) The ActivityManagerService does some initializations before it can start applications

bull The callback reaches back to system_server main thread where it starts the first app comandroidsystemui here (specifically SystemUiService of systemui component)

bull We are now mostly done with this thread of system_server (the main thread mainly deals with handling messages from other components and redirecting them)

httpandroidxrefcom700_r1xrefframeworksbaseservicesjavacomandroidserverSystemServerjava1275

mActivityManagerServicesystemReady(new Runnable()

Override

public void run()

hellip

try

startSystemUi(context)

catch (Throwable e)

reportWtf(starting System UI e)

httpswwwlinkedincominsg1993 24georgeshibin1993gmailcom

BOOTANIMATION

bull Wondering what is being displayed on the screen during this entire process

bull After init starts what you see is bootanimation

bull The bootanim is a service that displays the bootanimation and is started by init

bull The rc file is parsed by init during startup But init does not start it right away (Notice the disabled)

bull This also means that someone has to explicitly start bootanim This is done by SurfaceFlinger in its init()

httpandroidxrefcom700_r1xrefframeworksbasecmdsbootanimationbootanimrc

service bootanim systembinbootanimation

class core

user graphics

group graphics audio

disabled

oneshot

httpandroidxrefcom700_r1xrefframeworksbaseservicesjavacomandroidserverSystemServerjava1275

start boot animation

startBootAnim()

httpandroidxrefcom700_r1xrefframeworksnativeservicessurfaceflingerSurfaceFlingercpp506

void SurfaceFlingerstartBootAnim()

start boot animation

property_set(servicebootanimexit 0)

property_set(ctlstart bootanim)

httpswwwlinkedincominsg1993 25georgeshibin1993gmailcom

BOOTANIMATION

bull Note that SF doesnrsquot directly spawnfork a process Rather it sets a property ctlstart to bootanim

bull ctl is special because there is no actual property named ctlstartstop (it wonrsquot appear in getprop output)

bull Note the special handling of a property if the property_name starts with ctl

httpandroidxrefcom700_r1xrefsystemcoreinitproperty_servicecpp280

case PROP_MSG_SETPROP

hellip

if(memcmp(msgnamectl4) == 0)

hellip

if (check_control_mac_perms(msgvalue source_ctx ampcr))

handle_control_message((char) msgname + 4 (char) msgvalue)

hellip

else

if (check_mac_perms(msgname source_ctx ampcr))

property_set((char) msgname (char) msgvalue)

hellip

httpswwwlinkedincominsg1993 26georgeshibin1993gmailcom

LAUNCHER

bull When the call reaches init it starts the service which is assigned to ctlstart

bull So when SF sets ctlstart to bootanim init starts the service bootanim

bull Bootanim gets the media files from systemmediabootanimationzip

bull But who stops bootanim Lets get back to system_server to find that out

bull Remember we informed ActivityManagerService that we are ready to executelaunch 3rd party codeapplications here

bull AMS on executing this calls startHomeActivityLocked() Internally this sends an Intent with category IntentCATEGORY_HOME This intent category is special because if an app registers for this intent it means that the application is a Launcher-appHome-screen replacement app

bull On receving this intent Launcher is started as it had registered for the same (see Manifest)

bull Ok Launcher has started but you are still not seeing it on the display

httpswwwlinkedincominsg1993 27georgeshibin1993gmailcom

LAUNCHERbull For Launcher to be displayed bootanimation has to be stopped There is only one entity that can tell SF to stop

bootanim via a binder transaction ie WindowManagerService WindowManagerServicersquosperformEnableScreen() API needs to be invoked

httpandroidxrefcom700_r1xrefframeworksbaseservicescorejavacomandroidserverwmWindowManagerServicejava5866

if (mBootAnimationStopped)

Do this one time

TraceasyncTraceBegin(TraceTRACE_TAG_WINDOW_MANAGER Stop bootanim 0)

try

IBinder surfaceFlinger = ServiceManagergetService(SurfaceFlinger)

if (surfaceFlinger = null)

Slogi(TAG_WM TELLING SURFACE FLINGER WE ARE BOOTED)

Parcel data = Parcelobtain()

datawriteInterfaceToken(androiduiISurfaceComposer)

surfaceFlingertransact(IBinderFIRST_CALL_TRANSACTION BOOT_FINISHED

data null 0)

datarecycle()

catch (RemoteException ex)

Sloge(TAG_WM Boot completed SurfaceFlinger is dead)

mBootAnimationStopped = true

httpswwwlinkedincominsg1993 28georgeshibin1993gmailcom

bull So SF receives a binder call from WindowManagerService with the code IBinderFIRST_CALL_TRANSACTION SurfaceFlinger Binder IPC interface has defined the following

bull The call ultimately reaches bootFinished()

httpandroidxrefcom700_r1xrefframeworksnativeincludeguiISurfaceComposerh177

Note BOOT_FINISHED must remain this value it is called from

Java by ActivityManagerService

BOOT_FINISHED = IBinderFIRST_CALL_TRANSACTION

httpandroidxrefcom700_r1xrefframeworksnativeservicessurfaceflingerSurfaceFlingercpp292

void SurfaceFlingerbootFinished()

hellip

ALOGI(Boot is finished (ld ms) long(ns2ms(duration)) )

mBootFinished = true

stop boot animation

formerly we would just kill the process but we now ask it to exit so it

can choose where to stop the animation

property_set(servicebootanimexit 1)

httpswwwlinkedincominsg1993 29georgeshibin1993gmailcom

BOOTANIMATION

bull SF sets the property serviebootanim to 1 How does this stop bootanim

bull All this while since the time it was started bootanim has been executing playAnimation()

bull While doing so it also periodically calls checkExit()

bull On detecting that this property is set to 1 bootanim gracefully exits

httpandroidxrefcom700_r1xrefframeworksbasecmdsbootanimationBootAnimationcpp387

Allow surface flinger to gracefully request shutdown

char value[PROPERTY_VALUE_MAX]

property_get(servicebootanimexit value 0)

int exitnow = atoi(value)

if (exitnow)

requestExit()

if (mAudioPlayer = NULL)

mAudioPlayer-gtrequestExit()

httpswwwlinkedincominsg1993 30georgeshibin1993gmailcom

BOOT_COMPLETEDbull WindowManager invoked binder transaction to tell SF to stop bootanim

bull After that it calls ActivityManagerrsquos bootAnimationComplete() function

bull In ActivityManagerService finishBooting() is invoked where the property sysboot_completed is set to 1 This property is important because it is the ldquoofficialrdquo way of letting native-servicesdaemons know that boot is now complete

bull After this AMS tells UserController (which is a helper class for handling multi-user functionality) to send the 2 criticalimportant intents

bull Before you unlockswipe the lock screen the intent IntentACTION_LOCKED_BOOT_COMPLETED is sent here

bull Once the user is unlocked (by entering PINswiping-the-lock screen) the intent IntentACTION_BOOT_COMPLETED is sent here This intent is important because it lets Java-services3rd-party apps know that system boot-up is now officially complete and that user is now in the home screen

httpandroidxrefcom700_r1xrefframeworksbaseservicescorejavacomandroidserverwmWindowManagerServicejav

a5899

try

mActivityManagerbootAnimationComplete()

catch (RemoteException e)

httpswwwlinkedincominsg1993 31georgeshibin1993gmailcom

Aaaaand you are now in Home screen

httpswwwlinkedincominsg1993 32georgeshibin1993gmailcom

REFERENCES

bull My highlights on Karim Yaghmourrsquos famous book (Embedded Android) httpswwwsafaribooksonlinecomu001o000000YZt6HAATembedded-android9781449327958

bull Kernel boot process

bull httpduartesorggustavoblogpostkernel-boot-process

bull https0xaxgitbooksiolinux-insidescontentInitializationlinux-initialization-4html

bull httposr507docxinuoscomenPERFORMprocess_stateshtml

bull httpstackoverflowcomquestions464483why-do-we-need-a-swapper-task-in-linux

bull httpunixstackexchangecomquestions83322which-process-has-pid-0

bull BinderServiceManager

bull httpwwwmacrobugcomblog20071215decoding-a-service-call-in-android

bull httpwwwcubridorgblogdev-platformbinder-communication-mechanism-of-android-processes

bull httpwwwprogrameringcomaMjMyMDMwATQhtml

And most importantly httpandroidxrefcom700_r1xref

httpswwwlinkedincominsg1993 33georgeshibin1993gmailcom

Thank You for reading this far

httpswwwlinkedincominsg1993 34

Disclaimer

Almost none (okay fine absolutely zilch) of the information that I put up is proprietary to Qualcomm Inc

Some of the source-code hyperlinks to Qualcommrsquos internal repository which is not accessible to others anyway

For all the other stuff I have provided Android-xref links and is openly accessible to all

However I wonrsquot vouch for the correctness of all information presented here Nope

You are welcome to correcteditpresent this material according to your needs

However it would be nice if you could shoot me a mail (at georgeshibin1993gmailcom) andor provide a

reference to the original material Just sayinghellip it would be nice

georgeshibin1993gmailcom

Page 18: Android bootup

ZYGOTE

bull App_process is a native proc (written in C++) Source for app_process resides here

bull ndashzygote option passed is to rename the process name from app_process to zygote here

bull comandroidinternalosZygoteInitjava is called (through runtimestart()) which starts systemServer and then polls

bull ndashstart-system_server option passed makes the zygote spawn system_server

bull Zygote uses an entity called ldquoAndroidRuntimerdquo that starts a VM to run Java Runtimestart() starts a new virtual machine As you know all code written in Java runs in a VM

bull Interesting tidbit the main() of ZygoteInitjava is the first piece of Java code that runs since the device was turned on (Reason is that this is the first time VM was created and java bytecode runs in VM)

httpandroidxrefcom700_r1xrefframeworksbasecmdsapp_processapp_maincpp306

if (zygote)

runtimestart(comandroidinternalosZygoteInit args zygote)

httpandroidxrefcom700_r1xrefframeworksbasecorejavacomandroidinternalosZygoteInitjava746

if (startSystemServer)

startSystemServer(abiList socketName)

httpswwwlinkedincominsg1993 18georgeshibin1993gmailcom

ZYGOTE

bull The most important reason behind Zygotersquos existence can be summarized in this one line of code

bull Zygote preloads classes (as in java class files) resources some shared libraries (so files) etc

bull You can find the list of these classes to be preloaded here on your device at systemetcpreloaded-classes Zygote reads this file here

bull On my device running Android Nougat the total number of preloaded classes alone is 4165 to be exact

httpandroidxrefcom700_r1xrefframeworksbasecorejavacomandroidinternalosZygoteInitjava722

preload()

httpswwwlinkedincominsg1993 19georgeshibin1993gmailcom

ZYGOTE

bull So how exactly is preloading helping

bull To know this we come back to one of the important tasks of zygote ie spawning each and every single application process (remember it is the parent process of all application processes)

bull After starting system_server zygote runs in an infinite while loop here

bull It keeps on polling a socket ndash devsocketzygote When you launch an application the request to create a new process comes from system_server to Zygote on this socket The call reaches hereand then it executes a fork system call as shown below

httpandroidxrefcom700_r1xrefframeworksbasecorejavacomandroidinternalosZygoteConnectionjava225

pid = ZygoteforkAndSpecialize(parsedArgsuid parsedArgsgid parsedArgsgids

parsedArgsdebugFlags rlimits parsedArgsmountExternal parsedArgsseInfo

parsedArgsniceName fdsToClose parsedArgsinstructionSet

parsedArgsappDataDir)

httpswwwlinkedincominsg1993 20georgeshibin1993gmailcom

ZYGOTEbull Here is where you will appreciate the virtue of a great design

bull When a process forks it creates a clone of itself It replicates itself in another memory space When this happens to Zygote it creates a clean new Dalvik VM preloaded with all necessary classes and resources that any App will need (the same 4165 I mentioned earlier)

bull Except that it is never copied

bull You see the Linux Kernel implements a strategy called Copy On Write (COW) With COW Linux doesnrsquot actually copy anything Instead it maps the pages of the new process over to those of the parent process and makes copies only when the new process writes to a page But the classeslibrariesresources preloaded by Zygote are all read-only and not modified by any application This means that all processes forked from Zygote are using the exact same copy of the system classes and resources till EOL These preloaded objects live in the Zygote heap

bull This is what saves the time when apps are launched Also the memory saved is worth mentioning as no matter how many applications are started only one copy of the system classes and the resources is ever loaded in RAM

bull Personally I think the reason we still need Zygote (and cannot be replaced by system_server) is because we would like a process that does almost nothing other than fork() so that COW can do its magic Something like system_server would be counterproductive as its own heap and loaded classes would be huge

httpswwwlinkedincominsg1993 21georgeshibin1993gmailcom

ZYGOTEbull Thats pretty much what Zygote does during its lifetime Lets move onto system_server Notice the class name passed

as argument to Zygotersquos fork call for system_server

bull Just like in Zygotersquos case the AndroidRuntime knows how to execute the main() function in comandroidserverSystemServerjava

httpandroidxrefcom700_r1xrefframeworksbasecorejavacomandroidinternalosZygoteInitjava632

String args[] =

--setuid=1000

--setgid=1000

--setgroups=10011002100310041005100610071008100910101018102110323001300230033006300730093010

--capabilities= + capabilities + + capabilities

--nice-name=system_server

--runtime-args

comandroidserverSystemServer

httpandroidxrefcom700_r1xrefframeworksbaseservicesjavacomandroidserverSystemServerjava205

The main entry point from zygote

public static void main(String[] args)

new SystemServer()run()

httpswwwlinkedincominsg1993 22georgeshibin1993gmailcom

SYSTEM-SERVERbull The run() of system_server starts bootstrap-services core-services and some other services

bull Bootstrap-services are a small number of critical services

bull These are ActivityManagerService PowerManagerService DisplayManagerService PackageManagerService UserManagerService and sSensorService Bootstrap services are started almost together as they have internal dependencies with each other

bull Core services are some essential services that do not have dependencies on bootstrap services so can be started some time later One of these is the WindowManagerService

bull After that a couple of services which are not as critical as the above two classes Infact some of them even need not be started for device bootup

httpandroidxrefcom700_r1xrefframeworksbaseservicesjavacomandroidserverSystemServerjava320

try

TracetraceBegin(TraceTRACE_TAG_SYSTEM_SERVER StartServices)

startBootstrapServices()

startCoreServices()

startOtherServices()

httpswwwlinkedincominsg1993 23georgeshibin1993gmailcom

SYSTEM-SERVERbull Later down the line after starting almost all of the criticalcore services the system_server

(ie its main thread) proceeds to notify ActivityManagerService that the system is now ready to execute third-party code (read apps) The ActivityManagerService does some initializations before it can start applications

bull The callback reaches back to system_server main thread where it starts the first app comandroidsystemui here (specifically SystemUiService of systemui component)

bull We are now mostly done with this thread of system_server (the main thread mainly deals with handling messages from other components and redirecting them)

httpandroidxrefcom700_r1xrefframeworksbaseservicesjavacomandroidserverSystemServerjava1275

mActivityManagerServicesystemReady(new Runnable()

Override

public void run()

hellip

try

startSystemUi(context)

catch (Throwable e)

reportWtf(starting System UI e)

httpswwwlinkedincominsg1993 24georgeshibin1993gmailcom

BOOTANIMATION

bull Wondering what is being displayed on the screen during this entire process

bull After init starts what you see is bootanimation

bull The bootanim is a service that displays the bootanimation and is started by init

bull The rc file is parsed by init during startup But init does not start it right away (Notice the disabled)

bull This also means that someone has to explicitly start bootanim This is done by SurfaceFlinger in its init()

httpandroidxrefcom700_r1xrefframeworksbasecmdsbootanimationbootanimrc

service bootanim systembinbootanimation

class core

user graphics

group graphics audio

disabled

oneshot

httpandroidxrefcom700_r1xrefframeworksbaseservicesjavacomandroidserverSystemServerjava1275

start boot animation

startBootAnim()

httpandroidxrefcom700_r1xrefframeworksnativeservicessurfaceflingerSurfaceFlingercpp506

void SurfaceFlingerstartBootAnim()

start boot animation

property_set(servicebootanimexit 0)

property_set(ctlstart bootanim)

httpswwwlinkedincominsg1993 25georgeshibin1993gmailcom

BOOTANIMATION

bull Note that SF doesnrsquot directly spawnfork a process Rather it sets a property ctlstart to bootanim

bull ctl is special because there is no actual property named ctlstartstop (it wonrsquot appear in getprop output)

bull Note the special handling of a property if the property_name starts with ctl

httpandroidxrefcom700_r1xrefsystemcoreinitproperty_servicecpp280

case PROP_MSG_SETPROP

hellip

if(memcmp(msgnamectl4) == 0)

hellip

if (check_control_mac_perms(msgvalue source_ctx ampcr))

handle_control_message((char) msgname + 4 (char) msgvalue)

hellip

else

if (check_mac_perms(msgname source_ctx ampcr))

property_set((char) msgname (char) msgvalue)

hellip

httpswwwlinkedincominsg1993 26georgeshibin1993gmailcom

LAUNCHER

bull When the call reaches init it starts the service which is assigned to ctlstart

bull So when SF sets ctlstart to bootanim init starts the service bootanim

bull Bootanim gets the media files from systemmediabootanimationzip

bull But who stops bootanim Lets get back to system_server to find that out

bull Remember we informed ActivityManagerService that we are ready to executelaunch 3rd party codeapplications here

bull AMS on executing this calls startHomeActivityLocked() Internally this sends an Intent with category IntentCATEGORY_HOME This intent category is special because if an app registers for this intent it means that the application is a Launcher-appHome-screen replacement app

bull On receving this intent Launcher is started as it had registered for the same (see Manifest)

bull Ok Launcher has started but you are still not seeing it on the display

httpswwwlinkedincominsg1993 27georgeshibin1993gmailcom

LAUNCHERbull For Launcher to be displayed bootanimation has to be stopped There is only one entity that can tell SF to stop

bootanim via a binder transaction ie WindowManagerService WindowManagerServicersquosperformEnableScreen() API needs to be invoked

httpandroidxrefcom700_r1xrefframeworksbaseservicescorejavacomandroidserverwmWindowManagerServicejava5866

if (mBootAnimationStopped)

Do this one time

TraceasyncTraceBegin(TraceTRACE_TAG_WINDOW_MANAGER Stop bootanim 0)

try

IBinder surfaceFlinger = ServiceManagergetService(SurfaceFlinger)

if (surfaceFlinger = null)

Slogi(TAG_WM TELLING SURFACE FLINGER WE ARE BOOTED)

Parcel data = Parcelobtain()

datawriteInterfaceToken(androiduiISurfaceComposer)

surfaceFlingertransact(IBinderFIRST_CALL_TRANSACTION BOOT_FINISHED

data null 0)

datarecycle()

catch (RemoteException ex)

Sloge(TAG_WM Boot completed SurfaceFlinger is dead)

mBootAnimationStopped = true

httpswwwlinkedincominsg1993 28georgeshibin1993gmailcom

bull So SF receives a binder call from WindowManagerService with the code IBinderFIRST_CALL_TRANSACTION SurfaceFlinger Binder IPC interface has defined the following

bull The call ultimately reaches bootFinished()

httpandroidxrefcom700_r1xrefframeworksnativeincludeguiISurfaceComposerh177

Note BOOT_FINISHED must remain this value it is called from

Java by ActivityManagerService

BOOT_FINISHED = IBinderFIRST_CALL_TRANSACTION

httpandroidxrefcom700_r1xrefframeworksnativeservicessurfaceflingerSurfaceFlingercpp292

void SurfaceFlingerbootFinished()

hellip

ALOGI(Boot is finished (ld ms) long(ns2ms(duration)) )

mBootFinished = true

stop boot animation

formerly we would just kill the process but we now ask it to exit so it

can choose where to stop the animation

property_set(servicebootanimexit 1)

httpswwwlinkedincominsg1993 29georgeshibin1993gmailcom

BOOTANIMATION

bull SF sets the property serviebootanim to 1 How does this stop bootanim

bull All this while since the time it was started bootanim has been executing playAnimation()

bull While doing so it also periodically calls checkExit()

bull On detecting that this property is set to 1 bootanim gracefully exits

httpandroidxrefcom700_r1xrefframeworksbasecmdsbootanimationBootAnimationcpp387

Allow surface flinger to gracefully request shutdown

char value[PROPERTY_VALUE_MAX]

property_get(servicebootanimexit value 0)

int exitnow = atoi(value)

if (exitnow)

requestExit()

if (mAudioPlayer = NULL)

mAudioPlayer-gtrequestExit()

httpswwwlinkedincominsg1993 30georgeshibin1993gmailcom

BOOT_COMPLETEDbull WindowManager invoked binder transaction to tell SF to stop bootanim

bull After that it calls ActivityManagerrsquos bootAnimationComplete() function

bull In ActivityManagerService finishBooting() is invoked where the property sysboot_completed is set to 1 This property is important because it is the ldquoofficialrdquo way of letting native-servicesdaemons know that boot is now complete

bull After this AMS tells UserController (which is a helper class for handling multi-user functionality) to send the 2 criticalimportant intents

bull Before you unlockswipe the lock screen the intent IntentACTION_LOCKED_BOOT_COMPLETED is sent here

bull Once the user is unlocked (by entering PINswiping-the-lock screen) the intent IntentACTION_BOOT_COMPLETED is sent here This intent is important because it lets Java-services3rd-party apps know that system boot-up is now officially complete and that user is now in the home screen

httpandroidxrefcom700_r1xrefframeworksbaseservicescorejavacomandroidserverwmWindowManagerServicejav

a5899

try

mActivityManagerbootAnimationComplete()

catch (RemoteException e)

httpswwwlinkedincominsg1993 31georgeshibin1993gmailcom

Aaaaand you are now in Home screen

httpswwwlinkedincominsg1993 32georgeshibin1993gmailcom

REFERENCES

bull My highlights on Karim Yaghmourrsquos famous book (Embedded Android) httpswwwsafaribooksonlinecomu001o000000YZt6HAATembedded-android9781449327958

bull Kernel boot process

bull httpduartesorggustavoblogpostkernel-boot-process

bull https0xaxgitbooksiolinux-insidescontentInitializationlinux-initialization-4html

bull httposr507docxinuoscomenPERFORMprocess_stateshtml

bull httpstackoverflowcomquestions464483why-do-we-need-a-swapper-task-in-linux

bull httpunixstackexchangecomquestions83322which-process-has-pid-0

bull BinderServiceManager

bull httpwwwmacrobugcomblog20071215decoding-a-service-call-in-android

bull httpwwwcubridorgblogdev-platformbinder-communication-mechanism-of-android-processes

bull httpwwwprogrameringcomaMjMyMDMwATQhtml

And most importantly httpandroidxrefcom700_r1xref

httpswwwlinkedincominsg1993 33georgeshibin1993gmailcom

Thank You for reading this far

httpswwwlinkedincominsg1993 34

Disclaimer

Almost none (okay fine absolutely zilch) of the information that I put up is proprietary to Qualcomm Inc

Some of the source-code hyperlinks to Qualcommrsquos internal repository which is not accessible to others anyway

For all the other stuff I have provided Android-xref links and is openly accessible to all

However I wonrsquot vouch for the correctness of all information presented here Nope

You are welcome to correcteditpresent this material according to your needs

However it would be nice if you could shoot me a mail (at georgeshibin1993gmailcom) andor provide a

reference to the original material Just sayinghellip it would be nice

georgeshibin1993gmailcom

Page 19: Android bootup

ZYGOTE

bull The most important reason behind Zygotersquos existence can be summarized in this one line of code

bull Zygote preloads classes (as in java class files) resources some shared libraries (so files) etc

bull You can find the list of these classes to be preloaded here on your device at systemetcpreloaded-classes Zygote reads this file here

bull On my device running Android Nougat the total number of preloaded classes alone is 4165 to be exact

httpandroidxrefcom700_r1xrefframeworksbasecorejavacomandroidinternalosZygoteInitjava722

preload()

httpswwwlinkedincominsg1993 19georgeshibin1993gmailcom

ZYGOTE

bull So how exactly is preloading helping

bull To know this we come back to one of the important tasks of zygote ie spawning each and every single application process (remember it is the parent process of all application processes)

bull After starting system_server zygote runs in an infinite while loop here

bull It keeps on polling a socket ndash devsocketzygote When you launch an application the request to create a new process comes from system_server to Zygote on this socket The call reaches hereand then it executes a fork system call as shown below

httpandroidxrefcom700_r1xrefframeworksbasecorejavacomandroidinternalosZygoteConnectionjava225

pid = ZygoteforkAndSpecialize(parsedArgsuid parsedArgsgid parsedArgsgids

parsedArgsdebugFlags rlimits parsedArgsmountExternal parsedArgsseInfo

parsedArgsniceName fdsToClose parsedArgsinstructionSet

parsedArgsappDataDir)

httpswwwlinkedincominsg1993 20georgeshibin1993gmailcom

ZYGOTEbull Here is where you will appreciate the virtue of a great design

bull When a process forks it creates a clone of itself It replicates itself in another memory space When this happens to Zygote it creates a clean new Dalvik VM preloaded with all necessary classes and resources that any App will need (the same 4165 I mentioned earlier)

bull Except that it is never copied

bull You see the Linux Kernel implements a strategy called Copy On Write (COW) With COW Linux doesnrsquot actually copy anything Instead it maps the pages of the new process over to those of the parent process and makes copies only when the new process writes to a page But the classeslibrariesresources preloaded by Zygote are all read-only and not modified by any application This means that all processes forked from Zygote are using the exact same copy of the system classes and resources till EOL These preloaded objects live in the Zygote heap

bull This is what saves the time when apps are launched Also the memory saved is worth mentioning as no matter how many applications are started only one copy of the system classes and the resources is ever loaded in RAM

bull Personally I think the reason we still need Zygote (and cannot be replaced by system_server) is because we would like a process that does almost nothing other than fork() so that COW can do its magic Something like system_server would be counterproductive as its own heap and loaded classes would be huge

httpswwwlinkedincominsg1993 21georgeshibin1993gmailcom

ZYGOTEbull Thats pretty much what Zygote does during its lifetime Lets move onto system_server Notice the class name passed

as argument to Zygotersquos fork call for system_server

bull Just like in Zygotersquos case the AndroidRuntime knows how to execute the main() function in comandroidserverSystemServerjava

httpandroidxrefcom700_r1xrefframeworksbasecorejavacomandroidinternalosZygoteInitjava632

String args[] =

--setuid=1000

--setgid=1000

--setgroups=10011002100310041005100610071008100910101018102110323001300230033006300730093010

--capabilities= + capabilities + + capabilities

--nice-name=system_server

--runtime-args

comandroidserverSystemServer

httpandroidxrefcom700_r1xrefframeworksbaseservicesjavacomandroidserverSystemServerjava205

The main entry point from zygote

public static void main(String[] args)

new SystemServer()run()

httpswwwlinkedincominsg1993 22georgeshibin1993gmailcom

SYSTEM-SERVERbull The run() of system_server starts bootstrap-services core-services and some other services

bull Bootstrap-services are a small number of critical services

bull These are ActivityManagerService PowerManagerService DisplayManagerService PackageManagerService UserManagerService and sSensorService Bootstrap services are started almost together as they have internal dependencies with each other

bull Core services are some essential services that do not have dependencies on bootstrap services so can be started some time later One of these is the WindowManagerService

bull After that a couple of services which are not as critical as the above two classes Infact some of them even need not be started for device bootup

httpandroidxrefcom700_r1xrefframeworksbaseservicesjavacomandroidserverSystemServerjava320

try

TracetraceBegin(TraceTRACE_TAG_SYSTEM_SERVER StartServices)

startBootstrapServices()

startCoreServices()

startOtherServices()

httpswwwlinkedincominsg1993 23georgeshibin1993gmailcom

SYSTEM-SERVERbull Later down the line after starting almost all of the criticalcore services the system_server

(ie its main thread) proceeds to notify ActivityManagerService that the system is now ready to execute third-party code (read apps) The ActivityManagerService does some initializations before it can start applications

bull The callback reaches back to system_server main thread where it starts the first app comandroidsystemui here (specifically SystemUiService of systemui component)

bull We are now mostly done with this thread of system_server (the main thread mainly deals with handling messages from other components and redirecting them)

httpandroidxrefcom700_r1xrefframeworksbaseservicesjavacomandroidserverSystemServerjava1275

mActivityManagerServicesystemReady(new Runnable()

Override

public void run()

hellip

try

startSystemUi(context)

catch (Throwable e)

reportWtf(starting System UI e)

httpswwwlinkedincominsg1993 24georgeshibin1993gmailcom

BOOTANIMATION

bull Wondering what is being displayed on the screen during this entire process

bull After init starts what you see is bootanimation

bull The bootanim is a service that displays the bootanimation and is started by init

bull The rc file is parsed by init during startup But init does not start it right away (Notice the disabled)

bull This also means that someone has to explicitly start bootanim This is done by SurfaceFlinger in its init()

httpandroidxrefcom700_r1xrefframeworksbasecmdsbootanimationbootanimrc

service bootanim systembinbootanimation

class core

user graphics

group graphics audio

disabled

oneshot

httpandroidxrefcom700_r1xrefframeworksbaseservicesjavacomandroidserverSystemServerjava1275

start boot animation

startBootAnim()

httpandroidxrefcom700_r1xrefframeworksnativeservicessurfaceflingerSurfaceFlingercpp506

void SurfaceFlingerstartBootAnim()

start boot animation

property_set(servicebootanimexit 0)

property_set(ctlstart bootanim)

httpswwwlinkedincominsg1993 25georgeshibin1993gmailcom

BOOTANIMATION

bull Note that SF doesnrsquot directly spawnfork a process Rather it sets a property ctlstart to bootanim

bull ctl is special because there is no actual property named ctlstartstop (it wonrsquot appear in getprop output)

bull Note the special handling of a property if the property_name starts with ctl

httpandroidxrefcom700_r1xrefsystemcoreinitproperty_servicecpp280

case PROP_MSG_SETPROP

hellip

if(memcmp(msgnamectl4) == 0)

hellip

if (check_control_mac_perms(msgvalue source_ctx ampcr))

handle_control_message((char) msgname + 4 (char) msgvalue)

hellip

else

if (check_mac_perms(msgname source_ctx ampcr))

property_set((char) msgname (char) msgvalue)

hellip

httpswwwlinkedincominsg1993 26georgeshibin1993gmailcom

LAUNCHER

bull When the call reaches init it starts the service which is assigned to ctlstart

bull So when SF sets ctlstart to bootanim init starts the service bootanim

bull Bootanim gets the media files from systemmediabootanimationzip

bull But who stops bootanim Lets get back to system_server to find that out

bull Remember we informed ActivityManagerService that we are ready to executelaunch 3rd party codeapplications here

bull AMS on executing this calls startHomeActivityLocked() Internally this sends an Intent with category IntentCATEGORY_HOME This intent category is special because if an app registers for this intent it means that the application is a Launcher-appHome-screen replacement app

bull On receving this intent Launcher is started as it had registered for the same (see Manifest)

bull Ok Launcher has started but you are still not seeing it on the display

httpswwwlinkedincominsg1993 27georgeshibin1993gmailcom

LAUNCHERbull For Launcher to be displayed bootanimation has to be stopped There is only one entity that can tell SF to stop

bootanim via a binder transaction ie WindowManagerService WindowManagerServicersquosperformEnableScreen() API needs to be invoked

httpandroidxrefcom700_r1xrefframeworksbaseservicescorejavacomandroidserverwmWindowManagerServicejava5866

if (mBootAnimationStopped)

Do this one time

TraceasyncTraceBegin(TraceTRACE_TAG_WINDOW_MANAGER Stop bootanim 0)

try

IBinder surfaceFlinger = ServiceManagergetService(SurfaceFlinger)

if (surfaceFlinger = null)

Slogi(TAG_WM TELLING SURFACE FLINGER WE ARE BOOTED)

Parcel data = Parcelobtain()

datawriteInterfaceToken(androiduiISurfaceComposer)

surfaceFlingertransact(IBinderFIRST_CALL_TRANSACTION BOOT_FINISHED

data null 0)

datarecycle()

catch (RemoteException ex)

Sloge(TAG_WM Boot completed SurfaceFlinger is dead)

mBootAnimationStopped = true

httpswwwlinkedincominsg1993 28georgeshibin1993gmailcom

bull So SF receives a binder call from WindowManagerService with the code IBinderFIRST_CALL_TRANSACTION SurfaceFlinger Binder IPC interface has defined the following

bull The call ultimately reaches bootFinished()

httpandroidxrefcom700_r1xrefframeworksnativeincludeguiISurfaceComposerh177

Note BOOT_FINISHED must remain this value it is called from

Java by ActivityManagerService

BOOT_FINISHED = IBinderFIRST_CALL_TRANSACTION

httpandroidxrefcom700_r1xrefframeworksnativeservicessurfaceflingerSurfaceFlingercpp292

void SurfaceFlingerbootFinished()

hellip

ALOGI(Boot is finished (ld ms) long(ns2ms(duration)) )

mBootFinished = true

stop boot animation

formerly we would just kill the process but we now ask it to exit so it

can choose where to stop the animation

property_set(servicebootanimexit 1)

httpswwwlinkedincominsg1993 29georgeshibin1993gmailcom

BOOTANIMATION

bull SF sets the property serviebootanim to 1 How does this stop bootanim

bull All this while since the time it was started bootanim has been executing playAnimation()

bull While doing so it also periodically calls checkExit()

bull On detecting that this property is set to 1 bootanim gracefully exits

httpandroidxrefcom700_r1xrefframeworksbasecmdsbootanimationBootAnimationcpp387

Allow surface flinger to gracefully request shutdown

char value[PROPERTY_VALUE_MAX]

property_get(servicebootanimexit value 0)

int exitnow = atoi(value)

if (exitnow)

requestExit()

if (mAudioPlayer = NULL)

mAudioPlayer-gtrequestExit()

httpswwwlinkedincominsg1993 30georgeshibin1993gmailcom

BOOT_COMPLETEDbull WindowManager invoked binder transaction to tell SF to stop bootanim

bull After that it calls ActivityManagerrsquos bootAnimationComplete() function

bull In ActivityManagerService finishBooting() is invoked where the property sysboot_completed is set to 1 This property is important because it is the ldquoofficialrdquo way of letting native-servicesdaemons know that boot is now complete

bull After this AMS tells UserController (which is a helper class for handling multi-user functionality) to send the 2 criticalimportant intents

bull Before you unlockswipe the lock screen the intent IntentACTION_LOCKED_BOOT_COMPLETED is sent here

bull Once the user is unlocked (by entering PINswiping-the-lock screen) the intent IntentACTION_BOOT_COMPLETED is sent here This intent is important because it lets Java-services3rd-party apps know that system boot-up is now officially complete and that user is now in the home screen

httpandroidxrefcom700_r1xrefframeworksbaseservicescorejavacomandroidserverwmWindowManagerServicejav

a5899

try

mActivityManagerbootAnimationComplete()

catch (RemoteException e)

httpswwwlinkedincominsg1993 31georgeshibin1993gmailcom

Aaaaand you are now in Home screen

httpswwwlinkedincominsg1993 32georgeshibin1993gmailcom

REFERENCES

bull My highlights on Karim Yaghmourrsquos famous book (Embedded Android) httpswwwsafaribooksonlinecomu001o000000YZt6HAATembedded-android9781449327958

bull Kernel boot process

bull httpduartesorggustavoblogpostkernel-boot-process

bull https0xaxgitbooksiolinux-insidescontentInitializationlinux-initialization-4html

bull httposr507docxinuoscomenPERFORMprocess_stateshtml

bull httpstackoverflowcomquestions464483why-do-we-need-a-swapper-task-in-linux

bull httpunixstackexchangecomquestions83322which-process-has-pid-0

bull BinderServiceManager

bull httpwwwmacrobugcomblog20071215decoding-a-service-call-in-android

bull httpwwwcubridorgblogdev-platformbinder-communication-mechanism-of-android-processes

bull httpwwwprogrameringcomaMjMyMDMwATQhtml

And most importantly httpandroidxrefcom700_r1xref

httpswwwlinkedincominsg1993 33georgeshibin1993gmailcom

Thank You for reading this far

httpswwwlinkedincominsg1993 34

Disclaimer

Almost none (okay fine absolutely zilch) of the information that I put up is proprietary to Qualcomm Inc

Some of the source-code hyperlinks to Qualcommrsquos internal repository which is not accessible to others anyway

For all the other stuff I have provided Android-xref links and is openly accessible to all

However I wonrsquot vouch for the correctness of all information presented here Nope

You are welcome to correcteditpresent this material according to your needs

However it would be nice if you could shoot me a mail (at georgeshibin1993gmailcom) andor provide a

reference to the original material Just sayinghellip it would be nice

georgeshibin1993gmailcom

Page 20: Android bootup

ZYGOTE

bull So how exactly is preloading helping

bull To know this we come back to one of the important tasks of zygote ie spawning each and every single application process (remember it is the parent process of all application processes)

bull After starting system_server zygote runs in an infinite while loop here

bull It keeps on polling a socket ndash devsocketzygote When you launch an application the request to create a new process comes from system_server to Zygote on this socket The call reaches hereand then it executes a fork system call as shown below

httpandroidxrefcom700_r1xrefframeworksbasecorejavacomandroidinternalosZygoteConnectionjava225

pid = ZygoteforkAndSpecialize(parsedArgsuid parsedArgsgid parsedArgsgids

parsedArgsdebugFlags rlimits parsedArgsmountExternal parsedArgsseInfo

parsedArgsniceName fdsToClose parsedArgsinstructionSet

parsedArgsappDataDir)

httpswwwlinkedincominsg1993 20georgeshibin1993gmailcom

ZYGOTEbull Here is where you will appreciate the virtue of a great design

bull When a process forks it creates a clone of itself It replicates itself in another memory space When this happens to Zygote it creates a clean new Dalvik VM preloaded with all necessary classes and resources that any App will need (the same 4165 I mentioned earlier)

bull Except that it is never copied

bull You see the Linux Kernel implements a strategy called Copy On Write (COW) With COW Linux doesnrsquot actually copy anything Instead it maps the pages of the new process over to those of the parent process and makes copies only when the new process writes to a page But the classeslibrariesresources preloaded by Zygote are all read-only and not modified by any application This means that all processes forked from Zygote are using the exact same copy of the system classes and resources till EOL These preloaded objects live in the Zygote heap

bull This is what saves the time when apps are launched Also the memory saved is worth mentioning as no matter how many applications are started only one copy of the system classes and the resources is ever loaded in RAM

bull Personally I think the reason we still need Zygote (and cannot be replaced by system_server) is because we would like a process that does almost nothing other than fork() so that COW can do its magic Something like system_server would be counterproductive as its own heap and loaded classes would be huge

httpswwwlinkedincominsg1993 21georgeshibin1993gmailcom

ZYGOTEbull Thats pretty much what Zygote does during its lifetime Lets move onto system_server Notice the class name passed

as argument to Zygotersquos fork call for system_server

bull Just like in Zygotersquos case the AndroidRuntime knows how to execute the main() function in comandroidserverSystemServerjava

httpandroidxrefcom700_r1xrefframeworksbasecorejavacomandroidinternalosZygoteInitjava632

String args[] =

--setuid=1000

--setgid=1000

--setgroups=10011002100310041005100610071008100910101018102110323001300230033006300730093010

--capabilities= + capabilities + + capabilities

--nice-name=system_server

--runtime-args

comandroidserverSystemServer

httpandroidxrefcom700_r1xrefframeworksbaseservicesjavacomandroidserverSystemServerjava205

The main entry point from zygote

public static void main(String[] args)

new SystemServer()run()

httpswwwlinkedincominsg1993 22georgeshibin1993gmailcom

SYSTEM-SERVERbull The run() of system_server starts bootstrap-services core-services and some other services

bull Bootstrap-services are a small number of critical services

bull These are ActivityManagerService PowerManagerService DisplayManagerService PackageManagerService UserManagerService and sSensorService Bootstrap services are started almost together as they have internal dependencies with each other

bull Core services are some essential services that do not have dependencies on bootstrap services so can be started some time later One of these is the WindowManagerService

bull After that a couple of services which are not as critical as the above two classes Infact some of them even need not be started for device bootup

httpandroidxrefcom700_r1xrefframeworksbaseservicesjavacomandroidserverSystemServerjava320

try

TracetraceBegin(TraceTRACE_TAG_SYSTEM_SERVER StartServices)

startBootstrapServices()

startCoreServices()

startOtherServices()

httpswwwlinkedincominsg1993 23georgeshibin1993gmailcom

SYSTEM-SERVERbull Later down the line after starting almost all of the criticalcore services the system_server

(ie its main thread) proceeds to notify ActivityManagerService that the system is now ready to execute third-party code (read apps) The ActivityManagerService does some initializations before it can start applications

bull The callback reaches back to system_server main thread where it starts the first app comandroidsystemui here (specifically SystemUiService of systemui component)

bull We are now mostly done with this thread of system_server (the main thread mainly deals with handling messages from other components and redirecting them)

httpandroidxrefcom700_r1xrefframeworksbaseservicesjavacomandroidserverSystemServerjava1275

mActivityManagerServicesystemReady(new Runnable()

Override

public void run()

hellip

try

startSystemUi(context)

catch (Throwable e)

reportWtf(starting System UI e)

httpswwwlinkedincominsg1993 24georgeshibin1993gmailcom

BOOTANIMATION

bull Wondering what is being displayed on the screen during this entire process

bull After init starts what you see is bootanimation

bull The bootanim is a service that displays the bootanimation and is started by init

bull The rc file is parsed by init during startup But init does not start it right away (Notice the disabled)

bull This also means that someone has to explicitly start bootanim This is done by SurfaceFlinger in its init()

httpandroidxrefcom700_r1xrefframeworksbasecmdsbootanimationbootanimrc

service bootanim systembinbootanimation

class core

user graphics

group graphics audio

disabled

oneshot

httpandroidxrefcom700_r1xrefframeworksbaseservicesjavacomandroidserverSystemServerjava1275

start boot animation

startBootAnim()

httpandroidxrefcom700_r1xrefframeworksnativeservicessurfaceflingerSurfaceFlingercpp506

void SurfaceFlingerstartBootAnim()

start boot animation

property_set(servicebootanimexit 0)

property_set(ctlstart bootanim)

httpswwwlinkedincominsg1993 25georgeshibin1993gmailcom

BOOTANIMATION

bull Note that SF doesnrsquot directly spawnfork a process Rather it sets a property ctlstart to bootanim

bull ctl is special because there is no actual property named ctlstartstop (it wonrsquot appear in getprop output)

bull Note the special handling of a property if the property_name starts with ctl

httpandroidxrefcom700_r1xrefsystemcoreinitproperty_servicecpp280

case PROP_MSG_SETPROP

hellip

if(memcmp(msgnamectl4) == 0)

hellip

if (check_control_mac_perms(msgvalue source_ctx ampcr))

handle_control_message((char) msgname + 4 (char) msgvalue)

hellip

else

if (check_mac_perms(msgname source_ctx ampcr))

property_set((char) msgname (char) msgvalue)

hellip

httpswwwlinkedincominsg1993 26georgeshibin1993gmailcom

LAUNCHER

bull When the call reaches init it starts the service which is assigned to ctlstart

bull So when SF sets ctlstart to bootanim init starts the service bootanim

bull Bootanim gets the media files from systemmediabootanimationzip

bull But who stops bootanim Lets get back to system_server to find that out

bull Remember we informed ActivityManagerService that we are ready to executelaunch 3rd party codeapplications here

bull AMS on executing this calls startHomeActivityLocked() Internally this sends an Intent with category IntentCATEGORY_HOME This intent category is special because if an app registers for this intent it means that the application is a Launcher-appHome-screen replacement app

bull On receving this intent Launcher is started as it had registered for the same (see Manifest)

bull Ok Launcher has started but you are still not seeing it on the display

httpswwwlinkedincominsg1993 27georgeshibin1993gmailcom

LAUNCHERbull For Launcher to be displayed bootanimation has to be stopped There is only one entity that can tell SF to stop

bootanim via a binder transaction ie WindowManagerService WindowManagerServicersquosperformEnableScreen() API needs to be invoked

httpandroidxrefcom700_r1xrefframeworksbaseservicescorejavacomandroidserverwmWindowManagerServicejava5866

if (mBootAnimationStopped)

Do this one time

TraceasyncTraceBegin(TraceTRACE_TAG_WINDOW_MANAGER Stop bootanim 0)

try

IBinder surfaceFlinger = ServiceManagergetService(SurfaceFlinger)

if (surfaceFlinger = null)

Slogi(TAG_WM TELLING SURFACE FLINGER WE ARE BOOTED)

Parcel data = Parcelobtain()

datawriteInterfaceToken(androiduiISurfaceComposer)

surfaceFlingertransact(IBinderFIRST_CALL_TRANSACTION BOOT_FINISHED

data null 0)

datarecycle()

catch (RemoteException ex)

Sloge(TAG_WM Boot completed SurfaceFlinger is dead)

mBootAnimationStopped = true

httpswwwlinkedincominsg1993 28georgeshibin1993gmailcom

bull So SF receives a binder call from WindowManagerService with the code IBinderFIRST_CALL_TRANSACTION SurfaceFlinger Binder IPC interface has defined the following

bull The call ultimately reaches bootFinished()

httpandroidxrefcom700_r1xrefframeworksnativeincludeguiISurfaceComposerh177

Note BOOT_FINISHED must remain this value it is called from

Java by ActivityManagerService

BOOT_FINISHED = IBinderFIRST_CALL_TRANSACTION

httpandroidxrefcom700_r1xrefframeworksnativeservicessurfaceflingerSurfaceFlingercpp292

void SurfaceFlingerbootFinished()

hellip

ALOGI(Boot is finished (ld ms) long(ns2ms(duration)) )

mBootFinished = true

stop boot animation

formerly we would just kill the process but we now ask it to exit so it

can choose where to stop the animation

property_set(servicebootanimexit 1)

httpswwwlinkedincominsg1993 29georgeshibin1993gmailcom

BOOTANIMATION

bull SF sets the property serviebootanim to 1 How does this stop bootanim

bull All this while since the time it was started bootanim has been executing playAnimation()

bull While doing so it also periodically calls checkExit()

bull On detecting that this property is set to 1 bootanim gracefully exits

httpandroidxrefcom700_r1xrefframeworksbasecmdsbootanimationBootAnimationcpp387

Allow surface flinger to gracefully request shutdown

char value[PROPERTY_VALUE_MAX]

property_get(servicebootanimexit value 0)

int exitnow = atoi(value)

if (exitnow)

requestExit()

if (mAudioPlayer = NULL)

mAudioPlayer-gtrequestExit()

httpswwwlinkedincominsg1993 30georgeshibin1993gmailcom

BOOT_COMPLETEDbull WindowManager invoked binder transaction to tell SF to stop bootanim

bull After that it calls ActivityManagerrsquos bootAnimationComplete() function

bull In ActivityManagerService finishBooting() is invoked where the property sysboot_completed is set to 1 This property is important because it is the ldquoofficialrdquo way of letting native-servicesdaemons know that boot is now complete

bull After this AMS tells UserController (which is a helper class for handling multi-user functionality) to send the 2 criticalimportant intents

bull Before you unlockswipe the lock screen the intent IntentACTION_LOCKED_BOOT_COMPLETED is sent here

bull Once the user is unlocked (by entering PINswiping-the-lock screen) the intent IntentACTION_BOOT_COMPLETED is sent here This intent is important because it lets Java-services3rd-party apps know that system boot-up is now officially complete and that user is now in the home screen

httpandroidxrefcom700_r1xrefframeworksbaseservicescorejavacomandroidserverwmWindowManagerServicejav

a5899

try

mActivityManagerbootAnimationComplete()

catch (RemoteException e)

httpswwwlinkedincominsg1993 31georgeshibin1993gmailcom

Aaaaand you are now in Home screen

httpswwwlinkedincominsg1993 32georgeshibin1993gmailcom

REFERENCES

bull My highlights on Karim Yaghmourrsquos famous book (Embedded Android) httpswwwsafaribooksonlinecomu001o000000YZt6HAATembedded-android9781449327958

bull Kernel boot process

bull httpduartesorggustavoblogpostkernel-boot-process

bull https0xaxgitbooksiolinux-insidescontentInitializationlinux-initialization-4html

bull httposr507docxinuoscomenPERFORMprocess_stateshtml

bull httpstackoverflowcomquestions464483why-do-we-need-a-swapper-task-in-linux

bull httpunixstackexchangecomquestions83322which-process-has-pid-0

bull BinderServiceManager

bull httpwwwmacrobugcomblog20071215decoding-a-service-call-in-android

bull httpwwwcubridorgblogdev-platformbinder-communication-mechanism-of-android-processes

bull httpwwwprogrameringcomaMjMyMDMwATQhtml

And most importantly httpandroidxrefcom700_r1xref

httpswwwlinkedincominsg1993 33georgeshibin1993gmailcom

Thank You for reading this far

httpswwwlinkedincominsg1993 34

Disclaimer

Almost none (okay fine absolutely zilch) of the information that I put up is proprietary to Qualcomm Inc

Some of the source-code hyperlinks to Qualcommrsquos internal repository which is not accessible to others anyway

For all the other stuff I have provided Android-xref links and is openly accessible to all

However I wonrsquot vouch for the correctness of all information presented here Nope

You are welcome to correcteditpresent this material according to your needs

However it would be nice if you could shoot me a mail (at georgeshibin1993gmailcom) andor provide a

reference to the original material Just sayinghellip it would be nice

georgeshibin1993gmailcom

Page 21: Android bootup

ZYGOTEbull Here is where you will appreciate the virtue of a great design

bull When a process forks it creates a clone of itself It replicates itself in another memory space When this happens to Zygote it creates a clean new Dalvik VM preloaded with all necessary classes and resources that any App will need (the same 4165 I mentioned earlier)

bull Except that it is never copied

bull You see the Linux Kernel implements a strategy called Copy On Write (COW) With COW Linux doesnrsquot actually copy anything Instead it maps the pages of the new process over to those of the parent process and makes copies only when the new process writes to a page But the classeslibrariesresources preloaded by Zygote are all read-only and not modified by any application This means that all processes forked from Zygote are using the exact same copy of the system classes and resources till EOL These preloaded objects live in the Zygote heap

bull This is what saves the time when apps are launched Also the memory saved is worth mentioning as no matter how many applications are started only one copy of the system classes and the resources is ever loaded in RAM

bull Personally I think the reason we still need Zygote (and cannot be replaced by system_server) is because we would like a process that does almost nothing other than fork() so that COW can do its magic Something like system_server would be counterproductive as its own heap and loaded classes would be huge

httpswwwlinkedincominsg1993 21georgeshibin1993gmailcom

ZYGOTEbull Thats pretty much what Zygote does during its lifetime Lets move onto system_server Notice the class name passed

as argument to Zygotersquos fork call for system_server

bull Just like in Zygotersquos case the AndroidRuntime knows how to execute the main() function in comandroidserverSystemServerjava

httpandroidxrefcom700_r1xrefframeworksbasecorejavacomandroidinternalosZygoteInitjava632

String args[] =

--setuid=1000

--setgid=1000

--setgroups=10011002100310041005100610071008100910101018102110323001300230033006300730093010

--capabilities= + capabilities + + capabilities

--nice-name=system_server

--runtime-args

comandroidserverSystemServer

httpandroidxrefcom700_r1xrefframeworksbaseservicesjavacomandroidserverSystemServerjava205

The main entry point from zygote

public static void main(String[] args)

new SystemServer()run()

httpswwwlinkedincominsg1993 22georgeshibin1993gmailcom

SYSTEM-SERVERbull The run() of system_server starts bootstrap-services core-services and some other services

bull Bootstrap-services are a small number of critical services

bull These are ActivityManagerService PowerManagerService DisplayManagerService PackageManagerService UserManagerService and sSensorService Bootstrap services are started almost together as they have internal dependencies with each other

bull Core services are some essential services that do not have dependencies on bootstrap services so can be started some time later One of these is the WindowManagerService

bull After that a couple of services which are not as critical as the above two classes Infact some of them even need not be started for device bootup

httpandroidxrefcom700_r1xrefframeworksbaseservicesjavacomandroidserverSystemServerjava320

try

TracetraceBegin(TraceTRACE_TAG_SYSTEM_SERVER StartServices)

startBootstrapServices()

startCoreServices()

startOtherServices()

httpswwwlinkedincominsg1993 23georgeshibin1993gmailcom

SYSTEM-SERVERbull Later down the line after starting almost all of the criticalcore services the system_server

(ie its main thread) proceeds to notify ActivityManagerService that the system is now ready to execute third-party code (read apps) The ActivityManagerService does some initializations before it can start applications

bull The callback reaches back to system_server main thread where it starts the first app comandroidsystemui here (specifically SystemUiService of systemui component)

bull We are now mostly done with this thread of system_server (the main thread mainly deals with handling messages from other components and redirecting them)

httpandroidxrefcom700_r1xrefframeworksbaseservicesjavacomandroidserverSystemServerjava1275

mActivityManagerServicesystemReady(new Runnable()

Override

public void run()

hellip

try

startSystemUi(context)

catch (Throwable e)

reportWtf(starting System UI e)

httpswwwlinkedincominsg1993 24georgeshibin1993gmailcom

BOOTANIMATION

bull Wondering what is being displayed on the screen during this entire process

bull After init starts what you see is bootanimation

bull The bootanim is a service that displays the bootanimation and is started by init

bull The rc file is parsed by init during startup But init does not start it right away (Notice the disabled)

bull This also means that someone has to explicitly start bootanim This is done by SurfaceFlinger in its init()

httpandroidxrefcom700_r1xrefframeworksbasecmdsbootanimationbootanimrc

service bootanim systembinbootanimation

class core

user graphics

group graphics audio

disabled

oneshot

httpandroidxrefcom700_r1xrefframeworksbaseservicesjavacomandroidserverSystemServerjava1275

start boot animation

startBootAnim()

httpandroidxrefcom700_r1xrefframeworksnativeservicessurfaceflingerSurfaceFlingercpp506

void SurfaceFlingerstartBootAnim()

start boot animation

property_set(servicebootanimexit 0)

property_set(ctlstart bootanim)

httpswwwlinkedincominsg1993 25georgeshibin1993gmailcom

BOOTANIMATION

bull Note that SF doesnrsquot directly spawnfork a process Rather it sets a property ctlstart to bootanim

bull ctl is special because there is no actual property named ctlstartstop (it wonrsquot appear in getprop output)

bull Note the special handling of a property if the property_name starts with ctl

httpandroidxrefcom700_r1xrefsystemcoreinitproperty_servicecpp280

case PROP_MSG_SETPROP

hellip

if(memcmp(msgnamectl4) == 0)

hellip

if (check_control_mac_perms(msgvalue source_ctx ampcr))

handle_control_message((char) msgname + 4 (char) msgvalue)

hellip

else

if (check_mac_perms(msgname source_ctx ampcr))

property_set((char) msgname (char) msgvalue)

hellip

httpswwwlinkedincominsg1993 26georgeshibin1993gmailcom

LAUNCHER

bull When the call reaches init it starts the service which is assigned to ctlstart

bull So when SF sets ctlstart to bootanim init starts the service bootanim

bull Bootanim gets the media files from systemmediabootanimationzip

bull But who stops bootanim Lets get back to system_server to find that out

bull Remember we informed ActivityManagerService that we are ready to executelaunch 3rd party codeapplications here

bull AMS on executing this calls startHomeActivityLocked() Internally this sends an Intent with category IntentCATEGORY_HOME This intent category is special because if an app registers for this intent it means that the application is a Launcher-appHome-screen replacement app

bull On receving this intent Launcher is started as it had registered for the same (see Manifest)

bull Ok Launcher has started but you are still not seeing it on the display

httpswwwlinkedincominsg1993 27georgeshibin1993gmailcom

LAUNCHERbull For Launcher to be displayed bootanimation has to be stopped There is only one entity that can tell SF to stop

bootanim via a binder transaction ie WindowManagerService WindowManagerServicersquosperformEnableScreen() API needs to be invoked

httpandroidxrefcom700_r1xrefframeworksbaseservicescorejavacomandroidserverwmWindowManagerServicejava5866

if (mBootAnimationStopped)

Do this one time

TraceasyncTraceBegin(TraceTRACE_TAG_WINDOW_MANAGER Stop bootanim 0)

try

IBinder surfaceFlinger = ServiceManagergetService(SurfaceFlinger)

if (surfaceFlinger = null)

Slogi(TAG_WM TELLING SURFACE FLINGER WE ARE BOOTED)

Parcel data = Parcelobtain()

datawriteInterfaceToken(androiduiISurfaceComposer)

surfaceFlingertransact(IBinderFIRST_CALL_TRANSACTION BOOT_FINISHED

data null 0)

datarecycle()

catch (RemoteException ex)

Sloge(TAG_WM Boot completed SurfaceFlinger is dead)

mBootAnimationStopped = true

httpswwwlinkedincominsg1993 28georgeshibin1993gmailcom

bull So SF receives a binder call from WindowManagerService with the code IBinderFIRST_CALL_TRANSACTION SurfaceFlinger Binder IPC interface has defined the following

bull The call ultimately reaches bootFinished()

httpandroidxrefcom700_r1xrefframeworksnativeincludeguiISurfaceComposerh177

Note BOOT_FINISHED must remain this value it is called from

Java by ActivityManagerService

BOOT_FINISHED = IBinderFIRST_CALL_TRANSACTION

httpandroidxrefcom700_r1xrefframeworksnativeservicessurfaceflingerSurfaceFlingercpp292

void SurfaceFlingerbootFinished()

hellip

ALOGI(Boot is finished (ld ms) long(ns2ms(duration)) )

mBootFinished = true

stop boot animation

formerly we would just kill the process but we now ask it to exit so it

can choose where to stop the animation

property_set(servicebootanimexit 1)

httpswwwlinkedincominsg1993 29georgeshibin1993gmailcom

BOOTANIMATION

bull SF sets the property serviebootanim to 1 How does this stop bootanim

bull All this while since the time it was started bootanim has been executing playAnimation()

bull While doing so it also periodically calls checkExit()

bull On detecting that this property is set to 1 bootanim gracefully exits

httpandroidxrefcom700_r1xrefframeworksbasecmdsbootanimationBootAnimationcpp387

Allow surface flinger to gracefully request shutdown

char value[PROPERTY_VALUE_MAX]

property_get(servicebootanimexit value 0)

int exitnow = atoi(value)

if (exitnow)

requestExit()

if (mAudioPlayer = NULL)

mAudioPlayer-gtrequestExit()

httpswwwlinkedincominsg1993 30georgeshibin1993gmailcom

BOOT_COMPLETEDbull WindowManager invoked binder transaction to tell SF to stop bootanim

bull After that it calls ActivityManagerrsquos bootAnimationComplete() function

bull In ActivityManagerService finishBooting() is invoked where the property sysboot_completed is set to 1 This property is important because it is the ldquoofficialrdquo way of letting native-servicesdaemons know that boot is now complete

bull After this AMS tells UserController (which is a helper class for handling multi-user functionality) to send the 2 criticalimportant intents

bull Before you unlockswipe the lock screen the intent IntentACTION_LOCKED_BOOT_COMPLETED is sent here

bull Once the user is unlocked (by entering PINswiping-the-lock screen) the intent IntentACTION_BOOT_COMPLETED is sent here This intent is important because it lets Java-services3rd-party apps know that system boot-up is now officially complete and that user is now in the home screen

httpandroidxrefcom700_r1xrefframeworksbaseservicescorejavacomandroidserverwmWindowManagerServicejav

a5899

try

mActivityManagerbootAnimationComplete()

catch (RemoteException e)

httpswwwlinkedincominsg1993 31georgeshibin1993gmailcom

Aaaaand you are now in Home screen

httpswwwlinkedincominsg1993 32georgeshibin1993gmailcom

REFERENCES

bull My highlights on Karim Yaghmourrsquos famous book (Embedded Android) httpswwwsafaribooksonlinecomu001o000000YZt6HAATembedded-android9781449327958

bull Kernel boot process

bull httpduartesorggustavoblogpostkernel-boot-process

bull https0xaxgitbooksiolinux-insidescontentInitializationlinux-initialization-4html

bull httposr507docxinuoscomenPERFORMprocess_stateshtml

bull httpstackoverflowcomquestions464483why-do-we-need-a-swapper-task-in-linux

bull httpunixstackexchangecomquestions83322which-process-has-pid-0

bull BinderServiceManager

bull httpwwwmacrobugcomblog20071215decoding-a-service-call-in-android

bull httpwwwcubridorgblogdev-platformbinder-communication-mechanism-of-android-processes

bull httpwwwprogrameringcomaMjMyMDMwATQhtml

And most importantly httpandroidxrefcom700_r1xref

httpswwwlinkedincominsg1993 33georgeshibin1993gmailcom

Thank You for reading this far

httpswwwlinkedincominsg1993 34

Disclaimer

Almost none (okay fine absolutely zilch) of the information that I put up is proprietary to Qualcomm Inc

Some of the source-code hyperlinks to Qualcommrsquos internal repository which is not accessible to others anyway

For all the other stuff I have provided Android-xref links and is openly accessible to all

However I wonrsquot vouch for the correctness of all information presented here Nope

You are welcome to correcteditpresent this material according to your needs

However it would be nice if you could shoot me a mail (at georgeshibin1993gmailcom) andor provide a

reference to the original material Just sayinghellip it would be nice

georgeshibin1993gmailcom

Page 22: Android bootup

ZYGOTEbull Thats pretty much what Zygote does during its lifetime Lets move onto system_server Notice the class name passed

as argument to Zygotersquos fork call for system_server

bull Just like in Zygotersquos case the AndroidRuntime knows how to execute the main() function in comandroidserverSystemServerjava

httpandroidxrefcom700_r1xrefframeworksbasecorejavacomandroidinternalosZygoteInitjava632

String args[] =

--setuid=1000

--setgid=1000

--setgroups=10011002100310041005100610071008100910101018102110323001300230033006300730093010

--capabilities= + capabilities + + capabilities

--nice-name=system_server

--runtime-args

comandroidserverSystemServer

httpandroidxrefcom700_r1xrefframeworksbaseservicesjavacomandroidserverSystemServerjava205

The main entry point from zygote

public static void main(String[] args)

new SystemServer()run()

httpswwwlinkedincominsg1993 22georgeshibin1993gmailcom

SYSTEM-SERVERbull The run() of system_server starts bootstrap-services core-services and some other services

bull Bootstrap-services are a small number of critical services

bull These are ActivityManagerService PowerManagerService DisplayManagerService PackageManagerService UserManagerService and sSensorService Bootstrap services are started almost together as they have internal dependencies with each other

bull Core services are some essential services that do not have dependencies on bootstrap services so can be started some time later One of these is the WindowManagerService

bull After that a couple of services which are not as critical as the above two classes Infact some of them even need not be started for device bootup

httpandroidxrefcom700_r1xrefframeworksbaseservicesjavacomandroidserverSystemServerjava320

try

TracetraceBegin(TraceTRACE_TAG_SYSTEM_SERVER StartServices)

startBootstrapServices()

startCoreServices()

startOtherServices()

httpswwwlinkedincominsg1993 23georgeshibin1993gmailcom

SYSTEM-SERVERbull Later down the line after starting almost all of the criticalcore services the system_server

(ie its main thread) proceeds to notify ActivityManagerService that the system is now ready to execute third-party code (read apps) The ActivityManagerService does some initializations before it can start applications

bull The callback reaches back to system_server main thread where it starts the first app comandroidsystemui here (specifically SystemUiService of systemui component)

bull We are now mostly done with this thread of system_server (the main thread mainly deals with handling messages from other components and redirecting them)

httpandroidxrefcom700_r1xrefframeworksbaseservicesjavacomandroidserverSystemServerjava1275

mActivityManagerServicesystemReady(new Runnable()

Override

public void run()

hellip

try

startSystemUi(context)

catch (Throwable e)

reportWtf(starting System UI e)

httpswwwlinkedincominsg1993 24georgeshibin1993gmailcom

BOOTANIMATION

bull Wondering what is being displayed on the screen during this entire process

bull After init starts what you see is bootanimation

bull The bootanim is a service that displays the bootanimation and is started by init

bull The rc file is parsed by init during startup But init does not start it right away (Notice the disabled)

bull This also means that someone has to explicitly start bootanim This is done by SurfaceFlinger in its init()

httpandroidxrefcom700_r1xrefframeworksbasecmdsbootanimationbootanimrc

service bootanim systembinbootanimation

class core

user graphics

group graphics audio

disabled

oneshot

httpandroidxrefcom700_r1xrefframeworksbaseservicesjavacomandroidserverSystemServerjava1275

start boot animation

startBootAnim()

httpandroidxrefcom700_r1xrefframeworksnativeservicessurfaceflingerSurfaceFlingercpp506

void SurfaceFlingerstartBootAnim()

start boot animation

property_set(servicebootanimexit 0)

property_set(ctlstart bootanim)

httpswwwlinkedincominsg1993 25georgeshibin1993gmailcom

BOOTANIMATION

bull Note that SF doesnrsquot directly spawnfork a process Rather it sets a property ctlstart to bootanim

bull ctl is special because there is no actual property named ctlstartstop (it wonrsquot appear in getprop output)

bull Note the special handling of a property if the property_name starts with ctl

httpandroidxrefcom700_r1xrefsystemcoreinitproperty_servicecpp280

case PROP_MSG_SETPROP

hellip

if(memcmp(msgnamectl4) == 0)

hellip

if (check_control_mac_perms(msgvalue source_ctx ampcr))

handle_control_message((char) msgname + 4 (char) msgvalue)

hellip

else

if (check_mac_perms(msgname source_ctx ampcr))

property_set((char) msgname (char) msgvalue)

hellip

httpswwwlinkedincominsg1993 26georgeshibin1993gmailcom

LAUNCHER

bull When the call reaches init it starts the service which is assigned to ctlstart

bull So when SF sets ctlstart to bootanim init starts the service bootanim

bull Bootanim gets the media files from systemmediabootanimationzip

bull But who stops bootanim Lets get back to system_server to find that out

bull Remember we informed ActivityManagerService that we are ready to executelaunch 3rd party codeapplications here

bull AMS on executing this calls startHomeActivityLocked() Internally this sends an Intent with category IntentCATEGORY_HOME This intent category is special because if an app registers for this intent it means that the application is a Launcher-appHome-screen replacement app

bull On receving this intent Launcher is started as it had registered for the same (see Manifest)

bull Ok Launcher has started but you are still not seeing it on the display

httpswwwlinkedincominsg1993 27georgeshibin1993gmailcom

LAUNCHERbull For Launcher to be displayed bootanimation has to be stopped There is only one entity that can tell SF to stop

bootanim via a binder transaction ie WindowManagerService WindowManagerServicersquosperformEnableScreen() API needs to be invoked

httpandroidxrefcom700_r1xrefframeworksbaseservicescorejavacomandroidserverwmWindowManagerServicejava5866

if (mBootAnimationStopped)

Do this one time

TraceasyncTraceBegin(TraceTRACE_TAG_WINDOW_MANAGER Stop bootanim 0)

try

IBinder surfaceFlinger = ServiceManagergetService(SurfaceFlinger)

if (surfaceFlinger = null)

Slogi(TAG_WM TELLING SURFACE FLINGER WE ARE BOOTED)

Parcel data = Parcelobtain()

datawriteInterfaceToken(androiduiISurfaceComposer)

surfaceFlingertransact(IBinderFIRST_CALL_TRANSACTION BOOT_FINISHED

data null 0)

datarecycle()

catch (RemoteException ex)

Sloge(TAG_WM Boot completed SurfaceFlinger is dead)

mBootAnimationStopped = true

httpswwwlinkedincominsg1993 28georgeshibin1993gmailcom

bull So SF receives a binder call from WindowManagerService with the code IBinderFIRST_CALL_TRANSACTION SurfaceFlinger Binder IPC interface has defined the following

bull The call ultimately reaches bootFinished()

httpandroidxrefcom700_r1xrefframeworksnativeincludeguiISurfaceComposerh177

Note BOOT_FINISHED must remain this value it is called from

Java by ActivityManagerService

BOOT_FINISHED = IBinderFIRST_CALL_TRANSACTION

httpandroidxrefcom700_r1xrefframeworksnativeservicessurfaceflingerSurfaceFlingercpp292

void SurfaceFlingerbootFinished()

hellip

ALOGI(Boot is finished (ld ms) long(ns2ms(duration)) )

mBootFinished = true

stop boot animation

formerly we would just kill the process but we now ask it to exit so it

can choose where to stop the animation

property_set(servicebootanimexit 1)

httpswwwlinkedincominsg1993 29georgeshibin1993gmailcom

BOOTANIMATION

bull SF sets the property serviebootanim to 1 How does this stop bootanim

bull All this while since the time it was started bootanim has been executing playAnimation()

bull While doing so it also periodically calls checkExit()

bull On detecting that this property is set to 1 bootanim gracefully exits

httpandroidxrefcom700_r1xrefframeworksbasecmdsbootanimationBootAnimationcpp387

Allow surface flinger to gracefully request shutdown

char value[PROPERTY_VALUE_MAX]

property_get(servicebootanimexit value 0)

int exitnow = atoi(value)

if (exitnow)

requestExit()

if (mAudioPlayer = NULL)

mAudioPlayer-gtrequestExit()

httpswwwlinkedincominsg1993 30georgeshibin1993gmailcom

BOOT_COMPLETEDbull WindowManager invoked binder transaction to tell SF to stop bootanim

bull After that it calls ActivityManagerrsquos bootAnimationComplete() function

bull In ActivityManagerService finishBooting() is invoked where the property sysboot_completed is set to 1 This property is important because it is the ldquoofficialrdquo way of letting native-servicesdaemons know that boot is now complete

bull After this AMS tells UserController (which is a helper class for handling multi-user functionality) to send the 2 criticalimportant intents

bull Before you unlockswipe the lock screen the intent IntentACTION_LOCKED_BOOT_COMPLETED is sent here

bull Once the user is unlocked (by entering PINswiping-the-lock screen) the intent IntentACTION_BOOT_COMPLETED is sent here This intent is important because it lets Java-services3rd-party apps know that system boot-up is now officially complete and that user is now in the home screen

httpandroidxrefcom700_r1xrefframeworksbaseservicescorejavacomandroidserverwmWindowManagerServicejav

a5899

try

mActivityManagerbootAnimationComplete()

catch (RemoteException e)

httpswwwlinkedincominsg1993 31georgeshibin1993gmailcom

Aaaaand you are now in Home screen

httpswwwlinkedincominsg1993 32georgeshibin1993gmailcom

REFERENCES

bull My highlights on Karim Yaghmourrsquos famous book (Embedded Android) httpswwwsafaribooksonlinecomu001o000000YZt6HAATembedded-android9781449327958

bull Kernel boot process

bull httpduartesorggustavoblogpostkernel-boot-process

bull https0xaxgitbooksiolinux-insidescontentInitializationlinux-initialization-4html

bull httposr507docxinuoscomenPERFORMprocess_stateshtml

bull httpstackoverflowcomquestions464483why-do-we-need-a-swapper-task-in-linux

bull httpunixstackexchangecomquestions83322which-process-has-pid-0

bull BinderServiceManager

bull httpwwwmacrobugcomblog20071215decoding-a-service-call-in-android

bull httpwwwcubridorgblogdev-platformbinder-communication-mechanism-of-android-processes

bull httpwwwprogrameringcomaMjMyMDMwATQhtml

And most importantly httpandroidxrefcom700_r1xref

httpswwwlinkedincominsg1993 33georgeshibin1993gmailcom

Thank You for reading this far

httpswwwlinkedincominsg1993 34

Disclaimer

Almost none (okay fine absolutely zilch) of the information that I put up is proprietary to Qualcomm Inc

Some of the source-code hyperlinks to Qualcommrsquos internal repository which is not accessible to others anyway

For all the other stuff I have provided Android-xref links and is openly accessible to all

However I wonrsquot vouch for the correctness of all information presented here Nope

You are welcome to correcteditpresent this material according to your needs

However it would be nice if you could shoot me a mail (at georgeshibin1993gmailcom) andor provide a

reference to the original material Just sayinghellip it would be nice

georgeshibin1993gmailcom

Page 23: Android bootup

SYSTEM-SERVERbull The run() of system_server starts bootstrap-services core-services and some other services

bull Bootstrap-services are a small number of critical services

bull These are ActivityManagerService PowerManagerService DisplayManagerService PackageManagerService UserManagerService and sSensorService Bootstrap services are started almost together as they have internal dependencies with each other

bull Core services are some essential services that do not have dependencies on bootstrap services so can be started some time later One of these is the WindowManagerService

bull After that a couple of services which are not as critical as the above two classes Infact some of them even need not be started for device bootup

httpandroidxrefcom700_r1xrefframeworksbaseservicesjavacomandroidserverSystemServerjava320

try

TracetraceBegin(TraceTRACE_TAG_SYSTEM_SERVER StartServices)

startBootstrapServices()

startCoreServices()

startOtherServices()

httpswwwlinkedincominsg1993 23georgeshibin1993gmailcom

SYSTEM-SERVERbull Later down the line after starting almost all of the criticalcore services the system_server

(ie its main thread) proceeds to notify ActivityManagerService that the system is now ready to execute third-party code (read apps) The ActivityManagerService does some initializations before it can start applications

bull The callback reaches back to system_server main thread where it starts the first app comandroidsystemui here (specifically SystemUiService of systemui component)

bull We are now mostly done with this thread of system_server (the main thread mainly deals with handling messages from other components and redirecting them)

httpandroidxrefcom700_r1xrefframeworksbaseservicesjavacomandroidserverSystemServerjava1275

mActivityManagerServicesystemReady(new Runnable()

Override

public void run()

hellip

try

startSystemUi(context)

catch (Throwable e)

reportWtf(starting System UI e)

httpswwwlinkedincominsg1993 24georgeshibin1993gmailcom

BOOTANIMATION

bull Wondering what is being displayed on the screen during this entire process

bull After init starts what you see is bootanimation

bull The bootanim is a service that displays the bootanimation and is started by init

bull The rc file is parsed by init during startup But init does not start it right away (Notice the disabled)

bull This also means that someone has to explicitly start bootanim This is done by SurfaceFlinger in its init()

httpandroidxrefcom700_r1xrefframeworksbasecmdsbootanimationbootanimrc

service bootanim systembinbootanimation

class core

user graphics

group graphics audio

disabled

oneshot

httpandroidxrefcom700_r1xrefframeworksbaseservicesjavacomandroidserverSystemServerjava1275

start boot animation

startBootAnim()

httpandroidxrefcom700_r1xrefframeworksnativeservicessurfaceflingerSurfaceFlingercpp506

void SurfaceFlingerstartBootAnim()

start boot animation

property_set(servicebootanimexit 0)

property_set(ctlstart bootanim)

httpswwwlinkedincominsg1993 25georgeshibin1993gmailcom

BOOTANIMATION

bull Note that SF doesnrsquot directly spawnfork a process Rather it sets a property ctlstart to bootanim

bull ctl is special because there is no actual property named ctlstartstop (it wonrsquot appear in getprop output)

bull Note the special handling of a property if the property_name starts with ctl

httpandroidxrefcom700_r1xrefsystemcoreinitproperty_servicecpp280

case PROP_MSG_SETPROP

hellip

if(memcmp(msgnamectl4) == 0)

hellip

if (check_control_mac_perms(msgvalue source_ctx ampcr))

handle_control_message((char) msgname + 4 (char) msgvalue)

hellip

else

if (check_mac_perms(msgname source_ctx ampcr))

property_set((char) msgname (char) msgvalue)

hellip

httpswwwlinkedincominsg1993 26georgeshibin1993gmailcom

LAUNCHER

bull When the call reaches init it starts the service which is assigned to ctlstart

bull So when SF sets ctlstart to bootanim init starts the service bootanim

bull Bootanim gets the media files from systemmediabootanimationzip

bull But who stops bootanim Lets get back to system_server to find that out

bull Remember we informed ActivityManagerService that we are ready to executelaunch 3rd party codeapplications here

bull AMS on executing this calls startHomeActivityLocked() Internally this sends an Intent with category IntentCATEGORY_HOME This intent category is special because if an app registers for this intent it means that the application is a Launcher-appHome-screen replacement app

bull On receving this intent Launcher is started as it had registered for the same (see Manifest)

bull Ok Launcher has started but you are still not seeing it on the display

httpswwwlinkedincominsg1993 27georgeshibin1993gmailcom

LAUNCHERbull For Launcher to be displayed bootanimation has to be stopped There is only one entity that can tell SF to stop

bootanim via a binder transaction ie WindowManagerService WindowManagerServicersquosperformEnableScreen() API needs to be invoked

httpandroidxrefcom700_r1xrefframeworksbaseservicescorejavacomandroidserverwmWindowManagerServicejava5866

if (mBootAnimationStopped)

Do this one time

TraceasyncTraceBegin(TraceTRACE_TAG_WINDOW_MANAGER Stop bootanim 0)

try

IBinder surfaceFlinger = ServiceManagergetService(SurfaceFlinger)

if (surfaceFlinger = null)

Slogi(TAG_WM TELLING SURFACE FLINGER WE ARE BOOTED)

Parcel data = Parcelobtain()

datawriteInterfaceToken(androiduiISurfaceComposer)

surfaceFlingertransact(IBinderFIRST_CALL_TRANSACTION BOOT_FINISHED

data null 0)

datarecycle()

catch (RemoteException ex)

Sloge(TAG_WM Boot completed SurfaceFlinger is dead)

mBootAnimationStopped = true

httpswwwlinkedincominsg1993 28georgeshibin1993gmailcom

bull So SF receives a binder call from WindowManagerService with the code IBinderFIRST_CALL_TRANSACTION SurfaceFlinger Binder IPC interface has defined the following

bull The call ultimately reaches bootFinished()

httpandroidxrefcom700_r1xrefframeworksnativeincludeguiISurfaceComposerh177

Note BOOT_FINISHED must remain this value it is called from

Java by ActivityManagerService

BOOT_FINISHED = IBinderFIRST_CALL_TRANSACTION

httpandroidxrefcom700_r1xrefframeworksnativeservicessurfaceflingerSurfaceFlingercpp292

void SurfaceFlingerbootFinished()

hellip

ALOGI(Boot is finished (ld ms) long(ns2ms(duration)) )

mBootFinished = true

stop boot animation

formerly we would just kill the process but we now ask it to exit so it

can choose where to stop the animation

property_set(servicebootanimexit 1)

httpswwwlinkedincominsg1993 29georgeshibin1993gmailcom

BOOTANIMATION

bull SF sets the property serviebootanim to 1 How does this stop bootanim

bull All this while since the time it was started bootanim has been executing playAnimation()

bull While doing so it also periodically calls checkExit()

bull On detecting that this property is set to 1 bootanim gracefully exits

httpandroidxrefcom700_r1xrefframeworksbasecmdsbootanimationBootAnimationcpp387

Allow surface flinger to gracefully request shutdown

char value[PROPERTY_VALUE_MAX]

property_get(servicebootanimexit value 0)

int exitnow = atoi(value)

if (exitnow)

requestExit()

if (mAudioPlayer = NULL)

mAudioPlayer-gtrequestExit()

httpswwwlinkedincominsg1993 30georgeshibin1993gmailcom

BOOT_COMPLETEDbull WindowManager invoked binder transaction to tell SF to stop bootanim

bull After that it calls ActivityManagerrsquos bootAnimationComplete() function

bull In ActivityManagerService finishBooting() is invoked where the property sysboot_completed is set to 1 This property is important because it is the ldquoofficialrdquo way of letting native-servicesdaemons know that boot is now complete

bull After this AMS tells UserController (which is a helper class for handling multi-user functionality) to send the 2 criticalimportant intents

bull Before you unlockswipe the lock screen the intent IntentACTION_LOCKED_BOOT_COMPLETED is sent here

bull Once the user is unlocked (by entering PINswiping-the-lock screen) the intent IntentACTION_BOOT_COMPLETED is sent here This intent is important because it lets Java-services3rd-party apps know that system boot-up is now officially complete and that user is now in the home screen

httpandroidxrefcom700_r1xrefframeworksbaseservicescorejavacomandroidserverwmWindowManagerServicejav

a5899

try

mActivityManagerbootAnimationComplete()

catch (RemoteException e)

httpswwwlinkedincominsg1993 31georgeshibin1993gmailcom

Aaaaand you are now in Home screen

httpswwwlinkedincominsg1993 32georgeshibin1993gmailcom

REFERENCES

bull My highlights on Karim Yaghmourrsquos famous book (Embedded Android) httpswwwsafaribooksonlinecomu001o000000YZt6HAATembedded-android9781449327958

bull Kernel boot process

bull httpduartesorggustavoblogpostkernel-boot-process

bull https0xaxgitbooksiolinux-insidescontentInitializationlinux-initialization-4html

bull httposr507docxinuoscomenPERFORMprocess_stateshtml

bull httpstackoverflowcomquestions464483why-do-we-need-a-swapper-task-in-linux

bull httpunixstackexchangecomquestions83322which-process-has-pid-0

bull BinderServiceManager

bull httpwwwmacrobugcomblog20071215decoding-a-service-call-in-android

bull httpwwwcubridorgblogdev-platformbinder-communication-mechanism-of-android-processes

bull httpwwwprogrameringcomaMjMyMDMwATQhtml

And most importantly httpandroidxrefcom700_r1xref

httpswwwlinkedincominsg1993 33georgeshibin1993gmailcom

Thank You for reading this far

httpswwwlinkedincominsg1993 34

Disclaimer

Almost none (okay fine absolutely zilch) of the information that I put up is proprietary to Qualcomm Inc

Some of the source-code hyperlinks to Qualcommrsquos internal repository which is not accessible to others anyway

For all the other stuff I have provided Android-xref links and is openly accessible to all

However I wonrsquot vouch for the correctness of all information presented here Nope

You are welcome to correcteditpresent this material according to your needs

However it would be nice if you could shoot me a mail (at georgeshibin1993gmailcom) andor provide a

reference to the original material Just sayinghellip it would be nice

georgeshibin1993gmailcom

Page 24: Android bootup

SYSTEM-SERVERbull Later down the line after starting almost all of the criticalcore services the system_server

(ie its main thread) proceeds to notify ActivityManagerService that the system is now ready to execute third-party code (read apps) The ActivityManagerService does some initializations before it can start applications

bull The callback reaches back to system_server main thread where it starts the first app comandroidsystemui here (specifically SystemUiService of systemui component)

bull We are now mostly done with this thread of system_server (the main thread mainly deals with handling messages from other components and redirecting them)

httpandroidxrefcom700_r1xrefframeworksbaseservicesjavacomandroidserverSystemServerjava1275

mActivityManagerServicesystemReady(new Runnable()

Override

public void run()

hellip

try

startSystemUi(context)

catch (Throwable e)

reportWtf(starting System UI e)

httpswwwlinkedincominsg1993 24georgeshibin1993gmailcom

BOOTANIMATION

bull Wondering what is being displayed on the screen during this entire process

bull After init starts what you see is bootanimation

bull The bootanim is a service that displays the bootanimation and is started by init

bull The rc file is parsed by init during startup But init does not start it right away (Notice the disabled)

bull This also means that someone has to explicitly start bootanim This is done by SurfaceFlinger in its init()

httpandroidxrefcom700_r1xrefframeworksbasecmdsbootanimationbootanimrc

service bootanim systembinbootanimation

class core

user graphics

group graphics audio

disabled

oneshot

httpandroidxrefcom700_r1xrefframeworksbaseservicesjavacomandroidserverSystemServerjava1275

start boot animation

startBootAnim()

httpandroidxrefcom700_r1xrefframeworksnativeservicessurfaceflingerSurfaceFlingercpp506

void SurfaceFlingerstartBootAnim()

start boot animation

property_set(servicebootanimexit 0)

property_set(ctlstart bootanim)

httpswwwlinkedincominsg1993 25georgeshibin1993gmailcom

BOOTANIMATION

bull Note that SF doesnrsquot directly spawnfork a process Rather it sets a property ctlstart to bootanim

bull ctl is special because there is no actual property named ctlstartstop (it wonrsquot appear in getprop output)

bull Note the special handling of a property if the property_name starts with ctl

httpandroidxrefcom700_r1xrefsystemcoreinitproperty_servicecpp280

case PROP_MSG_SETPROP

hellip

if(memcmp(msgnamectl4) == 0)

hellip

if (check_control_mac_perms(msgvalue source_ctx ampcr))

handle_control_message((char) msgname + 4 (char) msgvalue)

hellip

else

if (check_mac_perms(msgname source_ctx ampcr))

property_set((char) msgname (char) msgvalue)

hellip

httpswwwlinkedincominsg1993 26georgeshibin1993gmailcom

LAUNCHER

bull When the call reaches init it starts the service which is assigned to ctlstart

bull So when SF sets ctlstart to bootanim init starts the service bootanim

bull Bootanim gets the media files from systemmediabootanimationzip

bull But who stops bootanim Lets get back to system_server to find that out

bull Remember we informed ActivityManagerService that we are ready to executelaunch 3rd party codeapplications here

bull AMS on executing this calls startHomeActivityLocked() Internally this sends an Intent with category IntentCATEGORY_HOME This intent category is special because if an app registers for this intent it means that the application is a Launcher-appHome-screen replacement app

bull On receving this intent Launcher is started as it had registered for the same (see Manifest)

bull Ok Launcher has started but you are still not seeing it on the display

httpswwwlinkedincominsg1993 27georgeshibin1993gmailcom

LAUNCHERbull For Launcher to be displayed bootanimation has to be stopped There is only one entity that can tell SF to stop

bootanim via a binder transaction ie WindowManagerService WindowManagerServicersquosperformEnableScreen() API needs to be invoked

httpandroidxrefcom700_r1xrefframeworksbaseservicescorejavacomandroidserverwmWindowManagerServicejava5866

if (mBootAnimationStopped)

Do this one time

TraceasyncTraceBegin(TraceTRACE_TAG_WINDOW_MANAGER Stop bootanim 0)

try

IBinder surfaceFlinger = ServiceManagergetService(SurfaceFlinger)

if (surfaceFlinger = null)

Slogi(TAG_WM TELLING SURFACE FLINGER WE ARE BOOTED)

Parcel data = Parcelobtain()

datawriteInterfaceToken(androiduiISurfaceComposer)

surfaceFlingertransact(IBinderFIRST_CALL_TRANSACTION BOOT_FINISHED

data null 0)

datarecycle()

catch (RemoteException ex)

Sloge(TAG_WM Boot completed SurfaceFlinger is dead)

mBootAnimationStopped = true

httpswwwlinkedincominsg1993 28georgeshibin1993gmailcom

bull So SF receives a binder call from WindowManagerService with the code IBinderFIRST_CALL_TRANSACTION SurfaceFlinger Binder IPC interface has defined the following

bull The call ultimately reaches bootFinished()

httpandroidxrefcom700_r1xrefframeworksnativeincludeguiISurfaceComposerh177

Note BOOT_FINISHED must remain this value it is called from

Java by ActivityManagerService

BOOT_FINISHED = IBinderFIRST_CALL_TRANSACTION

httpandroidxrefcom700_r1xrefframeworksnativeservicessurfaceflingerSurfaceFlingercpp292

void SurfaceFlingerbootFinished()

hellip

ALOGI(Boot is finished (ld ms) long(ns2ms(duration)) )

mBootFinished = true

stop boot animation

formerly we would just kill the process but we now ask it to exit so it

can choose where to stop the animation

property_set(servicebootanimexit 1)

httpswwwlinkedincominsg1993 29georgeshibin1993gmailcom

BOOTANIMATION

bull SF sets the property serviebootanim to 1 How does this stop bootanim

bull All this while since the time it was started bootanim has been executing playAnimation()

bull While doing so it also periodically calls checkExit()

bull On detecting that this property is set to 1 bootanim gracefully exits

httpandroidxrefcom700_r1xrefframeworksbasecmdsbootanimationBootAnimationcpp387

Allow surface flinger to gracefully request shutdown

char value[PROPERTY_VALUE_MAX]

property_get(servicebootanimexit value 0)

int exitnow = atoi(value)

if (exitnow)

requestExit()

if (mAudioPlayer = NULL)

mAudioPlayer-gtrequestExit()

httpswwwlinkedincominsg1993 30georgeshibin1993gmailcom

BOOT_COMPLETEDbull WindowManager invoked binder transaction to tell SF to stop bootanim

bull After that it calls ActivityManagerrsquos bootAnimationComplete() function

bull In ActivityManagerService finishBooting() is invoked where the property sysboot_completed is set to 1 This property is important because it is the ldquoofficialrdquo way of letting native-servicesdaemons know that boot is now complete

bull After this AMS tells UserController (which is a helper class for handling multi-user functionality) to send the 2 criticalimportant intents

bull Before you unlockswipe the lock screen the intent IntentACTION_LOCKED_BOOT_COMPLETED is sent here

bull Once the user is unlocked (by entering PINswiping-the-lock screen) the intent IntentACTION_BOOT_COMPLETED is sent here This intent is important because it lets Java-services3rd-party apps know that system boot-up is now officially complete and that user is now in the home screen

httpandroidxrefcom700_r1xrefframeworksbaseservicescorejavacomandroidserverwmWindowManagerServicejav

a5899

try

mActivityManagerbootAnimationComplete()

catch (RemoteException e)

httpswwwlinkedincominsg1993 31georgeshibin1993gmailcom

Aaaaand you are now in Home screen

httpswwwlinkedincominsg1993 32georgeshibin1993gmailcom

REFERENCES

bull My highlights on Karim Yaghmourrsquos famous book (Embedded Android) httpswwwsafaribooksonlinecomu001o000000YZt6HAATembedded-android9781449327958

bull Kernel boot process

bull httpduartesorggustavoblogpostkernel-boot-process

bull https0xaxgitbooksiolinux-insidescontentInitializationlinux-initialization-4html

bull httposr507docxinuoscomenPERFORMprocess_stateshtml

bull httpstackoverflowcomquestions464483why-do-we-need-a-swapper-task-in-linux

bull httpunixstackexchangecomquestions83322which-process-has-pid-0

bull BinderServiceManager

bull httpwwwmacrobugcomblog20071215decoding-a-service-call-in-android

bull httpwwwcubridorgblogdev-platformbinder-communication-mechanism-of-android-processes

bull httpwwwprogrameringcomaMjMyMDMwATQhtml

And most importantly httpandroidxrefcom700_r1xref

httpswwwlinkedincominsg1993 33georgeshibin1993gmailcom

Thank You for reading this far

httpswwwlinkedincominsg1993 34

Disclaimer

Almost none (okay fine absolutely zilch) of the information that I put up is proprietary to Qualcomm Inc

Some of the source-code hyperlinks to Qualcommrsquos internal repository which is not accessible to others anyway

For all the other stuff I have provided Android-xref links and is openly accessible to all

However I wonrsquot vouch for the correctness of all information presented here Nope

You are welcome to correcteditpresent this material according to your needs

However it would be nice if you could shoot me a mail (at georgeshibin1993gmailcom) andor provide a

reference to the original material Just sayinghellip it would be nice

georgeshibin1993gmailcom

Page 25: Android bootup

BOOTANIMATION

bull Wondering what is being displayed on the screen during this entire process

bull After init starts what you see is bootanimation

bull The bootanim is a service that displays the bootanimation and is started by init

bull The rc file is parsed by init during startup But init does not start it right away (Notice the disabled)

bull This also means that someone has to explicitly start bootanim This is done by SurfaceFlinger in its init()

httpandroidxrefcom700_r1xrefframeworksbasecmdsbootanimationbootanimrc

service bootanim systembinbootanimation

class core

user graphics

group graphics audio

disabled

oneshot

httpandroidxrefcom700_r1xrefframeworksbaseservicesjavacomandroidserverSystemServerjava1275

start boot animation

startBootAnim()

httpandroidxrefcom700_r1xrefframeworksnativeservicessurfaceflingerSurfaceFlingercpp506

void SurfaceFlingerstartBootAnim()

start boot animation

property_set(servicebootanimexit 0)

property_set(ctlstart bootanim)

httpswwwlinkedincominsg1993 25georgeshibin1993gmailcom

BOOTANIMATION

bull Note that SF doesnrsquot directly spawnfork a process Rather it sets a property ctlstart to bootanim

bull ctl is special because there is no actual property named ctlstartstop (it wonrsquot appear in getprop output)

bull Note the special handling of a property if the property_name starts with ctl

httpandroidxrefcom700_r1xrefsystemcoreinitproperty_servicecpp280

case PROP_MSG_SETPROP

hellip

if(memcmp(msgnamectl4) == 0)

hellip

if (check_control_mac_perms(msgvalue source_ctx ampcr))

handle_control_message((char) msgname + 4 (char) msgvalue)

hellip

else

if (check_mac_perms(msgname source_ctx ampcr))

property_set((char) msgname (char) msgvalue)

hellip

httpswwwlinkedincominsg1993 26georgeshibin1993gmailcom

LAUNCHER

bull When the call reaches init it starts the service which is assigned to ctlstart

bull So when SF sets ctlstart to bootanim init starts the service bootanim

bull Bootanim gets the media files from systemmediabootanimationzip

bull But who stops bootanim Lets get back to system_server to find that out

bull Remember we informed ActivityManagerService that we are ready to executelaunch 3rd party codeapplications here

bull AMS on executing this calls startHomeActivityLocked() Internally this sends an Intent with category IntentCATEGORY_HOME This intent category is special because if an app registers for this intent it means that the application is a Launcher-appHome-screen replacement app

bull On receving this intent Launcher is started as it had registered for the same (see Manifest)

bull Ok Launcher has started but you are still not seeing it on the display

httpswwwlinkedincominsg1993 27georgeshibin1993gmailcom

LAUNCHERbull For Launcher to be displayed bootanimation has to be stopped There is only one entity that can tell SF to stop

bootanim via a binder transaction ie WindowManagerService WindowManagerServicersquosperformEnableScreen() API needs to be invoked

httpandroidxrefcom700_r1xrefframeworksbaseservicescorejavacomandroidserverwmWindowManagerServicejava5866

if (mBootAnimationStopped)

Do this one time

TraceasyncTraceBegin(TraceTRACE_TAG_WINDOW_MANAGER Stop bootanim 0)

try

IBinder surfaceFlinger = ServiceManagergetService(SurfaceFlinger)

if (surfaceFlinger = null)

Slogi(TAG_WM TELLING SURFACE FLINGER WE ARE BOOTED)

Parcel data = Parcelobtain()

datawriteInterfaceToken(androiduiISurfaceComposer)

surfaceFlingertransact(IBinderFIRST_CALL_TRANSACTION BOOT_FINISHED

data null 0)

datarecycle()

catch (RemoteException ex)

Sloge(TAG_WM Boot completed SurfaceFlinger is dead)

mBootAnimationStopped = true

httpswwwlinkedincominsg1993 28georgeshibin1993gmailcom

bull So SF receives a binder call from WindowManagerService with the code IBinderFIRST_CALL_TRANSACTION SurfaceFlinger Binder IPC interface has defined the following

bull The call ultimately reaches bootFinished()

httpandroidxrefcom700_r1xrefframeworksnativeincludeguiISurfaceComposerh177

Note BOOT_FINISHED must remain this value it is called from

Java by ActivityManagerService

BOOT_FINISHED = IBinderFIRST_CALL_TRANSACTION

httpandroidxrefcom700_r1xrefframeworksnativeservicessurfaceflingerSurfaceFlingercpp292

void SurfaceFlingerbootFinished()

hellip

ALOGI(Boot is finished (ld ms) long(ns2ms(duration)) )

mBootFinished = true

stop boot animation

formerly we would just kill the process but we now ask it to exit so it

can choose where to stop the animation

property_set(servicebootanimexit 1)

httpswwwlinkedincominsg1993 29georgeshibin1993gmailcom

BOOTANIMATION

bull SF sets the property serviebootanim to 1 How does this stop bootanim

bull All this while since the time it was started bootanim has been executing playAnimation()

bull While doing so it also periodically calls checkExit()

bull On detecting that this property is set to 1 bootanim gracefully exits

httpandroidxrefcom700_r1xrefframeworksbasecmdsbootanimationBootAnimationcpp387

Allow surface flinger to gracefully request shutdown

char value[PROPERTY_VALUE_MAX]

property_get(servicebootanimexit value 0)

int exitnow = atoi(value)

if (exitnow)

requestExit()

if (mAudioPlayer = NULL)

mAudioPlayer-gtrequestExit()

httpswwwlinkedincominsg1993 30georgeshibin1993gmailcom

BOOT_COMPLETEDbull WindowManager invoked binder transaction to tell SF to stop bootanim

bull After that it calls ActivityManagerrsquos bootAnimationComplete() function

bull In ActivityManagerService finishBooting() is invoked where the property sysboot_completed is set to 1 This property is important because it is the ldquoofficialrdquo way of letting native-servicesdaemons know that boot is now complete

bull After this AMS tells UserController (which is a helper class for handling multi-user functionality) to send the 2 criticalimportant intents

bull Before you unlockswipe the lock screen the intent IntentACTION_LOCKED_BOOT_COMPLETED is sent here

bull Once the user is unlocked (by entering PINswiping-the-lock screen) the intent IntentACTION_BOOT_COMPLETED is sent here This intent is important because it lets Java-services3rd-party apps know that system boot-up is now officially complete and that user is now in the home screen

httpandroidxrefcom700_r1xrefframeworksbaseservicescorejavacomandroidserverwmWindowManagerServicejav

a5899

try

mActivityManagerbootAnimationComplete()

catch (RemoteException e)

httpswwwlinkedincominsg1993 31georgeshibin1993gmailcom

Aaaaand you are now in Home screen

httpswwwlinkedincominsg1993 32georgeshibin1993gmailcom

REFERENCES

bull My highlights on Karim Yaghmourrsquos famous book (Embedded Android) httpswwwsafaribooksonlinecomu001o000000YZt6HAATembedded-android9781449327958

bull Kernel boot process

bull httpduartesorggustavoblogpostkernel-boot-process

bull https0xaxgitbooksiolinux-insidescontentInitializationlinux-initialization-4html

bull httposr507docxinuoscomenPERFORMprocess_stateshtml

bull httpstackoverflowcomquestions464483why-do-we-need-a-swapper-task-in-linux

bull httpunixstackexchangecomquestions83322which-process-has-pid-0

bull BinderServiceManager

bull httpwwwmacrobugcomblog20071215decoding-a-service-call-in-android

bull httpwwwcubridorgblogdev-platformbinder-communication-mechanism-of-android-processes

bull httpwwwprogrameringcomaMjMyMDMwATQhtml

And most importantly httpandroidxrefcom700_r1xref

httpswwwlinkedincominsg1993 33georgeshibin1993gmailcom

Thank You for reading this far

httpswwwlinkedincominsg1993 34

Disclaimer

Almost none (okay fine absolutely zilch) of the information that I put up is proprietary to Qualcomm Inc

Some of the source-code hyperlinks to Qualcommrsquos internal repository which is not accessible to others anyway

For all the other stuff I have provided Android-xref links and is openly accessible to all

However I wonrsquot vouch for the correctness of all information presented here Nope

You are welcome to correcteditpresent this material according to your needs

However it would be nice if you could shoot me a mail (at georgeshibin1993gmailcom) andor provide a

reference to the original material Just sayinghellip it would be nice

georgeshibin1993gmailcom

Page 26: Android bootup

BOOTANIMATION

bull Note that SF doesnrsquot directly spawnfork a process Rather it sets a property ctlstart to bootanim

bull ctl is special because there is no actual property named ctlstartstop (it wonrsquot appear in getprop output)

bull Note the special handling of a property if the property_name starts with ctl

httpandroidxrefcom700_r1xrefsystemcoreinitproperty_servicecpp280

case PROP_MSG_SETPROP

hellip

if(memcmp(msgnamectl4) == 0)

hellip

if (check_control_mac_perms(msgvalue source_ctx ampcr))

handle_control_message((char) msgname + 4 (char) msgvalue)

hellip

else

if (check_mac_perms(msgname source_ctx ampcr))

property_set((char) msgname (char) msgvalue)

hellip

httpswwwlinkedincominsg1993 26georgeshibin1993gmailcom

LAUNCHER

bull When the call reaches init it starts the service which is assigned to ctlstart

bull So when SF sets ctlstart to bootanim init starts the service bootanim

bull Bootanim gets the media files from systemmediabootanimationzip

bull But who stops bootanim Lets get back to system_server to find that out

bull Remember we informed ActivityManagerService that we are ready to executelaunch 3rd party codeapplications here

bull AMS on executing this calls startHomeActivityLocked() Internally this sends an Intent with category IntentCATEGORY_HOME This intent category is special because if an app registers for this intent it means that the application is a Launcher-appHome-screen replacement app

bull On receving this intent Launcher is started as it had registered for the same (see Manifest)

bull Ok Launcher has started but you are still not seeing it on the display

httpswwwlinkedincominsg1993 27georgeshibin1993gmailcom

LAUNCHERbull For Launcher to be displayed bootanimation has to be stopped There is only one entity that can tell SF to stop

bootanim via a binder transaction ie WindowManagerService WindowManagerServicersquosperformEnableScreen() API needs to be invoked

httpandroidxrefcom700_r1xrefframeworksbaseservicescorejavacomandroidserverwmWindowManagerServicejava5866

if (mBootAnimationStopped)

Do this one time

TraceasyncTraceBegin(TraceTRACE_TAG_WINDOW_MANAGER Stop bootanim 0)

try

IBinder surfaceFlinger = ServiceManagergetService(SurfaceFlinger)

if (surfaceFlinger = null)

Slogi(TAG_WM TELLING SURFACE FLINGER WE ARE BOOTED)

Parcel data = Parcelobtain()

datawriteInterfaceToken(androiduiISurfaceComposer)

surfaceFlingertransact(IBinderFIRST_CALL_TRANSACTION BOOT_FINISHED

data null 0)

datarecycle()

catch (RemoteException ex)

Sloge(TAG_WM Boot completed SurfaceFlinger is dead)

mBootAnimationStopped = true

httpswwwlinkedincominsg1993 28georgeshibin1993gmailcom

bull So SF receives a binder call from WindowManagerService with the code IBinderFIRST_CALL_TRANSACTION SurfaceFlinger Binder IPC interface has defined the following

bull The call ultimately reaches bootFinished()

httpandroidxrefcom700_r1xrefframeworksnativeincludeguiISurfaceComposerh177

Note BOOT_FINISHED must remain this value it is called from

Java by ActivityManagerService

BOOT_FINISHED = IBinderFIRST_CALL_TRANSACTION

httpandroidxrefcom700_r1xrefframeworksnativeservicessurfaceflingerSurfaceFlingercpp292

void SurfaceFlingerbootFinished()

hellip

ALOGI(Boot is finished (ld ms) long(ns2ms(duration)) )

mBootFinished = true

stop boot animation

formerly we would just kill the process but we now ask it to exit so it

can choose where to stop the animation

property_set(servicebootanimexit 1)

httpswwwlinkedincominsg1993 29georgeshibin1993gmailcom

BOOTANIMATION

bull SF sets the property serviebootanim to 1 How does this stop bootanim

bull All this while since the time it was started bootanim has been executing playAnimation()

bull While doing so it also periodically calls checkExit()

bull On detecting that this property is set to 1 bootanim gracefully exits

httpandroidxrefcom700_r1xrefframeworksbasecmdsbootanimationBootAnimationcpp387

Allow surface flinger to gracefully request shutdown

char value[PROPERTY_VALUE_MAX]

property_get(servicebootanimexit value 0)

int exitnow = atoi(value)

if (exitnow)

requestExit()

if (mAudioPlayer = NULL)

mAudioPlayer-gtrequestExit()

httpswwwlinkedincominsg1993 30georgeshibin1993gmailcom

BOOT_COMPLETEDbull WindowManager invoked binder transaction to tell SF to stop bootanim

bull After that it calls ActivityManagerrsquos bootAnimationComplete() function

bull In ActivityManagerService finishBooting() is invoked where the property sysboot_completed is set to 1 This property is important because it is the ldquoofficialrdquo way of letting native-servicesdaemons know that boot is now complete

bull After this AMS tells UserController (which is a helper class for handling multi-user functionality) to send the 2 criticalimportant intents

bull Before you unlockswipe the lock screen the intent IntentACTION_LOCKED_BOOT_COMPLETED is sent here

bull Once the user is unlocked (by entering PINswiping-the-lock screen) the intent IntentACTION_BOOT_COMPLETED is sent here This intent is important because it lets Java-services3rd-party apps know that system boot-up is now officially complete and that user is now in the home screen

httpandroidxrefcom700_r1xrefframeworksbaseservicescorejavacomandroidserverwmWindowManagerServicejav

a5899

try

mActivityManagerbootAnimationComplete()

catch (RemoteException e)

httpswwwlinkedincominsg1993 31georgeshibin1993gmailcom

Aaaaand you are now in Home screen

httpswwwlinkedincominsg1993 32georgeshibin1993gmailcom

REFERENCES

bull My highlights on Karim Yaghmourrsquos famous book (Embedded Android) httpswwwsafaribooksonlinecomu001o000000YZt6HAATembedded-android9781449327958

bull Kernel boot process

bull httpduartesorggustavoblogpostkernel-boot-process

bull https0xaxgitbooksiolinux-insidescontentInitializationlinux-initialization-4html

bull httposr507docxinuoscomenPERFORMprocess_stateshtml

bull httpstackoverflowcomquestions464483why-do-we-need-a-swapper-task-in-linux

bull httpunixstackexchangecomquestions83322which-process-has-pid-0

bull BinderServiceManager

bull httpwwwmacrobugcomblog20071215decoding-a-service-call-in-android

bull httpwwwcubridorgblogdev-platformbinder-communication-mechanism-of-android-processes

bull httpwwwprogrameringcomaMjMyMDMwATQhtml

And most importantly httpandroidxrefcom700_r1xref

httpswwwlinkedincominsg1993 33georgeshibin1993gmailcom

Thank You for reading this far

httpswwwlinkedincominsg1993 34

Disclaimer

Almost none (okay fine absolutely zilch) of the information that I put up is proprietary to Qualcomm Inc

Some of the source-code hyperlinks to Qualcommrsquos internal repository which is not accessible to others anyway

For all the other stuff I have provided Android-xref links and is openly accessible to all

However I wonrsquot vouch for the correctness of all information presented here Nope

You are welcome to correcteditpresent this material according to your needs

However it would be nice if you could shoot me a mail (at georgeshibin1993gmailcom) andor provide a

reference to the original material Just sayinghellip it would be nice

georgeshibin1993gmailcom

Page 27: Android bootup

LAUNCHER

bull When the call reaches init it starts the service which is assigned to ctlstart

bull So when SF sets ctlstart to bootanim init starts the service bootanim

bull Bootanim gets the media files from systemmediabootanimationzip

bull But who stops bootanim Lets get back to system_server to find that out

bull Remember we informed ActivityManagerService that we are ready to executelaunch 3rd party codeapplications here

bull AMS on executing this calls startHomeActivityLocked() Internally this sends an Intent with category IntentCATEGORY_HOME This intent category is special because if an app registers for this intent it means that the application is a Launcher-appHome-screen replacement app

bull On receving this intent Launcher is started as it had registered for the same (see Manifest)

bull Ok Launcher has started but you are still not seeing it on the display

httpswwwlinkedincominsg1993 27georgeshibin1993gmailcom

LAUNCHERbull For Launcher to be displayed bootanimation has to be stopped There is only one entity that can tell SF to stop

bootanim via a binder transaction ie WindowManagerService WindowManagerServicersquosperformEnableScreen() API needs to be invoked

httpandroidxrefcom700_r1xrefframeworksbaseservicescorejavacomandroidserverwmWindowManagerServicejava5866

if (mBootAnimationStopped)

Do this one time

TraceasyncTraceBegin(TraceTRACE_TAG_WINDOW_MANAGER Stop bootanim 0)

try

IBinder surfaceFlinger = ServiceManagergetService(SurfaceFlinger)

if (surfaceFlinger = null)

Slogi(TAG_WM TELLING SURFACE FLINGER WE ARE BOOTED)

Parcel data = Parcelobtain()

datawriteInterfaceToken(androiduiISurfaceComposer)

surfaceFlingertransact(IBinderFIRST_CALL_TRANSACTION BOOT_FINISHED

data null 0)

datarecycle()

catch (RemoteException ex)

Sloge(TAG_WM Boot completed SurfaceFlinger is dead)

mBootAnimationStopped = true

httpswwwlinkedincominsg1993 28georgeshibin1993gmailcom

bull So SF receives a binder call from WindowManagerService with the code IBinderFIRST_CALL_TRANSACTION SurfaceFlinger Binder IPC interface has defined the following

bull The call ultimately reaches bootFinished()

httpandroidxrefcom700_r1xrefframeworksnativeincludeguiISurfaceComposerh177

Note BOOT_FINISHED must remain this value it is called from

Java by ActivityManagerService

BOOT_FINISHED = IBinderFIRST_CALL_TRANSACTION

httpandroidxrefcom700_r1xrefframeworksnativeservicessurfaceflingerSurfaceFlingercpp292

void SurfaceFlingerbootFinished()

hellip

ALOGI(Boot is finished (ld ms) long(ns2ms(duration)) )

mBootFinished = true

stop boot animation

formerly we would just kill the process but we now ask it to exit so it

can choose where to stop the animation

property_set(servicebootanimexit 1)

httpswwwlinkedincominsg1993 29georgeshibin1993gmailcom

BOOTANIMATION

bull SF sets the property serviebootanim to 1 How does this stop bootanim

bull All this while since the time it was started bootanim has been executing playAnimation()

bull While doing so it also periodically calls checkExit()

bull On detecting that this property is set to 1 bootanim gracefully exits

httpandroidxrefcom700_r1xrefframeworksbasecmdsbootanimationBootAnimationcpp387

Allow surface flinger to gracefully request shutdown

char value[PROPERTY_VALUE_MAX]

property_get(servicebootanimexit value 0)

int exitnow = atoi(value)

if (exitnow)

requestExit()

if (mAudioPlayer = NULL)

mAudioPlayer-gtrequestExit()

httpswwwlinkedincominsg1993 30georgeshibin1993gmailcom

BOOT_COMPLETEDbull WindowManager invoked binder transaction to tell SF to stop bootanim

bull After that it calls ActivityManagerrsquos bootAnimationComplete() function

bull In ActivityManagerService finishBooting() is invoked where the property sysboot_completed is set to 1 This property is important because it is the ldquoofficialrdquo way of letting native-servicesdaemons know that boot is now complete

bull After this AMS tells UserController (which is a helper class for handling multi-user functionality) to send the 2 criticalimportant intents

bull Before you unlockswipe the lock screen the intent IntentACTION_LOCKED_BOOT_COMPLETED is sent here

bull Once the user is unlocked (by entering PINswiping-the-lock screen) the intent IntentACTION_BOOT_COMPLETED is sent here This intent is important because it lets Java-services3rd-party apps know that system boot-up is now officially complete and that user is now in the home screen

httpandroidxrefcom700_r1xrefframeworksbaseservicescorejavacomandroidserverwmWindowManagerServicejav

a5899

try

mActivityManagerbootAnimationComplete()

catch (RemoteException e)

httpswwwlinkedincominsg1993 31georgeshibin1993gmailcom

Aaaaand you are now in Home screen

httpswwwlinkedincominsg1993 32georgeshibin1993gmailcom

REFERENCES

bull My highlights on Karim Yaghmourrsquos famous book (Embedded Android) httpswwwsafaribooksonlinecomu001o000000YZt6HAATembedded-android9781449327958

bull Kernel boot process

bull httpduartesorggustavoblogpostkernel-boot-process

bull https0xaxgitbooksiolinux-insidescontentInitializationlinux-initialization-4html

bull httposr507docxinuoscomenPERFORMprocess_stateshtml

bull httpstackoverflowcomquestions464483why-do-we-need-a-swapper-task-in-linux

bull httpunixstackexchangecomquestions83322which-process-has-pid-0

bull BinderServiceManager

bull httpwwwmacrobugcomblog20071215decoding-a-service-call-in-android

bull httpwwwcubridorgblogdev-platformbinder-communication-mechanism-of-android-processes

bull httpwwwprogrameringcomaMjMyMDMwATQhtml

And most importantly httpandroidxrefcom700_r1xref

httpswwwlinkedincominsg1993 33georgeshibin1993gmailcom

Thank You for reading this far

httpswwwlinkedincominsg1993 34

Disclaimer

Almost none (okay fine absolutely zilch) of the information that I put up is proprietary to Qualcomm Inc

Some of the source-code hyperlinks to Qualcommrsquos internal repository which is not accessible to others anyway

For all the other stuff I have provided Android-xref links and is openly accessible to all

However I wonrsquot vouch for the correctness of all information presented here Nope

You are welcome to correcteditpresent this material according to your needs

However it would be nice if you could shoot me a mail (at georgeshibin1993gmailcom) andor provide a

reference to the original material Just sayinghellip it would be nice

georgeshibin1993gmailcom

Page 28: Android bootup

LAUNCHERbull For Launcher to be displayed bootanimation has to be stopped There is only one entity that can tell SF to stop

bootanim via a binder transaction ie WindowManagerService WindowManagerServicersquosperformEnableScreen() API needs to be invoked

httpandroidxrefcom700_r1xrefframeworksbaseservicescorejavacomandroidserverwmWindowManagerServicejava5866

if (mBootAnimationStopped)

Do this one time

TraceasyncTraceBegin(TraceTRACE_TAG_WINDOW_MANAGER Stop bootanim 0)

try

IBinder surfaceFlinger = ServiceManagergetService(SurfaceFlinger)

if (surfaceFlinger = null)

Slogi(TAG_WM TELLING SURFACE FLINGER WE ARE BOOTED)

Parcel data = Parcelobtain()

datawriteInterfaceToken(androiduiISurfaceComposer)

surfaceFlingertransact(IBinderFIRST_CALL_TRANSACTION BOOT_FINISHED

data null 0)

datarecycle()

catch (RemoteException ex)

Sloge(TAG_WM Boot completed SurfaceFlinger is dead)

mBootAnimationStopped = true

httpswwwlinkedincominsg1993 28georgeshibin1993gmailcom

bull So SF receives a binder call from WindowManagerService with the code IBinderFIRST_CALL_TRANSACTION SurfaceFlinger Binder IPC interface has defined the following

bull The call ultimately reaches bootFinished()

httpandroidxrefcom700_r1xrefframeworksnativeincludeguiISurfaceComposerh177

Note BOOT_FINISHED must remain this value it is called from

Java by ActivityManagerService

BOOT_FINISHED = IBinderFIRST_CALL_TRANSACTION

httpandroidxrefcom700_r1xrefframeworksnativeservicessurfaceflingerSurfaceFlingercpp292

void SurfaceFlingerbootFinished()

hellip

ALOGI(Boot is finished (ld ms) long(ns2ms(duration)) )

mBootFinished = true

stop boot animation

formerly we would just kill the process but we now ask it to exit so it

can choose where to stop the animation

property_set(servicebootanimexit 1)

httpswwwlinkedincominsg1993 29georgeshibin1993gmailcom

BOOTANIMATION

bull SF sets the property serviebootanim to 1 How does this stop bootanim

bull All this while since the time it was started bootanim has been executing playAnimation()

bull While doing so it also periodically calls checkExit()

bull On detecting that this property is set to 1 bootanim gracefully exits

httpandroidxrefcom700_r1xrefframeworksbasecmdsbootanimationBootAnimationcpp387

Allow surface flinger to gracefully request shutdown

char value[PROPERTY_VALUE_MAX]

property_get(servicebootanimexit value 0)

int exitnow = atoi(value)

if (exitnow)

requestExit()

if (mAudioPlayer = NULL)

mAudioPlayer-gtrequestExit()

httpswwwlinkedincominsg1993 30georgeshibin1993gmailcom

BOOT_COMPLETEDbull WindowManager invoked binder transaction to tell SF to stop bootanim

bull After that it calls ActivityManagerrsquos bootAnimationComplete() function

bull In ActivityManagerService finishBooting() is invoked where the property sysboot_completed is set to 1 This property is important because it is the ldquoofficialrdquo way of letting native-servicesdaemons know that boot is now complete

bull After this AMS tells UserController (which is a helper class for handling multi-user functionality) to send the 2 criticalimportant intents

bull Before you unlockswipe the lock screen the intent IntentACTION_LOCKED_BOOT_COMPLETED is sent here

bull Once the user is unlocked (by entering PINswiping-the-lock screen) the intent IntentACTION_BOOT_COMPLETED is sent here This intent is important because it lets Java-services3rd-party apps know that system boot-up is now officially complete and that user is now in the home screen

httpandroidxrefcom700_r1xrefframeworksbaseservicescorejavacomandroidserverwmWindowManagerServicejav

a5899

try

mActivityManagerbootAnimationComplete()

catch (RemoteException e)

httpswwwlinkedincominsg1993 31georgeshibin1993gmailcom

Aaaaand you are now in Home screen

httpswwwlinkedincominsg1993 32georgeshibin1993gmailcom

REFERENCES

bull My highlights on Karim Yaghmourrsquos famous book (Embedded Android) httpswwwsafaribooksonlinecomu001o000000YZt6HAATembedded-android9781449327958

bull Kernel boot process

bull httpduartesorggustavoblogpostkernel-boot-process

bull https0xaxgitbooksiolinux-insidescontentInitializationlinux-initialization-4html

bull httposr507docxinuoscomenPERFORMprocess_stateshtml

bull httpstackoverflowcomquestions464483why-do-we-need-a-swapper-task-in-linux

bull httpunixstackexchangecomquestions83322which-process-has-pid-0

bull BinderServiceManager

bull httpwwwmacrobugcomblog20071215decoding-a-service-call-in-android

bull httpwwwcubridorgblogdev-platformbinder-communication-mechanism-of-android-processes

bull httpwwwprogrameringcomaMjMyMDMwATQhtml

And most importantly httpandroidxrefcom700_r1xref

httpswwwlinkedincominsg1993 33georgeshibin1993gmailcom

Thank You for reading this far

httpswwwlinkedincominsg1993 34

Disclaimer

Almost none (okay fine absolutely zilch) of the information that I put up is proprietary to Qualcomm Inc

Some of the source-code hyperlinks to Qualcommrsquos internal repository which is not accessible to others anyway

For all the other stuff I have provided Android-xref links and is openly accessible to all

However I wonrsquot vouch for the correctness of all information presented here Nope

You are welcome to correcteditpresent this material according to your needs

However it would be nice if you could shoot me a mail (at georgeshibin1993gmailcom) andor provide a

reference to the original material Just sayinghellip it would be nice

georgeshibin1993gmailcom

Page 29: Android bootup

bull So SF receives a binder call from WindowManagerService with the code IBinderFIRST_CALL_TRANSACTION SurfaceFlinger Binder IPC interface has defined the following

bull The call ultimately reaches bootFinished()

httpandroidxrefcom700_r1xrefframeworksnativeincludeguiISurfaceComposerh177

Note BOOT_FINISHED must remain this value it is called from

Java by ActivityManagerService

BOOT_FINISHED = IBinderFIRST_CALL_TRANSACTION

httpandroidxrefcom700_r1xrefframeworksnativeservicessurfaceflingerSurfaceFlingercpp292

void SurfaceFlingerbootFinished()

hellip

ALOGI(Boot is finished (ld ms) long(ns2ms(duration)) )

mBootFinished = true

stop boot animation

formerly we would just kill the process but we now ask it to exit so it

can choose where to stop the animation

property_set(servicebootanimexit 1)

httpswwwlinkedincominsg1993 29georgeshibin1993gmailcom

BOOTANIMATION

bull SF sets the property serviebootanim to 1 How does this stop bootanim

bull All this while since the time it was started bootanim has been executing playAnimation()

bull While doing so it also periodically calls checkExit()

bull On detecting that this property is set to 1 bootanim gracefully exits

httpandroidxrefcom700_r1xrefframeworksbasecmdsbootanimationBootAnimationcpp387

Allow surface flinger to gracefully request shutdown

char value[PROPERTY_VALUE_MAX]

property_get(servicebootanimexit value 0)

int exitnow = atoi(value)

if (exitnow)

requestExit()

if (mAudioPlayer = NULL)

mAudioPlayer-gtrequestExit()

httpswwwlinkedincominsg1993 30georgeshibin1993gmailcom

BOOT_COMPLETEDbull WindowManager invoked binder transaction to tell SF to stop bootanim

bull After that it calls ActivityManagerrsquos bootAnimationComplete() function

bull In ActivityManagerService finishBooting() is invoked where the property sysboot_completed is set to 1 This property is important because it is the ldquoofficialrdquo way of letting native-servicesdaemons know that boot is now complete

bull After this AMS tells UserController (which is a helper class for handling multi-user functionality) to send the 2 criticalimportant intents

bull Before you unlockswipe the lock screen the intent IntentACTION_LOCKED_BOOT_COMPLETED is sent here

bull Once the user is unlocked (by entering PINswiping-the-lock screen) the intent IntentACTION_BOOT_COMPLETED is sent here This intent is important because it lets Java-services3rd-party apps know that system boot-up is now officially complete and that user is now in the home screen

httpandroidxrefcom700_r1xrefframeworksbaseservicescorejavacomandroidserverwmWindowManagerServicejav

a5899

try

mActivityManagerbootAnimationComplete()

catch (RemoteException e)

httpswwwlinkedincominsg1993 31georgeshibin1993gmailcom

Aaaaand you are now in Home screen

httpswwwlinkedincominsg1993 32georgeshibin1993gmailcom

REFERENCES

bull My highlights on Karim Yaghmourrsquos famous book (Embedded Android) httpswwwsafaribooksonlinecomu001o000000YZt6HAATembedded-android9781449327958

bull Kernel boot process

bull httpduartesorggustavoblogpostkernel-boot-process

bull https0xaxgitbooksiolinux-insidescontentInitializationlinux-initialization-4html

bull httposr507docxinuoscomenPERFORMprocess_stateshtml

bull httpstackoverflowcomquestions464483why-do-we-need-a-swapper-task-in-linux

bull httpunixstackexchangecomquestions83322which-process-has-pid-0

bull BinderServiceManager

bull httpwwwmacrobugcomblog20071215decoding-a-service-call-in-android

bull httpwwwcubridorgblogdev-platformbinder-communication-mechanism-of-android-processes

bull httpwwwprogrameringcomaMjMyMDMwATQhtml

And most importantly httpandroidxrefcom700_r1xref

httpswwwlinkedincominsg1993 33georgeshibin1993gmailcom

Thank You for reading this far

httpswwwlinkedincominsg1993 34

Disclaimer

Almost none (okay fine absolutely zilch) of the information that I put up is proprietary to Qualcomm Inc

Some of the source-code hyperlinks to Qualcommrsquos internal repository which is not accessible to others anyway

For all the other stuff I have provided Android-xref links and is openly accessible to all

However I wonrsquot vouch for the correctness of all information presented here Nope

You are welcome to correcteditpresent this material according to your needs

However it would be nice if you could shoot me a mail (at georgeshibin1993gmailcom) andor provide a

reference to the original material Just sayinghellip it would be nice

georgeshibin1993gmailcom

Page 30: Android bootup

BOOTANIMATION

bull SF sets the property serviebootanim to 1 How does this stop bootanim

bull All this while since the time it was started bootanim has been executing playAnimation()

bull While doing so it also periodically calls checkExit()

bull On detecting that this property is set to 1 bootanim gracefully exits

httpandroidxrefcom700_r1xrefframeworksbasecmdsbootanimationBootAnimationcpp387

Allow surface flinger to gracefully request shutdown

char value[PROPERTY_VALUE_MAX]

property_get(servicebootanimexit value 0)

int exitnow = atoi(value)

if (exitnow)

requestExit()

if (mAudioPlayer = NULL)

mAudioPlayer-gtrequestExit()

httpswwwlinkedincominsg1993 30georgeshibin1993gmailcom

BOOT_COMPLETEDbull WindowManager invoked binder transaction to tell SF to stop bootanim

bull After that it calls ActivityManagerrsquos bootAnimationComplete() function

bull In ActivityManagerService finishBooting() is invoked where the property sysboot_completed is set to 1 This property is important because it is the ldquoofficialrdquo way of letting native-servicesdaemons know that boot is now complete

bull After this AMS tells UserController (which is a helper class for handling multi-user functionality) to send the 2 criticalimportant intents

bull Before you unlockswipe the lock screen the intent IntentACTION_LOCKED_BOOT_COMPLETED is sent here

bull Once the user is unlocked (by entering PINswiping-the-lock screen) the intent IntentACTION_BOOT_COMPLETED is sent here This intent is important because it lets Java-services3rd-party apps know that system boot-up is now officially complete and that user is now in the home screen

httpandroidxrefcom700_r1xrefframeworksbaseservicescorejavacomandroidserverwmWindowManagerServicejav

a5899

try

mActivityManagerbootAnimationComplete()

catch (RemoteException e)

httpswwwlinkedincominsg1993 31georgeshibin1993gmailcom

Aaaaand you are now in Home screen

httpswwwlinkedincominsg1993 32georgeshibin1993gmailcom

REFERENCES

bull My highlights on Karim Yaghmourrsquos famous book (Embedded Android) httpswwwsafaribooksonlinecomu001o000000YZt6HAATembedded-android9781449327958

bull Kernel boot process

bull httpduartesorggustavoblogpostkernel-boot-process

bull https0xaxgitbooksiolinux-insidescontentInitializationlinux-initialization-4html

bull httposr507docxinuoscomenPERFORMprocess_stateshtml

bull httpstackoverflowcomquestions464483why-do-we-need-a-swapper-task-in-linux

bull httpunixstackexchangecomquestions83322which-process-has-pid-0

bull BinderServiceManager

bull httpwwwmacrobugcomblog20071215decoding-a-service-call-in-android

bull httpwwwcubridorgblogdev-platformbinder-communication-mechanism-of-android-processes

bull httpwwwprogrameringcomaMjMyMDMwATQhtml

And most importantly httpandroidxrefcom700_r1xref

httpswwwlinkedincominsg1993 33georgeshibin1993gmailcom

Thank You for reading this far

httpswwwlinkedincominsg1993 34

Disclaimer

Almost none (okay fine absolutely zilch) of the information that I put up is proprietary to Qualcomm Inc

Some of the source-code hyperlinks to Qualcommrsquos internal repository which is not accessible to others anyway

For all the other stuff I have provided Android-xref links and is openly accessible to all

However I wonrsquot vouch for the correctness of all information presented here Nope

You are welcome to correcteditpresent this material according to your needs

However it would be nice if you could shoot me a mail (at georgeshibin1993gmailcom) andor provide a

reference to the original material Just sayinghellip it would be nice

georgeshibin1993gmailcom

Page 31: Android bootup

BOOT_COMPLETEDbull WindowManager invoked binder transaction to tell SF to stop bootanim

bull After that it calls ActivityManagerrsquos bootAnimationComplete() function

bull In ActivityManagerService finishBooting() is invoked where the property sysboot_completed is set to 1 This property is important because it is the ldquoofficialrdquo way of letting native-servicesdaemons know that boot is now complete

bull After this AMS tells UserController (which is a helper class for handling multi-user functionality) to send the 2 criticalimportant intents

bull Before you unlockswipe the lock screen the intent IntentACTION_LOCKED_BOOT_COMPLETED is sent here

bull Once the user is unlocked (by entering PINswiping-the-lock screen) the intent IntentACTION_BOOT_COMPLETED is sent here This intent is important because it lets Java-services3rd-party apps know that system boot-up is now officially complete and that user is now in the home screen

httpandroidxrefcom700_r1xrefframeworksbaseservicescorejavacomandroidserverwmWindowManagerServicejav

a5899

try

mActivityManagerbootAnimationComplete()

catch (RemoteException e)

httpswwwlinkedincominsg1993 31georgeshibin1993gmailcom

Aaaaand you are now in Home screen

httpswwwlinkedincominsg1993 32georgeshibin1993gmailcom

REFERENCES

bull My highlights on Karim Yaghmourrsquos famous book (Embedded Android) httpswwwsafaribooksonlinecomu001o000000YZt6HAATembedded-android9781449327958

bull Kernel boot process

bull httpduartesorggustavoblogpostkernel-boot-process

bull https0xaxgitbooksiolinux-insidescontentInitializationlinux-initialization-4html

bull httposr507docxinuoscomenPERFORMprocess_stateshtml

bull httpstackoverflowcomquestions464483why-do-we-need-a-swapper-task-in-linux

bull httpunixstackexchangecomquestions83322which-process-has-pid-0

bull BinderServiceManager

bull httpwwwmacrobugcomblog20071215decoding-a-service-call-in-android

bull httpwwwcubridorgblogdev-platformbinder-communication-mechanism-of-android-processes

bull httpwwwprogrameringcomaMjMyMDMwATQhtml

And most importantly httpandroidxrefcom700_r1xref

httpswwwlinkedincominsg1993 33georgeshibin1993gmailcom

Thank You for reading this far

httpswwwlinkedincominsg1993 34

Disclaimer

Almost none (okay fine absolutely zilch) of the information that I put up is proprietary to Qualcomm Inc

Some of the source-code hyperlinks to Qualcommrsquos internal repository which is not accessible to others anyway

For all the other stuff I have provided Android-xref links and is openly accessible to all

However I wonrsquot vouch for the correctness of all information presented here Nope

You are welcome to correcteditpresent this material according to your needs

However it would be nice if you could shoot me a mail (at georgeshibin1993gmailcom) andor provide a

reference to the original material Just sayinghellip it would be nice

georgeshibin1993gmailcom

Page 32: Android bootup

Aaaaand you are now in Home screen

httpswwwlinkedincominsg1993 32georgeshibin1993gmailcom

REFERENCES

bull My highlights on Karim Yaghmourrsquos famous book (Embedded Android) httpswwwsafaribooksonlinecomu001o000000YZt6HAATembedded-android9781449327958

bull Kernel boot process

bull httpduartesorggustavoblogpostkernel-boot-process

bull https0xaxgitbooksiolinux-insidescontentInitializationlinux-initialization-4html

bull httposr507docxinuoscomenPERFORMprocess_stateshtml

bull httpstackoverflowcomquestions464483why-do-we-need-a-swapper-task-in-linux

bull httpunixstackexchangecomquestions83322which-process-has-pid-0

bull BinderServiceManager

bull httpwwwmacrobugcomblog20071215decoding-a-service-call-in-android

bull httpwwwcubridorgblogdev-platformbinder-communication-mechanism-of-android-processes

bull httpwwwprogrameringcomaMjMyMDMwATQhtml

And most importantly httpandroidxrefcom700_r1xref

httpswwwlinkedincominsg1993 33georgeshibin1993gmailcom

Thank You for reading this far

httpswwwlinkedincominsg1993 34

Disclaimer

Almost none (okay fine absolutely zilch) of the information that I put up is proprietary to Qualcomm Inc

Some of the source-code hyperlinks to Qualcommrsquos internal repository which is not accessible to others anyway

For all the other stuff I have provided Android-xref links and is openly accessible to all

However I wonrsquot vouch for the correctness of all information presented here Nope

You are welcome to correcteditpresent this material according to your needs

However it would be nice if you could shoot me a mail (at georgeshibin1993gmailcom) andor provide a

reference to the original material Just sayinghellip it would be nice

georgeshibin1993gmailcom

Page 33: Android bootup

REFERENCES

bull My highlights on Karim Yaghmourrsquos famous book (Embedded Android) httpswwwsafaribooksonlinecomu001o000000YZt6HAATembedded-android9781449327958

bull Kernel boot process

bull httpduartesorggustavoblogpostkernel-boot-process

bull https0xaxgitbooksiolinux-insidescontentInitializationlinux-initialization-4html

bull httposr507docxinuoscomenPERFORMprocess_stateshtml

bull httpstackoverflowcomquestions464483why-do-we-need-a-swapper-task-in-linux

bull httpunixstackexchangecomquestions83322which-process-has-pid-0

bull BinderServiceManager

bull httpwwwmacrobugcomblog20071215decoding-a-service-call-in-android

bull httpwwwcubridorgblogdev-platformbinder-communication-mechanism-of-android-processes

bull httpwwwprogrameringcomaMjMyMDMwATQhtml

And most importantly httpandroidxrefcom700_r1xref

httpswwwlinkedincominsg1993 33georgeshibin1993gmailcom

Thank You for reading this far

httpswwwlinkedincominsg1993 34

Disclaimer

Almost none (okay fine absolutely zilch) of the information that I put up is proprietary to Qualcomm Inc

Some of the source-code hyperlinks to Qualcommrsquos internal repository which is not accessible to others anyway

For all the other stuff I have provided Android-xref links and is openly accessible to all

However I wonrsquot vouch for the correctness of all information presented here Nope

You are welcome to correcteditpresent this material according to your needs

However it would be nice if you could shoot me a mail (at georgeshibin1993gmailcom) andor provide a

reference to the original material Just sayinghellip it would be nice

georgeshibin1993gmailcom

Page 34: Android bootup

Thank You for reading this far

httpswwwlinkedincominsg1993 34

Disclaimer

Almost none (okay fine absolutely zilch) of the information that I put up is proprietary to Qualcomm Inc

Some of the source-code hyperlinks to Qualcommrsquos internal repository which is not accessible to others anyway

For all the other stuff I have provided Android-xref links and is openly accessible to all

However I wonrsquot vouch for the correctness of all information presented here Nope

You are welcome to correcteditpresent this material according to your needs

However it would be nice if you could shoot me a mail (at georgeshibin1993gmailcom) andor provide a

reference to the original material Just sayinghellip it would be nice

georgeshibin1993gmailcom