freescale i.mx23平台上移植android2.2(2)

第二章:  编译kernel
    这部分主要是linux内核的配置与调试。各种板子因为设计不同需要做各种改动,其中就有各种驱动的调试,如USB,USB-otg,触摸屏,网络,按键等等。为了Android能跑起来,我们首要的还是触摸屏的调试。
    1:使用自带的toolchain进行linux的编译,并在板子上运行测试
        a) 配置toolchain
            1) ./ltib -m config 配置总体环境,Platform选择imx233,Toolchain选择4.1.2,其他的选择默认的即可。
            2) ./ltib -m prep -p kernel-2.6.31.spec,准备kernel的源文件。生成在rpm/BUILD/linux-2.6.31 ,
            3) cd rpm/BUILD ; mv linux-2.6.31 linux-2.6.31-imx233 ; 因为我们要修改kernel的内容,所以我们使用custom的kernel- source
            4) ./ltib -m config 重新配置kernel路径。将Kernel选项改为Local Linux directory build。将 Enter your Linux source directory 修改为你刚才改的那个路径(/home/lancer/freescale/ltib/ltib/rpm/BUILD/linux-2.6.31- imx233), 保存退出
            5) 如果你要修改kernel command line,请在./ltib -m config时,进入PackageList,修改相应。
            6) 如果你要对kernel选项进行设置,请在./ltib -m config时,将Configure the kernel选中。
            7) 配置完成后,你可以运行./ltib了,运行完成后就可以得到boot_steam和文件系统了。文件系统在rootfs目录下,rootfs.jffs2是打包好的jffs2格式文件系统。boot_stream在rootfs/boot 下。
            8) 在编译过程中,可能会遇到 .gvfs不能访问的错误,这是Ubuntu中gnome文件系统的一个东西,在你的家目录下。这个错误是不要紧的,忽略即可。
        b) 测试kernel
            1) 主要是用dd命令进行写操作。我写了一个脚本(burn_linux.sh)专门用于写boot_stream到sd卡中。可以在脚本所在目录直接运行 sudo ./burn_linux.sh。
                # burn_linux.sh start
                #imx23_linux=/home/lancer/freescale/ltib/ltib/rpm/BUILD/imx-bootlets-src-10.05.02/imx23_linux.sb
                imx23_linux=../../ltib/ltib/rootfs/boot/imx23_linux.sb
                echo "generate linux raw data."
                dd if=/dev/zero of=mmc_linux_partition.raw bs=512 count=4
                dd if=$imx23_linux of=mmc_linux_partition.raw ibs=512 seek=4 conv=sync,notrunc
                echo "write raw data to mmc card."
                size=$(find -name mmc_linux_partition.raw -printf %s)
                count=$(($size/512))
                dd if=/dev/zero of=/dev/mmcblk0p2 bs=512 count=10240
                sleep 1
                dd if=mmc_linux_partition.raw of=/dev/mmcblk0p2 bs=512 count=$count
                sync
                echo "finish write $count blocks"
                # burn_linux.sh end
            2) 你要是有兴趣也可以将uboot烧进去玩玩,这样对调试可能更方便,可以通过网络进行kernel下载。但我的板子因为usb及基于usb的 ethernet并没有调试通过,所以不能用uboot来下载。
            3) 将文件系统rootfs拷贝到/dev/mmcblk0p3分区中。
            4) 插入sd卡,上电。从串口中应该能进入shell了,触摸屏上应该也能看到东西了。
        c) 到目前为止,基本上没有编写代码。只是做做设置。
        d) 移植tslib,目的是为了得到pointercal文件中的触摸屏校准参数,用于android平台
            1) git clone https://github.com/kergoth/tslib.git
            2) configure tslib
                ./autogen
                export PATH=$PATH:/opt/freescale/usr/local/gcc-4.1.2-glibc-2.5-nptl-3/arm-none-linux-gnueabi/bin
                export CC=arm-none-linux-gnueabi-gcc
                export CPP=arm-none-linux-gnueabi-cpp
                ./configure --prefix=/usr/local/Trolltech/tslib --host=arm-linux --cache-file=arm-linux.cache --enable-debug
            3) make;make install
            4) 修改/usr/local/Trolltech/tslib/etc/ts.conf,打开module_raw input,即去掉module_raw input前的#和空格。注意module_raw input前不能有空格!
            5) 写一个脚本文件ts_env.sh,用于运行ts_calibrate前做环境设置
                # ts_env.sh start
                export TSLIB_ROOT=/usr/local/Trolltech/tslib
                export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$TSLIB_ROOT/lib
                export TSLIB_CONSOLEDEVICE=none
                export TSLIB_FBDEVICE=/dev/fb0
                export TSLIB_TSDEVICE=/dev/input/ts0
                export TSLIB_CONFFILE=$TSLIB_ROOT/etc/ts.conf
                export TSLIB_PLUGINDIR=$TSLIB_ROOT/lib/ts
                export TSLIB_CALIBFILE=$TSLIB_ROOT/etc/pointercal
                #used for qt
                export QWS_MOUSE_PROTO=Tslib:/dev/input/ts0
                # ts_env.sh end
            6) 将生成于/usr/local/Trolltech/tslib的文件拷贝到sd卡中文件系统的/usr/local/Trolltech/tslib 下,并启动机器即可运行/usr/local/Trolltech/tslib/bin下的测试程序
            7) 注意:我用的屏的驱动是linux-2.6.31-imx233/drivers/input/touchscreen/mxs-ts.c。这个驱动是不发送EV_KEY消息的,所以以上移植的tslib不能正常工作。
                vi tslib/plugins/input-raw.c
                找到check_fd函数,将下面这段代码#if 0掉
                #if 0
                    if ( (ioctl(ts->fd, EVIOCGBIT(0, sizeof(evbit)), evbit) < 0) ||
                        !(evbit[BIT_WORD(EV_ABS)] & BIT_MASK(EV_ABS)) ||
                        !(evbit[BIT_WORD(EV_KEY)] & BIT_MASK(EV_KEY)) ) {
                        fprintf(stderr, "tslib: Selected device is not a touchscreen (must support ABS and KEY event types)\n");
                        return -1;
                    }
                #endif
            8) 之后重新编译。运行ts_calibrate得到校准文件于/usr/local/Trolltech/tslib/etc/pointercal。此文件中数据将用于修改触摸屏驱动。
    2:使用android的toolchain进行linux的编译 (这个部分对于上一步没有修改过boot_stream的人来所有点问题,请参考本文后备注)
        为什么要用android的toolchain来编译内核,而不用ltib自带的编译器? 我曾尝试用ltib自带的编译器来编译android的init,在修改及增加了很多��码的基础上,总算是通过了。然后将init放到rootfs的 sbin/目录下,希望能init成功,可是第一句打印也出不来。在做了更多的尝试之后,对这个方式失去了信心。故而产生了用android的 toolchain来编译linux内核的想法,因为内核是不需要c库支持的,并且android所用的编译器是armv5te的,与i.mx233吻合,这个想法最后成功了。等有时间,再尝试找出用ltib自带编译器编的init无法运行的原因。
        a) 修改ltib配置成使用android的编译器
            1) ./ltib -m config ,修改Toolchain选项为Custom, 修改Enter the custom toolchain path为(/home/lancer/freescale/android/prebuilt/linux-x86/toolchain/arm- eabi-4.4.0),修改 Enter the toolchain prefix.为(arm-eabi-)。
            2) 去掉uboot支持,android上编译器编不过uboot
            3) 在Package Selection中保留boot_stream,其他package全部取消。因为toolchain修改为android的toolchain了,而 android的toolchain没有c库。
        b) ./ltib开始编译,这个编译过程不能最后成功。会在boot_stream生成imx23_uboot.sb的过程中停止。不要担心,原因在于我们没有选择编译uboot包。如果你愿意,你可以修改uboot,使得它在android的编译器上能成功编译即可不出现此错误。
        c) 编译过程异常退出的时候,imx23_linux.sb其实已经生成了,不过不在rootfs/boot下,而是在rpm/BUILD/imx- bootlets-src-10.05.02下。你可以修改burn_linux.sh,让它烧这个到sd卡中。
        d) 到这一步之后,默认的内核已经生成了。
        e) 到你下载的android源文件目录去编译android。目前的2.2的android默认用的4.4.0的编译器,正是我们所需要armv5te。直接make。
        f) 编译完成后进入/home/lancer/freescale/android/out/target/product/generic,这里面就有 root,system,data分别对于sd卡上的p3,p5,p6分区。为了测试init是否搭配kernel,建议写一个简单的init程序,在 main函数中做循环打印。
            1) 在android目录运行 . ./build/envsetup.sh
            2) cd android/system/core/init ; vi test.c
                // test.c start
                #include <stdio.h>
                #include <stdlib.h>
                int main(int argc, char **argv)
                {
                    printf ("we enter android init!!!\n");
                    while (1) {
                        printf ("test and test !\n");
                        sleep (1);
                    }
                    return 0;
                }
                // test.c end
            3) 修改Android.mk,在LOCAL_MODULE:= init前加一行LOCAL_SRC_FILES:= test.c 就只编译test.c文件
            4) 编译init,用mmm system/core/init 或make init编译
        g) 重新运行./burn_linux.sh,然后将/dev/mmcblk0p3分区上根文件系统内容删除干净(记得先要记录/usr/local /Trolltech/tslib/etc/pointercal内容),将root,system,data内容拷贝到sd卡相应分区。
        h) 为了方便我们调试,我们需要看到终端打印信息。到sd卡的root分区的dev目录下创建一个console设备,我的mmcblk0p3是mount到 /media/android_root。
            1) cd /media/android_root
            2) sudo mknod console c 5 1
        g) 插sd卡到板子上运行。如果从终端不停打印出内容,说明ltib和kernel设置正确了,能和android相匹配了。这时候你可以将 system/core/init/Android.mk文件改回来了。到这里,环境方面基本搞定。

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wwxxys.html