上·志

上下求索,志在千里。

导航

AM3715/DM3730 更改内存大小后kernel boot不起来的解决办法

Author: 朱上志

Date:2012.11.22

转载请注明出处

 

调试所用的kernel源代码是来自Devkit8500的,Linux-2.6.32,启动到

Starting kernel ...
Uncompressing Linux................................................................

done, booting the kernel. 

 就不再继续下去了,google发现这是个很常见的问题,搜到了很多解决办法,特别是搜到这个

Kernel - Common Problems Booting Linux(中译版:kernel starting 内核引导失败常见解决办法) 

时很兴奋,以为能解决问题了,但是一一试了都不见效,郁闷啊。

后来想到了我们的硬件组成和Devkit8500有一个很大的区别就是:Devkit8500是512MB 的DRR,我们的

是256MB的, 问题应该出在这里.看了很久源代码,也没找到解决点。从网上看到关于bootargs参数的设置, 

Devkit8500参数的设置是通过boot.scr(boot.scr的生成请参考:使用mkimage生成boot.scr)来设置的, 

原来bootargs参数的设置如下:

setenv bootargs 'console=ttyS2,115200n8 androidboot.console=ttyS2 mem=256M root=/dev/mmcblk0p2 rw  

rootfstype=ext3 rootdelay=1 init=/init ip=off mpurate=1000 omap_vout.vid1_static_vrfb_alloc=y'

看起来没什么问题,mem=256M, 我们的DDR正式256MB,所以就没理会mem这个参数了,而是去捣鼓其他方面了,

却想不到正是这个256M出的问题。在其他方面折腾了很久还是没有解决后,再次回想到mem这个参数,256M是原来的

值,也就是针对于512MB DDR而设定,那么现在变为256MB DDR,DDR减半了后,mem是不是也应该减半呢?想到

这里,就设mem=128M,重新生成boot.scr,拷进TF卡,插入,开机,再次来到了

 done, booting the kernel. 

稍微顿了一下,就出来了:

Linux version 2.6.32 (root@zhushangzhi-virtual-machine) (gcc version 4.4.0 (GCC) ) #3 Tue Nov 20 10:42:26 CST 2012
CPU: ARMv7 Processor [413fc082] revision 2 (ARMv7), cr=10c53c7f
CPU: VIPT nonaliasing data cache, VIPT nonaliasing instruction cache
Machine: OMAP3 DEVKIT8500 Board
Memory policy: ECC disabled, Data cache writeback
OMAP3630/DM3730 ES1.0 (l2cache iva sgx neon isp 192mhz_clk )

SRAM: Mapped pa 0x40200000 to va 0xfe400000 size: 0x100000 

 

哈哈,It's work! 

所以,解决问题的思路方向很重要,走错了方向,得到的就只会是瞎折腾 。

更新:

date:2013.05.02

 

上面通过更改mem=128M来解决问题显然是有问题的,因为这样的或Linux系统会使用到128MB内存(cat /proc/meminfo 可看到Linux内存使用情况),而板上256MB内存,还有128MB没有用的。所以还是必须改回mem=256M,然后通过别的办法解决启动的问题。

在x-load的omap3beagle.c里,看到

void config_3430sdram_ddr(void)
{
//    printf("config_3430sdram_ddr\n");
    /* reset sdrc controller */
    __raw_writel(SOFTRESET, SDRC_SYSCONFIG);
    wait_on_value(BIT0, BIT0, SDRC_STATUS, 12000000);
    __raw_writel(0, SDRC_SYSCONFIG);

    /* setup sdrc to ball mux */
    __raw_writel(SDP_SDRC_SHARING, SDRC_SHARING);
    if ((beagle_revision() == REVISION_XM) || (beagle_revision() == REVISION_XMC))
    {
        //printf("256MB/bank\n");
        __raw_writel(0x2, SDRC_CS_CFG); /* 256MB/bank */
        __raw_writel(SDP_SDRC_MDCFG_0_DDR_XM, SDRC_MCFG_0);
        __raw_writel(SDP_SDRC_MDCFG_0_DDR_XM, SDRC_MCFG_1);
        __raw_writel(MICRON_V_ACTIMA_200, SDRC_ACTIM_CTRLA_0);
        __raw_writel(MICRON_V_ACTIMB_200, SDRC_ACTIM_CTRLB_0);
        __raw_writel(MICRON_V_ACTIMA_200, SDRC_ACTIM_CTRLA_1);
        __raw_writel(MICRON_V_ACTIMB_200, SDRC_ACTIM_CTRLB_1);
        __raw_writel(SDP_3430_SDRC_RFR_CTRL_200MHz, SDRC_RFR_CTRL_0);
        __raw_writel(SDP_3430_SDRC_RFR_CTRL_200MHz, SDRC_RFR_CTRL_1);
    }
    else
    {
        //printf("128MB/bank\n");
        __raw_writel(0x1, SDRC_CS_CFG); /* 128MB/bank */
        __raw_writel(SDP_SDRC_MDCFG_0_DDR, SDRC_MCFG_0);
        __raw_writel(SDP_SDRC_MDCFG_0_DDR, SDRC_MCFG_1);
        __raw_writel(MICRON_V_ACTIMA_165, SDRC_ACTIM_CTRLA_0);
        __raw_writel(MICRON_V_ACTIMB_165, SDRC_ACTIM_CTRLB_0);
        __raw_writel(MICRON_V_ACTIMA_165, SDRC_ACTIM_CTRLA_1);
        __raw_writel(MICRON_V_ACTIMB_165, SDRC_ACTIM_CTRLB_1);
        __raw_writel(SDP_3430_SDRC_RFR_CTRL_165MHz, SDRC_RFR_CTRL_0);
        __raw_writel(SDP_3430_SDRC_RFR_CTRL_165MHz, SDRC_RFR_CTRL_1);
    }

    __raw_writel(SDP_SDRC_POWER_POP, SDRC_POWER);

    /* init sequence for mDDR/mSDR using manual commands (DDR is different) */
    __raw_writel(CMD_NOP, SDRC_MANUAL_0);
    __raw_writel(CMD_NOP, SDRC_MANUAL_1);

    delay(5000);

    __raw_writel(CMD_PRECHARGE, SDRC_MANUAL_0);
    __raw_writel(CMD_PRECHARGE, SDRC_MANUAL_1);

    __raw_writel(CMD_AUTOREFRESH, SDRC_MANUAL_0);
    __raw_writel(CMD_AUTOREFRESH, SDRC_MANUAL_1);

    __raw_writel(CMD_AUTOREFRESH, SDRC_MANUAL_0);
    __raw_writel(CMD_AUTOREFRESH, SDRC_MANUAL_1);

    /* set mr0 */
    __raw_writel(SDP_SDRC_MR_0_DDR, SDRC_MR_0);
    __raw_writel(SDP_SDRC_MR_0_DDR, SDRC_MR_1);

    /* set up dll */
    __raw_writel(SDP_SDRC_DLLAB_CTRL, SDRC_DLLA_CTRL);
    delay(0x2000);    /* give time to lock */
}
 

发现里面的if语句只能运行else部分,也就是"128MB/bank",将这部分屏蔽掉,并使"256MB/bank"部分能直接执行,重新编译,然后设mem=256M,上电,可以顺利启动Linux Kernel.原来就是这个原因!

执行

cat /proc/meminfo

MemTotal:         250432 kB

...