基于优龙FS2410开发板u-boot-1.1.6的移植(NAND FLASH)

 

本文实现u-boot的写操作,实验过程中,参考了网上资料,列举如下:
《uboot1.1.4移植》网址:
http://hi.baidu.com/edaworld/blog/item/c40f83a8a2e6d1b5cb130cca.html
《uboot for s3c2410 nandboot 使用saveenv保存环境变量》网址:

《基于smdk2410 开发板u-boot-1.2.0 对 nand flash的支持》PDF文档。
涉及文件:
common/env_nand.c
Driver/nand_legacy/ nand_legacy.c
Include/configs/fs2410.h
具体修改分析:
Lib_arm/board.c
u-boot 运行至第二阶段进入 start_armboot()函数。其中 nand_init()函数是对 nand flash 的最初初始化函数。其调用与 CFG_NAND_LEGACY 宏有关,如果没定义 CFG_NAND_LEGACY 这个宏,就按照start_armboot()调用 drivers/nand/nand.c 中的 nand_init 函数(该函数在 1.1.6 已经被实现), 但还有个 board_nand_init()函数没实现,需自己添加。如果定义了CFG_NAND_LEGACY,就不使用默认的 nand_init,而调用自己写的 nand_init 函数了,这里我们选择第二种方式。
具体步骤如下:
1. 加入 NAND 闪存芯片型号
在/include/linux/mtd/ nand_ids.h 中对如下结构体赋值进行修改:
static struct nand_flash_dev nand_flash_ids[]= {
......
{"Samsung K9F1208U0M", NAND_MFR_SAMSUNG, 0x76, 26, 0, 3, 0x4000, 0}, /*2008-6-25*/
......
}
这样对于该款 NAND 闪存芯片的操作才能正确执行。
2. 编写 NAND 闪存初始化函数
在/drivers/nand_legacy/nand_legacy.c 中加入 nand_init()函数。
/*08-6-25 START*/
/*-----------------------------------------------------------------------
* NAND flash basic functions
* Added by wei jing 2008.6.25
* Copied from board/mpl/vcma9/vcma9.h & vcma9.c
*/
#if (CONFIG_COMMANDS & CFG_CMD_NAND)
#include
/*----------------------------------------------------------------------*/
typedef enum {
NFCE_LOW,
NFCE_HIGH
} NFCE_STATE;
static inline void NF_Conf(u16 conf)
{
S3C2410_NAND * const nand = S3C2410_GetBase_NAND();
nand->NFCONF = conf;
}
static inline void NF_Cmd(u8 cmd)
{
S3C2410_NAND * const nand = S3C2410_GetBase_NAND();
nand->NFCMD = cmd;
}
static inline void NF_CmdW(u8 cmd)
{
NF_Cmd(cmd);
udelay(1);
}
static inline void NF_Addr(u8 addr)
{
S3C2410_NAND * const nand = S3C2410_GetBase_NAND();
nand->NFADDR = addr;
}
static inline void NF_SetCE(NFCE_STATE s)
{
S3C2410_NAND * const nand = S3C2410_GetBase_NAND();
switch (s) {
case NFCE_LOW:
nand->NFCONF &= ~(1NFCONF |= (1NFSTAT & (1NFDATA = data;
}
static inline u8 NF_Read(void)
{
S3C2410_NAND * const nand = S3C2410_GetBase_NAND();
return(nand->NFDATA);
}
static inline void NF_Init_ECC(void)
{
S3C2410_NAND * const nand = S3C2410_GetBase_NAND();
nand->NFCONF |= (1NFECC);
}
extern ulong
nand_probe(ulong physadr);
static inline void NF_Reset(void)
{
int i;
NF_SetCE(NFCE_LOW);
NF_Cmd(0xFF); /* reset command */
for(i = 0; i NFCONF = (1> 20);
}
#endif /* CONFIG_COMMANDS & CFG_CMD_NAND */
/*08-6-25 END*****************************************************/
/*
* Exported variables etc.
*/
可以看到 nand_init()调用 NF_Init()函数,使能 nand flash 控制器和 nand flash;调用 NF_Reset()函数置位,NF_WaitRB()查询 nand flash 的状态,最后在调用 nand_probe((ulong)nand)函数探测 nand flash.
3. 修改include/configs/fs2410.h,在上次修改的基础上加上如下代码,定义 NAND 闪存命令层的底
接口函数等:
#define CFG_NAND_LEGACY 1//#define NFCE_LOW 0//#define NFCE_HIGH 1#define CFG_ENV_IS_IN_NAND 1#define CFG_NAND_BASE 0x4E000000#define CMD_SAVEENV#define CFG_ENV_SIZE 0x10000 /* Total Size of Environment Sector */ #define CFG_ENV_OFFSET 0x20000 /*环境变量在NAND FLASH的0x20000处*/#define CFG_MONITOR_BASE PHYS_SDRAM_1 /*----------------------------------------------------------------------- * NAND flash settings */ #if (CONFIG_COMMANDS & CFG_CMD_NAND)#define CFG_NAND_LEGACY#define CFG_MAX_NAND_DEVICE 1 /* Max number of NAND devices */#define SECTORSIZE 512#define ADDR_COLUMN 1#define ADDR_PAGE 2#define ADDR_COLUMN_PAGE 3#define NAND_ChipID_UNKNOWN 0x00#define NAND_MAX_FLOORS 1#define NAND_MAX_CHIPS 1#define NAND_WAIT_READY(nand) NF_WaitRB()#define NAND_DISABLE_CE(nand) NF_SetCE(NFCE_HIGH)#define NAND_ENABLE_CE(nand) NF_SetCE(NFCE_LOW)#define WRITE_NAND_COMMAND(d, adr) NF_Cmd(d)#define WRITE_NAND_COMMANDW(d, adr) NF_CmdW(d)#define WRITE_NAND_ADDRESS(d, adr) NF_Addr(d)#define WRITE_NAND(d, adr) NF_Write(d)#define READ_NAND(adr) NF_Read()/* the following functions are NOP's because S3C24X0 handles this in hardware */#define NAND_CTL_CLRALE(nandptr)#define NAND_CTL_SETALE(nandptr)#define NAND_CTL_CLRCLE(nandptr)#define NAND_CTL_SETCLE(nandptr)#define CONFIG_MTD_NAND_VERIFY_WRITE 1#define CONFIG_MTD_NAND_ECC_JFFS2 1#endif /* CONFIG_COMMANDS & CFG_CMD_NAND */ /*08-6-25***************************************************/
4. 在fs2410.h中打开命令:
/***********************************************************
* Command definition
***********************************************************/

首先引用《嵌入式系统 Boot Loader 技术内幕》的一段话:Boot Loader 的设计与实现是一个非常复杂的过程。如果不能从串口收到那激动人心的"uncompressing linux.................. done, booting the kernel……"内核启动信息,恐怕谁也不能说:"嗨,我的 boot loader 已经成功地转起来了!" 我对此深有体会,这就是为什么这篇文章推迟一个星期才出来的原因。
u-boot实现linux内核引导步骤:
1、U-BOOT给linux内核传递合适参数的定义
修改include/configs/fs2410.h如下:
……
……
/************************************************************
* RTC
************************************************************/
#define CONFIG_RTC_S3C24X0 1
/* allow to overwrite serial and ethaddr */
#define CONFIG_ENV_OVERWRITE
#define CONFIG_BAUDRATE 115200

/************************************************************/
/* enable passing of ATAGs */
#define CONFIG_CMDLINE_TAG 1
#define CONFIG_SETUP_MEMORY_TAGS 1
#define CONFIG_INITRD_TAG 1

/***********************************************************
* Command definition
***********************************************************/
#define CONFIG_COMMANDS \
(CONFIG_CMD_DFL | \
CFG_CMD_CACHE | \
CFG_CMD_NAND | \
/*CFG_CMD_EEPROM |*/ \
/*CFG_CMD_I2C |*/ \
/*CFG_CMD_USB |*/ \
CFG_CMD_REGINFO | \
CFG_CMD_DATE | \
CFG_CMD_ELF)
……
……
2、修改UBOOT的2410CPU频率
smdk2410的U-BOOT原来运行频率是202.8M,而FS2410的BIOS里面是200M,所以不修改频率可能会出点问题。按照网上的说法,内核中,在\arch\arm\mach_s3c2410\s3c2410.c 中,fclk = s3c2410_get_pll(MPLLCON, xtal); //读出来的fclk结果和bootloader的频率不一致。
修改board/fs2410/fs2410.c文件如下:
#define FCLK_SPEED 1
#if FCLK_SPEED==0 /* Fout = 203MHz, Fin = 12MHz for Audio */
#define M_MDIV 0xC3
#define M_PDIV 0x4
#define M_SDIV 0x1
#elif FCLK_SPEED==1 /* Fout = 202.8MHz */
//#define M_MDIV 0xA1
//#define M_PDIV 0x3
//#define M_SDIV 0x1
#define M_MDIV 0x5c /* Fout = 200MHz */
#define M_PDIV 0x4
#define M_SDIV 0x0
#endif
3、修改include/configs/fs2410.h中的CFG_LOAD_ADDR的地址为0x30007FC0
这是内核的加载地址,board/smdk2410/config.mk文件注释中提到Linux内核希望自己被加载到0x30008000的内存地址,而由于uImage会在kernel镜像之前加上大小为0x40的头文件消息,所以需要减去0x40。
4、制作uImage
在编译内核的时候如果用命令make uImage来生成uImage的话,我发现Load Address 30008000, Entry Point 30008000,为什么这样我没细研究,所以我用mkimage来生成uImage,做法如下:
[root@localhost tftpboot]#mkimage -n 'linux-2.6.25' -A arm -O linux -T kernel -C none -a 0x30007fc0 -e 0x30008000 -d zImage uImage
Image Name linux-2.6.25
Created Thu Jul 3 101845 2008
Image Type ARM Linux Kernel Image (uncompressed)
Data Size 1556188 Bytes =1556252 kB = 1.5 MB
Load Address 0x30007fc0
Entry Point 0x30008000

这里解释一下参数的意义:
-A == set architecture to 'arch'
-O == set operating system to 'os'
-T == set image type to 'type'
-C == set compression type 'comp'
-a == set load address to 'addr' (hex)
-e == set entry point to 'ep' (hex)
-n == set image name to 'name'
-d == use image data from 'datafile'
-x == set XIP (execute in place)
这里我移植的是2.6.25内核,当然也可以:Load Address 0x30008000 、Entry Point 0x30008040
5、固化
make修改好的u-boot,将u-boot.bin和uImage写入flash相应位置,然后设置u-boot启动命令:
[FS2410]#setenv bootargs root=1f02 init=/linuxrc console=ttySAC0,115200 devfs=mount
[FS2410]#setenv bootcmd nand read 0x30007fc0 0x40000 0x1c0000\;bootm 0x30007fc0
[FS2410]#saveenv
Saving Environment to NAND...
Erasing Nand...Writing to Nand... done
好了,可以通过printenv、bdinfo等命令查看自己的u-boot参数了,最后reset一下,如果运气好点的话,就会看到那激动人心的
Uncompressing Linux....................................................... done, booting the kernel.
之后就是一阵洋文飘过……
后记:
s3c2410上移植uboot和linux2.6内核.虽然网上的文章多多,但真正要在自己的板子上跑起来还真是问题多。其间参考了不少网上同行们的文章,受益匪浅。最后我还将调制过程中遇到的问题总结列出,供后人参考。

 


问题一:Load Address 、Entry Point 设置问题
Starting kernel ...
undefined instruction
pc : [] lr : []
sp : 33f4fc10 ip : 00000001 fp : 33f4fca4
r10: 33f9e70c r9 : 33ece9cd r8 : 33f4ffdcc
r7 : 33f4ffb8 r6 : 00000000 r5 : 00000000 r4 : 00000000
r3 : 30008000 r2 : c0000100 r1 : 000000c1 r0 : 00000000
Flags: nZCv IRQs off FIQs off Mode SVC_32
Resetting CPU ...


引导内核在这里进不去,网上也没一个很好的说法,由上图可知:Load Address 0x30008000 、Entry Point 0x30008000 ,#bootm的时候,显示是的内核前头加上的64byte的信息r1:000000c1 r0:00000000……按照上述制作uImage的方法设Load Address 、Entry Point 就ok。

 


 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
资源包主要包含以下内容: ASP项目源码:每个资源包中都包含完整的ASP项目源码,这些源码采用了经典的ASP技术开发,结构清晰、注释详细,帮助用户轻松理解整个项目的逻辑和实现方式。通过这些源码,用户可以学习到ASP的基本语法、服务器端脚本编写方法、数据库操作、用户权限管理等关键技术。 数据库设计文件:为了方便用户更好地理解系统的后台逻辑,每个项目中都附带了完整的数据库设计文件。这些文件通常包括数据库结构图、数据表设计文档,以及示例数据SQL脚本。用户可以通过这些文件快速搭建项目所需的数据库环境,并了解各个数据表之间的关系和作用。 详细的开发文档:每个资源包都附有详细的开发文档,文档内容包括项目背景介绍、功能模块说明、系统流程图、用户界面设计以及关键代码解析等。这些文档为用户提供了深入的学习材料,使得即便是从零开始的开发者也能逐步掌握项目开发的全过程。 项目演示与使用指南:为帮助用户更好地理解和使用这些ASP项目,每个资源包中都包含项目的演示文件和使用指南。演示文件通常以视频或图文形式展示项目的主要功能和操作流程,使用指南则详细说明了如何配置开发环境、部署项目以及常见问题的解决方法。 毕业设计参考:对于正在准备毕业设计的学生来说,这些资源包是绝佳的参考材料。每个项目不仅功能完善、结构清晰,还符合常见的毕业设计要求和标准。通过这些项目,学生可以学习到如何从零开始构建一个完整的Web系统,并积累丰富的项目经验。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值