一万年太久,只争朝夕
分类: Android平台
2015-02-09 20:43:01
Android手机启动主要分为以下几个大的部分:
ROMCODE:
手机上电后,ROMCODE代码从0x00000000地址开始执行,初始化内部ram(IRAM)加载spl代码到内部ram并执行。
SPL:
Spl代码运行在IRAM里面,因此代码的起始执行地址应该在是在芯片内存布局IRAM地址空间的起始地址。Spl代码功能如下:
1、关闭MMU;//在MMU启动之前,系统启动内存空间的地址都是实际的物理地址,启动MMU之后,所提到的地址是虚拟地址
2、Chip_Init;//低端初始化,主要包括 MCU_Init()和sdram_init(),MCU、DDR时钟、时序参数设置;
3、nand_boot,初始化NAND(EMMC)
4、拷贝uboot代码到DDR并跳转至DDR运行
Uboot:
Uboot代码在DDR中执行,主要任务是完成NAND/EMMC的初始化,将kernel相关代码搬到DDR对应的地址空间执行。uboot代码有两个重要的C语言函数构,board_init_f和board_init_r。
其中board_init_f函数主要是对uboot的两个重要的结构体bd_t和gd_t进行参数设置,为board_init_r函数的执行准备C语言环境。board_init_r函数则完全运行在C语言环境,主要完成一些必要的硬件初始化,初始化NAND/EMMC,加载Linux代码并运行。
serial_initialize();//串口初始化
nand_init()/mmc_legacy_init();//NAND/EMMC初始化
drv_vfd_init();//LCD初始化
stdio_init ();//获取设备链表
……
interrupt_init ();
enable_interrupts ();
board_keypad_init();
do_cboot();
do_cboot函数判断开机原因,并进入到相应的开机模式:
1、显示开机logo
2、加载nv、dsp、modem等分区
3、加载kernel、ramdisk镜像
4、creat_cmdline
5、start_linux;//theKernel = (void
(*)(int, int, u32))KERNEL_ADR;
Kernel:
Kernel部分的代码从kernel/arch/kernel/head.S开始,完成zImage的自解压,Kernel的初始化由start_kernel函数到第一个用户进程init结束,调用了一系列的初始化函数对所有的内核组件进行初始化。Start_kernel、rest_init、kernel_init、init_post这四个函数构成了kernel初始化的主线。在kernel_init函数最后执行init,按照默认路径搜索init.rc文件启动下一步的动作。
Android:
1、init启动ueventd(ueventd.rc),挂载文件系统,挂载system、data、cache分区
2、ueventd.rc启动system里面的一些sh
3、servicemanager
4、一系列的服务xxxd
5、zygote
6、mediaserver
7、用户态守护进程
servicemanager和zygote进程是android的基础,Zygote从main(…)@frameworks/base/cmds/app_main.cpp开始。
(1) main(…)@frameworks/base/cmds/app_main.cpp
建立Java Runtime
runtime.start("com.android.internal.os.ZygoteInit", startSystemServer);
(2) runtime.start@AndroidRuntime.cpp
建立虚拟机
运行:com.android.internal.os.ZygoteInit:main函数。
(3) main()@com.android.internal.os.ZygoteInit//正真的Zygote。