Chinaunix首页 | 论坛 | 博客
  • 博客访问: 91085
  • 博文数量: 25
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 221
  • 用 户 组: 普通用户
  • 注册时间: 2014-01-08 16:03
个人简介

一万年太久,只争朝夕

文章分类
文章存档

2016年(4)

2015年(19)

2014年(2)

我的朋友

分类: Android平台

2015-02-09 20:43:01

Android手机启动主要分为以下几个大的部分:

 

ROMCODE:

手机上电后,ROMCODE代码从0x00000000地址开始执行,初始化内部ramIRAM)加载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。

     registerZygoteSocket();//登记Listen端口
     startSystemServer();
     进入Zygote服务框架。
     经过这几个步骤,Zygote就建立好了,利用Socket通讯,接收ActivityManangerService的请求,Fork应用程序。

阅读(1176) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~