• 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 ", __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拔掉,不然再重新上电时你的串口是看不到打印信息的

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

  • 相关阅读:
    IDEA复制module
    input输入框限制输入数字(含小数)
    毕设周总结---3
    皮尔森相关系数算法
    毕设周总结---2
    毕设周总结---1
    解释器模式实例
    架构模式——解释器模式
    课后作业---质量属性
    软件架构师如何工作
  • 原文地址:https://www.cnblogs.com/thinkinglife/p/3920244.html
Copyright © 2020-2023  润新知