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条评论)
登录后参与讨论