学习Android系统移植已经一年有余,至今也未能学得精髓,android的博大精深大家皆知,前面的路还很漫长,还等着我们继续前行。根据前期所学以及参与项目实战获取到的经验,把自己所掌握的,所理解的记录成文,一来算是对所学知识的一个总结,二来给刚开始研究Android系统移植的同行以及爱好者提供参考。文中若有不对的地方还请批评指正,共同探讨学习,不胜感激。
一、Android系统运行的硬件前提
一个系统要想运行,必然要有硬件的支持。而并非所有硬件都是必须的,只需保证三大必备硬件,系统即可正常运行。这三大硬件就是CPU+PMIC+Memory,当然现在可能很多处理器内部已集成有PMIC和Memory,那只需要一个CPU硬件系统即可运行,但这几个模块都是不可或缺的。相信各位都有一定计算机及电子知识,此处就不做详细讨论。
其实在项目开发中这种最小硬件系统经常使用,因为使用此方法可以更快速、准确的验证系统是否可运行,是否稳定,可以有效排除其他外设的干扰。以MTK平台开发为例,MTK会提供HW一个参考设计,同时也会Release给SW一包对应参考设计的Codebase。一个项目中HW对于这三大硬件的电路设计基本上会保留参考设计,所以SW基本上也就无需改动即可实现系统正常运行。因为MTK方案CPU和PMIC都是MTK自己的IC,基本上是固定搭配;通常会改动的就是Memory的型号,Memory会因为成本以及物料库存等因素而换用其他型号。但是目前Memory的接口统一,电路设计上不会有差别,而且换用的型号也都是MTK验证过的,通常不会有问题,所以对于硬件设计没有明显差异,只需在软件上更改配置或做兼容设计即可。
二、Android系统移植前期的主要工作
如前面所谈,要想保证Android系统正常运行,只需保证三大硬件正常工作即可。所以Android系统移植的主要工作就是围绕三大硬件展开。
(1) Memory配置
MTK平台Memory的配置较为简单,MTK对所验证过的Memory做了初始化部分兼容设计,对于我们来说基本上只需在Code中替换为项目实际使用的型号即可。当然一个项目一般会兼容多个型号的Memory,此时就要考虑多个Memory的兼容性,基本上只要EMMC ID(或NAND ID)不同即可实现兼容,更复杂的情况有专门的FAQ讲解。其次还有一个问题需要考虑就是MCP的分区大小(此处的分区并非我们平常讲的android的几个分区,而是MCP出厂时设定好的分区,如BOOT,RPMB,GP),因大多数MCP出厂时BOOT+RPMB+GP小于6MB,所以MTK将User分区起始地址设定在6MB处,但是还有可能一些型号的MCP三者之和大于6MB,这时就会导致系统不能开机,一直重启。这时就需要修改MTK 默认设置来兼容此中Memory。注:6592之后平台MTK采取新的算法来计算USER分区起始地址,不在存在此问题。
(2) GPIO配置
外设想要正常工作,GPIO的配置至关重要。GPIO的配置需要参考硬件电路图及HW提供的GPIO List,需要根据所连外设将GPIO配置为相应的模式。MTK提供了丰富的GPIO功能口和常用GPIO变量供用户选择使用。通常当GPIO配置为功能口时无需配置上下拉及输入输出,MTK会根据具体的功能口智能选择上下拉和输入输出,而且在程序中通常也无需指定使用的是哪几个GPIO,只需配置硬件使用的通讯方式即可,因为提供特定功能口的GPIO是固定的,并非所有GPIO都可作为此功能使用,程序会根据配置自动找到对应的GPIO。当GPIO作为普通的通用输入输出口使用时,需要根据具体的硬件功能来配置上下拉,输入输出模式等,在定义GPIO的变量时尽量使用系统提供的变量名,若找不到合适的变量名可以自己添加定义使用。
(3) PMIC配置
系统所有的电压源和电流源均来自于PMIC。PMIC是整个系统的动力来源,PMIC是否能正常工作直接影响到整个系统是否能正常WORK。既然PMIC如此重要,MTK为减少客户的工作量和工作难度,无论是在硬件上还是软件上都直接帮我们完成了大部分工作,留给我们要做的微乎及微。系统上比较重要的电源均是固定的链接,不能任意改动,只是留了部分PIN根据不同外设需要来配置为相应的电压。在使用电压可变的LDO时,需要注意的是,当需要切换电压时必须先下电再上电,否则会切换不成功。
三、Android系统移植的主要Porting工作
完成第二步的工作后即可实现最简系统的正常运行,此后就是将各功能模块的驱动程序移植进系统,使外设能够正常工作。各模块的Porting均可参考MTK提供的Driver AllIn One文档来完成,在此不做阐述。需要重点检查的两个点仍是GPIO配置和上电时序,只有确保这两点配置正确,Code的Porting才有意义。
四、MTK平台Android系统的组成
完成Android系统驱动移植之后,就可以编译出能够正常工作的系统镜像。生成的系统镜像主要有Preloader 、lk(uboot) 、bootimg 、systemimg 、cache 、userdata 等。在系统开机启动时,CPU内部固化的Bootloader会把preloader加载到CPU内部自带的SRAM中运行。Preloader主要完成Memory和PMIC的初始化,为后面加载lk提供运行环境。在lk阶段主要完成GPIO的初始化(即GPIO默认模式,其他模式在驱动中用到时还会再次配置)和LCM的初始化。Lk执行结束后会向kernel跳转,由kernel来完成各模块驱动的加载和初始化。再完成驱动模块的初始化后就开始为Android系统的运行做准备,此部分的工作由init来完成,init会根据不同启动模式来加载相应的init.rc脚本文件完成Android运行环境的初始化。
五、Android系统移植心得体会
在Android系统移植的过程中难免遇到各种各样的问题,如果能快速定位导致该问题的原因,将会大大节省我们的时间。经常使用的一个办法就是交叉验证来快速定位,若无法满足交叉验证,可以将改问题划分为几个大的模块,逐个排查,先锁定大的方向,再逐步细分,最终找到Root Cause。
六、结语
首先感谢各位耐心的阅读本文,因个人能力所限,部分地方个人理解可能存在差错,讲解可能不够清晰透彻,欢迎各位批评指正,多多补充。一个人的能力是有限的,后续的学习大家相互交流,共同探讨,大家才能够更快的成长。