kernel停在Starting kernel 分析

解决方法:

1.看门狗问题,可能会造成这种显现。

2.IMX6Q的PMU被bypass导致cpu没有供电而无法开机,只要donwload imx6q ldo版本的boot image即可。

log:

U-Boot 2015.04-14409-g6cf684a-dirty (Mar 10 2016 – 13:56:17)

CPU: Freescale i.MX6Q rev1.5 at 792 MHz
CPU: Temperature 27 C
Reset cause: POR
Board: MX6-SabreSD
I2C: ready
DRAM: 2 GiB
PMIC: PFUZE100 ID=0x10
MMC: FSL_SDHC: 0, FSL_SDHC: 1, FSL_SDHC: 2
*** Warning – bad CRC, using default environment

No panel detected: default to Hannstar-XGA
Display: Hannstar-XGA (1024×768)
In: serial
Out: serial
Err: serial
check_and_clean: reg 0, flag_set 0
Fastboot: Normal
flash target is MMC:1
Net: Phy 1 not found
PHY reset timed out
FEC [PRIME]
Error: FEC address not set.

Normal Boot
Hit any key to stop autoboot: 0
boota mmc1
kernel @ 14008000 (7272264)
ramdisk @ 15000000 (868699)
fdt @ 14f00000 (44216)
## Current stack ends at 0x8ef3cbf0 ## Booting Android Image at 0x12000000 …
Kernel load addr 0x14008000 size 7102 KiB
Kernel command line: console=ttymxc1,115200 init=/init video=mxcfb0:dev=ldb,bpp=32 video=mxcfb1:off video=mxcfb2:off video=mxcfb3:off vmalloc=256M androidboot.console=ttymxc1 consoleblank=0 androidboot.hardware=freescale cma=384M
kernel data at 0x12000800, len = 0x006ef748 (7272264)
* fdt: cmdline image address = 0x14f00000
## Checking for ‘FDT’/’FDT Image’ at 14f00000
* fdt: raw FDT blob
## Flattened Device Tree blob at 14f00000
111 Booting using the fdt blob at 0x14f00000
of_flat_tree at 0x14f00000 size 0x0000acb8
Loading Kernel Image … OK
kernel loaded at 0x14008000, end = 0x146f7748
using: FDT
Using Device Tree in place at 14f00000, end 14f0dcb7
## Transferring control to Linux (at address 14008000)…
switch to ldo_bypass mode!
Starting kernel …

思路:

说明kernel和dts都已经找到,但是kernel一条log都没有。

本来想参考

https://community.freescale.com/thread/385298

在reset之后通过u-boot的命令来dump ddr中的ddr log,

无奈我们的硬件设计是cold reset, memory信息都丢失,无法抓log。

此问题断断续续困扰了我好几天,检查了dts和kernel中compatible确实也是一致的,

修改过的uart配置应该也没有问题。

u-boot 中有条log让我很好奇:

switch to ldo_bypass mode.

记得build bootimage的时候有个boot-imx6q-ldo.img,试了下,居然开机进kernel了!!!

原因:

IMX6Q提供了ldo bypass功能,这是什么东西呢?先看下图:
20160310170755315

图一 使用内部PMU的LDO即非bypass

20160310170831885
图二 使用外部PMIC而直接bypass内部PMU

两图的区别在于图二的VDDARM_IN直接短接到了VDD_ARM_CAP而作为cpu的电源,而图一是需要经过LDO电压转换的。

如果要使用bypass功能,那么硬件上必须要使用图二,否则VDD_ARM_CAP是没有电的。

PS: VDDARM_IN从外部PMIC输出的。

boot-imx6q-ldo.img 和boot-imx6q.img的区别在于:

kernel_imx/arch/arm/boot/dts/imx6q-sabresd-ldo.dts

……
#include “imx6q-sabresd.dts”

&cpu0 {
arm-supply = <&reg_arm>;
soc-supply = <&reg_soc>;
};

&gpc {
/* use ldo-enable, u-boot will check it and configure */
fsl,ldo-bypass = <0>;
/* watchdog select of reset source */
fsl,wdog-reset = <1>;
};
……

这些property会覆盖kernel_imx/arch/arm/boot/dts/imx6qdl-sabresd.dts里的配置:

&gpc {
/* use ldo-bypass, u-boot will check it and configure */
fsl,ldo-bypass = <1>;
fsl,wdog-reset = <2>;
};
&cpu0 {
arm-supply = <&sw1a_reg>;
soc-supply = <&sw1c_reg>;
};

arm-supply和soc-supply默认使用的是PMIC的电源,改成了内部PMU的reg_arm和reg_soc.

那么fsl,ldo-bypass怎么被用到的呢?且看u-boot!

cpu.c

void arch_preboot_os(void)
{
……
#if defined(CONFIG_LDO_BYPASS_CHECK)
ldo_mode_set(check_ldo_bypass());
#endif
…..
}

soc.c

int check_ldo_bypass(void)
{
……
ldo_mode = fdt_getprop(gd->fdt_blob, node, “fsl,ldo-bypass”, NULL);
/*
* return 1 if “fsl,ldo-bypass = <1>“, else return 0 if
* “fsl,ldo-bypass = <0>” or no “fsl,ldo-bypass” property
*/
ldo_bypass = fdt32_to_cpu(*ldo_mode) == 1 ? 1 : 0;

return ldo_bypass;
}

mx6qecovacs.c

#ifdef CONFIG_LDO_BYPASS_CHECK
void ldo_mode_set(int ldo_bypass)
{
……
/* switch to ldo_bypass mode , boot on 800Mhz */
if (ldo_bypass) {
prep_anatop_bypass();
if (is_mx6dqp()) {
/* decrease VDDARM for 400Mhz DQP:1.1V*/
pmic_reg_read(p, PFUZE100_SW2VOL, &value);
value &= ~0x3f;
value |= 0x1c;
pmic_reg_write(p, PFUZE100_SW2VOL, value);
} else {
/* decrease VDDARM for 400Mhz DQ:1.1V, DL:1.275V */
pmic_reg_read(p, PFUZE100_SW1ABVOL, &value);
value &= ~0x3f;
#if defined(CONFIG_MX6DL)
value |= 0x27;
#else
value |= 0x20;
#endif

pmic_reg_write(p, PFUZE100_SW1ABVOL, value);
}
/* increase VDDSOC to 1.3V */
pmic_reg_read(p, PFUZE100_SW1CVOL, &value);
value &= ~0x3f;
value |= 0x28;
pmic_reg_write(p, PFUZE100_SW1CVOL, value);

/*
* MX6Q/DQP:
* VDDARM:1.15V@800M; VDDSOC:1.175V@800M
* VDDARM:0.975V@400M; VDDSOC:1.175V@400M
* MX6DL:
* VDDARM:1.175V@800M; VDDSOC:1.175V@800M
* VDDARM:1.075V@400M; VDDSOC:1.175V@400M
*/
is_400M = set_anatop_bypass(2);
if (is_mx6dqp()) {
pmic_reg_read(p, PFUZE100_SW2VOL, &value);
value &= ~0x3f;
if (is_400M)
value |= 0x17;
else
value |= 0x1e;
pmic_reg_write(p, PFUZE100_SW2VOL, value);
}

if (is_400M)
#if defined(CONFIG_MX6DL)
vddarm = 0x1f;
#else
vddarm = 0x1b;
#endif
else
#if defined(CONFIG_MX6DL)
vddarm = 0x23;
#else
vddarm = 0x22;
#endif
pmic_reg_read(p, PFUZE100_SW1ABVOL, &value);
value &= ~0x3f;
value |= vddarm;
pmic_reg_write(p, PFUZE100_SW1ABVOL, value);

/* decrease VDDSOC to 1.175V */
pmic_reg_read(p, PFUZE100_SW1CVOL, &value);
value &= ~0x3f;
value |= 0x23;
pmic_reg_write(p, PFUZE100_SW1CVOL, value);

finish_anatop_bypass();
printf(“switch to ldo_bypass mode!\n”);
}
}
#endif

也就是说u-boot会根据dts中的ldo-bypass值来修改PMIC的输出电压,而我们硬件却是用的内部PMU方案!

参考:

1. IMX6Q datasheet

2. https://community.freescale.com/thread/385298

3. https://community.freescale.com/message/507621

4.http://blog.csdn.net/kris_fei/article/details/50848099

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值