i.MX51平台的Android系统移植

2013-10-11 06:23郭利全谢维波
关键词:宿主机源码镜像

郭利全,谢维波

(1.华侨大学 计算机科学与技术学院,福建 厦门361021;

2.华侨大学 厦门软件园嵌入式技术开放实验室,福建 厦门361008)

近年来,随着经济的高速增长及科学技术的突飞猛进,人们的生活质量和生活水平有了显著地提高,智能手机逐渐走进了人们的生活.智能手机可以方便地获取互联网信息,带来高端的服务与享受.除苹果系列使用其专用的IOS操作系统外,其他智能手机大多使用Android操作系统.Android系统具有代码开源、兼容性好、系统可移植等特点,还具有界面美观、应用软件开发简单、音视频解码库齐全等优势.Android系统的优势使其在硬件平台的移植显得非常必要,将Android系统移植到非手机硬件平台具有巨大的商业价值.i.MX51平台是由美国Freescale公司自主研发的,中央处理器基于ARM Cortex A8核心的i.MX51处理器,主频可扩展到1GHz.Android操作系统在i.MX51平台上能良好地运行,这为Android系统的移植奠定了硬件基础.本文对i.MX51平台上的Android系统移植进行研究.

1 Android系统启动流程

1.1 Android与嵌入式Linux

Android系统是基于Linux内核搭建的,Linux内核的优势在于大内存管理、进程管理、基于权限的安全模型、统一的驱动模型、对共享库的支持和代码开源等.Android系统在设计过程之中针对移动终端资源有限的特点,对Linux进行了一定程度地裁剪,去除了原生的窗口系统、对GUN libc的支持,并裁剪了一些标准的Linux工具.针对移动终端的特点,对内核在闹钟、内核调试、进程间通信、日志、电源管理等方面作了大量地优化.Android使用Linux完成其内存管理、进程管理、网络和其他服务工作,应用程序不会直接进行Linux的调用,但Linux在Android中的确存在[1].

1.2 Android系统启动流程

Android可以作为嵌入式系统的软件操作系统.Bootloader是嵌入式系统的引导加载程序,也是系统上电后运行的第一段程序,它除了完成基本的初始化系统和调用Linux内核的基本任务外,还对Linux的启动参数进行设置.Bootloader最后一项任务是调用Linux内核.

Linux内核一般存放于flash或SD卡中,但由于内核在flash中执行时代码会有限制,而且速度还没有在RAM中快,所以一般在嵌入式系统中都是将Linux内核解压到RAM中,然后跳转到RAM中去执行.Linux内核启动完成后,会创建init进程,而init进程首先进行一系列硬件初始化,然后通过命令行传递的参数挂载根文件系统.根文件系统包含系统引导和使其他文件系统得以挂载所必需的文件,也包括Linux启动时所必需的目录和关键性的文件.

Android系统自下而上分为linux内核及驱动层、系统运行库和java运行环境层、应用程序框架层、应用层[2].应用程序框架层包括有java层和jni层,jni是Android程序访问硬件抽象层的一种手段.Android系统底层采用Linux2.6内核,Android系统的启动包括Linux启动的全过程.在Linux启动init进程后,init进程根据init.rc脚本文件建立起servicemanamger和zygote等最基本的服务,其中servicemanamger的功能是管理系统中各种服务,zygote的功能是建立java程序运行时的环境并启动虚拟机,初始化建立的基本服务都是运行在java运行环境层的本地服务.zygote启动虚拟机后,建立systemserver进程,systemserver是Android java层的系统服务模块,主要功能是管理供Android应用开发的系统服务,最后由system server建立Android应用层要使用的服务,包括Home Activity启动所需的Activity Manager.

Android系统启动流程,如图1所示.由图1可知:Android系统的启动是以Linux启动为基础,Android系统的移植包含有Linux系统的移植.嵌入式Linux的移植包括bootloader,Linux内核、根文件系统3大部分移植[3].Android系统的移植除上述移植外,还必须进行system.img,recover.img,userdata.img等镜像的移植[4].

图1 Android系统启动流程图Fig.1 Android system startup flowchart

2 软硬件平台的搭建

由于硬件平台的特殊性及局限性,在此选用交叉开发模式[5].交叉开发模式是指Linux交叉开发采用宿主机和目标机模式进行,宿主机是一台运行Linux的个人计算机,目标机为嵌入式硬件平台.开发时使用宿主机上的交叉编译、汇编及连接工具,形成可以在目标机上执行的二进制代码,这种代码并不能在宿主机上执行,而只能在目标机上执行,然后把可执行文件下载到目标机上运行.调试时可以通过串口、以太网口等进行.

本次移植过程中,宿主机为计算机,操作系统为federa 13,在宿主机上下载u-boot,Linux 2.6内核、Android源代码,并进行交叉编译.为了支持EABI,交叉编译工具采用arm-none-Linux-gnueabi工具链.引导程序选用u-boot,Linux内核版本采用linx-2.6.31.14,Android系统版本采用froyo.编译好镜像后使用ATK工具通过串口进行镜像的烧写.

3 Android系统的移植

Android系统具有可移植性.可移植性指的是在一定程度上,软部件从一种环境迁移到另一种环境后还能正常工作的能力.Android系统的移植需要经历源码的获取、源码裁剪、交叉编译源码、下载镜像这四个步骤[6].

3.1 源码的获取

源码的获取使用git工具.git是为了帮助管理Linux内核开发而开发的一个开放源码的分布式版本控制软件.尽管开发之初是为了辅助Linux内核开发,但现在包括Android在内的很多其他自由开源软件项目也使用了git.

Android是由kernel,Dalvik,Bionic,prebuilt等多个git项目组成,Android项目编写了一个名为repo的Python脚本统一管理这些项目使git的使用更加简单.Android源码的获取分为以下5个步骤.

1)yum install git,安装git工具.

2)curl https:∥dl-ssl.google.com/dl/googlesource/git-repo/repo〉~/bin/repo下载repo脚本.3)chmod a+x~/bin/repo改变下载后的repo权限,使其可以直接被运行.

4)repo init-u https:∥android.googlesource.com/platform/manifest-b froyo.由于 Android现在的版本为4.0,本次移植工作使用的版本为2.2.使用这条语句从服务器端的master主分支中切换参数“-b”后面指定版本分支.

5)repo sync-j4.由于repo sync是从源码服务器上进行下载,Android源码一般在10GB左右.由于执行时间比较长,可以使用多线程来并行下载,使用参数“-j4”,4是并行的线程数.

Android源码目录及各目录包含的内容,如表1所示.

表1 Android源码目录及作用Tab.1 Android source code directory role

获取Android源码后,接着获取u-boot及Linux内核源码.在Linux shell终端输入以下git命令.git clone git:∥git.denx.de/u-boot.git uboot-imx获取u-boot源码保存至uboot-imx目录.

git clone git:∥git.kernel.org/pub/scm/Linux/kernel/git/stable/Linux-2.6.31.y.git kernel_imx获取Linux内核源码,保存至kernel_imx文件夹中.

3.2 Linux内核裁剪

Linux内核的裁剪是移植工作重要的环节,不同的硬件厂商,裁剪的方式各不相同.每个硬件厂商都会提供硬件的板级支持包(即BSP).BSP可以屏蔽硬件,提供操作系统及硬件的驱动.本文使用板级支持包加速对Linux内核裁剪工作.

i.MX51的硬件支持包是以补丁文件的形式存在.BSP包下载地址为http:∥www.freescale.com.将Linux内核拷贝到Android源码同一级目录,对源码打上补丁,即可完成对Linux内核的裁剪.裁剪流程有如下2个步骤.

1).imx-android-r9.2/code/r9.2/android_pach.sh.运行支持包中的bash文件,设定环境变量.

2)c_patch imx-android-r9.2/code/r9.2imx_r9.2.使用支持包为源码打补丁.

裁剪后的Linux源码增加了对i.mx51处理器的支持,源码位于kernel/arch/arm/mach-mx5目录下;对共享内存处理方式上进行了改变,增加kernel/mm/ashmem.c文件,它为进程间提供大块内存,同时为内核提供管理和回收这些内存的机制;在驱动程序中增加了mxc目录,包括对Android相关的驱动的支持,如IPC系统、日志系统、电源、闹钟管理、内存控制台、时钟控制的gpio,switch驱动等,也包括如图像处理单元iPU,视频处理单元VPU等驱动.

3.3 源码的编译

下载arm-none-linux-gnueabi交叉编译工具链,将其bin目录加入PATH环境变量.Android源码的编译过程有如下3个步骤.

1).build/envsetup.sh使用envsetup.sh脚本初始化环境变量.

2)lunch imx51_bbg-eng完整编译在imx51平台运行,使能所有的调试方法.

3)make-j4使用make命令进行编译.采用4个线程的多线程编译方式.编译源码的配置情况,如图2所示.

由图2可知:Android的版本为2.2.1,宿主机为Linux操作系统x86CPU,目标机为arm型CPU.对源码的编译配置通过指定参数进行,本次配置参数为imx51_bbg-eng,参数含义如表2~3所示.

图2 Android源码编译配置Fig.2 Android source code compiled configuration

表2 平台参数说明Tab.2 Parameter description of platform

表3 BUILDTYPE参数说明Tab.3 Parameter description of BUILDTYPE

3.4 镜像的烧写

Android系统源码编译完成后,在out文件夹下会生成对应的镜像文件,包括system.img,userdata.img,ramdisk.img等镜像.system.img包括了主要的包、库等文件;userdata.img包括了一些用户数据;ramdisk.img是emulator的文件系统,emulator加载这3个镜像文件后,会把system.img和userdata.img分别加载到ramdisk文件系统中的system和userdata目录下,ramdisk.img在文件系统中解压后为root目录,其中包括了init,init.rc等文件.ATK是Freescale公司开发出的一款针对MX系列CPU为核心的flash、SD卡烧录软件,可以用来烧录bootloader和kernel到SD卡上.本次移植过程中使用ATK工具通过串口进行烧写镜像.

使用ATK工具将u-boot,kernel,ramdisk.img镜像烧写到SD卡上,烧写的起始地址分别为1K,1 M,4M的地址处.使用Linux中的fdisk命令对SD卡进行分区.分区时不应将u-boot和kenel划入任何1个分区,第1个分区从10MB的位置开始划分.分区后,各分区的文件系统信息及分区大小设计,如表4所示.

表4 SD卡分区说明Tab.4 Partition description of SD card

在宿主机上,使用dd命令将system.img及recovery.img拷贝到sd2,sd6分区,拷贝的步骤如下:

经过以上的过程,Android系统平台运行所需的全部文件都已经烧写到SD卡上.SD卡上存储区域分布,如图3所示.图3中:MBR主要是存储SD卡的分区信息,起始地址为0kB.

由图3可知:第一个分区(Media分区)从大于10MB的位置开始划分,可避免MBR、引导程序、内核、根文件系统在分区中因误操作而被破坏的情况发生,保证系统正常启动.

图3 SD卡存储区域分布图Fig.3 Storage area maps of SD card

4 Android系统的调试

Linux内核开发者为保证内核代码正确性,不愿在Linux内核源代码中加入调试器.内核调试可采用监视内核代码和错误跟踪的方法.对Android的调试方法包括Linux方法和Android特殊方法.标准Linux调试有如下3个方法.

1)启动Android仿真器环境,使用adb shell进行连接,在终端使用ps查看系统各个进程.也可以使用linux的proc文件系统跟踪进程相关信息.

2)使用Linux的vmstat和top命令统计系统中性能的信息.

3)使用dmesg查看内核打印出来的信息,可以方便地跟踪内核状态信息.

Android的toolbox中包含了一些非标准化的辅助命令,这些命令在Linux的Shell中没有,专为Andorid系统所使用.Android特殊调试命令有如下4个方法.

1)使用netcfg命令进行网络配置调试,可用于检查Android系统的网络状况.

2)使用service命令获取Android系统已经启动的服务,显示某一个服务调用进程的情况.

3)Android的am命令可以在控制台启动和管理活动、服务和发送广播等.

4)对基于Android系统的程序开发,使用logcat命令可以方便得到程序的log信息.

5 实现效果

Android系统在i.MX51平台移植完成并调试成功后,将开发板上的启动模式设置成从SD卡引导.串口调试信息,如图4所示.

图4 Android OS串口打印信息图Fig.4 Serial print of Android OS

从启动信息中可以看出,u-boot先从MBR中读取分区信息,将Linux镜像解压到RAM地址为0x9000800处,将Android镜像解压到地址为0x90308000处.启动信息中也包括了CPU信息、内核版本、大小、Android文件系统版本等信息.Android平台在i.MX51平台启动后,其程序测试效果图如图5所示.

6 结论

随着嵌入式技术的发展,嵌入式系统的软件从只有前后台程序,发展到使用μC/OS-Ⅱ等小型操作系统,再发展到现在应用如Linux,WinCE等大型操作系统.Android系统是目前最前沿的嵌入式操作系统,虽然设计之初只是针对手机等移动平台,但在其他非手机硬件平台的应用已经成为一种趋势.只有将最前沿的嵌入式操作系统与硬件平台相结合,嵌入式系统才会更具生命力和竞争力.

所介绍的Android系统在i.MX51平台的移植过程及调试方法,对Android系统在其他嵌入式平台的移植具有指导意义.然而,由于对Linux内核裁剪部分使用的是i.MX51的板级支持包,在其他硬件平台的移植应使用相应的板级支持包,有一定的局限性,也是移植工作的不足,有待今后进一步提高.

图5 Android程序测试效果图Fig.5 Effect diagram of Android application test

[1] 王茜.Android嵌入式系统架构及内核浅析[J].电脑开发与应用,2011,24(4):59-61.

[2] 李凯.Android操作系统分析与移植[D].广州:华南理工大学,2011:59-61.

[3] 曹木莲,姚放吾.基于i.MX21的嵌入式Linux研究与移植[J].计算机技术与发展,2009,19(9):97-98.

[4] ABHYUDAI S,SOMYA L.Android porting concepts[C]∥Proceedings of 3rd International Conference on Electronics Computer Technology.Kanyakumari:[s.n.],2011:129-133.

[5] 孙纪坤,张小全.嵌入式Linux系统开发技术详解[M].北京:人民邮电出版社,2007:129-132.

[6] 韩超,梁泉.Android系统级深入开发-移植与调试[M].北京:电子工业出版社,2011:70-72.

猜你喜欢
宿主机源码镜像
面向数据可靠传输的高译码率带反馈的LT码
国内一站式工程设备租赁平台众能联合完成C2、C3两轮融资
浅谈开源操作系统的历史
镜像
企业如何保护源码
嵌入式计算机软件测试关键技术研究
镜像
虚拟网络实验室在农村职校计算机网络技术教学中的应用研究
镜像