AM3715/DM3730 更改内存大小后kernel boot不起来的解决办法
Author: 朱上志
Date:2012.11.22
转载请注明出处
调试所用的kernel源代码是来自Devkit8500的,Linux-2.6.32,启动到
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.
稍微顿了一下,就出来了:
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
...