Qualcomm 的平台软件支持两种启动方式:一种是Nor Flash启动方式,另外一种就是Nand Flash启动方式.Nor Flash 启动方式就相当于硬件直接找到一个入口点开始执行代码,Nand Flash启动方式和PC的启动方式比较相像.
本文主要针对Nand Flash方式进行分析。
按下开机键之后,将产生一个时钟中断,从而通知AMSS主芯片的BootLoad硬件去将放置于Nand Flash上面的第一个Block(8K)里面的Boot代码拷贝到内核内存(RAM,这是CPU自带的内存,同后面提到的SDRAM有一定的区别,可以把它当作CPU的Cache)的0xFFFF0000地址,并开始执行Boot代码。
Boot的主要任务是完成整个系统的硬件初始化工作(类似于PC上面的BIOS所完成的硬件自检工作)。Boot所完成的工作里,最重要的一件事就是会将整个手机软件代码(AMSS软件包)拷贝到SDRAM中,并将控制权交给AMSS软件。代码的执行点将由Boot跳转到AMSS软件的入口函数main()(此函数在mobile.c里实现)。
代码运行到了Main()之后,在这个函数里面将完成操作系统(rex)的初始化工作,其实现方法是调用rex_init()。
rex_init()要完成的工作很简单:
1)完成操作系统必要的一些数据结构(timer链表,task链表等)的初始化之外;
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的影子。Brew的运行环境AEE是如何跑起来的呢?关键在于ui_task(),由于ui_task和手机开发的关系非常密切,其地位也相当重要。现在我们只知道ui_task将AEE加载起来了,并且,它起到了一个中间层的作用,即所有AMSS底层服务组件的消息,都将经由ui_task而转到AEE,并最终转到具体的App(Applet)的执行代码里面(HandleEvent())。
注意:
1)上述的开机过程,在每一次按开机键都需要走一遍,即关机之后,整个系统的所有功能都将消失,而不像有些手机,看起来是关了机,但实际上底层还是有一些软件模块在跑。为什么可以肯定地说上述开机过程每次都必须走一遍?原因是因为我们的平台软件是基于nand flash启动的,所有的代码都需要拷贝到SDRAM才能运行,而关机断电之后,SDRAM里的东东会全部丢失,所以,毫无疑问,上述过程必须每次开机都要执行。
2)关机的过程相对比较简单,系统检测到关机中断之后,将调用tmc_powerdown_handler()来完成关机动作,它将把所有AMSS的任务都Stop掉,并最后调用rex_exit()退出Rex,从而完成整个关机动作。
3)显然,关机动作前,如果有必要,每个任务必须将它希望保存的信息保存到Flash上面,以便下次开机时可以得到这些信息;
开机流程简图:
说明:
1)Tmc是操作系统层和AMSS软件关系对密切的一个任务,不过需要OEM此处修改的地方应该不多;
2)ui_task是才操作系统层OEM需要重点研究的一个任务,它是连接底层Task和上层AL的一个中间层,有可能需要加入OEM的操作流程;
3)CoreApp是在Brew层的一个AL层的入口Applet,它起着管理整个上层AL层软件的作用,根据产品需求,这个App需要定做;
4)AEE是整个上层App的运行环境。