Android启动init.c
来源:互联网 发布:淘宝网店一颗心 编辑:程序博客网 时间:2024/05/01 16:05
首先是 init进程启动(一些native服务启动) 如: servicemanager启动 Zygote启动 SysytemServer启动,在 init1 init2函数中启动Android服务 init进程起来 后,解析init.rc和init.xxx.rc建立基本的服务,之后进入循环,并没有退出。 分析init.c@/system/core/init的main函数主要实现过程 ... mkdir("/dev", 0755) //创建具有可读写的目录 ”/dev“ 。。。 log_init(); //初始化log系统 。。。 parse_config_file("/init.rc"); /*解析init.rc文件,parse_config_file这个函数是/system/core/init/parse.c这个类中实现的,讲解析得到的service信息储存到service_list这个数据解构中*/ get_hardware_name(); snprintf(tmp, sizeof(tmp), "/init.%s.rc", hardware); parse_config_file(tmp); /*解析init.xxx.rc,和硬件相关*/ action_for_each_trigger("early-init", action_add_queue_tail); drain_action_queue(); /*执行解 析得到的”early-init”的action*/ INFO("device init/n"); device_fd = device_init(); /*设备的初始化。挂载结点倒/dev下还有下载firmwares*/ property_init(); 。。。 /*property初始化*/ /*读取/initlogo.rle(一张位图),如果成功则在/dev/graphics/fb0 显示Logo,如果失败则将/dev/tty0,设为TEXT模式并打开/dev/tty0,输出文本ANDROID。具体实现可看 /system/core/init/log.c */ if( load_565rle_image(INIT_IMAGE_FILE) ) { fd = open("/dev/tty0", O_WRONLY); if (fd >= 0) { 。。。 。。。 } /* 判断cmdline 中的參數,并设置属性系统中的参数: * 1、 如果 bootmode为 * - factory,设置ro.factorytest值为1 * - factory2,设置ro.factorytest值为2 * - 其他的設ro.factorytest值為0 * 2、如果有serialno参数,则设置ro.serialno,否则为"" * 3、如果有bootmod参数,则设置ro.bootmod,否则为"unknown" * 4、如果有baseband参数,则设置ro.baseband,否则为"unknown" * 5、如果有carrier参数,则设置ro.carrier,否则为"unknown" * 6、如果有bootloader参数,则设置ro.bootloader,否则为"unknown" * 7、通过全局变量(前面从/proc/cpuinfo中提取的)设置ro.hardware和ro.version。 */ if (qemu[0]) import_kernel_cmdline(1); if (!strcmp(bootmode,"factory")) property_set("ro.factorytest", "1"); else if (!strcmp(bootmode,"factory2")) property_set("ro.factorytest", "2"); else property_set("ro.factorytest", "0"); property_set("ro.serialno", serialno[0] ? serialno : ""); property_set("ro.bootmode", bootmode[0] ? bootmode : "unknown"); property_set("ro.baseband", baseband[0] ? baseband : "unknown"); property_set("ro.carrier", carrier[0] ? carrier : "unknown"); property_set("ro.bootloader", bootloader[0] ? bootloader : "unknown"); property_set("ro.hardware", hardware); snprintf(tmp, PROP_VALUE_MAX, "%d", revision); property_set("ro.revision", tmp); action_for_each_trigger("init", action_add_queue_tail); drain_action_queue(); /*执行解析 得到的init action */ property_set_fd = start_property_service(); //启动 property service 。。。 。。。 /* 为sigchld handler创建信号机制*/ if (socketpair(AF_UNIX, SOCK_STREAM, 0, s) == 0) { signal_fd = s[0]; signal_recv_fd = s[1]; fcntl(s[0], F_SETFD, FD_CLOEXEC); fcntl(s[0], F_SETFL, O_NONBLOCK); fcntl(s[1], F_SETFD, FD_CLOEXEC); fcntl(s[1], F_SETFL, O_NONBLOCK); } /* 确认所有初始化工作完成 * device_fd(device init 完成) * property_set_fd(property server start 完成) * signal_recv_fd (信号机制建立) */ if ((device_fd < 0) || (property_set_fd < 0) || (signal_recv_fd < 0)) { ERROR("init startup failure/n"); return 1; } action_for_each_trigger("early-boot", action_add_queue_tail); action_for_each_trigger("boot", action_add_queue_tail); drain_action_queue(); //执行解析的"early-boot"和"boot"action queue_all_property_triggers(); drain_action_queue(); //执行解 析的property action for(;;){ 。。。 /* 进入无限循环 等待一些device/property set/process eixt 这些event 比如SD插入时,会收到device add的event,然后它可以为这个设 备添加节点。处理一些process exit event,执行在*.rc中定义的 命令(在onrestart)的时候 */ 。。。 } 从上可以看出init依次执行五种触发器(Triggers) early-init init early-boot boot property:* 分析init.rc文件@/system/core/rootdir/init.rc 1 .关于init.rc 在Android中使用启动脚本init.rc,可以在系统的初始化过程中进行一些简单的初始化操作。这个脚本被直接安装到目标系统的根文件系统中, 被init可执行程序解析。 init.rc是在init启动后被执行的启动脚本,其余发主要包含了以下内容: * Commands:命令 * Actions:动作 * Triggers:触发条件 * Services:服务 * Options:选项 * Propertise:属性 Commands是 一些基本的操作,例如: mkdir /sdcard 0000 system system mkdir /system mkdir /data 0771 system system mkdir /cache 0770 system cache mkdir /config 0500 root root mkdir /sqlite_stmt_journals 01777 root root mount tmpfs tmpfs /sqlite_stmt_journals size=4m 这些命令在init可执行程序中被解析,然后调用相关的函数来实现。 Actions(动作)表示一系列的命令,通常在Triggers(触发条件)中调用,动作和触发条件例如: on init export PATH /sbin:/system/sbin:/system/bin:/system/xbin init 表示一个 触发条件,这个触发事件发生后,进行设置环境变量和建立目录的操作称为一个“动作”Services(服务)通常表示启动一个可执行程序,Options(选项)是服务的附加内容,用于配合服务使用。 service vold /system/bin/vold socket vold stream 0660 root mount service bootsound /system/bin/playmp3 user media group audio oneshot vold 和bootsound分别是两个服务的名称,/system/bin/vold和/system/bin/playmp3分别是他们所对应的可执行程序。 socket、user、group、oneshot就是配合服务使用的选项。 Properties(属性)是系统中使用的一些值,可以进行设置和读取。 setprop ro.FOREGROUND_APP_MEM 1536 setprop ro.VISIBLE_APP_MEM 2048 start adbd setprop 用 于设置属性,on property可以用于判断属 性,这里的属性在整个Android系统运行中都是一致的 init.rc启动 的服务 1.console 2.adbd adb deamon 可以通过property_set persist.service.adb.enable 来 控制其执行 3.servicemanager 启动binder system.IPC机制 通信相关的吧。。。 4.vold 5.nexus 6.mountd 7.debuggerd 8.ril-daemon 9.zygote 10.media 11.bootsound 12.bootanim 13.dbus 14.bluetoothd 15.hfag 16.hsag 17.opush 18.pbap 19.installd 20.flash_recovery 21.racoon 22.mtpd 23.keystore 24.dumpstate Zygote服务的 启动: service zygote /system/bin/app_process -Xzygote /system/bin --zygote –start-system-server 在app_main.cpp@/framework/base/cmds/app_process/的main函数中 // 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"); runtime.start("com.android.internal.os.ZygoteInit",startSystemServer); } 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 --zygote supplied."); fprintf(stderr, "Error: no class name or --zygote supplied./n"); app_usage(); return 10; } 创建AppRuntime对象 runtime,执行runtime.start("com.android.internal.os.ZygoteInit", startSystemServer)的方法,实现在AndroidRuntime.cpp中。 void AndroidRuntime::start(const char* className, const bool startSystemServe) { 。。。 /* start the virtual machine */ if (startVm(&mJavaVM, &env) != 0) goto bail; /* * Register android functions. */ if (startReg(env) < 0) { LOGE("Unable to register all android natives/n"); goto bail; } 。。。 } 创建虚拟机器,注册android jni方法,然后就是定位className的类 slashClassName = strdup(className); for (cp = slashClassName; *cp != '/0'; cp++) if (*cp == '.') *cp = '/'; startClass = env->FindClass(slashClassName); 执行该类的main方法 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 { env->CallStaticVoidMethod(startClass, startMeth, strArray); 在 ZygoteInit的main方法中 SamplingProfilerIntegration.start(); // Start profiling the zygote initialization. RegisterZygoteSocket(); //注册Zygote端口 //load preload classes 路径/frameworks/base/preloaded-classes preloadClasses(); //load preload resource 系统常用的资源 preloadResources(); /* startSystemServer()中调用 Zygote.forkSystemServer这个nitive方法,具体实现在dalvik/vm/native/dalvik_system_Zygote.c */ if (argv[1].equals("true")) { startSystemServer(); } /* 之后进入 runSelectLoopMode */ if (ZYGOTE_FORK_MODE) { runForkMode(); } else { runSelectLoopMode(); 在startSystemServer后,Zygote上forkSystemServer之后,建立了SystemServer进程,执行其main函数, //load android_servers.so System.loadLibrary("android_servers"); /*执行init1 native 方法。实现在/frameworks/base/cmds/system_server/library/system_init.cpp 1.如果是运行在模拟器上则instantiate AudioFlinger MediaPlayerService CameraService AudioPolicyService 2.调用runtime->callStatic("com/android/server/SystemServer", "init2") SystemServer中的init2方法, 3.如果不是运行在模拟器上,则执行 ProcessState::self()->startThreadPool(); IPCThreadState::self()->joinThreadPool(); */ 在systemServer init2中会创 建一个线程来启动所有的Android服务 1.Entropy Service 2.Power Manager 3.Activity Manager 4.Telephony Registry 5.Package Manager 6.Account Manager 7.Content Manager 8.System Content Providers 9.Battery Service 10.Hardware Service 11.Alarm Manager 12.Sensor Service 13.Window Manager 14.Bluetooth Service 15.Status Bar 16.Clipboard Service 17.Input Method Service 18.NetStat Service 19.Connectivity Service 20.Accessibility Manager 21.Notification Manager 22.Mount Service 23.Device Storage Monitor 24.Location Manager 25.Search Service 26.Checkin Service 27.Wallpaper Service 28.Audio Service 29.Headset Observer 30.Dock Observer 31.Backup Service 32.AppWidget Service 最后会调用ActivityManagerService 的systemReady方法, 依次执行 resumeTopActivityLocked startHomeActivityLocked(intent.addCategory(Intent.CATEGORY_HOME)) startActivityLocked 最终启动完成进入Home画面
- Android启动init.c
- Android 启动分析 --- init.c (system/core/init/init.c)
- Android 启动流程: Init.c 阅读笔记
- Android 启动流程: Init.c 阅读笔记
- Android 启动流程: Init.c 阅读笔记 .
- android init.c init.rc
- android init启动过程
- Android init进程启动
- Android init进程启动
- Android init启动理解
- Android init进程启动
- Android init进程启动
- Android启动详解-----init
- android启动过程中init.c文件分析
- android启动过程中init.c文件分析
- android启动代码init.c文件分析(一)
- android启动代码init.c文件分析(二)
- android启动代码init.c文件分析(三)
- 数组循环移位
- 一些PHP Coding Tips
- 十五: TranslateMessage(&msg) 函数 和DispatchMessage(&msg)函数
- 编码的问题--编码有三种(页面编码,文件格式的编码,后台处理所使用的编码)
- cat指令详解
- Android启动init.c
- FileVersionInfo类显示dll信息
- cmd 命令大全
- Eclipse开发前,常用设置
- dtree ajax 右键
- Excel导入数据库
- csdn没高手啊
- vs中的一些常用快捷键
- hdu1269 并查集 强联通