Galaxy S3刷机改内核的流水账(2)

来源:互联网 发布:sql union后字段为空 编辑:程序博客网 时间:2024/06/05 18:43

内核源码


它在这里,下载之。解开zip包,里面有两份tar压缩包,还有各自的README文件。我们暂时只关注GT-I9300_Kernel.tar.gz,这是kernel source code。

把它解压缩,注意,需要在Linux下解开。如果在Windows下解开的话,编译时可能会出问题。因为Windows下不区分文件名的大小写,个别"重名"文件可能会变成一个文件,导致编译失败。这事儿我干过,所以得注意!

我是把它放到我的Ubuntu12.04的某个路径下面,然后根据“README_Kernel.txt”里面的步骤去编译即可。

不过,遇到过问题,那就是toolchain的选择。


Toolchain的选择


我的系统里原先有好几个toolchain,都是曾经为不同平台编译时所安装的。

另外,我有使用codesourcery失败的惨痛经历,所以不打算按照“README_Kernel.txt”所说的去装那个什么codesourcery。

我试过用自己预装的toolchain编译了一个小程序,比如hello.c,像这样:

tomxue@ubuntu:~/workspace$ arm-none-linux-gnueabi-gcc -o hello --static hello.c

注意,--static这个必须有,可能是手机端没有相应的动态库,所以得在编译时静态链接进去。

然后把hello传至手机端

tomxue@ubuntu:~/workspace$ adb push hello /sdcard/Tom779 KB/s (587302 bytes in 0.736s)

登录手机

tomxue@ubuntu:~/workspace$ adb shellshell@android:/ $ cd /data/data                                                shell@android:/data/data $ ls...

获取管理员权限(这个管理员不是万能的)

shell@android:/data/data $ sushell@android:/data/data # 

在这里建个自己的目录并把hello拷贝过来

hell@android:/data/data # mkdir Tomshell@android:/data/data # cd Tomshell@android:/data/data/Tom # cp /sdcard/Tom/hello .  

执行之,不行?

shell@android:/data/data/Tom # ./hello                                         sh: ./hello: cannot execute - Permission denied

查看权限,改改,再试

126|shell@android:/data/data/Tom # ls -al-rw-rw-r-- root     root       587302 2012-10-31 10:07 helloshell@android:/data/data/Tom # chmod 700 helloshell@android:/data/data/Tom # ./helloHello Tom Android!19|shell@android:/data/data/Tom # 

成功了!

这就证明我系统之前安装的工具链arm-none-linux-gnueabi-是可用的。我也是这么认为的,但是事实往往出人意料,实际上它还是不行。

进入到内核源码目录,修改其Makefile,指定CROSS_COMPILE为相应的toolchain:

CROSS_COMPILE = arm-none-linux-gnueabi-

编译之,

  LD      arch/arm/mvp/commkm/built-in.o  CC [M]  arch/arm/mvp/commkm/check_kconfig.occ1: error: unrecognized command line option "-fno-dwarf2-cfi-asm"make[2]: *** [arch/arm/mvp/commkm/check_kconfig.o] Error 1make[1]: *** [arch/arm/mvp/commkm] Error 2make: *** [arch/arm/mvp] Error 2

报错如上,搜了一下,看到这位 同学的 帖子,明白了这个问题可能是toolchain本身引起的。

于是果断按照“README_Kernel.txt”说的,去寻找那个叫做arm-eabi-4.4.3的toolchain。找到了,在这里。

git check之。


重新修改Makefile如下:

CROSS_COMPILE?= /home/tomxue/Tom/Source_Code/Android/Samsung/toolchain/android_prebuilt_toolchains/arm-eabi-4.4.3/bin/arm-eabi-

再编译,这次没有出错了。


刷kernel之HC-kTool


有了kerne镜像zImage,接下来的问题是怎么把它刷进去。

我首先找到了这个工具:HC-kTool。

看看这个 帖子,先认识认识。

貌似很简单的样子,我就照做了,然后就失败了...手机会在开机初始画面那里反复闪屏。

看来问题不简单。

不过,看到下面的界面上那些绿色的按钮,我忍不住心动先点了几下:把该备份的备份,说不准啥时候有用呢。

其中,有一个叫elf的不知道是什么,查查看:

EFS
三星Galaxy Note刷机前备份EFS文件的“HK内核工具”下载

果然,很重要!


刷kernel之别人的做法


既然HC-kTool没成功,那么就看看别人都是怎么做的吧。

搜索成熟的供下载的kernel刷机包,找啊找,找到了下面的帖子。

How to root Samsung Galaxy S III

原来他还是用Odin进入下载模式刷包,那个包在帖子里有下载链接,我下载后打开研究了一下。

是一个tar包,里面放着一个boot.img的文件,4846K,貌似比一般的zImage大点儿,至少比我编译出来的zImage(4630K)大点儿(差值216K)。

于是,明白了,我要做的怎么把zImage转换成boot.img。


zImage -> boot.img


找吧,搜啊搜,搜到了这个:

把玩"魔术师" -- 帮 boot.img 换 kernel

其中,提到的boot.img哪里找呢?还记得前面我说过玩刷机要备份吗?备份的文件在手机的这个目录下:

/mnt/sdcard/clockworkmod/backup

进去可以看到一个以日期命名的目录,再进去,就可以看到boot,recovery等文件了。

这个boot就是我们要找的boot.img,注意:它的文件大小刚好8M

至于zImage,那是我们刚刚编译好的,你也可以在上面做些改动再编译,不过第一次编译建议原封不动,先把流程摸索清楚了再玩内核改造。

它的思路就是:把一个完好的boot.img解开,将其中的zImage替换成我们自己编译的,然后产生新的boot.img。如果想把自己的编译的模块也加进去,那么,还有它说的两种方法。

需要了解的是,内核镜像和模块往往是关联的,也就是你编译的内核镜像zImage只能加载同时产生的模块文件,如果只刷你自己的zImage,那么系统原有的模块,比如蓝牙、wifi就都用不了了。

我全部按照它说的方法试过了,结论是:还是不行!

貌似做了无用功了,写在这里好像也是浪费大家时间,其实也不然。因为,这个过程中,我意识到一件事:那就是boot.img其实是zImage加ramdisk的产物


卡刷


而帖子里提到的两种方法,最后都会生成一个叫做update_signed.zip的文件,这个文件可以直接刷机,怎么刷?卡刷!卡刷是什么?这里告诉你。


不过,还是那句话,这些我都没成功。但是没成功只是意味着发现某些路径不通而已,何况又多了一分认识!


G3,not GS3


要说走弯路,其实走得比你想象的多。我搜到了这个帖子,第一感觉是这下可以搞定了,于是一番折腾,发现还是不行。

再仔细一看,原来人家教的是如何刷G3,而不是GS3。只能怪咱眼神不好了...

不过,还是学到了点儿新东西,那就是原来编译内核时,可以直接把ramdisk编译进去,而得到的zImage,可以直接tar打包,再用Odin在下载模式下刷机


初步的结论


好吧,现在我有一些初步的结论:

要么得到boot.img(来自zImage+ramdisk),然后tar打包,Odin在下载模式下刷;

要么得到update_signed.zip,然后卡刷。



得到ramdisk.gz

perl split_bootimg.pl boot.img

其中,boot.img是从SGS3手机中利用HC-kTool dump出来的。这个操作完成以后,就会得到下面的两个文件,分别是原kernel和ramdisk.gz

$ lsboot.img  boot.img-kernel  boot.img-ramdisk.gz


终于成功!


到了这里,我终于要成功了,一切荣誉归功于这位大哥的帖子。

这哥们激动地一直在说:mdeejay is a genius.

mdeejay是谁?自己看帖,反正我是记住了这个名字,连目录都用它命名。

关键就是下面的语句:

./mkbootimg --cmdline "console=null androidboot.hardware=qcom user_debug=31" --kernel zImage --ramdisk ramdisk.gz --base 0x80200000 --ramdiskaddr 0x81500000 -o ./boot.img

对我来说,那就是zImage:自己编译的,ramdisk.gz:原机boot.img解出来的,可能用别的也问题不大,猜的。

还有就是那两地址,估计比较关键,暂时不深究。


用这个办法生成了boot.img,再tar一下,然后用Odin刷,试验证明这个办法非常成功!


再审视HC-kTool


不过,我还是觉得用Odin在下载模式下刷机挺担心的,而且,动不动USB就不识别了(前面有总结如何解决之)也挺不爽的。

另外,HC-kTool在Google Play上可以装,且支持GS3(好像除了美国的AT&T版本),那它没道理不行啊?再试试!

首先,注意到利用HC-kTool dump出来的zImage文件大小正好是8M,这点就很不寻常。因为我知道通常编译出来的zImage(手机,ARM)只有4M左右,差距这么大,为什么呢?

结合之前的经验,我有一个假设,那就是HC-kTool所用到的zImage其实是boot.img,而且是8M版本的。这可能是系统分配给这部分的空间是个整数的原因吧。

用vim查看boot.img,发现其59%之后的部分全是零。

于是,我有下面的做法:

首先自己编译出zImage,然后用上面说的成功的办法将其制成boot.img,如下:


我做好的boot.img(上图中的boot.img-Tom-mdeejay),文件大小为5289984,距离8M(8388608)还差3098624个字节(全零)。

于是,我们需要制作padding文件,大小为3098624=1024*3026

dd if=/dev/zero of=./padding bs=1024 count=3026

查看一下
tomxue@ubuntu:~/windows/Android/Samsung/flash_kernel/method___work___xda_mdeejay/Tom_OK$ ls -altotal 10779drwxrwxrwx 1 root root       0 Oct 25 11:38 .drwxrwxrwx 1 root root    4096 Oct 24 13:05 ..-rwxrwxrwx 1 root root 5289984 Oct 24 10:55 boot.img-Tom-mdeejay-rwxrwxrwx 1 root root 3098624 Oct 25 11:26 padding-rwxrwxrwx 1 root root 5294080 Oct 24 11:11 tom.tar

打padding
cat boot.img-Tom-mdeejay padding > zImage-Tom-padding


再查看
tomxue@ubuntu:~/windows/Android/Samsung/flash_kernel/method___work___xda_mdeejay/Tom_OK$ ls -altotal 10779drwxrwxrwx 1 root root       0 Oct 25 11:38 .drwxrwxrwx 1 root root    4096 Oct 24 13:05 ..-rwxrwxrwx 1 root root 5289984 Oct 24 10:55 boot.img-Tom-mdeejay-rwxrwxrwx 1 root root 3098624 Oct 25 11:26 padding-rwxrwxrwx 1 root root 5294080 Oct 24 11:11 tom.tar-rwxrwxrwx 1 root root 8388608 Oct 25 11:26 zImage-Tom-padding

利用HC-kTool把boot.img-Tom-mdeejay刷进去,即改名为boot.img后,放到内部SD card根目录上去,选择HC-kTool的"Flash kernel from /sdcard/zImage"

再重启,成功!

这件事的意义在于,以后只需要备好8M版的自己的boot.img就可以利用HC-kTool轻松的更换kernel了(需要重启一下)!



写个小程序

上面的做法很笨,很麻烦,还是由程序处理更简单。

我的程序在这里:https://github.com/tomxue/SGS3_kernel/blob/master/extend8M.cpp

就是把boot.img通过文件读写扩大至8M大小。



内核模块的编译


关于内核模块的编译,我觉得很简单,以前也总做。问题是,这次遇到点儿问题。

把文件放到内核目录下,改Makefile,一块编译,没问题,生成的ko文件加载也正常;

把文件单独拎出来,自己写Makefile,编译,出问题了,详情见 这里 这个帖子是我发到Stack Overflow上去问的,目前还没找到原因。



最有用的部分


写了一大堆,其实最有用的部分都在这里:

https://github.com/tomxue/SGS3_kernel.git

仔细看看README,反正我每次编译内核或者内核模块直接通过这个repo就可以了,简单至极。



结论


流水账就是啰嗦,不过实际过程也就是那样的。

刷机成功,后面的事情就好办了,以后想玩啥玩啥,真正的学习才刚刚开始。

还有很多事情我还没弄清楚,有更好方案的同学也希望能够不吝指正、赐教。



原创粉丝点击