u-boot-2010.09移植(B)

前面我们的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\n", __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\n", 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)\n", 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()\n");

 

    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\n");

    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:\Users\Administrator\Desktop\u-boot\bootstrap-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:\Users\Administrator\Desktop\u-boot\u-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拔掉,不然再重新上电时你的串口是看不到打印信息的

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

posted @ 2014-08-18 19:49  wssheng  阅读(817)  评论(0编辑  收藏  举报