在bsd上跑ndk-build

bsd一直是个官方不咋支持的Android开发平台…… 不过靠着linux兼容层,还是可以混混的…… 首先是ndk-build会报不支持的os(FreeBSD)和arch(amd64),而且ndk-build并不会使用环境变量里定义的值。所以有两个办法: 1. 直接调用gmake env HOST_OS=linux HOST_ARCH=x86 gmake -f $NDK_DIR/build/core/build-local.mk 这样啥都不用改。 2. 修改ndk-build 把HOST_OS设置成linux,HOST_ARCH设置成x86,并且export出来。 再把GNUMAKE设置成gmake,否则会调自带的linux版gmake导致一些麻烦的事情…… 然后直接跑就行了。 跑了之后会碰到一个问题:ld会segmentation fault。看系统log可能是因为fallocate和fstatfs64系统调用没有实现的关系。 解决办法是,到ndk目录里的toolchains/*/prebuilt/linux-x86/…/bin/,如果有ld.gold,那把老的ld干掉,改成到ld.bfd的符号链接。老的ld就是ld.gold…… 其实就是gold那个新的ld调了一些新的bsd还没实现的linux的system call…… 用老的bfd里的ld就没事了……

Xoom更新4.1.1

之前听说Android 4.1.1在Xoom上公开测试了,昨儿听说已经OTA了,于是去系统设置里检查更新,没有…… 去网上看,说可以清除Google Service Framework的数据再试。试了一次,果然刷出来一个更新,4.1.1的。Google这是故意的么…… 下完之后,更新,刚过百分之十几,就成了个倒了的Android的样子,上面还有个红色三角。 根据经验,反正是升级败了。重启,去/cache,发现recovery目录里有last_log。看最后说啥验证失败。 E: failed to verify whole-file signature E: signature verification failed Installation aborted 我一开始以为是更新包验证败了,但是弄到电脑上,能正常解开……(更新包就在/cache里,一个zip) 那估计和上次一样,因为这是个补丁包,所以要先验证源文件正确,才能打补丁,而某些文件可能被改过了,在Root或者别的时候。 这时候我想起来,上次见到过一个叫OTA RootKeeper的东西,可以在更新后保留Root,就去装了一个,打开之后,选保留Root以及暂时unroot。 然后重启到EOS Recovery,尝试装那个zip,果然有apply_patch_check失败的,首先是/system/bin/gzip。进去一看,貌似被改成了到busybox的链接…… 大约是哪个busybox安装器干的好事。从网上下了一个4.0.4的完整镜像,从里面扒出gzip换掉系统里那个符号链接,再试,这次换成了ip。重复操作,搞定了ping和toolbox之后,这次是boot分区校验和挂了…… 重启到fastboot,刷那个4.0.4镜像里的,再更新,还是不行…… 想想大概是4.0.4那个镜像的boot改过了,去下载的地方,发现是root过的镜像…… 搜了一圈,就是找不到没root过的4.0.4 boot分区。 网上的恢复办法都是刷回3.x然后一路更新上来,好像很麻烦…… 我想,可以弄来3.x的boot.img和之后所有的补丁,一路打上来,弄到一个4.0.4的boot.img,再刷进去…… 在xda的http://forum.xda-developers.com/showthread.php?t=1597609这个帖子里有个网站,里面有3.0.1的原始镜像和所有升级包。把镜像里的boot.img和升级包里的所有boot.img.p扒出来,然后就是咋打补丁的问题了。 我记得android里有applypatch,于是去android source里面找,果然有这个东西。尝试编译一份主机可用的,居然成功了,命令如下: 在applypatch目录里 gcc utils.c imgpatch.c bspatch.c freecache.c bsdiff.c main.c applypatch.c -o applypatch -I../../../system/core/include/ -I../ ../minelf/Retouch.c -lbz2 -lz ../../bootloader/legacy/libc/sha.c ../mtdutils/mtdutils.c 然后跑,发现命令格式挺简单,就是 applypatch …

Continue reading ‘Xoom更新4.1.1’ »

Android 3.0+的MTP,以及USB debugging

Android到了3.0+有个地方特别弱智,就是USB连上显示出来不是U盘设备,而是个MTP设备…… 其他系统的MTP问题 首先这个MTP一开始就是Microsoft自己搞出来的东西,主要是Windows Media Player支持这个东西,日后才被USB那啥论坛搞成一种正式的USB类。应该是因为这个,别的系统下的支持都不怎么样。 别的系统基本上都用了libmtp库,而这个库最弱智的地方,就是刚连上的时候,会扫描所有文件做个索引…… 如果只是个音乐播放器可能还好,文件不多,但是现在是一个Android设备,那里边乱七八糟的可多了…… 于是这个索引要做个4,5分钟。想想你插上一个设备,过个四五分钟才能显示内容,那不是很sx么…… Windows下,MTP文件连上后,过一会就可以看见内容了…… 读了代码,发现他是自己递归做索引的,而且好多接口函数都会去确保这个索引存在,不在就建出来…… 根据MTP的规范,其实每次请求一个目录也就列出它的子文件和子目录。也就是说,按照规范来说,并没有啥一定要一次性拿到所有文件的必要性。看windows那边的实现也可以说明这一点。或许本来它是考虑搞个缓存提高之后速度,但是这个初次访问速度实在不能忍。而且之后访问慢慢建出来索引也可以,没必要非要一开是就建出全部的索引。 但是USB的传输速度又比较快。理论上wifi也很快,但是我拿scp也好ftp也好adb也好,速度都最多1M多,还不清楚哪儿sx了…… 所以还是要想办法搞定这个事情,难道要重写libmtp么…… Win下的MTP问题 于是我想别的系统MTP支持糟糕,Win总该不错吧?于是打开WinXP虚拟机,嘿,这个MTP还没有驱动…… 上网查,说要装WMP10,装完还是不行。再查,说可以装WMP11,装完还是不行。再查,说有个MTP Porting Kit的东西,里面有驱动。下下来装好,里里外外翻了一遍,还是没有驱动…… 后来从WMP11的wmfdist11.exe,也就是Window Media Format 11 Runtime那一部分里,翻出来若干inf以及相关文件,貌似是MTP驱动。但是手动指定到这儿,倒好像装上去了,但还是不行…… 到此基本没法,上网继续查。在查了好久之后,终于有个地方说可能和USB debugging有关系。遂关掉USB debugging,立马就好了…… 自动装好驱动,啥都能访问。一开,又不成…… 继续观察,发现不开的时候,只有一个设备,VID_22B8&PID_70A8。这个设备的兼容类型里包括了USB\MS_COMP_MTP,所以驱动匹配上了。开了之后,这个设备变成了一个复合设备,VID_22B8&PID_70A9,很神奇的就是PID加了一,估计是为了和原来的区别开来。这个东西下有俩子设备,VID_22B8&PID_70A9&MI_00和VID_22B8&PID_70A9&MI_01。后一个在装了Moto的驱动之后,显示出来是个ADB设备,也就是USB debugging用的…… 前一个名称是MTP,估计就是MTP设备,但是兼容类型里没有USB\MS_COMP_MTP!于是驱动挂不上…… 就弱智了…… 解决方法其实很简单,只要改windows\inf下的wpdmtp.inf,在匹配段里面,在 %GenericMTP.DeviceDesc%=MTP, USB\MS_COMP_MTP 之后,加上 %GenericMTP.DeviceDesc%=MTP, USB\VID_22B8&PID_70A9&MI_00 ,一切都搞定了…… 于是我很难理解,到底是哪里脑残了导致开了USB debugging就不说自己是MTP设备了…… 蛋疼啊…… 为啥Google要用MTP…… 虽说Google那边说MTP有诸多好处,例如提高了抽象层次,使得一个文件对Android和电脑都可见啦之类(老的方式系统看见了一大块数据,里面有几个分区,所以如果允许两边都看见,那只要有改动,就会导致元数据不一致…… 新的方法等于系统看见了一堆抽象的文件和目录等,所以所有操作都要告诉那边才能做…… Android那边维持着一致性……),但是选MTP这个标准真是蛋疼,你大不了Google自己搞一套+开源实现也不难啊!MTP就不是给你做任意类型文件传输的么!

Android市场无法开始下载的问题以及解决

在学校的时候,Android市场上的东西下的好好的。回家之后,虽然能显示开始下载,但是从来也不会真的开始……一开始以为某地被屏蔽,于是开始抓包。但是确定开始下载的时候,连SYN都没有……去往上查,说要允许5228端口。但是根据抓包的情况,一直只有到mtalk.google.com:5228的连接,怎么看都是GTalk的事情。其实这里是被误导了,导致我继续研究了好几天也没有结果。今天猜测是不是这两者有关联。于是研究了5228的情况。在学校可以连mtalk.google.com:5228,在家连不上,看来是这个糟糕的有线通的问题。于是搞了个变通的办法:改hosts,把这个地址指向我的笔记本,然后在笔记本上用ssh把这个端口通过ssh隧道forward到目的地去,隧道出口在学校,因此就可以连上了。搞完之后一试,果然能上GTalk了。出乎意料的是,数秒之内,那些下载都开始了……这是什么意思……………… 你个android市场是要验证用户身份,但是为啥和GTalk捆绑在一起………………反正最后是可以下了……