本文共 13312 字,大约阅读时间需要 44 分钟。
1 Bootloader
对于一般的ARM处理器,CPU上电或复位执行第一条指令所在地址,即第一段程序Bootloader的开始地址,Bootloader一般存于Nor-flash(XIP),支持芯片内执行。
Bootloader的功能可总结为:1)初始化CPU时钟,内存,串口等。2)设置Linux启动参数。3)加载Linux内核镜像。Android源码位于根目录下的/bootable文件夹。
系统正常启动,运行Bootloader,初始化芯片,根据设置的启动参数cmdline,加载Linux内核镜像,将控制权交给内核。
系统在Bootloader模式下(非正常启动模式),可使用fastboot, mmcboot等工具烧写内核和文件系统,顺便提一下,Android手机分区一般分为内核区boot.img,系统区system.img,用户数据区userdata.img,数据恢复区recovery.img等。
2 Linux内核镜像
内核镜像被加载到内存,首先进行自解压,zImage, bzImage或uImage的头部都内嵌有解压缩程序,最终将内核解压到内存的指定位置,开始运行内核。
3 启动内核
源码位于/kernel/init/main.c,线索可归纳为:启动内核start_kernel() => 初始化Linux各大模块 + rest_init() => 开启内核线程kthreadd和kernel_init() => 初始化设备驱动程序do_basic_setup() + init_post() => 开启第一个用户进程init。
3.1 start_kernel()
源码位于/kernel/init/main.c的start_kernel()函数,完成初始化Linux系统的进程管理,内存管理,文件系统等工作,可以说个个都是重量级的工作。
这里有必要解释下内核选项,因为Linux各个子系统的初始化都建立在内核选项的解析之后。
parse_early_param();
parse_args("Booting kernel", static_command_line, __start___param, __stop___param - __start___param, &unknown_bootoption);1) 内核选项的注册
通过__early_parm(str, fn)或__setup(str, fn)宏来注册。两者都调用__setup_param宏实现,它将注册的内核选项str所关联的函数fn存放到.init.setup节。
2) 内核选项的解析
两次注册对应两次解析,即parse_early_param()和parse_param(),解析时,会在__setup_start和__setup_end之间查找内核选项,当识别有内核选项时,即会调用相应的处理函数。内核解析完后,各个子系统的初始化就可通过kernel_init()=>do_basic_setup()=>do_initcalls()来完成。
3.2 reset_init()
开启内核线程kthreadd和kernel_init,kthreadd用来运行kthread_create_list全局链表中的kthread,然后创建idle线程来占用掉cpu空闲的时间片。
内核线程又叫守护进程,关于内核线程和Linux普通进程的区别,归纳为以下三点:
3.3 kernel_init()
此时与体系相关的部分已经初始化完成,do_basic_setup()开始初始化设备,完成外设及驱动程序(直接编译进内核的模块)的加载和初始化。
3.4 init_post()
开启init用户进程,所谓Android的启动流程从这里才刚刚开始。
Android部分的启动流程参考
1. init进程
2. zygote进程
2.1 AndroidRuntime
2.2 ZygoteInit
3. system_server进程
3.1 init1阶段
3.2 init2阶段
接着Linux启动部分 http://blog.csdn.net/qianjin0703/article/details/6881107
1. init进程
系统在内核空间初始化进程,内存,文件系统,驱动模块之后,调用init_post()函数,开启第一个用户进程init,进入用户空间。
/kernel/init/main.c (仅截取部分重要代码)
static noinline int init_post(void){ run_init_process("/sbin/init"); run_init_process("/etc/init"); run_init_process("/bin/init"); run_init_process("/bin/sh");}
终端下查看1号进程,
可见,init是系统守护进程和zygote的父进程。
/system/core/init/init.c
int main(int argc, char **argv){ mkdir("/dev", 0755); mkdir("/proc", 0755); mkdir("/sys", 0755); mount("devpts", "/dev/pts", "devpts", 0, NULL); mount("proc", "/proc", "proc", 0, NULL); mount("sysfs", "/sys", "sysfs", 0, NULL); open_devnull_stdio(); klog_init(); property_init(); get_hardware_name(hardware, &revision); process_kernel_cmdline(); init_parse_config_file("/init.rc"); action_for_each_trigger("early-init", action_add_queue_tail); queue_builtin_action(wait_for_coldboot_done_action, "wait_for_coldboot_done"); queue_builtin_action(keychord_init_action, "keychord_init"); queue_builtin_action(console_init_action, "console_init"); action_for_each_trigger("init", action_add_queue_tail); for(;;) { execute_one_command(); restart_processes(); nr = poll(ufds, fd_count, timeout); for (i = 0; i < fd_count; i++) { if (ufds[i].revents == POLLIN) { if (ufds[i].fd == get_property_set_fd()) handle_property_set_fd(); else if (ufds[i].fd == get_keychord_fd()) handle_keychord(); else if (ufds[i].fd == get_signal_fd()) handle_signal(); } } } return 0;}
init进程归纳如下
2. zygote进程
zygote既是Android系统创建java世界的盘古,又是繁殖system_server和所有应用程序的女娲。
终端下查看zygote进程,
2.1 AndroidRuntime
/frameworks/base/cmds/app_process/app_main.cpp
int main(int argc, const char* const argv[]){ AppRuntime runtime; if (zygote) { runtime.start("com.android.internal.os.ZygoteInit", startSystemServer ? "start-system-server" : "");}
AppRuntime是从AndroidRuntime类派生的,最后由runtime.start()进入Java世界。
/frameworks/base/core/jni/AndroidRuntime.cpp
void AndroidRuntime::start(const char* className, const char* options){ /* start the virtual machine */ JNIEnv* env; if (startVm(&mJavaVM, &env) != 0) { return; } onVmCreated(env); /* * Register android functions. */ if (startReg(env) < 0) { ALOGE("Unable to register all android natives\n"); return; } /* * Start VM. This thread becomes the main thread of the VM, and will * not return until the VM exits. */ char* slashClassName = toSlashClassName(className); jclass startClass = env->FindClass(slashClassName); jmethodID startMeth = env->GetStaticMethodID(startClass, "main", "([Ljava/lang/String;)V"); env->CallStaticVoidMethod(startClass, startMeth, strArray);}
-> 创建虚拟机
注意这里会设置虚拟机的heapsize,默认16M,一般32M,不能太小,否则在操作大尺寸图片时无法分配所需内存。
-> 注册jni函数
这里注册了本地方法,这些方法最终被编译进动态链接库libandroid_runtime.so,供上层Java调用。
static const RegJNIRec gRegJNI[] = { REG_JNI(register_android_debug_JNITest), REG_JNI(register_com_android_internal_os_RuntimeInit), REG_JNI(register_android_os_SystemClock), REG_JNI(register_android_util_Log), REG_JNI(register_android_os_Process), REG_JNI(register_android_os_SystemProperties), REG_JNI(register_android_os_Binder), REG_JNI(register_android_view_Display), REG_JNI(register_android_graphics_Bitmap), REG_JNI(register_android_graphics_Camera), REG_JNI(register_android_database_SQLiteDatabase), REG_JNI(register_android_os_Power), REG_JNI(register_android_os_StatFs), REG_JNI(register_android_net_NetworkUtils), REG_JNI(register_android_nfc_NdefMessage), REG_JNI(register_com_android_internal_os_ZygoteInit), REG_JNI(register_android_hardware_Camera), REG_JNI(register_android_hardware_SensorManager), REG_JNI(register_android_hardware_UsbDevice), REG_JNI(register_android_media_AudioRecord), REG_JNI(register_android_media_AudioSystem), REG_JNI(register_android_media_AudioTrack), REG_JNI(register_android_opengl_classes), REG_JNI(register_android_bluetooth_BluetoothSocket), REG_JNI(register_android_server_BluetoothService), REG_JNI(register_android_app_ActivityThread), REG_JNI(register_android_app_NativeActivity), REG_JNI(register_android_view_InputChannel), REG_JNI(register_android_view_InputQueue), REG_JNI(register_android_view_KeyEvent), REG_JNI(register_android_view_MotionEvent), REG_JNI(register_android_view_PointerIcon),};
2.2 ZygoteInit
/frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
public static void main(String argv[]) { try { SamplingProfilerIntegration.start(); registerZygoteSocket(); preload(); SamplingProfilerIntegration.writeZygoteSnapshot(); if (argv[1].equals("start-system-server")) { startSystemServer(); } runSelectLoopMode(); closeServerSocket(); } }
-> 建立服务端Socket
zygote及系统中其他程序的通信没有使用Binder,而是采用了基于AF_UNIX类型的Socket.
-> 预加载类和资源
预加载的类可以在 /frameworks/base/preloaded-classes 查看。预加载的资源生成framewrok-res.apk,主要是一些图标,刷机达人经常修改它。
-> 启动system_server进程
zygote进程fork出system_server子进程,把任务繁重的系统服务全部托管出去,自己负责循环监听所有应用程序的请求。
-> 等待应用程序的请求
zygote通过runSelectLoopMode()处理应用程序客户端的请求,由ZygoteConnection的runOnce()孵化出新的应用程序。
综上所述,zygote进程归纳如下
3. system_server进程
/frameworks/base/services/java/com/android/SystemServer.java
public static void main(String[] args) { System.loadLibrary("android_servers"); init1(args); }
3.1 init1阶段
加载libandriod_server.so库,实现init1/frameworks/base/cmds/system_server/library/system_init.cpp
extern "C" status_t system_init(){ spgrim = new GrimReaper(); sm->asBinder()->linkToDeath(grim, grim.get(), 0); char propBuf[PROPERTY_VALUE_MAX]; property_get("system_init.startsurfaceflinger", propBuf, "1"); if (strcmp(propBuf, "1") == 0) { // Start the SurfaceFlinger SurfaceFlinger::instantiate(); } property_get("system_init.startsensorservice", propBuf, "1"); if (strcmp(propBuf, "1") == 0) { // Start the sensor service SensorService::instantiate(); } AndroidRuntime* runtime = AndroidRuntime::getRuntime(); jclass clazz = env->FindClass("com/android/server/SystemServer"); jmethodID methodId = env->GetStaticMethodID(clazz, "init2", "()V"); env->CallStaticVoidMethod(clazz, methodId); return NO_ERROR;}
3.2 init2阶段
init2回到Java层,启动一个ServerThread线程,启动系统的各项服务。