本来应该说说kernel中的input子系统和上层的对应关系的,但是碰到了开机的一些问题,下定决心把这个过程搞清楚。
U-boot之前的SPL的启动暂且不提,我们从U-boot在上电后被SPL从NAND中拷贝至SDRAM,然后执行board_init_f 跳转到board_init_r开始。
u-boot里的流程大家可以通过打串口log来看。
u-boot\arch\arm\lib\board.c
void board_init_r(gd_t *id, ulong dest_addr)
{
//.....初始化设备
stdio_init(); /* get the devices list going.*/ 此中会初始化各种设备,包括LCD
do_cboot(NULL, 0, 1, NULL); // 进入启动函数。
}
u-boot\property\cmd_cboot.c
int do_cboot(cmd_tbl_t *cmdtp,int flag, int argc, char *const argv[])
{
uint32_t key_mode = 0;
uint32_t key_code = 0;
volatile int i;
if(argc > 2)
goto usage;
#ifdef CONFIG_AUTOBOOT
normal_mode(); //如果down的是autopoweron的uboot,这里会直接去正常开机
#endif
boot_pwr_check();
#ifndef CONFIG_SC8810
CHG_ShutDown();
if(charger_connected()){
mdelay(10);
CHG_TurnOn();
}else{
if(is_bat_low()){
printf("shut down again forlow battery\n");
power_down_devices();
while(1)
;
}
}
#else
CHG_Init();
if(is_bat_low()){
printf("shutdown again for low battery\n");
power_down_devices();
while(1)
;
} //根据sp8810.h里的LOW_BAT_VOL,如果电压低于3.5V,则直接power down
#endif
boot_pwr_check();
board_keypad_init(); //初始化键盘。
boot_pwr_check();
unsigned check_reboot_mode(void);
unsigned rst_mode= check_reboot_mode(); //获取寄存器里HW的rest标志位,得到当前的开机模式,此处主要是异常重启,恢复出厂设置,关机闹钟等(没有按power键导致的开机)
if(rst_mode == RECOVERY_MODE){
DBG("func: %s line: %d\n",__func__, __LINE__);
recovery_mode();
}
else if(rst_mode == FASTBOOT_MODE){
DBG("func: %s line: %d\n",__func__, __LINE__);
fastboot_mode();
}else if(rst_mode == NORMAL_MODE){
normal_mode();
}else if(rst_mode == ALARM_MODE &&alarm_flag_check()){
alarm_mode();
}else if(rst_mode == SLEEP_MODE){
sleep_mode();
}
#ifdef CONFIG_SC8810
// normal_mode();
#endif
DBG("func: %s line: %d\n",__func__, __LINE__);
int recovery_init(void);
int ret =0;
ret = recovery_init();
if(ret == 1){ //检查是否是recovery模式
DBG("func: %s line: %d\n",__func__, __LINE__);
recovery_mode();
}
//find the power up trigger
if(boot_pwr_check() >=get_pwr_key_cnt()){ //如果按power键的“次数”达标了,认为这个是一次长按事件
DBG("%s: power buttonpress\n", __FUNCTION__);
//go on to check other keys
mdelay(50);
for(i=0; i<10;i++){
key_code = board_key_scan(); //获取另外一个按键
if(key_code != KEY_RESERVED){
key_mode= check_key_boot(key_code);//查找对应的按键码对应的开机模式
if(key_mode!= 0)
break;
}
}
switch(key_mode){
case BOOT_FASTBOOT:
fastboot_mode();
break;
case BOOT_RECOVERY:
recovery_mode();
break;
case BOOT_UPDATE:
update_mode();
break;
case BOOT_CALIBRATE:
engtest_mode();
return; //back to normal boot
break;
case BOOT_DLOADER:
dloader_mode();
break;
default:
break;//如果是正常开机模式,因为没有
}
}
elseif(charger_connected()){
DBG("%s: chargerconnected\n", __FUNCTION__);
charge_mode(); //如果没有按power键,且插入了充电器,则进入充电模式
}else if(alarm_triggered() &&alarm_flag_check()){
DBG("%s: alarm triggered\n",__FUNCTION__);
alarm_mode(); //如果是闹钟触发导致的开机,则进入关机闹钟模式
}else{
calibration_detect(0);
//if calibrate success, it will here
DBG("%s: power done again\n",__FUNCTION__);
power_down_devices();
while(1)
;
}
if(argc == 1){
DBG("func: %s line:%d\n", __func__, __LINE__);
normal_mode(); //如果只按了power键。
return 1;
}
if(argc == 2){
DBG("func: %s line: %d\n", __func__,__LINE__);
if(strcmp(argv[1],"normal") == 0){
normal_mode(); //如果只按了power键
return 1;
}
DBG("func: %s line: %d\n", __func__,__LINE__);
if(strcmp(argv[1],"recovery") == 0){
recovery_mode();
return 1;
}
DBG("func: %s line: %d\n",__func__, __LINE__);
if(strcmp(argv[1],"fastboot") == 0){
fastboot_mode();
return 1;
}
DBG("func: %s line: %d\n", __func__,__LINE__);
if(strcmp(argv[1],"dloader") == 0){
dloader_mode();
return 1;
}
DBG("func: %s line: %d\n", __func__,__LINE__);
if(strcmp(argv[1],"charge") == 0){
charge_mode();
return 1;
}
DBG("func: %s line: %d\n", __func__, __LINE__);
if(strcmp(argv[1],"caliberation") == 0){
calibration_detect(1);
return 1;
}
DBG("func: %s line: %d\n", __func__,__LINE__);
}
DBG("func: %s line: %d\n", __func__, __LINE__);
usage:
cmd_usage(cmdtp);
return 1;
}
接下来就是正常开机的normal_mode();
u-boot\property\normal_mode.c
void normal_mode(void)
{
#ifdef CONFIG_SC8810
//MMU_Init(CONFIG_MMU_TABLE_ADDR);
vibrator_hw_init();//初始化马达
#endif
set_vibrator(1);//起震,这个就是开机震的那一下
#if BOOT_NATIVE_LINUX
vlx_nand_boot(BOOT_PART, CONFIG_BOOTARGS, BACKLIGHT_ON);
#else
vlx_nand_boot(BOOT_PART, NULL, BACKLIGHT_ON);
#endif
}
void vlx_nand_boot(char * kernel_pname,char * cmdline, int backlight_set)
{
//..省略部分
#define SPLASH_PART "boot_logo"
ret= find_dev_and_part(SPLASH_PART, &dev, &pnum, &part);
if(ret){
printf("Nopartition named %s\n", SPLASH_PART);
return;
}elseif(dev->id->type != MTD_DEV_TYPE_NAND){
printf("Partition%s not a NAND device\n", SPLASH_PART);
return;
}
//读取下载到nand中的boot_logo,就是开机亮的那一屏
off=part->offset;
nand= &nand_info[dev->id->num];
//readboot image header
size= 1<<19;//where the size come from????//和dowload工具中的地址一致
char* bmp_img = malloc(size);
if(!bmp_img){
printf("not enough memory for splashimage\n");
return;
}
ret= nand_read_offset_ret(nand, off, &size, (void *)bmp_img, &off);
if(ret!= 0){
printf("function:%s nand read error %d\n", __FUNCTION__, ret);
return;
}
set_vibrator(0);//停止震动,如果发现开机狂震不止,那就是没走到这里。
extern int lcd_display_bitmap(ulong bmp_image, int x, int y);
extern void lcd_display(void);
extern voidset_backlight(uint32_t value);
//显示读取到的bitmap,并将屏幕点亮
if(backlight_set == BACKLIGHT_ON){
extern void *lcd_base;
extern void Dcache_CleanRegion(unsigned int addr, unsigned int length);
lcd_display_bitmap((ulong)bmp_img, 0, 0);
#ifdefCONFIG_SC8810
Dcache_CleanRegion((unsigned int)(lcd_base), size);//Size is to large.
#endif
lcd_display();
set_backlight(255);
}
#endif
//接下来就是挂载fixnv/runtimenv/productinfo/,如果有异常还会用backup的来恢复。
//略..
//读取kernel.dsp,modem,vm到SDRAM
//略..
creat_atags(VLX_TAG_ADDR, buf, NULL, 0);
void (*entry)(void) = (void*) VMJALUNA_ADR;
#ifndefCONFIG_SC8810
MMU_InvalideICACHEALL();
#endif
#ifdefCONFIG_SC8810
MMU_DisableIDCM();
#endif
#ifBOOT_NATIVE_LINUX
start_linux();
#else
entry(); //跳转到VM虚拟机的首地址
#endif
经过一系列的跳转(搜不到),最终到了start_kernel。
Kernel\init\main.c
asmlinkage void __init start_kernel(void)
{
/*
1. 调用setup_arch()函数进行与体系结构相关的第一个初始化工作;arch/arm/kernel/setup.c。进行处理器内核的初始化,内存结构的初始化,开启 MMU,创建内核页表,映射所有的物理内存和IO空间,并挂载ramdisk。
• 2) 创建异常向量表和初始化中断处理函数;
• 3) 初始化系统核心进程调度器和时钟中断处理机制;
• 4) 初始化串口控制台(serial-console),这样内核在启动过程中就可以通过串口输出信息以便开发者或用户了解系统的启动进程;
• 5) 创建和初始化系统cache,为各种内存调用机制提供缓存,包括;动态内存分配,虚拟文
• 件系统(Virtual File System)及页缓存。
• 6) 初始化内存管理,检测内存大小及被内核占用的内存情况;
• 7) 初始化系统的进程间通信机制(IPC);
• 当以上所有的初始化工作结束后,start_kernel()函数会调用 rest_init()函数来进行最后的初始化,包括创建系统的第一个进程-init进程来结束内核的启动。
*/
rest_init();
}
说一下setup_arch()
Kernel\arch\alpha\kernel\setup.c
setup_arch(char **cmdline_p)
{
//….
if(strcmp(COMMAND_LINE, "INSTALL") == 0) {
strlcpy(command_line,"root=/dev/fd0 load_ramdisk=1", sizeof command_line);
}else {
strlcpy(command_line,COMMAND_LINE, sizeof command_line);
}
strcpy(boot_command_line,command_line);
*cmdline_p= command_line;
//…..
}
摘录出的代码中的load_ramdisk=1,会调用到函数load_ramdisk。
Kernel\init\do_mounts.c
__setup("load_ramdisk=",load_ramdisk);
被__setup宏声明的函数会被放在init.setup节点,在系统起命令行到相关的字符串的时候会被调用,所以,当setup_arch走到这里的时候就回去挂载ramdisk!
而且类似的命令还有很多,如在uboot中LCD初始化后将ID通过参数lcd_id=ID传入(normal_mode.c line769),而在kernel起来的时候去读取
在fb_main.c中有声明:__setup("lcd_id=", calibration_start);
而ramdisk是什么呢?
简单的说,ramdisk就是将ram当作硬盘来用,里面包含了一些系统最基本的信息,大家打开编译的目录 out/target/hsdroid/root/ 里面就是ramdisk的内容了。
其结构就和android系统很类似,其中init就是上文中提到的第一个守护进程init的真身。
Init.rc 就是在init进程刚起来的时候读取和解析的配置文件,根据这个文件来初始化一系列设备,起服务等,下面继续分析。
static noinline void __init_refokrest_init(void)
__releases(kernel_lock)
{
intpid;
rcu_scheduler_starting();
/*
* We need to spawn init first so that itobtains pid 1, however
* the init task will end up wanting to createkthreads, which, if
* we schedule it before we create kthreadd,will OOPS.
*/
kernel_thread(kernel_init,NULL, CLONE_FS | CLONE_SIGHAND); //启动kernel_init来进行接下来的初始化
numa_default_policy();
pid= kernel_thread(kthreadd, NULL, CLONE_FS | CLONE_FILES);
rcu_read_lock();
kthreadd_task= find_task_by_pid_ns(pid, &init_pid_ns);
rcu_read_unlock();
complete(&kthreadd_done);
unlock_kernel();
/*
* The boot idle thread must execute schedule()
* at least once to get things moving:
*/
init_idle_bootup_task(current);
preempt_enable_no_resched();
schedule();
preempt_disable();
/*Call into cpu_idle with preempt disabled */
cpu_idle();//将系统交给调度器处理。
}
static int __init kernel_init(void *unused)
{
//…
do_basic_setup();//此函数中会调用各个驱动模块的加载函数(静态编译的,非ko)来初始化设备
// …
if(!ramdisk_execute_command)
ramdisk_execute_command= "/init";
if(sys_access((const char __user *) ramdisk_execute_command, 0) != 0) {
ramdisk_execute_command= NULL;
prepare_namespace();
}
/*
* Ok, we have completed the initial bootup,and
* we're essentially up and running. Get rid ofthe
* initmem segments and start the user-modestuff..
*/
init_post();
}
static noinline int init_post(void)
__releases(kernel_lock)
{
//…
if(ramdisk_execute_command) {
run_init_process(ramdisk_execute_command);
printk(KERN_WARNING"Failed to execute %s\n",
ramdisk_execute_command);
}//执行/init,也就是第一个进程。
}
接下来就是init咯。
System\core\init\init.c
int main(int argc, char **argv)
{
//
mkdir("/dev", 0755);
mkdir("/proc", 0755);
mkdir("/sys", 0755);
mount("tmpfs", "/dev", "tmpfs", 0,"mode=0755");
mkdir("/dev/pts", 0755);
mkdir("/dev/socket", 0755);
mount("devpts", "/dev/pts", "devpts", 0,NULL);
mount("proc", "/proc", "proc", 0, NULL);
mount("sysfs","/sys", "sysfs", 0, NULL);
//挂载了基本的节点
INFO("reading config file\n");
init_parse_config_file("/init.rc"); //解析了ramdisk中的init.rc
import_kernel_cmdline(0); //引用kernel的命令行
get_hardware_name(hardware, &revision);//sp8810
snprintf(tmp, sizeof(tmp),"/init.%s.rc", hardware);
init_parse_config_file(tmp); //解析init.sp8810.rc
action_for_each_trigger("early-init",action_add_queue_tail); //触发early-init声明的action,下面会详细说下init.rc
//进行一系列的初始化队列。
queue_builtin_action(wait_for_coldboot_done_action,"wait_for_coldboot_done");
queue_builtin_action(property_init_action,"property_init");
queue_builtin_action(keychord_init_action,"keychord_init");
queue_builtin_action(console_init_action,"console_init");
queue_builtin_action(set_init_properties_action,"set_init_properties");
// load 3rdparty.rc
snprintf(tmp, sizeof(tmp),"/init.%s.3rdparty.rc", hardware);
init_parse_config_file(tmp); //读取init.sp8810.3rdparty.rc,此文件是用3rdparty目录下所有驱动的init.3rdparty.rc拼接起来。
//接下来就是触发init、early-fs、fs、post-fs,early-bootboot等,同时也会将property_service_init_action signal_init_action等加入队列里。
//总的来说,init做了几件事情: 解析了*.rc文件,并根据得到的action按照特定的顺序去执行;初始化了一系列服务,如属性服务等。
//下面init进入了循环,等待消息。
}
接下来看下init.rc。
Init.rc位于\system\core\rootdir,具体的说明文档在\system\core\init\readme.txt.
简单的说来,init.rc就是将某个时间段内需要做的事情按照触发器归了类。
最常见的是mkdir ,chmod, chown 等对设备节点的操作,setprop对属性默认值进行设置,最多的就是声明service,android所有进程的爹--- zygote就是在init.rc里声明的(on boot 阶段)。
service zygote /system/bin/app_process-Xzygote /system/bin --zygote --start-system-server
#即声明了一个叫zygote的service,实体是system/bin/app_process,入参是“-Xzygote/system/bin --zygote --start-system-server”
socket zygotestream 666
#创建了socket,用于进程间通信
Critical
#级别, 这是一个设备关键服务 (device-criticalservice) . 如果它在 4 分钟内退出超过 4 次,设备将重启并进入恢复模式。
onrestart write /sys/android_power/request_state wake
onrestart write /sys/power/state on
onrestart restart media
onrestart restart netd
onrestartrestart mlistener
# 在重启服务的时候做的事情。
由于没有设置关键字 disabled,也就是说,zygote是个自启动的service,在init触发boot阶段时,zygote就会启动,也就会去执行app_process
下面就到了app_process的main函数。
frameworks\base\cmds\app_process\app_main.cpp
int main(int argc, const char* constargv[])
{
//…
int i = runtime.addVmArguments(argc, argv);
// Next arg is parent directory
if (i < argc) {
runtime.mParentDir = argv[i++];
}
// Next arg is startup classname or "--zygote"
if (i < argc) {
arg = argv[i++];
if (0 == strcmp("--zygote", arg)) {
bool startSystemServer = (i < argc) ?
strcmp(argv[i],"--start-system-server") == 0 : false;
setArgv0(argv0, "zygote");
set_process_name("zygote");
// do last shutdown check
doLastShutDownCheck();
runtime.start("com.android.internal.os.ZygoteInit",
startSystemServer);
//调用androidruntime来启动zygote,并且启动systemserver
} else {
set_process_name(argv0);
runtime.mClassName = arg;
// Remainder of args get passed to startup class main()
runtime.mArgC = argc-i;
runtime.mArgV = argv+i;
LOGV("App process is starting with pid=%d, class=%s.\n",
getpid(),runtime.getClassName());
runtime.start();
}
}else {
LOG_ALWAYS_FATAL("app_process: no class name or --zygotesupplied.");
fprintf(stderr, "Error: no class name or --zygotesupplied.\n");
app_usage();
return 10;
}
}
Frameworks\base\core\jni\AndroidRuntime.cpp
void AndroidRuntime::start(const char*className, const bool startSystemServer)
{
//…
if (startSystemServer) {
/* track our progress through the boot sequence */
const int LOG_BOOT_PROGRESS_START = 3000;
LOG_EVENT_LONG(LOG_BOOT_PROGRESS_START,
ns2ms(systemTime(SYSTEM_TIME_MONOTONIC)));
}
//设置root为/system
const char* rootDir = getenv("ANDROID_ROOT");
if (rootDir == NULL) {
rootDir = "/system";
if (!hasDir("/system")) {
LOG_FATAL("No root directory specified, and /android does notexist.");
goto bail;
}
setenv("ANDROID_ROOT", rootDir, 1);
}
/* 启动虚拟机*/
if (startVm(&mJavaVM, &env) != 0)
goto bail;
/*
* Register android functions.
*/
//注册native的函数
if (startReg(env) < 0) {
LOGE("Unable to register allandroid natives\n");
goto bail;
}
//省略C++的字符串转到JAVA的字符串
//此处的classname即是传入的com.android.internal.os.ZygoteInit
slashClassName = strdup(className);
for (cp = slashClassName; *cp != '\0';cp++)
if (*cp == '.')
*cp = '/';
startClass =env->FindClass(slashClassName);
if (startClass == NULL) {
LOGE("JavaVM unable to locateclass '%s'\n", slashClassName);
/* keep going */
} else {
startMeth =env->GetStaticMethodID(startClass, "main",
"([Ljava/lang/String;)V");
if (startMeth == NULL) {
LOGE("JavaVM unable to find main()in '%s'\n", className);
/* keep going */
} else {
//调用ZygoteInit的main方法,入参为true
env->CallStaticVoidMethod(startClass, startMeth, strArray);
#if 0
if (env->ExceptionCheck())
threadExitUncaughtException(env);
#endif
}
}
LOGD("Shutting down VM\n");
if (mJavaVM->DetachCurrentThread() !=JNI_OK)
LOGW("Warning: unable to detachmain thread\n");
if (mJavaVM->DestroyJavaVM() != 0)
LOGW("Warning: VM did not shut downcleanly\n");
bail:
free(slashClassName);
}
进入java世界:
Framework\base\core\java\com\android\internal\os\ZygoteInit.java
public static void main(String argv[]) {
try {
VMRuntime.getRuntime().setMinimumHeapSize(5 * 1024 * 1024);
// Start profiling the zygote initialization.
SamplingProfilerIntegration.start();
registerZygoteSocket(); //注册socket,就是在init.rc里声明的
EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_START,
SystemClock.uptimeMillis());
preloadClasses();
//cacheRegisterMaps();
preloadResources(); //提前加载类和framework-res.apk里的资源,加载一个类的时间如果超过1250MS,则会放在这里来加载
EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_END,
SystemClock.uptimeMillis());
// Finish profiling the zygote initialization.
SamplingProfilerIntegration.writeZygoteSnapshot();
// Do an initial gc to clean up after startup
gc(); //强制垃圾回收
// If requested, start system server directly from Zygote
if (argv.length != 2) {
throw newRuntimeException(argv[0] + USAGE_STRING);
}
if (argv[1].equals("true")) {
startSystemServer(); //如果上文的入参为true,则启动systemserver
} else if (!argv[1].equals("false")) {
throw newRuntimeException(argv[0] + USAGE_STRING);
}
if (ZYGOTE_FORK_MODE){
runForkMode();
} else {
runSelectLoopMode(); //使用建好的socket,进入循环等待
}
//。。。。
}
Zygote起来之后干的事情有这么几件:
1. 注册了zygote的Socket
2. 预加载了一些类和资源
3. 启动了systemserver
4. 启动loop等待调用。
接下来继续看systemserver:
private static boolean startSystemServer()
throws MethodAndArgsCaller, RuntimeException {
//….
try {
parsedArgs = new ZygoteConnection.Arguments(args);
/*
* Enable debugging of the system process if *either* the command lineflags
* indicate it should be debuggable or the ro.debuggable system property
* is set to "1"
*/
int debugFlags = parsedArgs.debugFlags;
if("1".equals(SystemProperties.get("ro.debuggable")))
debugFlags |=Zygote.DEBUG_ENABLE_DEBUGGER;
/* Request to fork the system server process */
//孵化systemserver
pid = Zygote.forkSystemServer(
parsedArgs.uid,parsedArgs.gid,
parsedArgs.gids,debugFlags, null,
parsedArgs.permittedCapabilities,
parsedArgs.effectiveCapabilities);
} catch (IllegalArgumentException ex) {
throw new RuntimeException(ex);
}
/* For child process */
if (pid == 0) {
//如果孵化成功,则调用次函数来处理
handleSystemServerProcess(parsedArgs);
}
return true;
}
Zygote.forkSystemServer方法位于:
Dalvik/vm/dalvik_system_Zygote.c
static voidDalvik_dalvik_system_Zygote_forkSystemServer(
const u4* args, JValue* pResult)
{
pid_t pid;
pid = forkAndSpecializeCommon(args, true);
/* The zygote process checks whether thechild process has died or not. */
if (pid > 0) {
int status;
LOGI("System server process %d hasbeen created", pid);
gDvm.systemServerPid = pid;
/* There is a slight window that thesystem server process has crashed
* but it went unnoticed because wehaven't published its pid yet. So
* we recheck here just to make surethat all is well.
*/
if (waitpid(pid, &status, WNOHANG)== pid) {
LOGE("System server process %d hasdied. Restarting Zygote!", pid);
/* FIXME: reboot instead ofrestarting android */
/* kill(getpid(), SIGKILL); */
//如果创建systemserver失败,则zygote会自杀。
sleep(2);
reboot(RB_AUTOBOOT);
}
}
RETURN_INT(pid);
}
forkAndSpecializeCommon函数中会fork出systemserver,并返回PID。
回到ZygoteInit.java ,startSystemServer方法中,如果forkSystemServer返回是正确的,那么就会调用handleSystemServerProcess来处理信息。
private static voidhandleSystemServerProcess(
ZygoteConnection.ArgumentsparsedArgs)
throwsZygoteInit.MethodAndArgsCaller {
closeServerSocket();
/*
* Pass the remaining arguments toSystemServer.
* "--nice-name=system_servercom.android.server.SystemServer"
*/
RuntimeInit.zygoteInit(parsedArgs.remainingArgs);//现在将转移到runtimeinit
/* should never reach here */
}
Framework\base\core\java\com\android\internal\os\RuntimeInit.java
public staticfinal void zygoteInit(String[] argv)
throwsZygoteInit.MethodAndArgsCaller {
//…初始化native的方法,binder相关,略
String startClass = argv[curArg++];
String[] startArgs = newString[argv.length - curArg];
System.arraycopy(argv, curArg, startArgs, 0,startArgs.length);
invokeStaticMain(startClass,startArgs); //启动com.android.server.SystemServer.main
}
Framework\base\services\java\com\android\server\SystemServer.java
public staticvoid main(String[] args) {
System.loadLibrary("android_servers");//load lib
init1(args); //init1是native的方法,真身是在com_android_server_systemserver.cpp的
//android_server_SystemServer_init1
}
Frameworks\bae\services\jni\com_android_server_systemserver.cpp
static voidandroid_server_SystemServer_init1(JNIEnv* env, jobject clazz)
{
system_init();
}
Frameworks\base\cmds\system_server_libary\system_init.cpp
extern"C" status_t system_init()
{
LOGI("Entered system_init()");
sp<ProcessState> proc(ProcessState::self());
sp<IServiceManager> sm =defaultServiceManager();
LOGI("ServiceManager: %p\n",sm.get());
sp<GrimReaper> grim = newGrimReaper();
sm->asBinder()->linkToDeath(grim,grim.get(), 0);
char propBuf[PROPERTY_VALUE_MAX];
property_get("system_init.startsurfaceflinger", propBuf,"1"); //判断是否支持surfaceflinger
if (strcmp(propBuf, "1") == 0) {
// Start the SurfaceFlinger
SurfaceFlinger::instantiate();//surfaceflinger初始化,完成后调用readytoRun,会启动在init.rc中声明的bootanimation,开始播放开机动画。
} SensorService::instantiate();
// On the simulator, audioflinger et aldon't get started the
// same way as on the device, and we needto start them here
if (!proc->supportsProcesses()) {
// Start the AudioFlinger
AudioFlinger::instantiate();
// Start the media playback service
MediaPlayerService::instantiate();
// Start the camera service
CameraService::instantiate();
// Start the audio policy service
AudioPolicyService::instantiate();
LOGI("System server: starting Androidruntime.\n");
AndroidRuntime* runtime =AndroidRuntime::getRuntime();
LOGI("System server: starting Androidservices.\n");
runtime->callStatic("com/android/server/SystemServer","init2");
//回调到init2
if (proc->supportsProcesses()) {
LOGI("System server: enteringthread pool.\n");
ProcessState::self()->startThreadPool();
IPCThreadState::self()->joinThreadPool();
LOGI("System server: exitingthread pool.\n");
}
return NO_ERROR;
}
Framework\base\services\java\com\android\server\SystemServer.java
public static final void init2() {
Slog.i(TAG, "Entered the Androidsystem server!");
Thread thr = new ServerThread();
thr.setName("android.server.ServerThread");
thr.start();
}
ServerThread.run(){
//….
//创建Criticalservice
//常见的有PMS,AMS,lightservice,packagemanagerservice
//创建WMS时候也会创建inputmanager,inputreader,eventhub等组件,在上一篇中讲过。
//等这些service都创建没问题后,会发送systemready,
wm.systemReady(); //通知keyguard锁屏。
power.systemReady(); //此处会点亮屏幕,唤醒真正的交由PMS处理。
try {
pm.systemReady();
} catch (RemoteException e) {
}
//启动AMS,通知另外一些应用系统已经boot完毕
((ActivityManagerService)ActivityManagerNative.getDefault())
.systemReady(new Runnable() {
public void run() {
Slog.i(TAG, "Makingservices ready");
if (statusBarF != null)statusBarF.systemReady2();
if (batteryF != null)batteryF.systemReady();
if (connectivityF != null)connectivityF.systemReady();
if (dockF != null)dockF.systemReady();
if (usbF != null)usbF.systemReady();
if (uiModeF != null)uiModeF.systemReady();
if (recognitionF != null)recognitionF.systemReady();
Watchdog.getInstance().start();
// It is now okay to let thevarious system services start their
// third party code...
if (appWidgetF != null)appWidgetF.systemReady(safeMode);
if (wallpaperF != null)wallpaperF.systemReady();
if (immF != null)immF.systemReady();
if (locationF != null)locationF.systemReady();
if (throttleF != null)throttleF.systemReady();
}
});
(new Thread(newWakelockMonitor(power))).start();
// For debug builds, log event loopstalls to dropbox for analysis.
if(StrictMode.conditionallyEnableDebugLogging()) {
Slog.i(TAG, "EnabledStrictMode for system server main thread.");
}
Looper.loop();
}
在AMS的systemready里,会调用
mMainStack.resumeTopActivityLocked(null);
其实也就是ams的startHomeActivityLocked()
Frameworks\base\services\java\com\android\server\am\ActivityManagerService.java
startHomeActivityLocked(){
if (mFactoryTest ==SystemServer.FACTORY_TEST_LOW_LEVEL
&& mTopAction == null){
// We are running in factory testmode, but unable to find
// the factory test app, so justsit around displaying the
// error message and don't try tostart anything.
return false;
}
Intent intent = new Intent(
mTopAction,
mTopData != null ?Uri.parse(mTopData) : null);
intent.setComponent(mTopComponent);
if (mFactoryTest !=SystemServer.FACTORY_TEST_LOW_LEVEL) {
intent.addCategory(Intent.CATEGORY_HOME);//在launcher的androidManifest里有声明如下:
/*
<categoryandroid:name="android.intent.category.HOME" />
*/
}
ActivityInfo aInfo =
intent.resolveActivityInfo(mContext.getPackageManager(),
STOCK_PM_FLAGS);
if (aInfo != null) {
intent.setComponent(newComponentName(
aInfo.applicationInfo.packageName,aInfo.name));
// Don't do this if the home app iscurrently being
// instrumented.
ProcessRecord app =getProcessRecordLocked(aInfo.processName,
aInfo.applicationInfo.uid);
if (app == null ||app.instrumentationClass == null) {
intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
mMainStack.startActivityLocked(null, intent, null, null, 0, aInfo,
null, null, 0, 0, 0, false, false);
}
}
return true;
}
所以launcher在这里就启动了。