原创 [博客大赛]U-Boot for AM335x (10) u-boot.img如何驱动SD卡

2014-8-28 15:51 3702 18 18 分类: MCU/ 嵌入式 文集: U-Boot

U-Boot for AM335x (10) u-boot.img如何驱动SD卡

调试SPL的阶段貌似进行得非常顺利,主要是它的功能并不多,除了初始化GPIO、UART0、PMIC、DRAM之外,还有就是把u-boot.img搬进DRAM运行。在这个阶段里面,MMC(SD卡)是被自动识别的,用户不需要任何设置,MLO就会被从SD卡中读取到内部的DRAM中运行,然后才有后续的一系列操作。

SPL里面初始化SD卡的代码在:
arch/arm/cpu/armv7/omap-common/boot-common.c
函数名是:
int board_mmc_init(bd_t *bis);
int omap_mmc_init(int dev_index, uint host_caps_mask, uint f_max, int cd_gpio,
                int wp_gpio);

在u-boot.img运行的时候,也会使用SPL里面初始化的MMC,默认就可以读取数据。有时候会发现这样的提示:
Card did not respond to voltage select!
这是因为AM335x默认会初始化MMC0/MMC1两个设备,而MMC1并不能检测到卡的存在,并不影响MMC0的使用。

实际上在u-boot.img的board_init_r函数中,又出现了MMC的初始化函数:
mmc_initialize(gd->bd);
它同样会调用board_mmc_init,但是这个board_mmc_init被mmc_initialize所在的文件:
driver/mmc/mmc.c
使用关键字weak alias将函数变成了什么都不做,而是直接返回-1:
int cpu_mmc_init(bd_t *bis) __attribute__((weak, alias("__def_mmc_init")));
int board_mmc_init(bd_t *bis) __attribute__((weak, alias("__def_mmc_init")));

虽然使用默认的配置也能工作,但是完整的SD卡引脚还定义了WP和CD,即写保护和状态检测,它们在SPL的初始化中被认为是-1和-1,这里给它赋上合适的值。在board_init_r中会调用函数board_init,用户可以填写自己的target代码,因此在这里加上:
configure_module_pin_mux(mmc0_pin_mux);
omap_mmc_init(0, 0, 0, 6, 114);

定义MMC0的MUX:
static struct module_pin_mux mmc0_pin_mux[] = {
        {OFFSET(mmc0_dat3), (MODE(0) | RXACTIVE | PULLUP_EN)},  /* MMC0_DAT3 */
        {OFFSET(mmc0_dat2), (MODE(0) | RXACTIVE | PULLUP_EN)},  /* MMC0_DAT2 */
        {OFFSET(mmc0_dat1), (MODE(0) | RXACTIVE | PULLUP_EN)},  /* MMC0_DAT1 */
        {OFFSET(mmc0_dat0), (MODE(0) | RXACTIVE | PULLUP_EN)},  /* MMC0_DAT0 */
        {OFFSET(mmc0_clk), (MODE(0) | RXACTIVE | PULLUP_EN)},   /* MMC0_CLK */
        {OFFSET(mmc0_cmd), (MODE(0) | RXACTIVE | PULLUP_EN)},   /* MMC0_CMD */
        {OFFSET(mcasp0_aclkr), (MODE(4) | RXACTIVE)},           /* MMC0_WP */
        {OFFSET(spi0_cs1), (MODE(5) | RXACTIVE | PULLUP_EN)},   /* MMC0_CD */
        {-1},
};

6和114的意义是GPIO0_6/GPIO3_18。

重新编译运行,在U-Boot命令提示符下输入fatls:
U-Boot# fatls mmc 0
    78092   mlo
   316860   u-boot.img
  3450576   uimage
   316796   u-boot.bin
            .trash-1000/

在U-Boot命令提示符下输入fatload命令(将uImage拷贝进相同的目录):
U-Boot# fatload mmc 0 0x82000000 uImage
reading uImage
3450576 bytes read in 333 ms (9.9 MiB/s)
U-Boot# bootm 0x82000000

运行uImage:
U-Boot# bootm 0x82000000

在U-Boot命令提示符出现之前,会有一个从MMC中读取reading uEnv.txt的步骤,在TI官网上的下面这篇文章里,给出了uEnv.txt建议的内容:
bootargs=console=ttyO0,115200n8 root=/dev/mmcblk0p2 mem=128M rootwait
bootcmd=mmc rescan; fatload mmc 0 0x82000000 uImage; bootm 0x82000000
uenvcmd=boot

它的格式必须是unix format,文件末尾必须加一个空行。将uEnv.txt和uImage拷贝进SD卡,设置AM335x从SD卡启动,此时就会发现熟悉的kernel解压信息出现啦
Importing environment from mmc ...
Running uenvcmd ...
reading uImage
3450576 bytes read in 333 ms (9.9 MiB/s)
## Booting kernel from Legacy Image at 82000000 ...
   Image Name:   Linux-3.2.0
   Image Type:   ARM Linux Kernel Image (uncompressed)
   Data Size:    3450512 Bytes = 3.3 MiB
   Load Address: 80008000
   Entry Point:  80008000
   Verifying Checksum ... OK
   Loading Kernel Image ... OK

Starting kernel ...

Uncompressing Linux... done, booting the kernel.
[    0.000000] Linux version 3.2.0 (root@adu-pc) (gcc version 4.5.3 20110311 (prerelease) (GCC) ) #1 Thu Jan 23 09:54:20 CST 2014
[    0.000000] CPU: ARMv7 Processor [413fc082] revision 2 (ARMv7), cr=10c53c7d
[    0.000000] CPU: PIPT / VIPT nonaliasing data cache, VIPT aliasing instruction cache
[    0.000000] Machine: am335xevm

(到目前为止,虽然顺利的从SD卡启动和解压Linux kernel,但是还是存在Linux kernel解压到一半卡住的问题。貌似在网上经常看到类似的帖子描述这个问题。anyway,这个等后面再解决,下一步先完善U-Boot的eth驱动。)
 

文章评论0条评论)

登录后参与讨论
我要评论
0
18
关闭 站长推荐上一条 /2 下一条