Simple Guide for Porting Android Kernel

本文详细介绍Android内核移植到实际硬件平台的过程,包括所需背景知识、软件环境、移植基本思路及流程,并提供了一些实用技巧。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

作者:刘旭晖 colorant@163.com 转载请注明出处
http://blog.youkuaiyun.com/colorant/

移植Android的kernel到实际的硬件平台上,很多人很早就做过这件事了,不过相关的文档和经验总结不多,我就写一个吧,也为了自己记录一下大致的流程,以后好继续。
1 Android内核Porting相关背景知识
1.1 运行平台
Google的Android平台到今天为止(2008-2-27),应用层部分还是以二进制的Binary的形式发布的,其编译的目标平台是ARM926EJ-S的CPU属于ARMV5T的版本,所以ARMV4架构的CPU平台无法使用其二进制代码。关于这点,可以参考下面这篇文章,Benno在此做了详尽的理论分析和代码测试:http://benno.id.au/blog/2007/11/21/android-neo1973
所以目前只有基于ArmV5或以上的架构的平台可以实际运行Android。
1.2 软件环境
SDK下载:http://code.google.com/android/download_list.html
KERNEL,模拟环境等SRC包下载:http://code.google.com/p/android/downloads/list
1.2.1 Kernel
到M5-r14 release 为止,Android的Kernel是基于Linux2.6.23的内核开发的,主要添加了一个名为Goldfish的虚拟CPU以及Android所需相关特定驱动代码。
你需要一个支持EABI的内核作为你内核Porting的起点(最低版本?不知道,只要EABI OK,应该没有本质区别,但是,Android的很多驱动依赖于2.6.23的内核API,版本越低的内核,移植修改内核相关代码的工作量越大)
1.2.2 Tools chain
SDK中的内核使用的是4.2.1版本的GCC,基本上,你需要的是一个支持EABI的工具链,比如你可以使用Codesourcery的最新工具链:http://www.codesourcery.com/

1.2.3 其它工具
Android的Emulator是一个很好的仿真工具,其底层是基于QEMU来实现的,可以使用SDK中的adb工具登陆Emulator的控制台,和控制台交换文件等,用于获取你所需的信息。

1.3 相关论坛资源等
http://benno.id.au/blog/
http://groups.google.com/group/android-internals
http://groups.google.com/group/android-developers
2 Porting基本思路
2.1 所需资源
2.1.1 硬件
首先,当然是需要一个可以用来向上porting的硬件开发板了,对硬件的需求除了上面说的,需要ArmV5+兼容的CPU以外,最低要求基本需要64M+的内存,64M-128M+的FLASH(取决于你加载文件系统的方式,如果可以透过网络使用NFS-ROOT或者MMC卡等来存放文件系统的话,这个应该就无所谓了)
2.1.2 软件
除了上述kernel和tools chain,为了方便调试,最好有静态编译的Busybox和Strace等工具。也可以从Benno的blog上下载到他编译好的版本。

2.2 基本流程
下载Android内核代码
下载官方2.6.23内核
制作Android和2.6.23内核的diff文件
去除diff文件中和Goldfish和QEMU相关的代码,如果你的系统已经支持YAFFS2,还可以去除这部分代码
将diff文件Patch到你自己的内核上,如果需要,修改内核相关文件代码使得patch能够顺利完成。(这部分大概是主要的工作量,如果你的内核版本差得比较远的话 8 )
如果必要,修改你的内核代码中Framebuffer的驱动,使其Virtual_yres 等于两倍的Yres,并实际分配两倍分辨率大小的framebuffer内存。
配置内核,确保下列内容得到配置:
CONFIG_ARM_THUMB=y
CONFIG_AEABI=y
CONFIG_BINDER=y
CONFIG_ANDROID_LOG=y
CONFIG_ANDROID_POWER=y
CONFIG_ANDROID_POWER_STAT=y
从SDK中获取Android的文件系统,基本上你只需要System etc sbin init这几个目录/文件就可以了,其它自建,其中data目录是有内容的,但是这个目录的内容可以由Android在启动时动态的创建出来。(可以使用adb工具在EMULATOR先tar包装,再拷贝出来。M3的release也可以从benno那里直接拿到他抓出来的文件系统)
确保你的dev目录下有足够系统启动的设备节点,如console等,其它的节点Android在启动过程中会自动创建出来。
使用NFSROOT或者chroot等手段启动Android的文件系统。

启动流程的大致外在表现分阶段依次是:

Ø LCD上出现Android几个字符
Ø LCD短时间的Blank
Ø LCD上出现一个左右滚动的红色滚动条 (如果有问题,基本上就死在这一步了 8 )
Ø 进入主界面

目前为止我的状态是:键盘可以工作,触摸屏有响应但是未校准,位置不对,启动最后阶段以及之后启动新的程序,出现Vmalloc分配内存Failed问题,导致如Brower等应用程序不能完全启动。其它网络等东东还没开始看呢 8 )
3 一些TIPS

Ø Android会对文件使用memory mapped的方式进行操作,JFFS2不支持这种操作,所以要使用别的文件系统。当然也有绕过去的办法,自己搜一下吧 8 )
即http://nemustech.blogspot.com/说的方法:
* if you have jffs2 for / patch /init
* modify with hexedit : "/system_property" -> "/tmp/sy_property"
* NOTE: jffs2 does not support memory mapped file
Ø 为了方便测试,可以修改/etc/init.rc,注释掉 runtime,dbus-daemon,Xzygote等相关内容,在init启动以后再手工启动这些进程:

/system/bin/app_process -Xzygote /system/bin --zygote &
/system/bin/dbus-daemon --system --nofork &
sleep 1;
/system/bin/runtime &

Ø Android的Init位于根目录下,所以如果你需要直接启动Init,可以在内核参数命令行中用init=/init 来指定,或者chroot 目录 /init来指定。 当然,启动/bin/sh以后,再手动启动/init也是可以的。

Ø /dev/binder /dev/alarm /dev/log/* 等文件是最重要的几个设备节点,由于这几个设备节点号的主次设备号是动态分配的,所以,最好确认你的文件系统中的这几个设备节点的主次设备号是否正确。如果不知道如何确认,直接删除掉再重启 8 )

Ø 如果flash速度太慢或者nfs网络连接太差,可以将data tmp这两个目录mount到内存里,前提是你的内存足够大 8 )

Ø 如果启动过程中,红色滚动条速度太快(和emulator里的表现比较),runtime或者system_server进程CPU占用率接近100%,那么你可以修改一下你的framebuffer代码中pan_display相关的函数的代码,保证其调用返回时得到足够的帧同步延迟时间。据Google的swetland给我的说法是:This is usually indicative of lack of vsync/pageflip in the fb driver.The surfaceflinger believes it will be limited by the vsync rate and the startup animation depends on that.

Ø 目前的Android的内核代码有M3-r20和M5-r14两个版本,这两个版本对binder和power两个驱动做了较大的修改,上层的文件系统和内核必须配套使用。( 另,我的板子上,M5版本可以跑起来,M3的版本会出现段错误,没跑起来 :(。如果一个版本实在跑不起来,不妨试试别的版本)

Ø 使用strace去跟踪问题!
<think>我们正在讨论将ILitek触摸屏驱动移植到MTK平台。这是一个嵌入式Linux驱动移植任务。以下步骤是通用的移植指南,具体细节可能需要根据硬件和内核版本调整。 ### 1. 获取ILitek触摸屏驱动源码 通常从ILitek供应商处获取驱动源码,可能是独立模块或集成到内核中的补丁形式。确保获得与你的触摸屏型号匹配的驱动版本。 ### 2. 分析MTK平台现有触摸驱动框架 MTK平台通常使用Linux Input子系统。检查: - 设备树(Device Tree)中触摸屏节点定义 - 现有触摸驱动(如`mediatek/kernel/drivers/input/touchscreen/`目录) - 确认MTK平台使用的内核版本(`uname -r`) ### 3. 集成ILitek驱动到内核 假设驱动为独立模块: - 将源码放入`drivers/input/touchscreen/ilitek/` - 修改`drivers/input/touchscreen/Makefile`,添加: ```makefile obj-$(CONFIG_TOUCHSCREEN_ILITEK) += ilitek/ ``` - 修改`drivers/input/touchscreen/Kconfig`,添加配置选项: ```kconfig config TOUCHSCREEN_ILITEK tristate "ILITEK I2C Touchscreen" depends on I2C help Say Y here to enable ILITEK I2C touchscreen support. ``` ### 4. 设备树配置 在设备树中(如`arch/arm64/boot/dts/mediatek/mtXXXX-your-board.dts`)添加I2C节点: ```dts &i2c0 { ilitek@41 { compatible = "ilitek,ili2120"; reg = <0x41>; interrupt-parent = <&pio>; interrupts = <6 IRQ_TYPE_EDGE_FALLING>; // 根据实际GPIO修改 reset-gpios = <&pio 5 0>; // 复位GPIO }; }; ``` 注意:`compatible`字符串必须与驱动中的匹配。 ### 5. 驱动适配关键点 - **中断处理**:确保驱动使用正确的IRQ触发方式(如`IRQF_TRIGGER_FALLING`) - **电源管理**:实现`resume/suspend`回调 - **I2C通信**:检查驱动中的I2C操作函数(如`i2c_transfer`)是否适配MTK的I2C控制器 - **输入子系统注册**:确保正确设置`input_dev`的坐标范围、事件类型(`EV_ABS`等) ### 6. 编译配置 在内核配置中启用驱动: ```bash make menuconfig ``` 路径:`Device Drivers -> Input device support -> Touchscreens -> <*> ILITEK I2C Touchscreen` ### 7. 调试技巧 - 查看I2C设备:`i2cdetect -l` 然后 `i2cdump -f -y 0 0x41`(假设I2C0总线) - 查看输入事件:`evtest /dev/input/eventX` - 内核日志:`dmesg | grep ilitek` §§相关问题§§ 1. 如何解决ILitek驱动与MTK I2C控制器的兼容性问题? 2. 触摸屏校准在驱动中如何实现? 3. 移植后触摸坐标反向或偏移如何调整?</think>### MTK平台 ILitek触摸屏驱动移植指南 #### 一、移植准备阶段 1. **环境确认** - 获取MTK平台SDK(如MT6765/MT6873等) - 确认内核版本:`cat /proc/version` - 准备ILitek驱动包(通常包含`.c`、`.h`文件和`Makefile`) 2. **硬件接口验证** ```c // 检查I2C/SPI接口兼容性(示例) struct i2c_adapter *adapter = i2c_get_adapter(0); if (!adapter) { printk(KERN_ERR "I2C adapter not found"); return -ENODEV; } ``` #### 二、驱动集成步骤 1. **源码整合** - 将ILitek驱动文件放入MTK内核目录: `mediatek/kernel/drivers/input/touchscreen/ilitek/` - 修改Makefile: ```makefile obj-$(CONFIG_TOUCHSCREEN_ILITEK) += ilitek_ts.o ilitek_platform.o ``` 2. **设备树配置** ```dts &i2c1 { ilitek@41 { compatible = "ilitek,ili9881"; reg = <0x41>; interrupt-parent = <&pio>; interrupts = <6 IRQ_TYPE_EDGE_FALLING>; // GPIO6 reset-gpio = <&pio 15 0>; // GPIO15 vdd-supply = <&mt_pmic_vtp_ldo_reg>; }; }; ``` 3. **电源管理适配** ```c static int ili_power_supply_init(struct device *dev) { // MTK PMIC配置 regulator = regulator_get(dev, "vdd"); if (IS_ERR(regulator)) { dev_err(dev, "Failed to get vdd regulator"); return PTR_ERR(regulator); } regulator_set_voltage(regulator, 2800000, 3300000); } ``` #### 三、关键适配点 1. **中断处理** ```c static irqreturn_t ili_irq_handler(int irq, void *dev_id) { struct ili_data *ts = dev_id; disable_irq_nosync(ts->irq); queue_work(ts->workqueue, &ts->work); return IRQ_HANDLED; } ``` 2. **触摸坐标转换** ```c static void ili_report_points(struct input_dev *input) { // MTK屏幕分辨率适配 input_report_abs(input, ABS_MT_POSITION_X, x * 1080 / 1024); input_report_abs(input, ABS_MT_POSITION_Y, y * 2246 / 2048); } ``` 3. **固件升级机制** ```c #ifdef CONFIG_MTK_FW_UPGRADE static int ili_fw_update(struct device *dev) { // 使用MTK平台flash工具 ret = mtk_flash_write(flash_addr, fw_data, fw_size); } #endif ``` #### 四、调试与测试 1. **日志分析工具** ```bash adb shell "echo 8 > /proc/sys/kernel/printk" adb logcat | grep -i ilitek ``` 2. **I2C通信检测** ```bash i2cdetect -y 1 # 扫描I2C1总线设备 i2cdump -f -y 1 0x41 # 读取ILitek寄存器 ``` 3. **输入事件验证** ```bash getevent -lt # 查看原始触摸数据流 ``` > **注意事项** > - 确保MTK的I2C时钟频率与ILitek规格书匹配(通常400kHz) > - 休眠唤醒时需重新加载固件:`ili_resume()`中调用初始化函数 > - 若出现坐标抖动,需调整`filter_level`参数[^1]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值