多语言展示
当前在线:1139今日阅读:84今日分享:32

Linux内核版本导致Android Recovery失败

由Linux内核版本名引发的Recovery问题(由+导致的问题),主要是由于REPO管理代码转为GIT管理时,编译出来的版本信息少了一个+号,从而导致Recovery功能运行过程中失败了。
方法/步骤
1

最近在移植RK3188 Android4.4,而我的平台是整个SDK用GIT来管理,但原厂提供的是用REPO管理,于是我将原厂的SDK里的.repo删除然后创建自己的GIT库,一切准备就绪,就在Recovery时失败了。

2

原来原厂在Recovery时会去insmod打包的NAND KO文件,此时KO版本与Linux内核版本对应不上,于是就一直失败了,KO要求的版本是3.0.36+,而我编译出来的Linux内核版本一直是3.0.36,为何会多了个+呢?于是从启动信息入手:

3

Linux version 3.0.36 (stxinu@x-slam) (gcc version 4.6.x-google 20120106 (prerelease) (GCC) ) #5 SMP PREEMPT Wed Dec 25 16:29:49 CST 2013

4

在Linux内核源码里搜索Linux version,定位到在源码根目录下的init/version.c中有如下内容:

5

const char linux_banner[] =        'Linux version ' UTS_RELEASE ' (' LINUX_COMPILE_BY '@'        LINUX_COMPILE_HOST ') (' LINUX_COMPILER ') ' UTS_VERSION '\n';

6

对照如下打印信息,刚好与UTS_RELEASE对应,于是继续搜索UTS_RELEASE,定位到根目录下的Makefile,有如下内容:

7

(echo \#define UTS_RELEASE '$(KERNELRELEASE)';

8

于是继续找KERNELRELEASE,在同文件中有如下内容:

9

KERNELRELEASE = $(shell cat include/config/kernel.release 2> /dev/null)

10

那么继续找下kernel.release这个文件是如何生成的吧!在同文件中有如下内容:

11

# Store (new) KERNELRELASE string in include/config/kernel.release    include/config/kernel.release: include/config/auto.conf FORCE        $(Q)rm -f $@        $(Q)echo '$(KERNELVERSION)$$($(CONFIG_SHELL) $(srctree)/scripts/setlocalversion $(srctree))' > $@

12

其中最后的+号应该是由$$($(CONFIG_SHELL) $(srctree)/scripts/setlocalversion $(srctree))生成的了,于是继续查找根目录下的scripts/setlocalversion文件,由于传进来的第一个参数不是--save-scmversion,故而scm_only一直为false,并且根目录下也不存在以“localversion”开头的文件名,还有CONFIG_LOCALVERSION和LOCALVERSION没有定义为任何内容,以及CONFIG_LOCALVERSION_AUTO也没有定义,故而最终定位到如下内容:

13

if test '${LOCALVERSION+set}' != 'set'; then            scm=$(scm_version --short)            res='$res${scm:++}'fi

14

因为LOCALVERSION为空,故而${LOCALVERSION+set}返回空,与set不相等,那么条件成立继续执行分支里的内容,执行scm_version函数,该函数开头有如下内容:

15

if test -e .scmversion; then        cat .scmversion        returnfi

16

为了方便,我直接在Linux内核源码根目录下创建一个名为.scmversion的文件,文件内容为+,如果不这样处理,往下会确认是否采用GIT或mercurial、SVN管理,并进行相应的提取处理,以便作为Linux内核版本号的后缀,故而返回+,即scm赋值为+,接下来的${scm:++}由于scm非空,此时会返回后面的+(其中:+为一个运算符),而res为空,故而连接后返回给res的为+,最终将res的+号返回,故而就有了3.0.36+的kernel.release文件中的内容了。END

推荐信息