一、建立编译环境
(1)、参考google官方提供的说明:http://source.android.com/source/initializing.html
#apt-get install qemu-user-static debootstrap emdebian-archive-keyring libusb-1.0-0-dev pkg-config libncurses5-dev rpm
# sudo apt-get install git gnupg flex bison gperf build-essential \
zip curl libc6-dev libncurses5-dev:i386 x11proto-core-dev \
libx11-dev:i386 libreadline6-dev:i386 libgl1-mesa-glx:i386 \
libgl1-mesa-dev g++-multilib mingw32 tofrodos \
python-markdown libxml2-utils xsltproc zlib1g-dev:i386 lunch python-lunch
# sudo ln -s /usr/lib/i386-linux-gnu/mesa/libGL.so.1 /usr/lib/i386-linux-gnu/libGL.so
(2)、安装JDK:jdk1.6
进入/usr/lib/jvm/解压,配置/etc/profile、/etc/environment
#gedit /etc/profile
#gedit /etc/environment
分别在文件最底下添加:
export JAVA_HOME=/usr/lib/jvm/jdk1.6.0_33
export JRE_HOME=$JAVA_HOME/jre
export PATH=$JAVA_HOME/bin:$JRE_HOME/bin:$PATH
export CLASSPATH=.:$JAVA_HOME/lib/:$JRE_HOME/lib:$CLASEEPATH
然后,
#update-alternatives --install /usr/bin/java java /usr/lib/jvm/jdk1.6.0_33/bin/java 300
#update-alternatives --install /usr/bin/javac javac /usr/lib/jvm/jdk1.6.0_33/bin/javac 300
#update-alternatives --install /usr/bin/jar jar /usr/lib/jvm/jdk1.6.0_33/bin/jar 300
#update-alternatives --install /usr/bin/javah javah /usr/lib/jvm/jdk1.6.0_33/bin/javah 300
#update-alternatives --install /usr/bin/javap javap /usr/lib/jvm/jdk1.6.0_33/bin/javap 300
#update-alternatives --install /usr/bin/javadoc javadoc /usr/lib/jvm/jdk1.6.0_33/bin \
/javadoc 300
#update-alternatives --config java
#update-alternatives --config javac
#ln -s /usr/lib/jvm/jdk1.6.0_33/bin/jar /bin/jar
#ln -s /usr/lib/jvm/jdk1.6.0_33/bin/java /bin/java
#ln -s /usr/lib/jvm/jdk1.6.0_33/bin/javac /bin/javac
#ln -s /usr/lib/jvm/jdk1.6.0_33/bin/javah /bin/javah
#ln -s /usr/lib/jvm/jdk1.6.0_33/bin/javadoc /bin/javadoc
(3)、为了保证能成功编译,我们修改一下swap分区的大小。
#free -m
以M为单位查看swap的大小。
#mkdir /swap
#cd swap
#dd if=/dev/zero of=swapfile bs=1024 count=2000000
创建一个2g的分区
#mkswap swapfile
#swapon swapfile
转化并激活swap分区文件。要每次开机都生效,需要修改/etc/fstab文件,添加:
/swap/swapfile swap swap defaults 0 0
取消分区要执行:
#swapoff swapfile
二、编译
(1)、官网下载A20-android-4.2.tar.xz
解压:
# xz -d A20-android-4.2.tar.xz
#tar xvf A20-android-4.2.tar
(2)、官方推荐64bit系统编译。
(如果是32bit的系统的话,则要更改好几个Android.mk文件)
gcc版本问题,需要降为4.4:
#apt-get install gcc-4.4
#apt-get install g++-4.4
到/usr/bin目录下查看gcc的连接情况:
#ls -l gcc*
然后备份和修改连接:
#mv gcc gcc.bak
#ln -s gcc-4.4 gcc
#gcc -v
g++和gcc执行同样的操作。
最后还需要安装:
#apt-get install g++-4.4-multilib
#apt-get install libc6-dev-i386
(3)、http://linux-sunxi.org/A20-Cubieboard/Building_your_own_Android_image
编译lichee,通过执行buildroot目录下的脚本,编译了uboot和kernel,也得到了交叉 编译工具。Lichee目录下,
#./build.sh -p sun7i_android
首次编译按照上述方式,如果修改了kernel配置,需要执行:
#cd linux3.3
#rm .config
然后再在lichee目录下,按照上述操作执行即可。
根据buildroot/scripts/mkcommon.sh中的解析可以有如下命令
./build.sh -p sun7i_android -m boot
./build.sh -p sun7i_android -m buildroot
./build.sh -p sun7i_android -m kernel
./build.sh -p sun7i_android -m uboot
./build.sh -p sun7i_android -m clean
./build.sh -p sun7i_android -m mrproer
./build.sh -p sun7i_android -m distclean
单独编译。
(4)、编译android:进入目录
#source build/envsetup.sh
#lunch
#extract-bsp
#make -j8 //(虚拟机make单核执行,时间虽长但不会老出错)
将会在out/target/product/sun7i-xxx/目录下生成boot.img、recovery.img、system.img三个文件镜像。Boot.img包括kernel和ramdisk,system.img为系统文件
(5)、打包固件。
A、完全打包。执行以下操作:
#pack
打包成功后,将会在lichee/tools/pack目录下生成sun7i_android_xxx.img镜像文件。
B、单独打包。
Boot.img镜像中包含kernel和内存盘ramdisk。如果内核或者ramdisk.img有改动,android目录下执行如下命令,打包生成boot.img文件
#source build/envsetup.sh
#lunch
#extract-bsp
#make bootimage
类似方法可以打包生成system.img文件
#source build/envsetup.sh
#lunch
#extract-bsp
#make systemimage-nodeps //make snod
************************************************
************************************************
#make bootimage
指令用到了 mkbootimg工具,源码在android目录下的/system/core/mkbootimg/下,
mkbootimg.c中。
Boot.img由:
** +-----------------+
** | boot header | 1 page
** +-----------------+
** | kernel | n pages
** +-----------------+
** | ramdisk | m pages
** +-----------------+
** | second stage | o pages
** +-----------------+
组成。out/target/product/sugar-cubieboard2下的ramdisk.img的解压指令:
#mkdir demo
#mv ramdisk.img demo/ramdisk.img.gz
#gunzip ramdisk.img.gz
#cpio -i -F ramdisk.img
解压出来的文件,和out/target/product/sugar-cubieboard2/root是一样的,ramdisk就是由这目录下的文件打包生成的,打包指令:
#find . |cpio -ov -H newc |gzip > ../ramdisk.img
如果修改root下文件,先打包成ramdisk后,再按照上述方式打包生成新的boot.img
Ps:ramdisk的使用有两种方法:1、编译进内核; 2、将ramdisk单独烧写。
A、全志A20 采用第一种方式。android bsp编译生成boot.img、recovery.img、system.img等文件。make bootimage,把ramdisk打包进kernel,生成boot.img镜像文件。所以我们的系统固件由uboot、boot.img、system.img、userdata.img组成。
B、三星X210II开发板,采用的是第二种方式。固件由uboot、zImage、x210.img。
X210.img的生成过程:
分别把out/target/product/x210/下的system/和data/目录下的文件对应拷贝到root目录下的system和data文件目录下,然后打包root目录:
#find . |cpio -ov -H newc |gzip > ../ramdisk.img
还得使用mkimage工具添加uboot字头,打包成uboot格式的ramdisk文件:
#mkimage -A arm -O linux -T ramdisk -C none -a 0x30800000 -n "ramdisk" -d ramdisk.img x210.img
详情看BSP包中的脚本文件(ramdisk.sh)。
三、固件烧写
1、 使用PhoenixSuit或者PhoenixCard,前一种烧写到nand中,后一种烧写到TF卡中。 PhoenixCard:卡启动 是直接从卡启动;卡量产 是把所有数据拷贝到nand,然后重新 开机会从nand启动。
2、 使用fastboot烧写。Fastboot烧写,需要进入uboot界面,从PC端串口命令行输入fastboot, 进入此模式。然后,通过PC端的fastboot工具烧录各个固件包(windows下的 一个工 具,android sdk中有),把fastboot.exe添加到PC windows的环境变量中。进入 CMD,到固件的文件目录下执行以下操作:
#fastboot erase boot
#fastboot erase system
#fastboot erase data
#fastboot flash boot boot.img
#fastboot flash system system.img
#fastboot flash data data.img
还可以使用以下方式,单独烧写boot.img:
> adb push Z:\boot.img /mnt/sdcard/
> adb shell sync
> adb shell dd if=/mnt/sdcard/boot.img of=/dev/block/nandc
> adb shell sync
> adb shell reboot
3、PC端执行:fastboot flash system system.img时,出现错误
fastboot FAILED<remote:data too large,larger than buffer>
android源码fastboot有个小bug,只需要重新编译主机上的fastboot就可以了.
main 文件在android42/system/core/fastboot/fastboot.c中
--> fb_download_data 文件在android42/system/core/fastboot/protocol.c中
中将 sprintf(cmd, "download:%08x", size);
改为 sprintf(cmd, "download:%08x:", size);
即后面随便加上一个除[0-9][a-f]外的一个字符,这样板子上的fastboot在解析cmd时就不会弄错了
四、系统定制
因全志原厂IC的优化和高度集成性,使得在大多数开发者在定制驱动方面更为方便和简化,如常规驱动开发,只需要配置好sys_config1.fex文件,即可满足用户的绝大部分需求,所以用户如需开发和定制驱动,必需详细参考和阅读本章内容。
sys_config1.fex文件是对单板一些相关功能的配置文件。通过对此文件的修改,可配置模块驱动功能的使能、关闭,以及其他参数的设置。可根据自己的硬件模块的实际情况进行配置和修改,即可实现相应的驱动功能。如还不能满足用户的需求,需要进一步深入和研究,定制自己的风格,请参考原厂IC的(A20 User manual--2011.11.17.pdf)。此文档新航道论坛中可下载。
sys_config.fex文件的实际路径:
lichee/tools/pack/chips/sun7i/configs/android/sugar-cubieboard2/
1、GPIO配置举例:
gpio_pin_1=port:PH20<1><default><default><1>
即:Port:端口+组内序号<功能分配><内部电阻状态><驱动能力><输出电平状态>
参数作用及意义:
功能分配:标识着当前GPIO被配置为什么功能。GPIO大多都是复用
内置电阻:使用0,表示内部电阻高阻态;1的话为内部电阻上拉;2就表示 内部电阻下拉。使用default的话,代表默认状态,即电阻上拉。
驱动能力:表示提供给当前GPIO的能力水平,也就是电流大小。这个值越大, 驱动能力越大。Default表示驱动能力为1。
电平状态:0表示输出低电平,1为高电平。
[gpio _para]
gpio_used=1
gpio_num=2
gpio_pin_1=port:PH20<1><default><default><1>
gpio_pin_2=port:PH19<1><default><default><1>
修改后重新打包镜像文件,进入android目录:
#source build/envsetup.sh
#lunch
#extract-bsp
#pack
也可以,不重新编译,需要fex2bin and bin2fex:
$ git clone git://github.com/linux-sunxi/sunxi-tools.git
$ cd sunxi-tools
$ make
$ With the using of ls, you can find the fex2bin and bin2fex.
从开发板上把script.bin拷贝下来:
$ adb shell
$ mkdir /mnt/tmp
$ mount -t vfat /dev/block/nanda /mnt/tmp
$ exit
$ adb pull /mnt/tmp/script.bin
把script.bin转换为script.fex格式文件,
$ chmod 777 script.bin
$ ./bin2fex script.bin > ./script.fex
$ gedit script.fex
现在就可以编辑修改或者替换script.fex文件了。最后把script.fex转换为script.bin格式 文件,上传到开发板中:
$ ./fex2bin script.fex > ./script.bin
$ adb push script.bin /mnt/tmp
$ adb shell
$ umount /mnt/tmp
$ reboot
2、测试GPIO。/sys/class/gpio下可以看到相关编号分布信息,也就是各个GPIO段的首个编 号,如gpiochip0、gpiochip24、gpiochip54、gpiochip85等,引脚编号按照如下分配的:
想看到gpiochip**对应哪个引脚的GPIO,可以cat /sys/class/gpiochip**/label。比如激活PH20,执行:
#echo 187 > /sys/class/gpio/export
就可以看到多出来一个gpio_ph20目录。
设置引脚模式:echo out > /sys/class/gpio/gpio1_ph20/direction
也可以输入对应:input(“Low”),output(“High”)
设置电平状态:echo 1 > /sys/class/gpio/gpio1_ph20/value
五、调试
1、调试修改kernel后,到lichee目录下重新编译内核
#./build.sh -p sun7i_android
此方式,不仅编译了kernel还编译了uboot,及安装交叉编译器
首次编译建议采用以上方式,以后编译的话,跳到linux-3.3目录下:
#rm .config
#make clean
#make ARCH=ARM CROSS_COMPILE=arm-linux-gnueabihf- uImage
如果不想每次都输入这么长,就得修改目录下的Makefile文件,修改一下两项:
ARCH=ARM
CROSS_COMPILE=arm-linux-gnueabihf-
最后,在android目录下执行以下命令,打包生成boot.img
#source build/envsetup.sh
#lunch
#extract-bsp
#make bootimage
生成新的boot.img,通过fastboot工具刷到板子上。
2、Ubuntu下交叉编译纯C应用程序:
安装交叉编译工具,把toolchain加入PATH环境变量:
/ct-droid1/lichee/out/android/common/buildroot/external-toolchain/bin
修改/etc/environment,添加上述链接就行。
或者解压buildroot/dl下的
arm-2010.09-50-arm-none-linux-gnueabi-i686-pc-linux-gnu.tar.bz2
到/usr/local/arm下:
#tar xjvf arm-2010.09-50-arm-none-linux-gnueabi-i686-pc-linux-gnu.tar.bz2 -C /usr/local/arm
把toolchain加入PATH环境变量,一种方式是:
#export PATH=.:/usr/local/arm/arm-2010.09/bin:$PATH
#source /etc/profile
可通过以下命令查看:
#echo $PATH
第二种方式是:
#gedit /etc/environment
然后加入
:/usr/local/arm/arm-2010.09/bin
#source /etc/environment
之后可以通过命令查看以上两种方式是否安装正确:
#arm-none-linux-gnueabi-gcc -v //查看路径及版本
以后编译应用程序(不带jni),就可以使用arm-none-linux-gnueabi-gcc test.c -o test
3、 修改android的system后,重新打包system.img文件
Android目录下:
#make snod
4、调试APK:
#source build/envsetup.sh
#lunch
#cd packages/apps/Gallery2
#mm
生成的apk在out/target/product/sugar-cubieboard2/data/app/Gallery2Tests.apk
然后在windows下使用adb上传到板子上:
adb push Gallery2Tests.apk /system/app
打包的话,采用以上方法。
补充点:
mm用于编译当前目录下的工程
mmm用于编译指定目录
adb shell - 登录设备shell,后面也可直接跟运行命令。如:adb shell rm -r /system/sd/app
adb pull - 从手机中下载文件到电脑上。如:adb pull /data/app_s/Stock.apk C:\\Stock.apk
adb push - 从电脑中上传文件到手机上。如:adb push C:\\Stock.apk /data/app_s/Stock.apk
adb install - 安装软件到手机上。如:adb install C:\\apps2sd.apk
adb uninstall - 卸载手机上的软件。如:adb uninstall linda.apk
mount -o remount,rw /system
5、内核中编译的模块,全被复制到以下目录中,供android后加载这些模块,提高启动速度: /out/target/product/sugar-cubieboard2/system/vendor/modules