GEC210(S5PV210)uboot引导内核配置

主机平台:Linux CentOS 6.5

arm平台:粤嵌GEC210开发板(S5PV210


        呼~~终于成功启动内核了,只是为了启动内核居然用了一个星期,每天调试时间都近10小时,几次想哭的心都有了,但不启动内核接下来什么也没法做,于是继续找问题,编译下载内核应该都有几百次了,终于在今天见到内核启动打印的信息了,真的开心到想哭啊。下面,讲下我的调试过程,如果不想看我废话要直接看结论的话就跳到最后吧。

        一开是只是想试一下自己写个ramdisk看一下可不可以用挂在上内核,但发现没法挂在上,研究了一阵子推测原因可能是当时的内核没有开启ramdisk支持,但因为这个是开发板配套的内核,没有提供源代码,所以就决定自己编译一个吧。首先用的内核版本是2.6.32.63,这个版本没有s5pv210的配置文件,但有s5pc100的,上网查了下发现这两个芯片差不多,就先用一下试试。根据网上的流程主要的就只有配置串口,其它可以使用默认设置,好,就这样,编译,下载!!!

        嗯嗯,然后,如预料中一样,果然不行,在uboot输出最后的信息后,就没有任何信息输出了。然后再在网上搜搜,发现很多人都说打开lowlevel调试就会输出“Uncompressing kernel...的信息,但我检查了一下,发现已经开启了。但还是没有输出,而且网上似乎没有多少人出现这个问题,大多是在这句后才没有输出的。那之后唯有靠自己了。因为没有信息输出,没办法确定是串口配置问题还是内核问题,但我认为内核应该不会有问题,所以就从串口方面入手了。

    (好,浪费时间的第一阶段开始~~~,其实串口已经配置好了

        串口配置的话我想到的有两个地方,一是内核的配置文件,二是uboot的bootargs里的串口相关设置参数。内核配置文件网上说就是两个地方,都是选串口号的,但不论怎么选就是一个样跟着看了uboot的bootargs这个环境变量了串口相关的参数,但试了各种写法,还是没改变。跟着用了一天在这个地方,东改改,西改改,有关系的也改,没关系的也改,但什么也没有发生。

        好了,接下来怎么办呢?终于决定改变思路了。在之前的查找中发现较新的内核直接有s5pv210的配置文件,就想难道是因为虽然s5pc100s5pv210相似,但还是有不同的地方?(其实这里对了,至少串口寄存器的地址不同,所以无论其它地方是否正确,也不可能有输出的当然其它地方是有问题的)那换内核吧!既然换就换个新点,就换了个3.14.25的。然后编译,但出错了,出现garbage什么什么的错误,继续搜,有人说是交叉编译器太旧的问题,那换吧,但网上的都不知到是旧是新,那就自己编译个交叉工具链吧,但用了一整天,出了一堆问题,最后还是没有弄出来。

        没办法了,换一个稍微旧一点的内核吧,然后换了个2.6.35.9的,这次有s5pv210的配置文件了,而且编译也通过了,可惜还是没有任何反应。到这里已经想不到办法了,只有从源码入手了查了一下内核启动流程,第一个执行的代码段是head.S里的start,然后也找到了打印“Uncomressing kernel ...”这句话的地方是decompressing_kernel函数,我把这个函数放在紧接start后面的地方,把函数里的打印语句putstr放在这个函数的最前面(这里悲剧了,虽说是最前面,但这是不包括赋值语句的,我怎么也想不到赋值会出现问题。。。)。当然,什么也没发生。继续想问题出在哪里,是打印函数出现问题?是寄存器地址不对?接下来花了不少时间看这里的源码,但结论是,打印函数没有问题!后面就是各种试了,改配置,改参数,换内核,换交叉工具,不记得用了多少时间了,有一次终于把decompress_kernel里的putstr放在赋值语句前面了,终于有东西打印出来了,好开心。虽然当时有想过为什么赋值语句会有问题,但没想明白(其实这里就是问题的核心)。那终于可以开始调试源码了。

        终于发现了在cache_on里调用的call_cache_fn中的某个地方无法打印出信息。(这里是浪费时间的第二阶段,打印语句放的地方是不会到达的。。。好了,接下来这里用了一两天左右的时间,这里依然没法解决。没办法,只有分析源码了,终于发现那里是不会到达的。。。在这之前会跳转到__armv7_mmu_cache_on,用打印函数测试,果真如此!接下来又发现在这个卡在了这个函数调用的_setup_mmu里,而且是不能执行过str r1,[r0]这条语句,当时就傻了,什么?这怎样才会出问题?然后继续有花了不少时间测试,发现问题出现在r0这个地址上,根据这个往上看,与r0值有关的最开始的数据是r4,再往前看,有个地方注释着:r4 = kernel execution address  那我的内核执行地址是0x30008000,我就从这里开始,根据每一条语句算出r0,但r0算出的是0x30004000,感觉没有问题啊,但为什么会卡住呢。那我就直接将0x30004000直接赋给r0再执行str好了。这次又可以通过了,完全不明白是为什么啊

        接下来大概有两天用在这里,中间还发现我的打印函数居然会影响寄存器,当时还很开心的以为就是这个原因出错的,但改过打印函数后,还是到这里就卡住了。唯有继续找原因了。

        终于,我把r4的值直接打印出来,发现是0x20008000,看来问题就处在这里了,往上找,看一下r4是怎么得到这个值。但后面遇到的问题就真是到现在也想不明白的。例如,r4在一条与r4完全无关的语句后改变了,我就想不会是延迟吧,就加了几句add r0,r0,#0   ,但后来发现居然跳不过这几句话,当时再次傻了。后来也不记得在这里花了多少时间了。

        后来,我放弃在这里找原因了,我相信源码是没有问题的!!!

        这之前的搜索中,我知道了内核有很多地址参数的,所以决定从这里入手,看一看各个地址的值。终于在mach-s5vp210下的Makefile.boot里有两个参数:

zreladdr-y    := 0x20008000
params_phys-y    := 0x20000100

修改成:

zreladdr-y    := 0x30008000
params_phys-y    := 0x30000100


之后,终于跳过了_setup_mmu的那条str语句了。

但还是有问题,这次到decompressing_kernel的赋值语句还是卡住了,打印出被赋值的变量的地址,是0x3000xxxx,应该是没有问题的,感觉应该还是地址配置的问题,继续找。

经过一番查找,在mach-s5pv210/include/mach下的memory.h里有一句话:

#define PHYS_OFFSET        UL(0x20000000)

改成:

#define PHYS_OFFSET        UL(0x30000000)

编译,下载,运行,终于看到内核打印的信息啦!!!!!!!!!!!!!!!!!!




好了,下面总结一下吧

1.确定你的配置文件与你的芯片型号相同

2.配置内核串口,方法网上很多地方都有,要注意的是串口号,要根据你的开发板配置(其它可以先使用默认配置)

(1)system type ---> (0) S3C UART to use for low-level messages

(2)Kernel hacking  --->  [*] Kernel low-level debugging functions 
                                      ---> (0) S3C UART to use for low-level debug

括号内的就是串口

3.修改arch/arm/mach-xxx/Makefile.boot
zreladdr-y    := 0x30008000              //内核的加载地址,uboot中设定的加载地址确定
params_phys-y    := 0x30000100    //内核参数的物理地址,由uboot设定的值确定

4.修改arch/arm/mach-xxx/include/memory.h中的

#define PHYS_OFFSET        UL(0x30000000)    //你的内存的起始物理地址








     


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值