U-Boot移植——Nand Flash

news/2024/7/6 5:04:37

0 开发环境

    宿主机:Ubuntu14.04

    开发板:MIni2440

    U-Boot:u-boot.1.1.6

1 准备工作

    先根据《U-Boot移植——添加新开发板》添加对MIini2440的支持,然后再继续本文的工作。本文的工作主要参考参考资料[5]p276-283

2 include/configs/mini2440.h

(1)CFG_CMD_NAND   

 打开include/configs/mini2440.h,取消CFG_CMD_NAND的注释:


(2)CFG_NAND_BASE CFG_MAX_NAND_DEVICE NAND_MAX_CHIPS

    添加上述CFG_CMD_NAND之后重新编译u-boot-1.1.6,出现以下错误:


    在include/configs/mini2440.h的最后添加以下宏定义:

#define CFG_NAND_BASE 0     /* 无实际意义: 基地址, 在board_nand_init中重新指定 */                                                              
#define CFG_MAX_NAND_DEVICE 1 /* NAND Flash"设备"的数目为1 */
#define NAND_MAX_CHIPS      1 /* 每个NAND Flash "设备"由1个NAND Flash"芯片"组成 */

3 board_nand_init()

    经过上述修改,再次编译提示:


    由上图可见,缺乏board_nand_init()的实现。下面描述如何一步一步实现board_nand_init()函数。

(1)include/s3c24x0.h

    打开include/s3c24x0.h,仿照S3C2410_NAND的定义添加S3C2440_NAND的定义:

/* NAND FLASH (see S3C2440 manual chapter 6) */
typedef struct {
    S3C24X0_REG32   NFCONF;
    S3C24X0_REG32   NFCONT;
    S3C24X0_REG32   NFCMD;
    S3C24X0_REG32   NFADDR;
    S3C24X0_REG32   NFDATA;
    S3C24X0_REG32   NFMECCD0;
    S3C24X0_REG32   NFMECCD1;
    S3C24X0_REG32   NFSECCD;
    S3C24X0_REG32   NFSTAT;
    S3C24X0_REG32   NFESTAT0;
    S3C24X0_REG32   NFESTAT1;
    S3C24X0_REG32   NFMECC0;
    S3C24X0_REG32   NFMECC1;
    S3C24X0_REG32   NFSECC;
    S3C24X0_REG32   NFSBLK;
    S3C24X0_REG32   NFEBLK;
} /*__attribute__((__packed__))*/ S3C2440_NAND;
    上述结构中的成员都是S3C2440的Nand Flash寄存器,详见S3C2440手册p6-12。
(2)include/s3c2410.h

    打开include/s3c2410.h,仿照S3C2410_GetBase_NAND()定义S3C2440_GetBase_Nand()

static inline S3C2440_NAND * const S3C2440_GetBase_NAND(void)                   
{
    return (S3C2440_NAND * const)S3C2410_NAND_BASE;// 注:这里是S3C2410_NAND_BASE,不是S3C2440_NAND_BASE
}

(3)cpu/arm920t/s3c24x0/nand_flash.c

   在cpu/arm920t/s3c24x0中创建一个源文件nand_flash.c,内容如下:

/*
 * s3c2440的Nand Flash控制器接口
 * 修改自Linux内核2.6.13文件drivers/mtd/nand/s3c2410.c
 */
#include <common.h>

#if (CONFIG_COMMANDS & CFG_CMD_NAND) && !defined(CFG_NAND_LEGACY)
#include <nand.h>
#include <s3c2410.h>

DECLARE_GLOBAL_DATA_PTR;

#define S3C2440_NFSTAT_READY (1<<0)
#define S3C2440_NFCONT_nFCE (1<<1)

/* NAND Flash的片选函数 */
static void s3c2440_nand_select_chip(struct mtd_info *mtd, int chip)
{
	S3C2440_NAND *const s3c2440nand = S3C2440_GetBase_NAND();
	
	if (chip == -1) {
		s3c2440nand->NFCONT |= S3C2440_NFCONT_nFCE; /* 禁止片选信号 */
	} else {
		s3c2440nand->NFCONT &= ~S3C2440_NFCONT_nFCE; /* 使能片选信号 */
	}
}

/* 命令和控制函数 */
static void s3c2440_nand_hwcontrol(struct mtd_info *mtd, int cmd)
{
	S3C2440_NAND *const s3c2440nand = S3C2440_GetBase_NAND();
	struct nand_chip *chip = mtd->priv;
	
	switch (cmd) {
		case NAND_CTL_SETNCE:
		case NAND_CTL_CLRNCE:
			printf("%s: called for NCE\n", __FUNCTION__);
			break;
		case NAND_CTL_SETCLE:
			chip->IO_ADDR_W = (void *)&s3c2440nand->NFCMD;
			break;
		case NAND_CTL_SETALE:
			chip->IO_ADDR_W = (void *)&s3c2440nand->NFADDR;
			break;
			/* NAND_CTL_CLRCLE */
			/* NAND_CTL_CLRALE */
		default:
			chip->IO_ADDR_W = (void *)&s3c2440nand->NFDATA;
			break;
	}
}

/*
 * S3C2440: 查询NAND Flash状态
 * 返回值: 0表示忙, 1表示就绪
 */
static int s3c2440_nand_devready(struct mtd_info *mtd)
{
	S3C2440_NAND * const s3c2440nand = S3C2440_GetBase_NAND();

	return (s3c2440nand->NFSTAT & S3C2440_NFSTAT_READY);
}

/* Nand Flash硬件初始化 */
static void s3c24x0_nand_inithw(void)
{
	S3C2440_NAND * const s3c2440nand = S3C2440_GetBase_NAND();

#define TACLS 	0
#define TWRPH0 	4
#define TWRPH1 	2

	/* 设置时序 */
	s3c2440nand->NFCONF = (TACLS<<12)|(TWRPH0<<8)|(TWRPH1<<4);
	
	/* 初始化ECC, 使能NAND Flash 控制器, 使能片选信号 */
	s3c2440nand->NFCONT = (1<<4)|(0<<1)|(1<<0);
}

/* 
 * 被dirver/nand/nand.c调用, 初始化NAND Flash硬件, 初始化访问接口函数
 */
void board_nand_init(struct nand_chip *chip)
{
	S3C2440_NAND * const s3c2440nand = S3C2440_GetBase_NAND();


	s3c24x0_nand_inithw(); /*NAND Flash硬件初始化 */

	chip->IO_ADDR_R = (void *)&s3c2440nand->NFDATA;
	chip->IO_ADDR_W = (void *)&s3c2440nand->NFDATA;
	chip->hwcontrol = s3c2440_nand_hwcontrol;
	chip->dev_ready = s3c2440_nand_devready;
	chip->select_chip = s3c2440_nand_select_chip;
	chip->options = 0; /* 设置位宽等, 位宽为8  */

	chip->eccmode = NAND_ECC_SOFT; /* ECC校验方式: 软件ECC */
}
#endif
(4)cpu/arm920t/s3c24x0/Makefile

    在cpu/arm920t/s3c24x0/Makefile添加nand_flash.o

4 编译&下载&运行

    通过上述修改,可以重新编译u-boot-1.1.6,然后下载到Mini2440中运行:


    可通过nand info命令进一步查看Nand Flash的信息:


    也可以通过nand erase/write对Nand Flash进行擦除/写。

5 容易出错的地方


    若根据参考资料[6]的提示可知这是s3c24x0_nand_inithw()有误所致的,例如将NFCONT误写为NFCONF时,就会出现上述错误。

参考资料

[1]u-boot移植之nand flash移植 

[2]TQ2440的学习——UBOOT移植(NAND FLASH的支持)——初步分析

[3]UBOOT移植(NAND FLASH的支持)——初步移植 (一)

[4]UBOOT移植(NAND FLASH的支持)——初步移植 (二) 

[5]韦东山. 嵌入式Linux应用开发完全手册. 人民邮电出版社,2012

[6]U-Boot出现No NAND device found!!!的解决办法 


http://www.niftyadmin.cn/n/847588.html

相关文章

sensors.goldfish.so是什么

sensors.goldfish.so是什么突然发现编译总是会有sensors.goldfish.so生成&#xff0c;今天追究了一下&#xff0c;它来自development/tools/emulator/system/sensors看样子是给模拟器用的。同样的例子还有一些库&#xff0c;都是模拟器用的。不用关心。也可以修改Android.mk不编…

vim删除文本的命令

x 删除光标下的字符 ("dl" 的缩写) X 删除光标前的字符 ("dh" 的缩写) D 从当前位置删除到行尾 ("d$" 的缩写) dw 从当前位置删除到下一个单词开头 db 从当前位置删除到前一个单词的开头 diw 删除光标上的单词 (不包括空白字符…

大数据虚拟化零起点-2基础运维第一步-环境规划和准备

大数据的虚拟化之旅以POC开启最为合适。POC是Proofof Concept的简称&#xff0c;意思是概念验证&#xff0c;也就是通常意义上指的测试&#xff0c;用以了解产品的特性是否符合预期的需求。那么&#xff0c;如何从零起点部署大数据虚拟化的POC环境呢&#xff1f;我认为&#xf…

java去重(1通过迭代器,2直接赋值)

1.List<Integer> listnew ArrayList<Integer>(); //有值 List<Integer> listTemp new ArrayList<Integer>(); //临时的list Iterator<Integer> itlist.iterator();//取得有值得list的迭代器 while(it.hasNext()){ int a it.next(); if(lis…

在ubuntu12.04中开启休眠功能

在ubuntu12.04中开启休眠功能1&#xff0c;调整swap分区大于等于内存。2&#xff0c;找出swap的UUID。sudo blkid3&#xff0c;修改/etc/default/grub文件。找到GRUB_CMDLINE_LINUX""&#xff0c;修改为GRUB_CMDLINE_LINUX"resumeUUID第二步找到的swap uuid&quo…

函数可重入性及编写规范

一、可重入函数1&#xff09;什么是可重入性&#xff1f;可重入&#xff08;reentrant&#xff09;函数可以由多于一个任务并发使用&#xff0c;而不必担心数据错误。相反&#xff0c; 不可重入&#xff08;non-reentrant&#xff09;函数不能由超过一个任务所共享&#xff0c;…

执行make menuconfig出来了N多错误

make menuconfig 出来了N多错误&#xff0c;配置界面也出不来&#xff0c;搜了下发现这些错误都是和menuconfig这个界面的显示程序有关解决办法:http://lzjyjh.blog.sohu.com/137854765.html用google查了原来是少了 ncurses-devel 组件&#xff0c;这就是menuconfig的显示程序。…

Ubuntu14.04中实现Mini2440裸板编程

宿主机&#xff1a;Ubuntu14.04 开发板&#xff1a;MIni2440 编译器&#xff1a;arm-linux-gcc 0 前言 在进行ARM开发板的裸板编程时&#xff08;无操作系统&#xff09;&#xff0c;通常需要使用一定的IDE&#xff08;集成了ARM相关的编译器和连接器&#xff09;&#xff0c;…