为AM335x移植Linux内核主线代码
七、使用SD卡中的U-Boot操作NAND Flash
使用OK335xD核心板上的NAND Flash,无论是速度还是稳定性,都比SD卡好,所以接下来的任务是使用SD中的U-Boot操作NAND Flash,把需要的镜像烧录进去之后,就可以从NAND Flash启动了!
第一步:按照《U-Boot for AM335x》的步骤准备好:
OK335x开发板
按照TI公司官方文档的要求,格式化的SD卡(create-sdcard.sh)
准备一份编译通过的可用的U-Boot源代码(uart/mmc0/eth/gpio/i2c功能)uImage和文件系统镜像
第二步:修改U-Boot源代码中mux部分:
static struct module_pin_mux nand_pin_mux[] = { {OFFSET(gpmc_ad0), MODE(0) | PULLUP_EN | RXACTIVE}, {OFFSET(gpmc_ad1), MODE(0) | PULLUP_EN | RXACTIVE}, {OFFSET(gpmc_ad2), MODE(0) | PULLUP_EN | RXACTIVE}, {OFFSET(gpmc_ad3), MODE(0) | PULLUP_EN | RXACTIVE}, {OFFSET(gpmc_ad4), MODE(0) | PULLUP_EN | RXACTIVE}, {OFFSET(gpmc_ad5), MODE(0) | PULLUP_EN | RXACTIVE}, {OFFSET(gpmc_ad6), MODE(0) | PULLUP_EN | RXACTIVE}, {OFFSET(gpmc_ad7), MODE(0) | PULLUP_EN | RXACTIVE}, {OFFSET(gpmc_wait0), MODE(0) | PULLUP_EN | RXACTIVE}, {OFFSET(gpmc_wpn), MODE(0) | PULLUP_EN | RXACTIVE}, {OFFSET(gpmc_csn0), MODE(0) | PULLUP_EN}, {OFFSET(gpmc_oen_ren), MODE(0) | PULLUP_EN}, {OFFSET(gpmc_wen), MODE(0) | PULLUP_EN}, {OFFSET(gpmc_be0n_cle), MODE(0) | PULLUP_EN}, {-1}, };
别忘了执行下面这句:
configure_module_pin_mux(nand_pin_mux);
第三步:在U-Boot源代码中board_init函数中添加:
gpmc_init();
第四步:在include/configs/maria_am335x.h中添加:
#define CONFIG_CMD_NAND #define CONFIG_SYS_MAX_NAND_DEVICE 1 #define CONFIG_SYS_NAND_BASE 0x800000 #define CONFIG_NAND_OMAP_GPMC #define CONFIG_NAND_OMAP_ELM #define CONFIG_SYS_NAND_5_ADDR_CYCLE #define CONFIG_SYS_NAND_PAGE_COUNT (CONFIG_SYS_NAND_BLOCK_SIZE / \ CONFIG_SYS_NAND_PAGE_SIZE) #define CONFIG_SYS_NAND_PAGE_SIZE 2048 #define CONFIG_SYS_NAND_OOBSIZE 64 #define CONFIG_SYS_NAND_BLOCK_SIZE (128*1024) #define CONFIG_SYS_NAND_BAD_BLOCK_POS NAND_LARGE_BADBLOCK_POS #define CONFIG_SYS_NAND_ECCPOS { 2, 3, 4, 5, 6, 7, 8, 9, \ 10, 11, 12, 13, 14, 15, 16, 17, \ 18, 19, 20, 21, 22, 23, 24, 25, \ 26, 27, 28, 29, 30, 31, 32, 33, \ 34, 35, 36, 37, 38, 39, 40, 41, \ 42, 43, 44, 45, 46, 47, 48, 49, \ 50, 51, 52, 53, 54, 55, 56, 57, } #define CONFIG_SYS_NAND_ECCSIZE 512 #define CONFIG_SYS_NAND_ECCBYTES 14 #define CONFIG_SYS_NAND_ONFI_DETECTION #define CONFIG_NAND_OMAP_ECCSCHEME OMAP_ECC_BCH8_CODE_HW #define CONFIG_SYS_NAND_U_BOOT_START CONFIG_SYS_TEXT_BASE #define CONFIG_SYS_NAND_U_BOOT_OFFS 0x80000
为什么不直接只用CONFIG_NAND,这些宏不就跟着定义了吗?
因为CONFIG_NAND的含义是从NAND启动,而这里只是要对NAND Flash进行读取和烧写操作,booting设备还是SD卡。
第五步:修改arch/arm/cpu/armv7/am33xx/mem.c中的"gpmc_init"函数:
void gpmc_init(void) { gpmc_cfg = (struct gpmc *)GPMC_BASE; const u32 gpmc_regs[GPMC_MAX_REG] = { M_NAND_GPMC_CONFIG1, M_NAND_GPMC_CONFIG2, M_NAND_GPMC_CONFIG3, M_NAND_GPMC_CONFIG4, M_NAND_GPMC_CONFIG5, M_NAND_GPMC_CONFIG6, 0 }; u32 size = GPMC_SIZE_256M; u32 base = CONFIG_SYS_NAND_BASE; writel(0x00000008, &gpmc_cfg->sysconfig); writel(0x00000000, &gpmc_cfg->irqstatus); writel(0x00000000, &gpmc_cfg->irqenable); writel(0x00000012, &gpmc_cfg->config); writel(0, &gpmc_cfg->cs[0].config7); sdelay(1000); enable_gpmc_cs_config(gpmc_regs, &gpmc_cfg->cs[0], base, size); }
这是因为gpmc_init依赖于CONFIG_NAND,要不然基本不干活,因此去掉它的宏判断。
第六步:编译它:
make ARCH=arm CROSS_COMPILE=/opt/arm-arago-linux-gcc/usr/bin/arm-linux-gnueabihf- -j8 O=../build maria_am335x_config
make ARCH=arm CROSS_COMPILE=/opt/arm-arago-linux-gcc/usr/bin/arm-linux-gnueabihf- -j8 O=../build all
第七步:将生成的MLO和u-boot.img放置到SD卡中:
cp ../build/MLO ../build/u-boot.img /run/media/maria/boot/
第八步:开发板插入SD卡,设置为从SD卡启动,上电。
在命令提示符下输入:
U-Boot# set ipaddr 192.168.1.117 U-Boot# set serverip 192.168.1.116 U-Boot# tftp 0x82000000 MLO U-Boot# nand erase 0x0 0x20000 U-Boot# nand write.i 0x82000000 0x0 0x20000 U-Boot# tftp 0x82000000 u-boot.img U-Boot# nand erase 0x80000 0x40000 U-Boot# nand write.i 0x82000000 0x80000 0x40000
这些命令的含义是,从tftp服务器上获取MLO和u-boot.img,存放在SRAM的0x82000000处,并分别烧写在NAND Flash的0x0和0x80000地址。拔除SD卡,重新上电,就能看到U-Boot从NAND Flash启动的串口打印信息了!
NOTICE: 存放在tftp上的MLO和u-boot.img不能是Forlinx光盘里面的镜像,也不是上面所述的这个,而是需要使用全新的源代码重新编译。因为Forlinx和这里的MLO和u-boot.img都是从SD卡启动的,全新编译出来的应该是从NAND Flash启动。参照boards.cfg文件!
现在,这张SD卡就相当于一个下载器了,可以使用它实现读取和烧写存储器的功能,包括串口、SD卡和NAND Flash操作,这也说明,U-Boot的重要性,硬件开发绝对绕不开它!
(转载自:MariannaZhu)
http://forum.eepw.com.cn/thread/262788/1