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

第三章:  Android的移植
    1:init.rc的修改
        主要的修改就是将system,data,cache等mount的地方改成你所用的文件系统的格式。
        a) loglevel 3 改为 loglevel 6 ,用于调试
        b) 将
                mount yaffs2 mtd@system /system
                mount yaffs2 mtd@system /system ro remount
            改为
                mount ext3 /dev/block/mmcblk0p6 /system
                mount ext3 /dev/block/mmcblk0p6 /system ro remount
        c) 将
                mount yaffs2 mtd@userdata /data nosuid nodev
            改为
                mount ext3 /dev/block/mmcblk0p5 /data nosuid nodev
        d) 将
                mount yaffs2 mtd@cache /cache nosuid nodev
            改为
                mount ext3 /dev/block/mmcblk0p7 /cache nosuid nodev
        e) 其他的,哪些service该起来,哪些不要起来,就自己决定了。
    2:ltib中关于android的配置
        ./ltib -m config 选择Config the kernel,保存退出
        ./ltib ,运行后配置kernel,如果不能进入配置kernel界面,请先./ltib -m config,取消选中Config the kernel,保存退出,然后再重复上一步。(以后如遇不能配置kernel的情况,请按照这一步骤进行)
        配置kernel时,进入到devices drivers---Staging drivers --- Android. 除了Android RAM buffer console外,其他都选中。保存退出,即开始编译内核。
    3:ashmem移植,可以从android 的kernel代码树中找到ashmm.c ashmm.h,并且对比修改makefile和shmm.h shmm.c
        a) 打开此链接: ?p=kernel/common.git;a=tree;h=f92ea0328d3a0bb5386d52fd68ae4e10ca1ebce6;hb=f92ea0328d3a0bb5386d52fd68ae4e10ca1ebce6 ,或者进入 ?p=kernel/common.git;a=summary 选择最新的tree。
        b) 下载 mm/ashmem.c 和 include/linux/ashmem.h 到 /home/lancer/freescale/ltib/ltib/rpm/BUILD/linux-2.6.31-imx233 目录下相应位置
        c) 查看 include/linux/mm.h文件,与本地相应文件对比,本地应该加入如下代码
            void shmem_set_file(struct vm_area_struct *vma, struct file *file);
        d) 查看 mm/shmem.c 文件,与本地文件对比,本地应该加入如下代码
            void shmem_set_file(struct vm_area_struct *vma, struct file *file)
            {
                if (vma->vm_file)
                    fput(vma->vm_file);
                vma->vm_file = file;
                vma->vm_ops = &shmem_vm_ops;
            }
        e) 查看 mm/Makefile 文件,应该在obj-y中加入ashmem.o
        f) 做完这些工作后,就可以开始再编译内核了
    4:修改framebuffer驱动,使其支持android的double buffer 和 android 565颜色模式,我们使用的驱动是mxs
        a) 修改 drivers/video/mxs/lcd_lms430.c ,将static struct mxs_platform_fb_entry fb_entry中.bpp修改为16,代码如下
            static struct mxs_platform_fb_entry fb_entry = {
                .name = "lms430",
                .x_res = 272,
                .y_res = 480,
                .bpp = 16,
        b) 修改 drivers/video/mxs/mxsfb.c ,将NUM_SCREENS 设置为2,即为double buffer
            #define NUM_SCREENS    2

c) 因为mxs的驱动比较简单,好多功能都没有实现。我们也没有兴趣将它实现完全,所以只能让它初始化的时候就成为我们的目标状态。改了上面2条还不够,还必须对他硬件初始化部分做改动。
        d) 修改 arch/arm/mach-mx23/include/mach/lcdif.h ,查看setup_dotclk_panel函数,它默认是32位真彩色,我们需要改成16位的 RGB565
            __raw_writel(BF_LCDIF_CTRL1_BYTE_PACKING_FORMAT(0xF) | //由7改为F
                     BM_LCDIF_CTRL1_RECOVER_ON_UNDERFLOW,
                     REGS_LCDIF_BASE + HW_LCDIF_CTRL1_SET);

__raw_writel(BF_LCDIF_CTRL_WORD_LENGTH(0) |/* 16 bit, 由3改为0 */
                     BM_LCDIF_CTRL_DATA_SELECT |/* data mode */
                     BF_LCDIF_CTRL_INPUT_DATA_SWIZZLE(0) |/* no swap */
                     BF_LCDIF_CTRL_LCD_DATABUS_WIDTH(3),/* 24 bit */
                     REGS_LCDIF_BASE + HW_LCDIF_CTRL_SET);
        e) 这样就修改完了framebuffer驱动,编译之后,烧到sd卡上,再启动时,你会发现linux启动过程中的企鹅翅膀变成绿色的,但大小还是跟原来一样!!为什么?因为它这个位图是24位的,而我们framebuffer是565的。如果你在启动过程中发现2只企鹅,或者更多,那么你的驱动改错了,再仔细分析分析吧。
    5:触摸屏驱动的修改,原理及过程我就不叙述了。
        对于我的触摸屏,我只需修改 drivers/input/touchscreen/mxs-ts.c 文件。
        a) 在#include <*****>之后加如下代码
            #define TS_ABS_XY 1
            static int axis_table[] = {-35, 8147, -1149876, 4999, -60, -1708204, 65536}; // from /etc/pointercal by ts_calibrate
        b) 修改process_lradc函数,将case TS_STATE_TOUCH_VERIFY:下的内容替换。
            原先是
                pr_debug("%s: touch verify state, sample_count %d\n", __func__,
                        info->sample_count);
                pr_debug("%s: x %d, y %d\n", __func__, info->x, info->y);
                input_report_abs(info->idev, ABS_X, info->x);
                input_report_abs(info->idev, ABS_Y, info->y);
                input_report_abs(info->idev, ABS_PRESSURE, pressure);
                input_sync(info->idev);
                /* fall through */
            替换为
            {
                unsigned long xraw, yraw, xtmp, ytmp;
                xraw = (info->x & 0xfff);
                yraw = (info->y & 0xfff);
                xtmp = (axis_table[2] + axis_table[0] * xraw + axis_table[1] * yraw ) / axis_table[6];
                ytmp = (axis_table[5] + axis_table[3] * xraw + axis_table[4] * yraw ) / axis_table[6];
                printk ("windsome: pen down(%d:%d): x=%x:%d, y=%x:%d, pressure=%x:%d\n",
                        xtmp, ytmp, info->x >> 12, info->x & 0xfff, info->y >> 12, info->y & 0xfff,
                        pressure >> 12, pressure & 0xfff);
                input_report_abs(info->idev, ABS_X, xtmp);
                input_report_abs(info->idev, ABS_Y, ytmp);
            input_report_abs(info->idev, ABS_PRESSURE, pressure);
            input_report_key(info->idev, BTN_TOUCH, pressure);
            input_sync(info->idev);
            }
            /* fall through */
        c) 修改mxs_ts_probe函数
            原先是
                idev->name = "MXS touchscreen";
                idev->evbit[0] = BIT(EV_ABS);
                input_set_abs_params(idev, ABS_X, 0, 0xFFF, 0, 0);
                input_set_abs_params(idev, ABS_Y, 0, 0xFFF, 0, 0);
            替换为
                idev->name = "MXS touchscreen";
                idev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
                idev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH);
                input_set_abs_params(idev, ABS_X, 0, 480, 0, 0);
                input_set_abs_params(idev, ABS_Y, 0, 272, 0, 0);
        d) 保存,编译成功。我们的触摸屏驱动在android2.2上就能正常运行了吗?
        e) android默认是多点触摸屏,需要修改frameworks/base/services/java/com/android/server /KeyInputQueue.java文件,找到
            final int classes = di.classes;
            改为
            final int classes = di.classes &(~(RawInputEvent.CLASS_TOUCHSCREEN_MT));
            这样,android就可以支持单点触摸了
        e) 接下来编译android。下载运行后,我们进了锁界面,却什么都不能动。为啥?想想你的G2,在锁界面的情况下,你触摸屏幕能进去吗?也不能,还得按个 menu键。我们的系统上没有按键!没办法了,去掉锁界面!
    6:开机进入无锁界面,因为我们没有按键,只有触摸屏,所以只能去掉锁了 。原理我不叙述了。
        a) 修改 frameworks/base/packages/SettingsProvider/res/values/defaults.xml ,
            <integer>60000</integer>
            改为
            <integer>-1</integer>
        b) 修改 frameworks/policies/base/phone/com/android/internal/policy/impl/KeyguardViewMediator.java ,
            private boolean mExternallyEnabled = true;
            改为
            private boolean mExternallyEnabled = false;
        c) make ,并更新到sd卡上,终于可以去操作了。
    7:电源管理,应该移植android的电源管理驱动。暂时没时间,所以,直接改android中代码。
        a) 修改frameworks/base/services/jni/com_android_server_BatteryService.cpp 文件,在android_server_BatteryService_update函数的最后加下面代码
            env->SetBooleanField(obj, gFieldIds.mAcOnline, true);
            env->SetIntField(obj, gFieldIds.mBatteryStatus, gConstants.statusUnknown);
            env->SetIntField(obj, gFieldIds.mBatteryHealth, gConstants.healthUnknown);

b) 修改hardware/libhardware_legacy/power/power.c 文件,
            原先
                const char * const OLD_PATHS[] = {
                    "/sys/android_power/acquire_partial_wake_lock",
                    "/sys/android_power/release_wake_lock",
                    "/sys/android_power/request_state"
                };
                const char * const NEW_PATHS[] = {
                    "/sys/power/wake_lock",
                    "/sys/power/wake_unlock",
                    "/sys/power/state"
                };
                const char * const AUTO_OFF_TIMEOUT_DEV = "/sys/android_power/auto_off_timeout";
            改为
                const char * const OLD_PATHS[] = {
                    "/cache/sys/android_power/acquire_partial_wake_lock",
                    "/cache/sys/android_power/release_wake_lock",
                    "/cache/sys/android_power/request_state"
                };
                const char * const NEW_PATHS[] = {
                    "/cache/sys/power/wake_lock",
                    "/cache/sys/power/wake_unlock",
                    "/cache/sys/power/state"
                };
                const char * const AUTO_OFF_TIMEOUT_DEV = "/cache/sys/android_power/auto_off_timeout";
        c) 在sd卡的cache分区建立上述文件,用文件模拟设备

第四章:  后记
    移植花了不少时间,这是移植完成后对过程的回忆及整理,可能有疏漏。错漏之处给您带来麻烦,还请原谅。如果您有什么问题或意见,可以给我发邮件 agooou@gmail.com 。

第五章: 补充
    在移植过程中,改动了很多地方,把一些有用的改动记录下来。
    1:修改system/core/init/init.c,这样我们可以看到打印信息
        a) 原先
                if (needs_console) {
                    setsid();
                    open_console();
                } else {
                    zap_stdio();
                }
        改为:
                    setsid();
                    open_console();
        b) main函数中注释掉
            //open_devnull_stdio();
    2:修改system/core/liblog/logd_write.c,我们可以看到java中的打印
        修改__write_to_log_init函数,将
                log_fds[LOG_ID_MAIN] = log_open("/dev/"LOGGER_LOG_MAIN, O_WRONLY);
                log_fds[LOG_ID_RADIO] = log_open("/dev/"LOGGER_LOG_RADIO, O_WRONLY);
                log_fds[LOG_ID_EVENTS] = log_open("/dev/"LOGGER_LOG_EVENTS, O_WRONLY);
                log_fds[LOG_ID_SYSTEM] = log_open("/dev/"LOGGER_LOG_SYSTEM, O_WRONLY);
        改为
        #if FAKE_LOG_DEVICE
                log_fds[LOG_ID_MAIN] = log_open("/dev/"LOGGER_LOG_MAIN, O_WRONLY);
                log_fds[LOG_ID_RADIO] = log_open("/dev/"LOGGER_LOG_RADIO, O_WRONLY);
                log_fds[LOG_ID_EVENTS] = log_open("/dev/"LOGGER_LOG_EVENTS, O_WRONLY);
                log_fds[LOG_ID_SYSTEM] = log_open("/dev/"LOGGER_LOG_SYSTEM, O_WRONLY);
        #else
                log_fds[LOG_ID_MAIN] = 1;
                log_fds[LOG_ID_RADIO] = 1;
                log_fds[LOG_ID_EVENTS] = 1;
                log_fds[LOG_ID_SYSTEM] = 1;
        #endif
    3:我们的工作平台为Ubuntu10.04LTS系统,32位主机。为了能将android编译通过需要做如下修改。
        a) 注释掉build/core/main.mk的76行
            #$(error stop)
        b) 修改external/clearsilver的子目录下的Android.mk,注释掉以下内容
            # This forces a 64-bit build for Java6
            #LOCAL_CFLAGS += -m64
            #LOCAL_LDFLAGS += -m64

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

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