环境
在uboot中分析emmc初始化流程代码,emmc在uboot中方便添加命令和打印调试,uboot版本:2017.03
开机打印
uboot启动打印
U-Boot 2017.03-g101318f (Jan 09 2019 - 17:37:10 +0800)
CPU: Freescale i.MX6UL rev1.2 696 MHz (running at 396 MHz)
CPU: Automotive temperature grade (-40C to 125C) at 58C
Reset cause: WDOG
Model: Freescale i.MX6 UltraLite 14x14 EVK Board
Board: MX6UL 14x14 EVK
DRAM: 256 MiB
SF: Detected n25q256 with page size 256 Bytes, erase size 4 KiB, total 32 MiB
Hardware version: 0x0401
MMC: board_mmc_init
CONFIG_MX6UL_14X14_EVK_EMMC_REWORK
FSL_SDHC: 0
Using default environment
SF: Detected n25q256 with page size 256 Bytes, erase size 4 KiB, total 32 MiB
In: serial
Out: serial
Err: serial
SF: Detected n25q256 with page size 256 Bytes, erase size 4 KiB, total 32 MiB
Net: eth1: ethernet@020b4000, eth0: ethernet@02188000 [PRIME]
Normal Boot
Hit any key to stop autoboot: 0
内核启动打印
mmc1: new DDR MMC card at address 0001
mmcblk1: mmc1:0001 P1XXXX 7.20 GiB
mmcblk1boot0: mmc1:0001 P1XXXX partition 1 16.0 MiB
mmcblk1boot1: mmc1:0001 P1XXXX partition 2 16.0 MiB
mmcblk1rpmb: mmc1:0001 P1XXXX partition 3 128 KiB
mmcblk1: p1 p2
启动参数
=> pri
baudrate=115200
board_name=EVK
board_rev=14X14
boot_fdt=try
bootcmd=run kernel_env;if test ${default_image} = system1; then echo Booting from ${default_image}......;sf probe 0; sf read ${itb_addr} 0x90000 0xF30000; bootm ${itb_addr}; fi;if test ${default_image} = system2; then echo Booting from ${default_image}......;sf probe 0; sf read ${itb_addr} 0xFC0000 0xF30000; bootm ${itb_addr}; fi;
bootdelay=1
console=ttymxc0
default_image=system1
eth1addr=08:ed:02:37:10:02
ethact=ethernet@02188000
ethaddr=08:ed:03:37:10:02
ethprime=eth0
fdt_addr=0x83000000
fdt_file=undefined
fdt_high=0xffffffff
fdtcontroladdr=8ef58068
initrd_high=0xffffffff
ip_dyn=yes
itb_addr=0x86800000
kernel_env=setenv bootargs initrd=0x84800000,0x2000000 init=/etc/preinit console=${console},115200 root=/dev/ram0 ro rootfstype=ext4 image=${default_image} cma=64M mtdparts=21e0000.qspi:512k(uboot),64k(boardcfg),15552k(system1),15552k(system2),1024k(rootfs_data),60k(crashlog),4k(flags)
loadaddr=0x80800000
EMMC信息
=> mmcinfo
Device: FSL_SDHC
Manufacturer ID: fe
OEM: 14e
Name: P1XXX
Tran Speed: 52000000
Rd Block Len: 512
MMC version 4.5
High Capacity: Yes
Capacity: 7.2 GiB
Bus Width: 8-bit
Erase Group Size: 512 KiB
HC WP Group Size: 8 MiB
User Capacity: 7.2 GiB
Boot Capacity: 16 MiB ENH
RPMB Capacity: 128 KiB ENH
EMMC初始化代码分析
emmc初始化函数
struct mmc *mmc; 定义一个结构体指针
mmc = init_mmc_device(curr_device, false);
struct mmc *mmc; 定义一个结构体指针
mmc = find_mmc_device(dev); 返回一个全局静态结构体地址:static struct mmc mmc_static;
return &mmc_static;
mmc_init(mmc)
return mmc;
mmc_init(struct mmc *mmc)
mmc_start_init(mmc);
mmc_power_init(mmc);
mmc->ddr_mode = 0;
mmc_set_bus_width(mmc, 1);
mmc_set_clock(mmc, 1);
/* Reset the Card */
err = mmc_go_idle(mmc);
struct mmc_cmd cmd;
#define MMC_CMD_GO_IDLE_STATE 0
cmd.cmdidx = MMC_CMD_GO_IDLE_STATE;
cmd.cmdarg = 0;
cmd.resp_type = MMC_RSP_NONE;
err = mmc_send_cmd(mmc, &cmd, NULL);
mmc->cfg->ops->send_cmd(mmc, cmd, data);
probe探测函数,文件fsl_esdhc.c,赋值操作函数指针。
static const struct mmc_ops esdhc_ops = {
.send_cmd = esdhc_send_cmd,
.set_ios = esdhc_set_ios,
.init = esdhc_init,
.getcd = esdhc_getcd,
};
static const struct udevice_id fsl_esdhc_ids[] = {
{ .compatible = "fsl,imx6ul-usdhc", },
fsl_esdhc_probe
fsl_esdhc_init(priv);
struct mmc *mmc;
memset(&priv->cfg, 0, sizeof(priv->cfg));
priv->cfg.name = "FSL_SDHC";
priv->cfg.ops = &esdhc_ops;
【怎么与mmc里面的mmc->cfg->ops对应?见下面】
mmc = mmc_create(&priv->cfg, priv);
struct mmc *mmc = &mmc_static;
mmc->cfg = cfg; 等同于mmc->cfg = priv->cfg
mmc->priv = priv;
return mmc;
priv->mmc = mmc;
dts表配置
arch/arm/dts/imx6ul.dtsi
usdhc2: usdhc@02194000 {
compatible = "fsl,imx6ul-usdhc", "fsl,imx6sx-usdhc";
reg = <0x02194000 0x4000>;
interrupts = <GIC_SPI 23 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clks IMX6UL_CLK_USDHC2>,
<&clks IMX6UL_CLK_USDHC2>,
<&clks IMX6UL_CLK_USDHC2>;
clock-names = "ipg", "ahb", "per";
bus-width = <4>;
status = "disabled";
};
arch/arm/dts/imx6ul-14x14-evk.dts
&usdhc2 {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_usdhc2_8bit>;
bus-width = <8>;
non-removable;
status = "okay";
};
uboot启动到emmc初始化流程
common/board_r.c
#ifdef CONFIG_GENERIC_MMC
static int initr_mmc(void)
{
puts("MMC: ");
mmc_initialize(gd->bd);
return 0;
}
#endif
drivers/mmc/mmc.c
mmc_initialize
mmc_probe(bis);
board_mmc_init(bis)
cpu_mmc_init(bis);
fsl_esdhc_mmc_init
mmc_do_preinit();
struct mmc *m = &mmc_static;
mmc_start_init(m);
board/freescale/mx6ul_14x14_evk/mx6ul_14x14_evk.c
board_mmc_init
printf("board_mmc_init\n");
fsl_esdhc_initialize(bis, &usdhc_cfg[i]);
drivers/mmc/fsl_esdhc.c
fsl_esdhc_initialize
fsl_esdhc_init(priv)
fsl_esdhc_mmc_init
fsl_esdhc_initialize