首页 资讯 应用 高压 设计 行业 低压 电路图 关于

单片机

旗下栏目: PLC 嵌入式 单片机 DCS

移植u-boot-2011.03到S3C2440(utu2440)的方法与步骤7.NAND FLASH部分移植和支持NAND FLASH启动和读写

单片机 | 发布时间:2018-06-28 | 人气: | #评论# | 本文关键字:u-boot,S3C2440,utu2440
摘要:开发环境:主机:Window XP SP2;linux:VMware7.01+ubuntu9.10;目标板:扬创utu2440-F开发板。交叉编译器:arm-linux-gcc4.3.2(一开始用的是编译内核的版本arm-linux-gcc3.4.1,但出现了软浮点问题,于是换成

开发环境:主机:Window XP SP2;linux:VMware7.01+ubuntu9.10;目标板:扬创utu2440-F开发板。交叉编译器:arm-linux-gcc4.3.2(一开始用的是编译内核的版本arm-linux-gcc3.4.1,但出现了软浮点问题,于是换成了现在用的版本,当然本人编译内核的时候还是用3.4.1版本)。详细描述了本人移植u-boot-2011.03到S3C2440(utu2440)的方法与步骤,同时把移植过程中遇到的问题及其解决方法记录了下来,以供参考步骤。本节详细描述:移植NAND FLASH部分,使u-boot支持从NAND FLASH启动和读写

1. u-boot的NAND FLASH部分移植准备

移植u-boot的NAND FLASH部分特别是支持u-boot从NAND FLASH启动部分,需要做一些相关准备。主要是:

1.1 掌握u-boot启动第一阶段的调试方法

详见关于使用AXD和JLINK调试u-boothttp://www.dqzdhw.com/danpianji/1847.html,以及参考 A.5所指的参考资料

1.2 挂机(即烧写自己移植的u-boot到NAND FLASH后启动不起来)了怎么办?

详见关于使用JLINK间接烧写u-boot的方法与步骤http://www.dqzdhw.com/danpianji/1848.html

1.3 从Nand Flash启动U-BOOT的基本原理

1.3.1 前4K的问题

如果S3C2440被配置成从Nand Flash启动(配置由硬件工程师在电路板设置), S3C2440的Nand Flash控制器有一个特殊的功能,在S3C2440上电后,Nand Flash控制器会自动的把Nand Flash上的前4K数据搬移到4K内部RAM中,并把0x00000000设置内部RAM的起始地址,CPU从内部RAM的0x00000000位置开 始启动。这个过程不需要程序干涉。程序员需要完成的工作,是把最核心的启动程序放在Nand Flash的前4K中。

1.3.2 启动程序的安排

由于Nand Flash控制器从Nand Flash中搬移到内部RAM的代码是有限的,所以在启动代码的前4K里,我们必须完成S3C2410的核心配置以及把启动代码(U-BOOT)剩余部分搬到RAM中运行。u-boot源码不支持从nand flash启动,可是s3c2410支持从nand flash启动,加电后s3c2440将nand flash的前4k(保存有u-boot的部分功能--拷贝功能--把nand flash中的内容拷贝到SDRAM)拷贝到sram(s3c2440芯片内的sram)。这就需要修改u-boot源码,增加u-boot的功能: 使u-boot在得到执行权后能够将其自身拷贝到开发板上SDRAM中,以便处理器能够执行u-boot

2. u-boot的NAND FLASH部分移植

以下的操作是经过整理的,详细过程见A.1.1所列出的网址

注意,如果u-boot要在SDRAM中调试,得把u-boot-2011.03/include/configs/reille2440.h文件中的宏定义CONFIG_SKIP_LOWLEVEL_INIT开启和关闭CONFIG_S3C2440_NAND_BOOT宏定义

2.1 修改u-boot-2011.03/include/configs/reille2440.h文件

2.1.1 注销如下定义:

/* del by guoyirong 2011.06.19 
#define    CONFIG_ENV_IS_IN_FLASH    1 
#define CONFIG_ENV_SIZE        0x10000    // Total Size of Environment Sector 
 */

2.1.2 reille2440.h文件末增加如下定义:

[c-sharp] view plain copy

  1. /**********************************************************/  

  2. /* 以下为NAND启动及驱动相关 added by guoyirong 2011.06.19 */  

  3. /* 

  4.  * 去掉NOR FLASH支持,如果不去掉,则arch/arm/lib/libarm.o被连接到了4K之外, 

  5.  * 4K之内没有这个程序libarm是不可能实现NAND启动的 

  6.  */  

  7. #define CONFIG_SYS_NO_FLASH  

  8. //#define CONFIG_CMD_FLASH      /* flinfo, erase, protect   */  

  9. //#define CONFIG_CMD_IMLS       /* List all found images  */  

  10. #define CONFIG_S3C2440_NAND_BOOT  1  

  11. #define CONFIG_NAND_S3C2440  

  12. #define NAND_CTL_BASE  0x4E000000  //Nand Flash配置寄存器基地址,查2440手册可得知  

  13. #define oNFCONF  0x00 //相对Nand配置寄存器基地址的偏移量,还是配置寄存器的基地址  

  14. #define oNFCONT  0x04 //相对Nand配置寄存器基地址的偏移量,可得到控制寄存器的基地址(0x4E000004)  

  15. #define oNFADDR  0x0c //相对Nand配置寄存器基地址的偏移量,可得到地址寄存器的基地址(0x4E00000c)  

  16. #define oNFDATA  0x10 //相对Nand配置寄存器基地址的偏移量,可得到数据寄存器的基地址(0x4E000010)  

  17. #define oNFCMD   0x08 //相对Nand配置寄存器基地址的偏移量,可得到指令寄存器的基地址(0x4E000008)  

  18. #define oNFSTAT  0x20 //相对Nand配置寄存器基地址的偏移量,可得到状态寄存器的基地址(0x4E000020)  

  19. #define oNFECC   0x2c //相对Nand配置寄存器基地址的偏移量,可得到ECC寄存器的基地址(0x4E00002c)  

  20. #define UBOOT_LENGTH  0x40000 /*256K*/  

  21. #define STACK_BASE  0x33f00000     //定义堆栈的地址  

  22. #define STACK_SIZE  0x8000         //堆栈的长度大小  

  23. #define CONFIG_CMD_NAND  

  24. #define CONFIG_CMDLINE_EDITING  

  25. #define  CONFIG_NAND_S3C2440  

  26. #ifdef CONFIG_CMDLINE_EDITING  

  27. #undef CONFIG_AUTO_COMPLETE  

  28. #else  

  29. #define CONFIG_AUTO_COMPLETE  

  30. #endif  

  31.   

  32. /* NAND flash settings */  

  33. #if defined(CONFIG_CMD_NAND)  

  34. #define CONFIG_SYS_NAND_BASE            0x4E000000 //Nand配置寄存器基地址  

  35. #define CONFIG_SYS_MAX_NAND_DEVICE      1  

  36. #define CONFIG_MTD_NAND_VERIFY_WRITE    1  

  37. //#define NAND_SAMSUNG_LP_OPTIONS       1  //注意:我们这里是64M的Nand Flash,所以不用,如果是128M的大块Nand Flash,则需加上  

  38. #endif  

  39. // 添加环境变量保存到Nand的宏(注意:如果你要使用从Nor启动的saveenv命令,则不要这些Nand宏定义)  

  40. #define CONFIG_ENV_IS_IN_NAND  1  

  41. #define CONFIG_ENV_OFFSET      0x30000 //将环境变量保存到nand中的0x30000位置  

  42. #define CONFIG_ENV_SIZE        0x10000 /* Total Size of Environment Sector */  

2.1.3 注释CONFIG_SKIP_LOWLEVEL_INIT

//#define CONFIG_SKIP_LOWLEVEL_INIT

2.2 增加从NAND FLASH读取数据到内存的函数,文件名为nand_read.c,

放到board/samsung/reille2440/nand_read.c下

nand_read.c文件内容如下:

  1. /* 

  2.  * board/samsung/reille2440/nand_read.c 

  3.  * 

  4.  * (C) Copyright 2011 

  5.  * reille <http://blog.csdn.net/reille/> <[email protected]> 

  6.  * 

  7.  * This program is free software; you can redistribute it and/or 

  8.  * modify it under the terms of the GNU General Public License as 

  9.  * published by the Free Software Foundation; either version 2 of 

  10.  * the License, or (at your option) any later version. 

  11.  * 

  12.  */  

  13. #include <config.h>  

  14. #define NF_BASE   0x4E000000  //Nand Flash配置寄存器基地址  

  15. #define __REGb(x) (*(volatile unsigned char *)(x))  

  16. #define __REGi(x) (*(volatile unsigned int  *)(x))  

  17. #define NFCONF __REGi(NF_BASE + 0x0 )  //通过偏移量还是得到配置寄存器基地址  

  18. #define NFCONT __REGi(NF_BASE + 0x4 )  //通过偏移量得到控制寄存器基地址  

  19. #define NFCMD  __REGb(NF_BASE + 0x8 )  //通过偏移量得到指令寄存器基地址  

  20. #define NFADDR __REGb(NF_BASE + 0xC )  //通过偏移量得到地址寄存器基地址  

  21. #define NFDATA __REGb(NF_BASE + 0x10)  //通过偏移量得到数据寄存器基地址  

  22. #define NFSTAT __REGb(NF_BASE + 0x20)  //通过偏移量得到状态寄存器基地址  

  23. #define NAND_CHIP_ENABLE  (NFCONT &= ~(1<<1))  //Nand片选使能  

  24. #define NAND_CHIP_DISABLE (NFCONT |= (1<<1))   //取消Nand片选  

  25. #define NAND_CLEAR_RB     (NFSTAT |= (1<<2))  

  26. #define NAND_DETECT_RB    { while(! (NFSTAT&(1<<2)) );}  

  27. #define NAND_SECTOR_SIZE 512  

  28. #define NAND_BLOCK_MASK (NAND_SECTOR_SIZE - 1)  

  29. #if 0  

  30. #define DEBUGN    printf  

  31. #else  

  32. #define DEBUGN(x, args ...) {}  

  33. #endif  

  34.   

  35. /* low level nand read function */  

  36. int nand_read_ll(unsigned char *buf, unsigned long start_addr, int size){  

  37.     int i, j;  

  38. //  DEBUGN("nand_read_ll............./n");// 这句不能有,否则uboot不能从NAND FLASH启动起来  

  39.     if ((start_addr & NAND_BLOCK_MASK) || (size & NAND_BLOCK_MASK)){  

  40.         return -1; //地址或长度不对齐  

  41.     }  

  42.     NAND_CHIP_ENABLE; //选中Nand片选  

  43.     for(i=start_addr; i < (start_addr + size);){  

  44.         //发出READ0指令  

  45.         NAND_CLEAR_RB;  

  46.         NFCMD = 0;  

  47.         //对Nand进行寻址  

  48.         NFADDR = i & 0xFF;  

  49.         NFADDR = (i >> 9) & 0xFF;  

  50.         NFADDR = (i >> 17) & 0xFF;  

  51.         NFADDR = (i >> 25) & 0xFF;  

  52.         NAND_DETECT_RB;  

  53.         for(j=0; j < NAND_SECTOR_SIZE; j++, i++){  

  54.             *buf = (NFDATA & 0xFF);  

  55.              buf++;  

  56.         }  

  57.     }  

  58.     NAND_CHIP_DISABLE; //取消片选信号  

  59.     return  0;  

  60. }  

2.3 修改cmd_bootm.c文件

a)把81和82行注释掉,如下:

// abort NOR FLASH  |del by guoyirong 2011.06.25 
//#include <mtd/cfi_flash.h> 
//extern flash_info_t flash_info[]; /* info for FLASH chips */

b)把函数int do_imls (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])整体注释掉,改为如下:

int do_imls (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]){return (0);}

做一步是因为要去掉NOR FLASH支持(如果不去掉,则arch/arm/lib/libarm.o被连接到了4K之外,

4K之内没有这个程序libarm是不可能实现NAND启动的),但去掉后,在这里会出现编译错误,如下所示:

In file included from cmd_bootm.c:80:

/home/reille/work/u-boot-2011.03/include/mtd/cfi_flash.h:174: error: expected ')' before '*' token

cmd_bootm.c:81: error: expected '=', ',', ';', 'asm' or '__attribute__' before 'flash_info'

cmd_bootm.c: In function 'do_imls':

cmd_bootm.c:1145: error: 'flash_info_t' undeclared (first use in this function)

cmd_bootm.c:1145: error: (Each undeclared identifier is reported only once

cmd_bootm.c:1145: error: for each function it appears in.)

cmd_bootm.c:1145: error: 'info' undeclared (first use in this function)

cmd_bootm.c:1149: error: 'flash_info' undeclared (first use in this function)

cmd_bootm.c:1152: error: 'FLASH_UNKNOWN' undeclared (first use in this function)

make[1]: *** [cmd_bootm.o] Error 1

make[1]: Leaving directory `/home/reille/work/u-boot-2011.03/common'

make: *** [common/libcommon.o] Error 2

[email protected]:~/work/u-boot-2011.03$

注释掉后就不会出现了,按理来说在u-boot-2011.03/include/configs/reille2440.h文件中

去掉了宏定义CONFIG_CMD_IMLS及加上宏定义CONFIG_SYS_NO_FLASH就不会出现编译

错误了,但不知道为什么没能起作用。

2.4 修改board/samsung/reille2440/makefile

#del by guoyirong 2011.06.25 
#COBJS    := reille2440.o flash.o nand_read.o 
# no nor flash |add by guoyirong 2011.06.25 
COBJS    := reille2440.o nand_read.o

注意,不再有NOR FLASH了,因此去掉flash.o

2.5 drivers/mtd/nand/目录下新建s3c2440_nand.c文件实现对NAND FLASH的操作

2.5.1 s3c2440_nand.c文件内容如下:

  1. /* 

  2.  * drivers/mtd/nand/s3c2440_nand.c 

  3.  * 

  4.  * 实现对nand FLASH的操作 

  5.  * 

  6.  * (C) Copyright 2011 

  7.  * reille <http://blog.csdn.net/reille/> <[email protected]> 

  8.  * 

  9.  * This program is free software; you can redistribute it and/or 

  10.  * modify it under the terms of the GNU General Public License as 

  11.  * published by the Free Software Foundation; either version 2 of 

  12.  * the License, or (at your option) any later version. 

  13.  * 

  14.  */  

  15.  #include <common.h>  

  16.  #include <nand.h>  

  17. #include <asm/arch/s3c24x0_cpu.h>  

  18. #include <asm/io.h>  

  19. #if 0  

  20. #define DEBUGN    printf  

  21. #else  

  22. #define DEBUGN(x, args ...) {}  

  23. #endif  

  24. #define __REGb(x)    (*(volatile unsigned char *)(x))  

  25. #define __REGi(x)    (*(volatile unsigned int *)(x))  

  26. #define NF_BASE  0x4e000000             //Nand配置寄存器基地址  

  27. #define NFCONF   __REGi(NF_BASE + 0x0)  //偏移后还是得到配置寄存器基地址  

  28. #define NFCONT   __REGi(NF_BASE + 0x4)  //偏移后得到Nand控制寄存器基地址  

  29. #define NFCMD    __REGb(NF_BASE + 0x8)  //偏移后得到Nand指令寄存器基地址  

  30. #define NFADDR   __REGb(NF_BASE + 0xc)  //偏移后得到Nand地址寄存器基地址  

  31. #define NFDATA   __REGb(NF_BASE + 0x10) //偏移后得到Nand数据寄存器基地址  

  32. #define NFMECCD0 __REGi(NF_BASE + 0x14) //偏移后得到Nand主数据区域ECC0寄存器基地址  

  33. #define NFMECCD1 __REGi(NF_BASE + 0x18) //偏移后得到Nand主数据区域ECC1寄存器基地址  

  34. #define NFSECCD  __REGi(NF_BASE + 0x1C) //偏移后得到Nand空闲区域ECC寄存器基地址  

  35. #define NFSTAT   __REGb(NF_BASE + 0x20) //偏移后得到Nand状态寄存器基地址  

  36. #define NFSTAT0  __REGi(NF_BASE + 0x24) //偏移后得到Nand ECC0状态寄存器基地址  

  37. #define NFSTAT1  __REGi(NF_BASE + 0x28) //偏移后得到Nand ECC1状态寄存器基地址  

  38. #define NFMECC0  __REGi(NF_BASE + 0x2C) //偏移后得到Nand主数据区域ECC0状态寄存器基地址  

  39. #define NFMECC1  __REGi(NF_BASE + 0x30) //偏移后得到Nand主数据区域ECC1状态寄存器基地址  

  40. #define NFSECC   __REGi(NF_BASE + 0x34) //偏移后得到Nand空闲区域ECC状态寄存器基地址  

  41. #define NFSBLK   __REGi(NF_BASE + 0x38) //偏移后得到Nand块开始地址  

  42. #define NFEBLK   __REGi(NF_BASE + 0x3c) //偏移后得到Nand块结束地址  

  43. #define S3C2440_NFCONT_nCE  (1<<1)  

  44. #define S3C2440_ADDR_NALE   0x0c  

  45. #define S3C2440_ADDR_NCLE   0x08  

  46. ulong IO_ADDR_W = NF_BASE;  

  47.   

  48. static void s3c2440_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int ctrl){  

  49.     struct nand_chip *chip = mtd->priv;  

  50.     DEBUGN("hwcontrol(): 0x%02x 0x%02x/n", cmd, ctrl);  

  51.     if (ctrl & NAND_CTRL_CHANGE) {  

  52.         IO_ADDR_W = NF_BASE;  

  53.         if (!(ctrl & NAND_CLE)){                //要写的是地址  

  54.             IO_ADDR_W |= S3C2440_ADDR_NALE;  

  55.         }  

  56.         if (!(ctrl & NAND_ALE)){                //要写的是命令  

  57.             IO_ADDR_W |= S3C2440_ADDR_NCLE;  

  58.         }  

  59.         if (ctrl & NAND_NCE){  

  60.             NFCONT &= ~S3C2440_NFCONT_nCE;    //使能nand flash  

  61.         }  

  62.         else{  

  63.             NFCONT |= S3C2440_NFCONT_nCE;     //禁止nand flash  

  64.         }  

  65.     }  

  66.     if (cmd != NAND_CMD_NONE){  

  67.         writeb(cmd,(void *)IO_ADDR_W);  

  68.     }  

  69. }  

  70.   

  71. static int s3c2440_dev_ready(struct mtd_info *mtd){  

  72.     DEBUGN("dev_ready/n");  

  73.     return (NFSTAT & 0x01);  

  74. }  

  75.   

  76. int board_nand_init(struct nand_chip *nand){  

  77.     u_int32_t cfg;  

  78.     u_int8_t tacls, twrph0, twrph1;  

  79.     struct s3c24x0_clock_power * const clk_power = s3c24x0_get_base_clock_power();  

  80.     DEBUGN("board_nand_init()/n");  

  81.     /*clk_power->CLKCON |= (1 << 4);*/  

  82.     writel(readl(&clk_power->clkcon) | (1 << 4), &clk_power->clkcon);  

  83.     twrph0 = 4; twrph1 = 2; tacls = 0;  

  84.     cfg = (tacls<<12)|(twrph0<<8)|(twrph1<<4);  

  85.     NFCONF = cfg;  

  86.     cfg = (1<<6)|(1<<4)|(0<<1)|(1<<0);  

  87.     NFCONT = cfg;  

  88.     /* initialize nand_chip data structure */  

  89.     nand->IO_ADDR_R = nand->IO_ADDR_W = (void *)0x4e000010;  

  90.     /* read_buf and write_buf are default */  

  91.     /* read_byte and write_byte are default */  

  92.     /* hwcontrol always must be implemented */  

  93.     nand->cmd_ctrl = s3c2440_hwcontrol;  

  94.     nand->dev_ready = s3c2440_dev_ready;  

  95.     return  0;  

  96. }  

2.5.2 在drivers/mtd/nand/Makefile文件中添加s3c2440_nand.c的编译项

COBJS-$(CONFIG_NAND_S3C2440) += s3c2440_nand.o

2.6 修改start.S文件

    /* 

  1.      * we do sys-critical inits only at reboot, 

  2.      * not when booting from ram! 

  3.      */  

  4. #ifndef CONFIG_SKIP_LOWLEVEL_INIT  

  5.     bl  cpu_init_crit  

  6. #endif  

  7. /************************START*******************************/  

  8. /* 添加2440中u-boot从Nand启动 added by guoyiorng 2011.06.25 */  

  9. #ifdef CONFIG_S3C2440_NAND_BOOT  

  10.     mov r1, #NAND_CTL_BASE          // 复位Nand Flash  

  11.     ldr r2, =( (7<<12)|(7<<8)|(7<<4)|(0<<0) )  

  12.     str r2, [r1, #oNFCONF]          // 设置配置寄存器的初始值,参考s3c2440手册  

  13.     ldr r2, [r1, #oNFCONF]  

  14.     ldr r2, =( (1<<4)|(0<<1)|(1<<0) )  

  15.     str r2, [r1, #oNFCONT]          // 设置控制寄存器  

  16.     ldr r2, [r1, #oNFCONT]  

  17.     ldr r2, =(0x6)                  // RnB Clear  

  18.     str r2, [r1, #oNFSTAT]  

  19.     ldr r2, [r1, #oNFSTAT]  

  20.     mov r2, #0xff                   // 复位command  

  21.     strb r2, [r1, #oNFCMD]  

  22.     mov r3, #0                      // 等待  

  23. nand1:  

  24.     add r3, r3, #0x1  

  25.     cmp r3, #0xa  

  26.     blt nand1  

  27. nand2:  

  28.     ldr r2, [r1, #oNFSTAT]          // 等待就绪  

  29.     tst r2, #0x4  

  30.     beq nand2  

  31.     ldr r2, [r1, #oNFCONT]  

  32.     orr r2, r2, #0x2                // 取消片选  

  33.     str r2, [r1, #oNFCONT]  

  34.     //get read to call C functions (for nand_read())  

  35.     ldr sp, DW_STACK_START          // 安装栈的起始地址,为C代码准备堆栈,DW_STACK_START定义在下面  

  36.     mov fp, #0                      // 初始化帧指针寄存器  

  37.     //copy U-Boot to RAM  

  38.     ldr r0, =CONFIG_SYS_TEXT_BASE   // 传递给C代码的第一个参数:u-boot在RAM中的起始地址  

  39.     mov r1, #0x0                    // 传递给C代码的第二个参数:Nand Flash的起始地址  

  40.     mov r2, #UBOOT_LENGTH           // 传递给C代码的第三个参数:u-boot的长度大小  

  41.     bl nand_read_ll                 // 此处调用C代码中读Nand的函数,现在还没有要自己编写实现  

  42.     tst r0, #0x0                    // 如果函数nand_read_ll的返回值为0,表示执行成功  

  43.     beq ok_nand_read  

  44. bad_nand_read:  

  45.     loop2: b loop2                  // infinite loop  

  46. ok_nand_read:  

  47.     //检查搬移后的数据,如果前4k完全相同,表示搬移成功  

  48.     mov r0, #0                      // 将R0设为0  

  49.     ldr r1, =CONFIG_SYS_TEXT_BASE   // 将R1设为虚拟地址起始处  

  50.     mov r2, #0x400                  // 4 bytes * 1024 = 4k-bytes  

  51. go_next:  

  52.     ldr r3, [r0], #4    // 取R0处地址的数据到R3中,然后R0自加4字节  

  53.     ldr r4, [r1], #4    // 读取R1处地址的数据到R4中,然后R1自加4字节  

  54.     teq r3, r4          // 比较R3和R4的数据是否相等,也就是检测Boot Internal SRAM和SDRAM中的数据是否相等  

  55.     bne notmatch        // 不等则跳转到notmatch  

  56.     subs r2, r2, #4 // 相等则R2自减4,当R2为0则跳转到relocations  

  57. //  beq board_init_f  

  58.     beq relocations         /* 注意此句,直接跳转到relocate_code函数的调整部分, 

  59.                                因为我们不打算在board_init_f()函数中再回来了*/  

  60.     bne go_next         // R2不为0则跳转回go_next继续检测  

  61. notmatch:  

  62.     loop3: b loop3           //infinite loop  

  63. #endif //CONFIG_S3C2440_NAND_BOOT  

  64. /**************************END********************************/  

  65.   

  66. /*------------------------------------------------------------------------------*/  

  67. /* 

  68.  * void relocate_code (addr_sp, gd, addr_moni) 

  69.  * 

  70.  * This "function" does not return, instead it continues in RAM 

  71.  * after relocating the monitor code. 

  72.  * 

  73.  */  

  74.     .globl  relocate_code  

  75. relocate_code:  

  76.     mov r4, r0  /* save addr_sp */  

  77.     mov r5, r1  /* save addr of gd */  

  78.     mov r6, r2  /* save addr of destination */  

  79.     /* Set up the stack                         */  

  80. stack_setup:  

  81.     mov sp, r4  

  82.     adr r0, _start  

  83.     cmp r0, r6  

  84.     beq clear_bss               /* skip relocation */  

  85.     mov r1, r6                  /* r1 <- scratch for copy_loop */  

  86.     ldr r3, _bss_start_ofs  

  87.     add r2, r0, r3              /* r2 <- source end address      */  

  88. copy_loop:  

  89.     ldmia   r0!, {r9-r10}       /* copy from source address [r0]    */  

  90.     stmia   r1!, {r9-r10}       /* copy to   target address [r1]    */  

  91.     cmp r0, r2                  /* until source end address [r2]    */  

  92.     blo copy_loop  

  93. /**************************START***************************/  

  94. /* 增加标号,以便跳转到这里 added by guoyirong 2011.06.25 */  

  95. relocations:  

  96.     ldr r6, =CONFIG_SYS_TEXT_BASE/*注意,R6下面被用到表示新的目标地址*/  

  97. /************************** END ***************************/  

  98. #ifndef CONFIG_PRELOADER  

  99.     /* 

  100.      * fix .rel.dyn relocations 

  101.      */  

  102.     ldr r0, _TEXT_BASE          /* r0 <- Text base */  

  103.     sub r9, r6, r0              /* r9 <- relocation offset */  

  104.     ldr r10, _dynsym_start_ofs  /* r10 <- sym table ofs */  

  105.     add r10, r10, r0            /* r10 <- sym table in FLASH */  

  106.     ldr r2, _rel_dyn_start_ofs  /* r2 <- rel dyn start ofs */  

  107.     add r2, r2, r0              /* r2 <- rel dyn start in FLASH */  

  108.     ldr r3, _rel_dyn_end_ofs    /* r3 <- rel dyn end ofs */  

  109.     add r3, r3, r0              /* r3 <- rel dyn end in FLASH */  

  110. fixloop:  

  111.     ldr r0, [r2]                /* r0 <- location to fix up, IN FLASH! */  

  112.     add r0, r0, r9              /* r0 <- location to fix up in RAM */  

  113.     ldr r1, [r2, #4]  

  114.     and r7, r1, #0xff  

  115.     cmp r7, #23                 /* relative fixup? */  

  116.     beq fixrel  

  117.     cmp r7, #2                  /* absolute fixup? */  

  118.     beq fixabs  

  119.     /* ignore unknown type of fixup */  

  120.     b   fixnext  

  121. fixabs:  

  122.     /* absolute fix: set location to (offset) symbol value */  

  123.     mov r1, r1, LSR #4          /* r1 <- symbol index in .dynsym */  

  124.     add r1, r10, r1             /* r1 <- address of symbol in table */  

  125.     ldr r1, [r1, #4]            /* r1 <- symbol value */  

  126.     add r1, r1, r9              /* r1 <- relocated sym addr */  

  127.     b   fixnext  

  128. fixrel:  

  129.     /* relative fix: increase location by offset */  

  130.     ldr r1, [r0]  

  131.     add r1, r1, r9  

  132. fixnext:  

  133.     str r1, [r0]  

  134.     add r2, r2, #8      /* each rel.dyn entry is 8 bytes */  

  135.     cmp r2, r3  

  136.     blo fixloop  

  137. #endif  

  138. clear_bss:  

  139. #ifndef CONFIG_PRELOADER  

  140.     ldr r0, _bss_start_ofs  

  141.     ldr r1, _bss_end_ofs  

  142.     ldr r3, _TEXT_BASE      /* add gy guoyirong 2011.06.25 */  

  143.     mov r4, r6              /* reloc addr */  

  144. //  add r0, r0, r4          /* del by guoyirong 2011.06.25 */  

  145. //  add r1, r1, r4          /* del by guoyirong 2011.06.25 */  

  146.     add r0, r0, r3          /* add by guoyirong 2011.06.25 */  

  147.     add r1, r1, r3          /* add by guoyirong 2011.06.25 */  

  148.     mov r2, #0x00000000     /* clear                */  

  149. clbss_l:str r2, [r0]        /* clear loop...            */  

  150.     add r0, r0, #4  

  151.     cmp r0, r1  

  152.     bne clbss_l  

  153. /* del by guoyirong 2011.06.25 

  154.     bl coloured_LED_init 

  155.     bl red_LED_on 

  156.  */  

  157.  #endif  

  158. /* Set stackpointer in internal RAM to call board_init_f */  

  159. call_board_init_f:  

  160.     ldr sp, =(CONFIG_SYS_INIT_SP_ADDR)  

  161.     bic sp, sp, #7 /* 8-byte alignment for ABI compliance */  

  162.     ldr r0,=0x00000000  

  163. //  bl  board_init_f        /* 用绝对地址跳转到内存去了,不再回来了del by guoyirong 2011.06.25 */  

  164.     ldr pc, _board_init_f   /* 增加此句,用绝对地址跳转到内存去了,不再回来add by guoyirong 2011.06.25*/  

  165. /**********************************************************/  

  166. /* 增加此句,我们用绝对地址跳转到内存去了,不再回来了add by guoyirong 2011.06.25*/  

  167. _board_init_f:  

  168.     .word board_init_f  

  169. /**********************************************************/  

  170. /* 

  171.  * We are done. Do not return, instead branch to second part of board 

  172.  * initialization, now running from RAM. 

  173.  */  

  174. #ifdef CONFIG_NAND_SPL  

  175.     ldr     r0, _nand_boot_ofs  

  176.     mov pc, r0  

  177. _nand_boot_ofs:  

  178.     .word nand_boot  

  179. #else  

  180.     ldr r0, _board_init_r_ofs  

  181.     adr r1, _start  

  182.     add lr, r0, r1  

  183.     add lr, lr, r9  

  184.     /* setup parameters for board_init_r */  

  185.     mov r0, r5      /* gd_t */  

  186.     mov r1, r6      /* dest_addr */  

  187.     /* jump to it ... */  

  188.     mov pc, lr  

  189. _board_init_r_ofs:  

  190.     .word board_init_r - _start  

  191. #endif  

  192. _rel_dyn_start_ofs:  

  193.     .word __rel_dyn_start - _start  

  194. _rel_dyn_end_ofs:  

  195.     .word __rel_dyn_end - _start  

  196. _dynsym_start_ofs:  

  197.     .word __dynsym_start - _start  

  198. // add by guoyirong 2011.06.25  

  199. .align 2  

  200. DW_STACK_START: .word STACK_BASE+STACK_SIZE-4  

2.7 修改arch/arm/cpu/arm920t/u-boot.lds

.text : 

    arch/arm/cpu/arm920t/start.o    (.text) 
    board/samsung/reille2440/libreille2440.o    (.text) 
    *(.text) 
}

2.8 修改修改/arch/arm/lib/board.c

a)修改一:board_init_f()函数

    bd_t *bd; 
    init_fnc_t **init_fnc_ptr; 
    gd_t *id; 
    ulong addr, addr_sp;

    /* Pointer is writable since we allocated a register for it */ 
    gd = (gd_t *) ((CONFIG_SYS_INIT_SP_ADDR) & ~0x07); 
    /* compiler optimization barrier needed for GCC >= 3.4 */ 
    __asm__ __volatile__("": : :"memory");

    memset ((void*)gd, 0, sizeof (gd_t));

//    gd->mon_len = _bss_end_ofs;    // del by guoyirong 2011.06.25

    /* 增加此句以保证与配置的一致性add by guoyirong 2011.06.25 
     * 具体原因请查看代码中对此变量的使用即可明白,注意我们的 _TEXT_BASE=0x33f80000 
     */ 
    gd->mon_len = 0x700000;

b)修改二:board_init_f()函数

    gd->relocaddr = addr; 
    gd->start_addr_sp = addr_sp; 
    gd->reloc_off = addr - _TEXT_BASE; 
    debug ("relocation Offset is: %08lx/n", gd->reloc_off); 
    memcpy (id, (void *)gd, sizeof (gd_t));

    __asm__ __volatile__("mov sp,%0"::"r"(addr_sp):"sp"); // added by guoyirong 2011.06.25

// add by guoyirong 2011.06.25 
#ifdef CONFIG_S3C2440_NAND_BOOT 
    board_init_r(id, addr); 
#else 
    relocate_code (addr_sp, id, addr); 
    /* NOTREACHED - relocate_code() does not return */ 
#endif

c)修改三:board_init_r()函数

debug ("Now running in RAM - U-Boot at: %08lx/n", dest_addr);

// u-boot启动时的输出版本信息 added by guoyirong 2011.06.25 
display_banner(); 
display_dram_config();

2.9 修改board/samsung/reille2440/config.mk

# tftp debug added by guoyirong 2011.06.11 
#CONFIG_SYS_TEXT_BASE = 0x33000000

CONFIG_SYS_TEXT_BASE = 0x33F80000

至此,该修改该移植的部分都完成了,重新编译,然后下载到NAND FLASH

3. 调试问题

严格按照上述的修改或者按照A.1.1网址进行修改,一般不会有问题

我在调试过程中,由于在nand_read_ll()函数中加了一句打印信息,导致不能正常启动,实际上在nand_read_ll()函数中不能加打印信息,弄得我用AXD去单步调试。

启动信息如下:

U-Boot 2011.03 (Jun 26 2011 - 02:40:58)

DRAM:  64 MiB 
NAND:  NAND_ECC_NONE selected by board driver. This is not recommended !! 
64 MiB 
*** Warning - bad CRC, using default environment

In:    serial 
Out:   serial 
Err:   serial 
Net:   CS8900-0 
[reille2440]#

责任编辑:u-boot
首页 | 电气资讯 | 应用技术 | 高压电器 | 电气设计 | 行业应用 | 低压电器 | 电路图 | 关于我们 | 版权声明

Copyright 2017-2018 电气自动化网 版权所有 辽ICP备17010593号-1

电脑版 | 移动版 原创声明:本站大部分内容为原创,转载请注明电气自动化网转载;部分内容来源网络,如侵犯您的权益请发送邮件到[email protected]联系我们删除。