原创 为AM335x移植Linux内核主线代码(7)使用SD卡中的U-Boot操作NAND Flash

2015-3-12 09:02 2814 18 20 分类: MCU/ 嵌入式 文集: Linux Kernel的DTS

使用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,存放在SDRAM的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的重要性,硬件开发绝对绕不开它!
 

文章评论2条评论)

登录后参与讨论

DiracFatCat 2015-3-12 09:01

对的,这里的SRAM应该是SDRAM,多谢啦~

用户1831437 2015-3-11 20:33

虽然对335X了解不是很多,但0x82000000这个地址应该是extern ram的起止地址(DDR2 or DDR3),并不是SRAM, SRAM一般是在系统自举的过程中才用的到
相关推荐阅读
DiracFatCat 2018-09-05 12:14
【博客大赛】卡尔曼滤波学习笔记(11)从位置估计速度
卡尔曼滤波器,不仅仅是一个低通滤波器,否则也不会持续发展50年。 示例:桑先生需要测试高速列车的性能。测试的目的是判断列车在直线上能否保持80m/s的速度。速度和位置每0.1秒测量一次,但是由于...
DiracFatCat 2018-08-31 19:32
【博客大赛】卡尔曼滤波学习笔记(10)一个简单的示例
《Kalman Filtering: Theory and Practice Using MATLAB》第三章,看不懂,暂时略过。《Kalman Filtering: Theory and Pract...
DiracFatCat 2018-07-19 15:09
对sed命令的练习
sed是流编辑器。它每次处理一个输入,因此很有效率。官方手册:https://www.gnu.org/software/sed/manual/sed.html学习Linux命令,当然要阅读官方手册,所...
DiracFatCat 2018-06-19 15:10
【博客大赛】卡尔曼滤波学习笔记(八)可观测性和可控制性 ...
可观测性是指,在给定模型的情况下,动力学系统的状态是否由它的输入输出唯一确定。可观测性是系统模型的特征。如果传感器矩阵H是可逆的,则本系统可观测,因为有:如果传感器矩阵H某些时候是不可逆的,则本系统仍...
DiracFatCat 2018-06-19 10:56
【博客大赛】卡尔曼滤波学习笔记(七)Z变换
如果我们仅仅对离散线性系统感兴趣,那么就使用下面这个表达式:如果u是常量,那么可以写成:为了简化表达式,我们可以将上面写成:离散线性时不变系统的Φ求解,可以使用Z变换。(* 由于本人已经忘记了Z变换的...
DiracFatCat 2018-06-19 10:54
【博客大赛】卡尔曼滤波学习笔记(六)拉普拉斯变换
对于线性时变/时不变系统,求解Φ(t)有多种方式,拉普拉斯变换是其中一种。(* 由于本人已经忘记了拉普拉斯变换的内容,因此本节待续。)...
我要评论
2
18
关闭 站长推荐上一条 /2 下一条