前面我们的u-boot只是在内存中运行,要想在nandflash中运行,以达到开机自启的目的,还需作如下修改
一.添加DM9000网卡支持
1.修改board/fl2440/fl2440.c中的board_eth_init函数,支持DM9000网卡
#ifdef CONFIG_CMD_NET
int board_eth_init(bd_t *bis)
{
int rc = 0;
#ifdef CONFIG_CS8900
rc = cs8900_initialize(0, CONFIG_CS8900_BASE);
#endif
#ifdef CONFIG_DRIVER_DM9000
rc = dm9000_initialize(bis);
#endif
return rc;
}
#endif
2.修改include/configs/fl2440.h中对网卡的支持,将58行左右 Hardware drivers的定义由
58 * Hardware drivers
59 */
60 #define CONFIG_NET_MULTI
61 #define CONFIG_CS8900 /* we have a CS8900 on-board */
62 #define CONFIG_CS8900_BASE 0x19000300
63 #define CONFIG_CS8900_BUS16 /* the Linux driver does accesses as shorts */
改为
#define CONFIG_NET_MULTI 1
#define CONFIG_NET_RETRY_COUNT 20
#define CONFIG_DRIVER_DM9000 1
#define CONFIG_DM9000_BASE 0x20000300 /* nGCS4*/
#define DM9000_IO CONFIG_DM9000_BASE
#define DM9000_DATA (CONFIG_DM9000_BASE+4)
#define CONFIG_DM9000_USE_16BIT 1
#define CONFIG_DM9000_NO_SROM 1
#undef CONFIG_DM9000_DEBUG
并添加
#define CONFIG_CMD_DHCP
#define CONFIG_CMD_PING
以支持运用网卡命令
修改IP addr,serverIP,等信息如下(这是我个人的配置,每个人的可能不同)
#define CONFIG_ETHADDR 08:00:3e:26:0a:6b //MAC地址
#define CONFIG_NETMASK 255.255.255.0 //掩码
#define CONFIG_IPADDR 192.168.1.228 //板子ip
#define CONFIG_SERVERIP 192.168.1.28 //服务器ip
3.修改drivers/net/dm9000x.c 文件中的dm9000_halt函数如下
static void dm9000_halt(struct eth_device *netdev)
{
DM9000_DBG("%s
", __func__);
#if 0
/* RESET devie */
phy_write(0, 0x8000); /* PHY RESET */
DM9000_iow(DM9000_GPR, 0x01); /* Power-Down PHY */
DM9000_iow(DM9000_IMR, 0x80); /* Disable all interrupt */
DM9000_iow(DM9000_RCR, 0x00); /* Disable RX */
#endif
}
这些修改之后,重新编译u-boot,将u-boot下载到开发板,开发板连接好网线,这个时候,开发板就能支持DM9000了,可以通过网络tftp下载了
U-Boot 2010.09 (Aug 18 2014 - 16:04:25)
DRAM: 64 MiB
Flash: 512 KiB
*** Warning - bad CRC, using default environment
In: serial
Out: serial
Err: serial
Net: dm9000
[fl2440@wss]#
[fl2440@wss]#
[fl2440@wss] ping 192.168.1.22
dm9000 i/o: 0x20000300, id: 0x90000a46
DM9000: running in 16 bit mode
MAC: 08:00:3e:26:0a:6b
could not establish link
Using dm9000 device
host 192.168.1.22 is alive
说明DM9000网卡已经工作。
二.添加nandflash支持
1.在arch/arm/cpu/arm920t/start.S 添加NOR Flash启动和NAND Flash启动的识别
原理:将地址4000003C置为0,如果在地址0000003C中读出的值为0,则代表u-boot从nandflash启动,如果读出的值是0xdeadbeaf,则代表u-boot从norflash启动(原理如下:s3c24x0在上电后,会把内部的sram映射到0x40000000地址上,如果从nandflash启动,sram还将映射到0x00000000地址上。因为0x3c之前的地址空间都被使用,在程序开始的时候做中断向量跳转去了,而且这个地址的值是确定的,也不属于程序,所以我们选择0x0000003c这个地址空间作为检测。如果我们往0x4000003c这个地址上写0,检测到0x0000003c是0,代表是从nandflash启动,如果检测到0xdeadbeaf,代表从norflash启动)
在 l84 行左右(184 beq stack_setup)
的后面添加
ldr r1, =( (4<<28)|(3<<4)|(3<<2) ) /*载入地址0x4000003C*/
mov r0, #0 /* r0 = 0 */
str r0, [r1] /*将R1所代表的地址(0x4000003C)写0*/
mov r1, #0x3c /*载入地址 0x0000003C*/
ldr r0, [r1]
cmp r0, #0 /*将0x0000003C中的值和0做比较,然后跳转*/
bne NORFLASH_BOOT
/* recovery address 0x0000003C date*/
ldr r0, =(0xdeadbeef) //前面我们修改了4000003c的内容,现在恢复4000003c的内容
ldr r1, =( (4<<28)|(3<<4)|(3<<2) )
str r0, [r1]
#define LENGTH_UBOOT 0x60000
NANDFLASH_BOOT:
/*Get ready to call C functions for nand_read_ll()*/
ldr sp, DW_STACK_START @ setup stack pointer
mov fp, #0 @ no previous frame, so fp=0
/* Read u-boot from Nandflash to SDRAM address $TEXT_BASE */
ldr r0, =TEXT_BASE /*nand_read_ll() 1st argument*/
mov r1, #0x0 /*nand_read_ll() 2nd argument*/
mov r2, #LENGTH_UBOOT /*nand_read_ll() 3rd argument*/
bl nand_read_ll
tst r0, #0x0 /*Check nand_read_ll() return value*/
bne infinite_loop /*nand_read_ll() not return 0, then goto dead loop*/
nand_read_ok:
/*Then verify the read data validation,读取前4K代码,和sram中的代码做比较,确认读取的代码有效,*/
mov r0, #0 /*The first 4K data in internal SRAM*/
ldr r1, =TEXT_BASE /*The first 4K data read from Nandflash in SDRAM*/
mov r2, #0x400 /*The compare data length*/
compare_next_byte:
ldr r3, [r0], #4
ldr r4, [r1], #4
teq r3, r4
bne infinite_loop /*如果出现数据不一样,跳转到infinite_loop,死循环*/
subs r2, r2, #4
beq stack_setup
bne compare_next_byte
infinite_loop:
b infinite_loop
#endif
#define GPBDAT 0x56000014
NORFLASH_BOOT: /* relocate U-Boot from Flash to RAM */
ldr r2, =GPBDAT
ldr r3, [r2]
bic r3, r3, #0x40 /*Set bit 6 as low level, Turn On LED*/
str r3, [r2]
ldr r1, =(0xdeadbeef)
cmp r0, r1
bne infinite_loop
adr r0, _start /* r0 <- current position of code */
ldr r1, _TEXT_BASE /* test if we run from flash or RAM */
2.添加C语言从NAND Flash搬移代码部分,刚刚我们看到了汇编部分会调用一个C函数nand_read_ll,这个函数就在nand_read.c文件中
首先在board/fl2440目录下新建一个名为nand_read.c的文件,内容如下
/* nand_read.c: Simple NAND read functions for booting from NAND
* This is used by cpu/arm920/start.S assembler code,
* and the board-specific linker script must make sure this
* file is linked within the first 4kB of NAND flash.
*
* Taken from GPLv2 licensed vivi bootloader,
* Copyright (C) 2002 MIZI Research, Inc.
* u-boot integration and bad-block skipping (C) 2006 by OpenMoko, Inc.
*Author: weishusheng<642613208@qq.com>
*/
#include <common.h>
#include <linux/mtd/nand.h>
#define __REGb(x) (*(volatile unsigned char *)(x))
#define __REGw(x) (*(volatile unsigned short *)(x))
#define __REGi(x) (*(volatile unsigned int *)(x))
#define NF_BASE 0x4e000000
#if defined(CONFIG_S3C2410)
#define NFCONF __REGi(NF_BASE + 0x0)
#define NFCMD __REGb(NF_BASE + 0x4)
#define NFADDR __REGb(NF_BASE + 0x8)
#define NFDATA __REGb(NF_BASE + 0xc)
#define NFSTAT __REGb(NF_BASE + 0x10)
#define NFSTAT_BUSY 1
#define nand_select() (NFCONF &= ~0x800)
#define nand_deselect() (NFCONF |= 0x800)
#define nand_clear_RnB()do {} while (0)
#elif defined(CONFIG_S3C2440) || defined(CONFIG_S3C2442)
#define NFCONF __REGi(NF_BASE + 0x0)
#define NFCONT __REGi(NF_BASE + 0x4)
#define NFCMD __REGb(NF_BASE + 0x8)
#define NFADDR __REGb(NF_BASE + 0xc)
#define NFDATA __REGb(NF_BASE + 0x10)
#define NFDATA16 __REGw(NF_BASE + 0x10)
#define NFSTAT __REGb(NF_BASE + 0x20)
#define NFSTAT_BUSY 1
#define nand_select() (NFCONT &= ~(1 << 1))
#define nand_deselect() (NFCONT |= (1 << 1))
#define nand_clear_RnB()(NFSTAT |= (1 << 2))
#endif
static inline void nand_wait(void)
{
int i;
while (!(NFSTAT & NFSTAT_BUSY))
for (i=0; i<10; i++);
}
struct boot_nand_t {
int page_size;
int block_size;
int bad_block_offset;
// unsigned long size;
};
#if 0
#if defined(CONFIG_S3C2410) || defined(CONFIG_MINI2440)
/* configuration for 2410 with 512byte sized flash */
#define NAND_PAGE_SIZE 512
#define BAD_BLOCK_OFFSET 5
#define NAND_BLOCK_MASK (NAND_PAGE_SIZE - 1)
#define NAND_BLOCK_SIZE 0x4000
#else
/* configuration for 2440 with 2048byte sized flash */
#define NAND_5_ADDR_CYCLE
#define NAND_PAGE_SIZE 2048
#define BAD_BLOCK_OFFSET NAND_PAGE_SIZE
#define NAND_BLOCK_MASK (NAND_PAGE_SIZE - 1)
#define NAND_BLOCK_SIZE (NAND_PAGE_SIZE * 64)
#endif
/* compile time failure in case of an invalid configuration */
#if defined(CONFIG_S3C2410) && (NAND_PAGE_SIZE != 512)
#error "S3C2410 does not support nand page size != 512"
#endif
#endif
static int is_bad_block(struct boot_nand_t * nand, unsigned long i)
{
unsigned char data;
unsigned long page_num;
nand_clear_RnB();
if (nand->page_size == 512) {
NFCMD = NAND_CMD_READOOB; /* 0x50 */
NFADDR = nand->bad_block_offset & 0xf;
NFADDR = (i >> 9) & 0xff;
NFADDR = (i >> 17) & 0xff;
NFADDR = (i >> 25) & 0xff;
} else if (nand->page_size == 2048) {
page_num = i >> 11; /* addr / 2048 */
NFCMD = NAND_CMD_READ0;
NFADDR = nand->bad_block_offset & 0xff;
NFADDR = (nand->bad_block_offset >> 8) & 0xff;
NFADDR = page_num & 0xff;
NFADDR = (page_num >> 8) & 0xff;
NFADDR = (page_num >> 16) & 0xff;
NFCMD = NAND_CMD_READSTART;
} else {
return -1;
}
nand_wait();
data = (NFDATA & 0xff);
if (data != 0xff)
return 1;
return 0;
}
static int nand_read_page_ll(struct boot_nand_t * nand, unsigned char *buf, unsigned long addr)
{
unsigned short *ptr16 = (unsigned short *)buf;
unsigned int i, page_num;
nand_clear_RnB();
NFCMD = NAND_CMD_READ0;
if (nand->page_size == 512) {
/* Write Address */
NFADDR = addr & 0xff;
NFADDR = (addr >> 9) & 0xff;
NFADDR = (addr >> 17) & 0xff;
NFADDR = (addr >> 25) & 0xff;
} else if (nand->page_size == 2048) {
page_num = addr >> 11; /* addr / 2048 */
/* Write Address */
NFADDR = 0;
NFADDR = 0;
NFADDR = page_num & 0xff;
NFADDR = (page_num >> 8) & 0xff;
NFADDR = (page_num >> 16) & 0xff;
NFCMD = NAND_CMD_READSTART;
} else {
return -1;
}
nand_wait();
#if defined(CONFIG_S3C2410)
for (i = 0; i < nand->page_size; i++) {
*buf = (NFDATA & 0xff);
buf++;
}
#elif defined(CONFIG_S3C2440) || defined(CONFIG_S3C2442)
for (i = 0; i < (nand->page_size>>1); i++) {
*ptr16 = NFDATA16;
ptr16++;
}
#endif
return nand->page_size;
}
static unsigned short nand_read_id()
{
unsigned short res = 0;
NFCMD = NAND_CMD_READID;
NFADDR = 0;
res = NFDATA;
res = (res << 8) | NFDATA;
return res;
}
extern unsigned int dynpart_size[];
/* low level nand read function */
int nand_read_ll(unsigned char *buf, unsigned long start_addr, int size)
{
int i, j;
unsigned short nand_id;
struct boot_nand_t nand;
/* chip Enable */
nand_select();
nand_clear_RnB();
for (i = 0; i < 10; i++)
;
nand_id = nand_read_id();
if (0) { /* dirty little hack to detect if nand id is misread */
unsigned short * nid = (unsigned short *)0x31fffff0;
*nid = nand_id;
}
if (nand_id == 0xec76 || /* Samsung K91208 on SD2410 board */
nand_id == 0xad76 ) { /*Hynix HY27US08121A*/
nand.page_size = 512;
nand.block_size = 16 * 1024;
nand.bad_block_offset = 5;
// nand.size = 0x4000000;
} else if (nand_id == 0xecf1 || /* Samsung K9F1G08U0B */
nand_id == 0xadda || /* Hynix HY27UF082G2B on FL2440 board */
nand_id == 0xecda || /* Samsung K9F2G08U0B on FL2440 board */
nand_id == 0xecd3 ) { /* Samsung K9K8G08 */
nand.page_size = 2048;
nand.block_size = 128 * 1024;
nand.bad_block_offset = nand.page_size;
// nand.size = 0x8000000;
} else {
return -1; // hang
}
if ((start_addr & (nand.block_size-1)) || (size & ((nand.block_size-1))))
return -1; /* invalid alignment */
for (i=start_addr; i < (start_addr + size);) {
#ifdef CONFIG_S3C2410_NAND_SKIP_BAD
if (i & (nand.block_size-1)== 0) {
if (is_bad_block(&nand, i) ||
is_bad_block(&nand, i + nand.page_size)) {
/* Bad block */
i += nand.block_size;
size += nand.block_size;
continue;
}
}
#endif
j = nand_read_page_ll(&nand, buf, i);
i += j;
buf += j;
}
/* chip Disable */
nand_deselect();
return 0;
}
3.修改board/fl2440/Makefile文件,使得nand_read.c能被编译到u-boot.bin中(28行)
COBJS := fl2440.o nand_read.o flash.o
4.修改文件arch/arm/cpu/arm920t/u-boot.lds,将u-boot从nandflash搬运的代码链接到前4K的u-boot.bin中(40行左右)
.text :
{
arch/arm/cpu/arm920t/start.o (.text)
board/fl2440/lowlevel_init.o (.text)
board/fl2440/nand_read.o (.text)
*(.text)
}
5.修改include/configs/fl2440.h文件,让u-boot支持nandflash串口操作
/*-----------------------------------------------------------------------
* NAND flash settings
*/
#if defined(CONFIG_CMD_NAND)
#define CONFIG_NAND_S3C2410
#define CONFIG_SYS_MAX_NAND_DEVICE 1 /* Max number of NAND devices */
#define CONFIG_SYS_NAND_BASE 0x4E000000
#define SECTORSIZE 512
#define SECTORSIZE_2K 2048
#define NAND_SECTOR_SIZE SECTORSIZE
#define NAND_SECTOR_SIZE_2K SECTORSIZE_2K
#define NAND_BLOCK_MASK 511
#define NAND_BLOCK_MASK_2K 2047
#define NAND_MAX_CHIPS 1
#define CONFIG_MTD_NAND_VERIFY_WRITE
#define CONFIG_SYS_64BIT_VSPRINTF /* needed for nand_util.c */
#endif /* CONFIG_CMD_NAND */
6.修改drivers/mtd/nand/s3c2410_nand.c文件,支持nandflash的读写(27行左右)把
27 #define S3C2410_NFCONF_EN (1<<15)
28 #define S3C2410_NFCONF_512BYTE (1<<14)
29 #define S3C2410_NFCONF_4STEP (1<<13)
30 #define S3C2410_NFCONF_INITECC (1<<12)
31 #define S3C2410_NFCONF_nFCE (1<<11)
32 #define S3C2410_NFCONF_TACLS(x) ((x)<<8)
33 #define S3C2410_NFCONF_TWRPH0(x) ((x)<<4)
34 #define S3C2410_NFCONF_TWRPH1(x) ((x)<<0)
35
36 #define S3C2410_ADDR_NALE 4
37 #define S3C2410_ADDR_NCLE 8
38
39 #ifdef CONFIG_NAND_SPL
修改宏定义如下
#define NF_BASE 0x4e000000
#if defined(CONFIG_S3C2410)
#define S3C2410_NFCONF_EN (1<<15)
#define S3C2410_NFCONF_512BYTE (1<<14)
#define S3C2410_NFCONF_4STEP (1<<13)
#define S3C2410_NFCONF_INITECC (1<<12)
#define S3C2410_NFCONF_nFCE (1<<11)
#define S3C2410_NFCONF_TACLS(x) ((x)<<8)
#define S3C2410_NFCONF_TWRPH0(x) ((x)<<4)
#define S3C2410_NFCONF_TWRPH1(x) ((x)<<0)
#define S3C2410_ADDR_NALE 4
#define S3C2410_ADDR_NCLE 8
#endif
#if defined(CONFIG_S3C2440)
#define S3C2410_NFCONT_EN (1<<0)
#define S3C2410_NFCONT_INITECC (1<<4)
#define S3C2410_NFCONT_nFCE (1<<1)
#define S3C2410_NFCONT_MAINECCLOCK (1<<5)
#define S3C2410_NFCONF_TACLS(x) ((x)<<12)
#define S3C2410_NFCONF_TWRPH0(x) ((x)<<8)
#define S3C2410_NFCONF_TWRPH1(x) ((x)<<4)
#define S3C2410_ADDR_NALE 0x08
#define S3C2410_ADDR_NCLE 0x0c
#endif
ulong IO_ADDR_W = NF_BASE;
#ifdef CONFIG_NAND_SPL
修改s3c2410_hwcontrol函数为如下
static void s3c2410_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int ctrl)
{
// struct nand_chip *chip = mtd->priv;
struct s3c2410_nand *nand = s3c2410_get_base_nand();
debugX(1, "hwcontrol(): 0x%02x 0x%02x ", cmd, ctrl);
if (ctrl & NAND_CTRL_CHANGE) {
//ulong IO_ADDR_W = (ulong)nand;
IO_ADDR_W = (ulong)nand;
if (!(ctrl & NAND_CLE))
IO_ADDR_W |= S3C2410_ADDR_NCLE;
if (!(ctrl & NAND_ALE))
IO_ADDR_W |= S3C2410_ADDR_NALE;
// chip->IO_ADDR_W = (void *)IO_ADDR_W;
if (ctrl & NAND_NCE)
#if defined(CONFIG_S3C2410) /* modify by hurryliu */
writel(readl(&nand->NFCONF) & ~S3C2410_NFCONF_nFCE,&nand->NFCONF);
#elif defined(CONFIG_S3C2440)
writel(readl(&nand->NFCONT) & ~S3C2410_NFCONT_nFCE,&nand->NFCONT);
#endif
else
#if defined(CONFIG_S3C2410)
writel(readl(&nand->NFCONF) | S3C2410_NFCONF_nFCE,&nand->NFCONF);
#elif defined(CONFIG_S3C2440)
writel(readl(&nand->NFCONT) | S3C2410_NFCONT_nFCE,&nand->NFCONT);
#endif
}
if (cmd != NAND_CMD_NONE)
//writeb(cmd, chip->IO_ADDR_W);
writeb(cmd, (void *)IO_ADDR_W);
}
修改s3c2410_nand_enable_hwecc函数如下:
void s3c2410_nand_enable_hwecc(struct mtd_info *mtd, int mode)
{
struct s3c2410_nand *nand = s3c2410_get_base_nand();
debugX(1, "s3c2410_nand_enable_hwecc(%p, %d) ", mtd, mode);
#if defined(CONFIG_S3C2410)
writel(readl(&nand->NFCONF) | S3C2410_NFCONF_INITECC, &nand->NFCONF);
#elif defined(CONFIG_S3C2440) /*add by hurryliu*/
writel(readl(&nand->NFCONT) | S3C2410_NFCONT_INITECC, &nand->NFCONT);
#endif
}
修改board_nand_init函数如下:
int board_nand_init(struct nand_chip *nand)
{
u_int32_t cfg;
u_int8_t tacls, twrph0, twrph1;
struct s3c24x0_clock_power *clk_power = s3c24x0_get_base_clock_power();
struct s3c2410_nand *nand_reg = s3c2410_get_base_nand();
debugX(1, "board_nand_init() ");
writel(readl(&clk_power->CLKCON) | (1 << 4), &clk_power->CLKCON);
#if defined(CONFIG_S3C2410)
/* initialize hardware */
twrph0 = 3;
twrph1 = 0;
tacls = 0;
cfg = S3C2410_NFCONF_EN;
cfg |= S3C2410_NFCONF_TACLS(tacls - 1);
cfg |= S3C2410_NFCONF_TWRPH0(twrph0 - 1);
cfg |= S3C2410_NFCONF_TWRPH1(twrph1 - 1);
writel(cfg, &nand_reg->NFCONF);
/* initialize nand_chip data structure */
nand->IO_ADDR_R = nand->IO_ADDR_W = (void *)&nand_reg->NFDATA;
#elif defined(CONFIG_S3C2440)
/* initialize hardware */
tacls = 0;
twrph0 = 4;
twrph1 = 2;
cfg = 0;
cfg |= S3C2410_NFCONF_TACLS(tacls - 1);
cfg |= S3C2410_NFCONF_TWRPH0(twrph0 - 1);
cfg |= S3C2410_NFCONF_TWRPH1(twrph1 - 1);
writel(cfg, &nand_reg->NFCONF);
cfg = (0<<13)|(0<<12)|(0<<10)|(0<<9)|(0<<8)|(0<<6)|(0<<5)|(1<<4)|(0<<1)|(1<<0);
writel(cfg, &nand_reg->NFCONT);
/* initialize nand_chip data structure */
nand->IO_ADDR_R = nand->IO_ADDR_W = (void *)&nand_reg->NFDATA;
#endif
nand->select_chip = NULL;
/* read_buf and write_buf are default */
/* read_byte and write_byte are default */
#ifdef CONFIG_NAND_SPL
nand->read_buf = nand_read_buf;
#endif
/* hwcontrol always must be implemented */
nand->cmd_ctrl = s3c2410_hwcontrol;
nand->dev_ready = s3c2410_dev_ready;
#ifdef CONFIG_S3C2410_NAND_HWECC
nand->ecc.hwctl = s3c2410_nand_enable_hwecc;
nand->ecc.calculate = s3c2410_nand_calculate_ecc;
nand->ecc.correct = s3c2410_nand_correct_data;
nand->ecc.mode = NAND_ECC_HW;
nand->ecc.size = CONFIG_SYS_NAND_ECCSIZE;
nand->ecc.bytes = CONFIG_SYS_NAND_ECCBYTES;
#else
nand->ecc.mode = NAND_ECC_SOFT;
#endif
#ifdef CONFIG_S3C2410_NAND_BBT
nand->options = NAND_USE_FLASH_BBT;
#else
nand->options = 0;
#endif
debugX(1, "end of nand_init ");
return 0;
}
7.在arch/arm/cpu/arm920t/start.S加上( _start_armboot: .word start_armboot后)
#ifdef CONFIG_S3C24X0
#define STACK_BASE 0x33f00000
#define STACK_SIZE 0x10000
.align 2
DW_STACK_START: .word STACK_BASE+STACK_SIZE-4
#endif
8.在include/configs/fl2440.h里 将
#define CONFIG_SKIP_LOWLEVEL_INIT 1
改为#undef CONFIG_SKIP_LOWLEVEL_INIT
以支持nandflash启动
9.include/configs/fl2440.h里把
#define CONFIG_S3C2410 1
#define CONFIG_SMDK2410
注释掉
并在其后面添加
#define CONFIG_MINI2440 1
10.board/fl2440/lowlevel_init.S里253行标号0前面添加
mem_init:
/* memory control configuration */
/* make r0 relative the current location so that it */
/* reads SMRDATA out of FLASH rather than memory ! */
ldr r0, =SMRDATA
ldr r1, =mem_init
sub r0, r0, r1
adr r3, mem_init /* r3 <- current position of code */
add r0, r0, r3
ldr r1, =BWSCON /* Bus Width Status Controller */
add r2, r0, #13*4
(少了这步,串口无输出)
11.在include/configs/fl2440.h里101行左右,#include <config_cmd_default.h>后面添加
#define CONFIG_CMD_NAND
支持nand 烧写等命令
12.在include/configs/fl2440.h里123行左右添加u-boot向内核传参模块
#define CONFIG_CPU "s3c2440"
#define CONFIG_CMD_ASKENV //add by wei
#define CONFIG_S3C2410_NAND_SKIP_BAD 1 //add by wei
/* Burn bootloader, linux kernel and rootfs command --add by wei */
#define CONFIG_BURNBL "tftp 30008000 u-boot-$cpu.bin;nand erase 0 100000;nand write
30008000 0 $filesize"
#define CONFIG_NORBURNBL "erase bank 1; tftp 30008000 u-boot-$cpu.bin;cp.b 30008000 0
$filesize"
#define CONFIG_BURNKERNEL "tftp 30008000 linuxrom-$cpu.bin;nand erase 100000 F00000;
nand write 30008000 100000 $filesize"
#define CONFIG_BURN_RAMDISK "tftp 30800000 ramdisk-$cpu.rootfs;nand erase 1000000 1400000;
nand write 30800000 1000000 $filesize"
#define CONFIG_BURN_CRAMFS "tftp 30800000 cramfs-$cpu.rootfs;nand erase 2400000 1400000;
nand write 30800000 2400000 $filesize"
#define CONFIG_BURN_JFFS2 "tftp 30800000 jffs2-$cpu.rootfs;nand erase 3800000 2800000;
nand write 30800000 3800000 $filesize"
#define CONFIG_BURN_YAFFS2 "tftp 30800000 yaffs2-$cpu.rootfs;nand erase 6000000 2800000;
nand write 30800000 6000000 $filesize"
#define CONFIG_BURN_UBIFS "tftp 30800000 ubifs-$cpu.rootfs;nand erase 8800000 2800000;
nand write 30800000 8800000 $filesize"
/* Ramdisk rootfs boot command */
#define CONFIG_BOOT_RAMDISK "nand read 30008000 100000 F00000;nand read 30800000 1000000
1400000;bootm 30008000"
/* Cramfs,jffs2,yaffs2,ubifs boot command */
#define CONFIG_BOOT_ROOTFS "nand read 30008000 100000 F00000;bootm 30008000"
/* tftp boot command */
#define CONFIG_TFTPBOOT "tftp 30008000 linuxrom-$cpu.bin;bootm 30008000 "
#define CONFIG_BOOTCOMMAND CONFIG_BOOT_ROOTFS
/* Bootargs for different root filesystem */
#define CONFIG_BOOTARGS_INITRAMFS "console=ttyS0,115200 mem=64M rw loglevel=7"
#define CONFIG_BOOTARGS_RAMDISK "console=ttyS0,115200 root=/dev/ram0 initrd=0x30800000,16M
init=/linuxrc mem=64M rw loglevel=7"
#define CONFIG_BOOTARGS_CRAMFS "console=ttyS0,115200 root=/dev/mtdblock3 rootfstype=cramfs
init=/linuxrc mem=64M noinitrd loglevel=7"
#define CONFIG_BOOTARGS_JFFS2 "console=ttyS0,115200 root=/dev/mtdblock4 rootfstype=jffs2
init=/linuxrc mem=64M rw noinitrd loglevel=7"
#define CONFIG_BOOTARGS_UBIFS "console=ttyS0,115200 ubi.mtd=6 root=ubi0:rootfs rootwait
rootfstype=ubifs init=/linuxrc mem=64M noinitrd rw loglevel=7"
#define CONFIG_BOOTARGS CONFIG_BOOTARGS_INITRAMFS
在220行把
220 #ifdef CONFIG_AMD_LV400
221 #define PHYS_FLASH_SIZE 0x00080000 /* 512KB */
222 #define CONFIG_SYS_MAX_FLASH_SECT (11) /* max number of sectors on one chip */
223 #define CONFIG_ENV_ADDR (CONFIG_SYS_FLASH_BASE + 0x070000) /* addr of environment */
224 #endif
及228行
228 #define CONFIG_SYS_MAX_FLASH_BANKS 1 /* max number of memory banks */
229 #ifdef CONFIG_AMD_LV800
230 #define PHYS_FLASH_SIZE 0x00100000 /* 1MB */
231 #define CONFIG_SYS_MAX_FLASH_SECT (19) /* max number of sectors on one chip */
232 #define CONFIG_ENV_ADDR (CONFIG_SYS_FLASH_BASE + 0x0F0000) /* addr of environment */
233 #endif
删掉
把
244 //#define CONFIG_ENV_IS_IN_FLASH 1
245 //#define CONFIG_ENV_SIZE 0x10000 /* Total Size of Environment Sector */注释掉
接着加上
246 #define CONFIG_ENV_IS_IN_NAND 1
247 #define CONFIG_ENV_OFFSET 0X60000
248 #define CONFIG_ENV_SIZE 0x20000 /* Total Size of Environment Sector */
在270行左右加上
/*add by wei ***************************************/
269 #define CONFIG_SETUP_MEMORY_TAGS
270 #define CONFIG_INITRD_TAG
271 #define CONFIG_CMDLINE_TAG
272 #define CONFIG_SYS_HUSH_PARSER
273 #define CONFIG_SYS_PROMPT_HUSH_PS2 "> "
至此,我们的u-boot移植就大功告成了。
接下来把uboot烧录到FL2440开发板上
a、连接j-link
b、连接串口,以便在uboot烧录好后“Hit any key to stop autoboot”,注意,此时在我们的secureCRT登录设置一定不能错,否则你按键是没用的,secureCRT登录设置如下:
c、
1.调整Jlink传输速度:
J-Link>r //reset
J-Link>speed 12000 //speed 12M
2.将SDRAM初始化工具bootstrap下载到CPU内存0地址并执行,对SDRAM进行初始化:
J-Link>loadbin C:UsersAdministratorDesktopu-bootootstrap-s3c2440.bin 0 //把文件装载到CPU的0地址 用于初始化SDRAM
J-Link>setpc 0 //指向程序
J-Link>g //go 执行
3.将直接在内存中运行的u-boot-s3c2440.bin文件下载到SDRAM中0x33f80000地址并执行:
J-Link>h //halt 停止(可以看到CPU的信息)
J-Link>loadbin C:UsersAdministratorDesktopu-bootu-boot-s3c2440.bin 0x33f80000 //文件传到SDRAM中
J-Link>setpc 0x33f80000
J-Link>g //串口有信息显示
4.在SecureCRT中使用tftp操作命令把tftp服务器上的u-boot-s3c2440.bin下到SDRAM的0x30000000
[ s3c2440@guowenxue ]# tftp 30000000 192.168.1.3:u-boot-s3c2440.bin
5.在SecureCRT中使用nand操作命令,对NAND Flash的bootloader区域进行擦除,然后把刚才下载到SDRAM中的0x30000000中的u-boot-s3c2440.bin写到NAND Flash中的bootloader区域:
[ s3c2440@guowenxue ]# nand erase 0 50000 //擦除nand数据0-50000
[ s3c2440@guowenxue ]# nand write 30000000 0 50000 //将SDRAM的内容写50000字节到nand flash
6.将开发板重启动
[ s3c2440@guowenxue ]# reset
7.当你真正把u-boot-s3c2440下到nandflash中去时,就要把j-link拔掉,不然再重新上电时你的串口是看不到打印信息的