U-Boot移植过程
① 获得发布的最新版本U-Boot源码,与Linux内核源码类似,也是 bzip2的压缩格式。可从U-Boot的官方网站http://sourceforge.net/projects/U-Boot上获得;
② 阅读相关文档,主要是U-Boot源码根目录下的README文档和U-Boot官方网站的DULG(The DENX U-Boot and Linux Guide)文档http://www.denx.de/twiki/bin/view/DULG/Manual。尤其是DULG文档,从如何安装建立交叉开发环境和解决U-Boot移植中常见问题都一一给出详尽的说明;
③ 订阅U-Boot用户邮件列表http://lists.sourceforge.net/lists/listinfo/u-boot-users。在移植U-Boot过程中遇有问题,在参考相关文<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />
下载:
http://sourceforge.net/projects/U-Boot
解压:
进入目录
移植:
一、在顶层Makefile中为开发板添加新的配置选项
smdk2410_config : unconfig
@./mkconfig $(@:_config=) arm arm920t smdk2410 NULL s3c24x0
参考上面2行,添加下面2行。
real2410_config : unconfig
@./mkconfig $(@:_config=) arm arm920t real2410 NULL s3c24x0
二、在board中创建一个新目录real2410存放开发板相关的代码,并且添加文 件。
cp rf board/smdk2410 board/real2410
#cd board/real2410
#mv smdk2410.c real2410.c
三、修改board/real2410/Makefile
将28行的 OBJS := smdk2410.o flash.o
改为 OBJS := real2410.o flash.o
四、修改board/real2410/flash.c 参考board/dave/common/flash.c
#define CMD_ERASE_BLOCK 0x0050
#elif defined(CONFIG_SST_39VF1601)
(SST_MANUFACT & FLASH_VENDMASK) |
(SST_ID_xF1601 & FLASH_TYPEMASK);
在int flash_erase (flash_info_t * info, int s_first, int s_last)
#if defined(CONFIG_SST_39VF1601) /* Ali + */
*addr = CMD_ERASE_BLOCK;
#else
*addr = CMD_ERASE_CONFIRM;
#endif
在volatile static int write_hword (flash_info_t * info, ulong dest, ushort data)
#if defined(CONFIG_SST_39VF1601) /* Ali + */
MEM_FLASH_ADDR1 = CMD_PROGRAM;
#else
MEM_FLASH_ADDR1 = CMD_UNLOCK_BYPASS;
*addr = CMD_PROGRAM;
#endif
五、为开发板添加新的配置文件
$cp include/configs/smdk2410.h include/configs/real2410.h
修改include/configs/real2410.h
#define CONFIG_SST_39VF1601 1
//#define CONFIG_AMD_LV400 1
#ifdef CONFIG_SST_39VF1601
#define PHYS_FLASH_SIZE 0x00200000 /* 2MB */
#define CFG_MAX_FLASH_SECT (35)
#define CFG_ENV_ADDR (CFG_FLASH_BASE + 0x1F0000)
#endif
六、$ make real2410_config
$ make
生成u-boot(elf映像)和u-boot.bin
七、支持NAND FLASH读写
①修改include/configs/real2410.h
#define rNFCONF (*(volatile unsigned int *)0x4e000000)
#define rNFCMD (*(volatile unsigned char *)0x4e000004)
#define rNFADDR (*(volatile unsigned char *)0x4e000008)
#define rNFDATA (*(volatile unsigned char *)0x4e00000c)
#define rNFSTAT (*(volatile unsigned int *)0x4e000010)
#define rNFECC (*(volatile unsigned int *)0x4e000014)
#define rNFECC0 (*(volatile unsigned char *)0x4e000014)
#define rNFECC1 (*(volatile unsigned char *)0x4e000015)
#define rNFECC2 (*(volatile unsigned char *)0x4e000016)
在CONFIG_COMMANDS中, 打开CFG_CMD_NAND选项.
#if(CONFIG_COMMANDS&CFG_CMD_NAND)
#define CFG_NAND_BASE 0x4E000000
#define CFG_NAND_LEGACY 1
#define CFG_MAX_NAND_DEVICE 1
#define SECTORSIZE 512
//#define NAND_SECTOR_SIZE SECTORSIZE
//#define NAND_BLOCK_MASK (NAND_SECTOR_SIZE-1)
#define ADDR_COLUMN 1
#define ADDR_PAGE 3
#define ADDR_COLUMN_PAGE 4
#define NAND_ChipID_UNKNOWN 0x00
#define NAND_MAX_FLOORS 1
#define NAND_MAX_CHIPS 1
#define NAND_WAIT_READY(nand) {while(!(rNFSTAT&(1<<0)));}
#define NAND_DISABLE_CE(nand) {rNFCONF|=(1<<11);}
#define NAND_ENABLE_CE(nand) {rNFCONF&=~(1<<11);}
#define WRITE_NAND_COMMAND(d,adr) do {rNFCMD=d;}while(0)
#define WRITE_NAND_ADDRESS(d,adr) do {rNFADDR=d;}while(0)
#define WRITE_NAND(d,adr) do {rNFDATA=d;}while(0)
#define READ_NAND(adr) (rNFDATA)
/*the following functions are NOP's because S3C24x0 handle 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)
②加入自己的Nand Flash芯片型号
在include/linux/mtd/ nand_ids.h中的对如下结构体赋值进行修改:
static struct nand_flash_dev nand_flash_ids[] = {
......
{"Samsung K9F1208U0B", NAND_MFR_SAMSUNG, 0x76, 26, 0, 4, 0x4000, 0},
.......
}
③编写自己的Nand Flash初始化函数
在board/real2410/real2410.c中加入nand_init()函数.
void nand_reset(void)
{
int i;
rNFCONF=0xf830;
rNFCONF&=~(1<<11);
rNFCMD=0xff;
for(i=0;i<10;i++);
while(!(rNFSTAT&(1<<0)));
rNFCONF|=(1<<11);
}
void nand_init(void)
{
/* 初始化Nand Flash控制器, 以及Nand Flash 芯片 */
nand_reset();
/* 调用nand_probe()来检测芯片类型 */
printf ("%4lu MB\n", nand_probe(CFG_NAND_BASE) >> 20);
}
④ make
在board/real2410加入NAND Flash读函数,建立nand_read.c, (copy from vivi)
修改include/configs/real2410.h
#define CONFIG_S3C2410_NAND_BOOT 1
#ifdef CONFIG_S3C2410_NAND_BOOT
#define STACK_BASE 0x33f00000
#define STACK_SIZE 0x8000
#define UBOOT_RAM_BASE 0x33f80000
/* NAND Flash Controller */
#define NAND_CTL_BASE 0x4E000000
#define bINT_CTL(Nb) __REG(INT_CTL_BASE + (Nb))
/* Offset */
#define oNFCONF 0x00
#define oNFCMD 0x04
#define oNFADDR 0x08
#define oNFDATA 0x0c
#define oNFSTAT 0x10
#define oNFECC 0x14
#endif
修改cpu/arm920t/start.S文件
在ldr pc, _start_armboot之前加入:
#ifdef CONFIG_S3C2410_NAND_BOOT
bl copy_myself
@ jump to ram
ldr r1, =on_the_ram
add pc, r1, #0
nop
nop
1: b 1b @ infinite loop
on_the_ram:
#endif
在_start_armboot: .word start_armboot之后加入:
#ifdef CONFIG_S3C2410_NAND_BOOT
copy_myself:
mov r10, lr
@ reset NAND
mov r1, #NAND_CTL_BASE
ldr r2, =0xf830 @ initial value
str r2, [r1, #oNFCONF]
ldr r2, [r1, #oNFCONF]
bic r2, r2, #0x800 @ enable chip
str r2, [r1, #oNFCONF]
mov r2, #0xff @ RESET command
strb r2, [r1, #oNFCMD]
mov r3, #0 @ wait
1:add r3, r3, #0x1
cmp r3, #0xa
blt 1b
2:ldr r2, [r1, #oNFSTAT] @ wait ready
tst r2, #0x1
beq 2b
ldr r2, [r1, #oNFCONF]
orr r2, r2, #0x800 @ disable chip
str r2, [r1, #oNFCONF]
@ get read to call C functions (for nand_read())
ldr sp, DW_STACK_START @ setup stack pointer
mov fp, #0 @ no previous frame, so fp="0"
@ copy vivi to RAM
ldr r0, =UBOOT_RAM_BASE
mov r1, #0x0
mov r2, #0x20000
bl nand_read_ll
tst r0, #0x0
beq ok_nand_read
#ifdef CONFIG_DEBUG_LL
bad_nand_read:
ldr r0, STR_FAIL
ldr r1, SerBase
bl PrintWord
1:b 1b @ infinite loop
#endif
ok_nand_read:
#ifdef CONFIG_DEBUG_LL
ldr r0, STR_OK
ldr r1, SerBase
bl PrintWord
#endif
@ verify
mov r0, #0
ldr r1, =UBOOT_RAM_BASE
mov r2, #0x400 @ 4 bytes * 1024 = 4K-bytes
go_next:
ldr r3, [r0], #4
ldr r4, [r1], #4
teq r3, r4
bne notmatch
subs r2, r2, #4
beq done_nand_read
bne go_next
notmatch:
#ifdef CONFIG_DEBUG_LL
sub r0, r0, #4
ldr r1, SerBase
bl PrintHexWord
ldr r0, STR_FAIL
ldr r1, SerBase
bl PrintWord
#endif
1:b 1b
done_nand_read:
#ifdef CONFIG_DEBUG_LL
ldr r0, STR_OK
ldr r1, SerBase
bl PrintWord
#endif
mov pc, r10
@ clear memory
@ r0: start address
@ r1: length
mem_clear:
mov r2, #0
mov r3, r2
mov r4, r2
mov r5, r2
mov r6, r2
mov r7, r2
mov r8, r2
mov r9, r2
clear_loop:
stmia r0!, {r2-r9}
subs r1, r1, #(8 * 4)
bne clear_loop
mov pc, lr
#endif @ CONFIG_S3C2410_NAND_BOOT
在文件的最后加入:
.align 2
DW_STACK_START:
.word STACK_BASE+STACK_SIZE-4
9. 支持nandflash读写
在include/configs/yl2410.h添加CFG_CMD_NAND
编译,在cmd_nand.c产生很多错误,原因是yl2410根本就没有nandflash的驱动支持,如:
NAND_DISABLE_CE()
NAND_ENABLE_CE()
NAND_WAIT_READY()
WRITE_NAND_COMMAND()
WRITE_NAND_COMMANDW()
WRITE_NAND_ADDRESS()
WRITE_NAND()
这些函数的实现都很简单,参考at91rm9200dk.h,对nand的驱动支持全部添加在include/configs/yl2410.h
加载运行,nand write 0x32000000 0x20000 0x200 (向nand flash写512字节),报错,nand_write_page : Failed write verify, 应该是sector(page)没擦除,nand erase 0x20000 0x200,出错,提示边界没对齐,查得资料获知,erase单位是一个block(16k),program单位是一个sector(512B),按要求先擦除后写入,正确
10. 支持nandflash启动
在cpu/arm920t/start.S添加对nandflash重定位的支持,在board/yl2410/nand_boot.c添加对nandflash的初始化和读取操作,在nandflash启动时被start.s调用,注意nand_boot.c的所有代码以及被调用的代码不能超出4k,因为按nandflash启动模式,开始只有4k的运行空间。
编译获得u-boot.bin
Tftp 0x32000000 u-boot.bin (load u-boot.bin to 0x32000000)
Nand erase 0 0x20000 (erase nandflash first 128k)
Nand write 0x32000000 0 0x20000 (write u-boot.bin to nandflash)
设置跳线到nandflash启动模式,重启即可
zhujun74_602010376 2013-2-19 17:11
用户190536 2009-4-21 17:46
用户1601871 2009-4-19 04:19