在上一篇文章中详细的分析了kthreadd进程的启动,init进程也是有idle进程去触发启动的,init进程分为前后两部分,前一部分是在内核启动的,主要是完成创建和内核初始化工作,内容都是跟Linux内核相关的;后一部分是在用户空间启动的,主要完成Android系统的初始化工作。
本文着重分析init进程的前一部分,init进程的后一部分将在下一篇文章中讲述。
1、init进程启动
在rest_init函数中启动了init进程,定义在kernel/msm-4.4/init/main.c中
kernel_thread会调用do_fork函数用于创建进程,进程创建成功后会通过函数指针回调执行kernel_init函数;进程创建过程在此就不做分析,着重来分析一下kernel_init函数
2、kernel_init
定义在kernel/msm-4.4/init/main.c中
kernel_init主要工作是完成一些init的初始化操作,然后去系统根目录下依次找ramdisk_execute_command和execute_command设置的应用程序,如果这两个目录都找不到,就依次去根目录下找 /sbin/init,/etc/init,/bin/init,/bin/sh 这四个应用程序进行启动,只要这些应用程序有一个启动了,其他就不启动了
ramdisk_execute_command和execute_command的值是通过bootloader传递过来的参数设置的,ramdisk_execute_command通过”rdinit”参数赋值,execute_command通过”init”参数赋值,ramdisk_execute_command如果没有被赋值,kernel_init_freeable函数会赋一个初始值”/init”
定义在device/qcom/XXX/BoardConfig.mk
2.1 kernel_init_freeable
定义在kernel/msm-4.4/init/main.c中
kernel_init_freeable函数做了很多重要的事情,启动了smp,smp全称是Symmetrical Multi-Processing,即对称多处理,是指在一个计算机上汇集了一组处理器(多CPU),各CPU之间共享内存子系统以及总线结构。初始化设备和驱动程序、打开标准输入和输出、初始化文件系统等等
2.1.1 do_basic_setup
定义在kernel/msm-4.4/init/main.c中
2.1.2 driver_init
定义在kernel/msm-4.4/drivers/base/init.c中
这个函数完成驱动子系统的构建,实现了Linux设备驱动的一个整体框架,但是它只是建立了目录结构,具体驱动的装载是在do_initcalls函数,kernel_init_freeable函数告一段落了,我们接着讲kernel_init中剩余的函数
2.2 free_initmem
定义在kernel/msm-4.4/arch/arm64/mm/init.c中中
所有使用__init标记过的函数和使用__initdata标记过的数据,在free_initmem函数执行后,都不能使用,它们曾经获得的内存现在可以重新用于其他目的。
2.3 flush_delayed_fput
定义在kernel/msm-4.4/arch/arm64/mm/init.c中,
这个函数主要用于释放&delayed_fput_list这个链表中的struct file,struct file即文件结构体,代表一个打开的文件,系统中的每个打开的文件在内核空间都有一个关联的 struct file。
2.4 run_init_process
定义在kernel/msm-4.4/init/main.c中
run_init_process就是运行可执行文件了,从kernel_init函数中可知,系统会依次去找根目录下的init,execute_command,/sbin/init,/etc/init,/bin/init,/bin/sh这六个可执行文件,只要找到其中一个,其他就不执行。
3、小结
上述分析了kernel部分的init进程启动过程,然而在Android系统一般会在根目录下放一个init的可执行文件,也就是说Linux系统的init进程在内核初始化完成后,就直接通过run_init_process函数执行init可执行文件,该可执行文件的源代码在system/core/init/init.cpp,下一篇文章中我将以这个文件为入口,分析Android系统的init进程启动过程。