摘要:
本文试图通过代码来深入剖析 Qualcomm 手机开机的整个过程,即从按下开机键一直到出现待机界面,
Qualcomm 的手机软件在整个流程中究竟完成了哪些工作。本文的主要目标是理清手机的初始化流程,并
为今后 Amoi 定做初始化工作提供一个参考。
关键字:开机、Rex、TMC、ui_task、CoreApp
一、开机的简要流程分析
Qualcomm 的平台软件支持两种启动方式:一种是 Nor Flash 启动方式,另外一种就
是 Nand Flash 启动方式。Nor Flash 启动方式就相当于硬件直接找到一个入口点开始执行代码,相比较而
言会 比较简单,且 Amoi 没有采用此种方式,所以本文对于这种方式不做详细分析。另外一种就是 Nand
Flash 启动方式,这种方式和 PC 的启动方式比较相像,也是 Amoi 采用的 Boot 方式,下面将详细分析在此
方式下面的开机过程。
按下开机键之后,将产生一个时钟中断,从而通知 AMSS 主芯片的 Boot Load 硬件去将放置于 Nand Flash
上面的第一个 Block(8K)里面的 Boot 代码 Copy 到内核内存(RAM,这个内存应该是 CPU 自带的内存,
同后面提到的 SDRAM 有一定区别,可以把它当作 CPU 的 Cache)的 0xFFFF0000 地址,并开始执行 Boot
代码。Boot 的主要任务是完成整个系统的硬件初始化工作(类似于 PC 上面的 BIOS 所完成的硬件自检工作,
至于 Boot 的详细工作机制,后文会有详细描述)。Boot 所完成的工作里面,最重要的一件事就是会将整个
手机软件代码(AMSS 软件包)拷贝到 SDRAM 中,并最后将控制权交给 AMSS 软件。说白了,就是 Boot
执行完成之后,代码的执行点将由 Boot 跳转到 AMSS 软件的的入口点函数 main().(此函数在 mobile.c 里
实现)。
代码运行到了 Main()之后,在这个函数里面将完成操作系统(rex)的初始化工作,其实现方法是调
用 rex_init()。Rex_init()完成的工作很简单:
1.完成操作系统必要的一些数据结构(timer 链表、任务链表等))的初始化之外;
2.接下来,它创建了三个任务,分别是:rex_idle_task、rex_dpc_task 和 tmc_task。
Idle 任务没什么好解释的,目前这个任务为空,什么也没做,dpc_task 目前不知道是做什么的,暂时
可以不用管。前面的这两个任务都属于操作系统层面的,由操作系统来维护,和手机软件关系不大。哪一
个和手机软件关系大呢?答案是:tmc_task。大家可以把这个当作操作系统的入口(主)任务,也可以把它
当作整个手机软件的入口任务。即 AMSS 软件里的所有其它任务的创建和维护就是由这个 tmc_task 来完成
的。
到此为止,整个 AMSS 软件还并没有跑起来,只是跑到了 tmc_task 里面了。在 tmc_task 里面,会调用
tmc_init()来完成整个 AMSS 软件包的初始化工作,其中最重要的一项工作就是调用 tmc_define_tasks()将
AMSS 软件包所有需要的任务都创建起来了。比如说 slee_task、dog_task、cm_task、wms_task、ui_task
等。这些任务,一般不需要直接和 AL 层软件打交道,但请大家记住,手机上所有功能的实现最根本点就是
由这些服务组件(Service Task)来完成的。将来大家跟踪一个具体的功能模块时,比如说通话模块,如果
需要,可以再去深入研究它的具体实现。
好了,到现在为止,所有的 AMSS 核心软件就全部跑起来了(手机的功能模块,在软件方面就体现为
OS 层面的一个任务)。但现在大家还根本看不到 Brew 和 AEE 的影子。呵呵,各位不要急。到了这个层面
之后,我想稍微多说几句。最早的 Qualcomm 平台,比如说 5xxx 系列,是根本没有 Brew 的,那个时候的
AL(Application Layer)层软件开发,是直接调用底层 Service task 所提供的 API 来完成相应的工作的。从
这种角度来看的话,显然那时的开发是比较郁闷和难度较高的。不过,到了 65xx 之后,Qualcomm 平台引
入了 Brew,手机开发商就没必要去从这么底层(Service API)的层面进行手机开发了,他们完全可以基于
Brew 来实现一台手机的所有功能(Qualcomm 给我们的参考代码,就是全 Brew 平台的)。
Brew 的运行环境 AEE 是如何跑起来的呢?关键在于 ui_task(),由于 ui_task 和我们手机开发的关系非
常密切,其地位也相当重要,所以,后文我将单独对它进行一个深入的研究与分析。到目前为止,大家只