Chinaunix首页 | 论坛 | 博客
  • 博客访问: 971204
  • 博文数量: 261
  • 博客积分: 10026
  • 博客等级: 上将
  • 技术积分: 3420
  • 用 户 组: 普通用户
  • 注册时间: 2009-02-24 12:10
个人简介

https://smart888.taobao.com/ 立观智能监控

文章分类

全部博文(261)

文章存档

2011年(1)

2010年(4)

2009年(256)

我的朋友

分类:

2009-03-10 22:28:02

1  分析代码

              Bootloader 代码是芯片复位后进入操作系统之前执行的一段代码,主要用于完成由硬件启动到操作系统启动的过渡,从而为操作系统提供基本的运行环境,如初始化CPU、堆栈、存储器系统等。

(1) start.S

  u-boot的stage1代码通常放在start.s文件中,它用汇编语言写成,其主要代码部分如下:

   ●定义入口 。由于一个可执行的Image必须有一个入口点,并且只能有一个全局入口,通常这个入口放在ROM(Flash)的0x0地址,因此,必须通知编译器以使其知道这个入口,该工作可通过修改连接器脚本来完成。

 ●设置异常向量(Exception Vector)。

     ●设置CPU的速度、时钟频率及中断控制寄存器。

     ●初始化内存控制器 。

     ●将ROM中的程序复制到RAM中。

     ●初始化堆栈 。

     ●转到RAM中执行,该工作可使用指令ldr pc来完成。

     (2)board.C 

libarm/board.c中的start armboot是C语言开始的函数,也是整个启动代码中C语言的主函数,同时还是整个u-boot(armboot)的主函数,该函数主要完成如下操作:

   ●调用一系列的初始化函数。

   ●初始化Flash设备。

   ●初始化系统内存分配函数。

   ●如果目标系统拥有NAND设备,则初始化NAND设备。

   ●如果目标系统有显示设备,则初始化该类设备。

   ●初始化相关网络设备,填写IP、MAC地址等。

   ●进入命令循环(即整个boot的工作循环),接受用户从串口输入的命令,然后进行相应的工作。

 

开始移植

第一步:建立开发环境

工作环境:

    RedHat Linux 9

交叉编译器:

                  arm-linux-gcc 4.0.0

U-BOOT版本:

                  1.1.6

目标板:

                  ZJ2410A,NAND FLASH 64M,RAM 64M,CS8900A

 

1、建立自己2410开发板的配置(我的是zj2410):

       (1)$ cp –r board/smdk2410 board/zj2410  

       (2)$ cp include/configs/smdk2410.h include/configs/zj2410.h 

zj2410.h是开发板的配置文件,他包括开发板的CPU、系统时钟、RAM、FLASH系统及其他相关的配置信息!由于国内大多数2410开发板都是抄袭韩国三星的SMDK2410开发板,因此这里都直接拷贝SMDK2410的配置文件,做相应的修改即可!

2、修改文件:

       (1)include/configs/zj2410.h:

             

              修改:

              # define   CFG_PROMPT     “SMDK2410#”

              为:

                       # define   CFG_PROMPT     “ZJ2410#”

                (2)Makefile:

                       参照SMDK2410配置

                       smdk2410_config   :      unconfig

                       @$(MKCONFIG) $(@:_config=) arm arm920t smdk2410 NULL s3c24x0

 

zj2410_config :      unconfig

                       @$(MKCONFIG) $(@:_config=) arm arm920t zj2410 NULL s3c24x0

 

 

第二步:使U-BOOT能够启动起来

     2410的启动代码可以在外部的NAND FLASH上执行,启动时,NAND FLASH的前4KB(地址为0x00000000,OM[1:0]=0)将被装载到SDRAM中被称为Setppingstone的地址中,然后开始执行这段代码。启动以后,这4KB的空间可以做其他用途!

    

     添加的代码主要来自于VIVI。

1。在cpu/arm920t/start.s中修改如下:

……

#ifndef CONFIG_SKIP_RELOCATE_UBOOT

relocate:              /* relocate U-Boot to RAM       */

   adr r0, _start      /* r0 <- current position of code   */

   ldr r1, _TEXT_BASE      /* test if we run from flash or RAM */

   cmp     r0, r1                  /* don't reloc during debug         */

   beq     stack_setup

 

@  ldr r2, _armboot_start

@  ldr r3, _bss_start

@  sub r2, r3, r2      /* r2 <- size of armboot            */

@  add r2, r0, r2      /* r2 <- source end address         */

 

@copy_loop:

@  ldmia   r0!, {r3-r10}       /* copy from source address [r0]    */

@  stmia   r1!, {r3-r10}       /* copy to   target address [r1]    */

@  cmp r0, r2          /* until source end addreee [r2]    */

@  ble copy_loop

 

#ifdef CONFIG_S3C2410_NAND_BOOT /*这个一定要放在堆栈设置之前*/

   bl  copy_myself

#endif /*CONFIG_S3C2410_NAND_BOOT*/

 

#endif /*CONFIG_SKIP_RELOCATE_UBOOT*/

                ……

                ……

                ……

       /**************************************************************************

 *

 * copy u-boot   to ram 放在start.S靠后的位置

 *

 *************************************************************************

 */

 #ifdef CONFIG_S3C2410_NAND_BOOT

@

@ copy_myself: copy u-boot to ram

@

copy_myself:

mov   r10, lr

 

@ reset NAND

mov r1, #NAND_CTL_BASE

ldr r2, =0xf830     @ initial value

str r2, [r1, #oNFCONF]

ldr r2, [r1, #oNFCONF]

bic r2, r2, #0x800      @ enable chip

str r2, [r1, #oNFCONF]

mov r2, #0xff       @ RESET command

strb    r2, [r1, #oNFCMD]

mov r3, #0          @ wait

1:   add r3, r3, #0x1

cmp r3, #0xa

blt 1b

2:   ldr r2, [r1, #oNFSTAT]  @ wait ready

tst r2, #0x1

beq 2b

ldr r2, [r1, #oNFCONF]

orr r2, r2, #0x800      @ disable chip

str r2, [r1, #oNFCONF]

 

@ get read to call C functions

ldr sp, DW_STACK_START  @ setup stack pointer

mov fp, #0          @ no previous frame, so fp=0

 

@ copy UBOOT to RAM

ldr r0, _TEXT_BASE

mov     r1, #0x0

mov r2, #0x20000

bl  nand_read_ll

 

teq r0, #0x0

beq ok_nand_read

 

bad_nand_read:

1:   b   1b      @ infinite loop


ok_nand_read:

 

@ verify


mov r0, #0

ldr r1, _TEXT_BASE

mov r2, #0x400  @ 4 bytes * 1024 = 4K-bytes

go_next:

ldr r3, [r0], #4

ldr r4, [r1], #4

teq r3, r4

bne notmatch

subs    r2, r2, #4

beq done_nand_read 

bne go_next

notmatch:

1:   b   1b

done_nand_read:

   

mov   pc, r10

 

#endif   

@ CONFIG_S3C2440_NAND_BOOT

 

DW_STACK_START:

.word   STACK_BASE+STACK_SIZE-4

2. 修改include/configs/zj2410.h

#ifndef __CONFIG_H

#define __CONFIG_H

 

/*

 * High Level Configuration Options

 * (easy to change)

 */

#define CONFIG_ARM920T         1     /* This is an ARM920T Core */

#define     CONFIG_S3C2410              1     /* in a SAMSUNG S3C2410 SoC     */

#define CONFIG_SMDK2410              1     /* on a SAMSUNG SMDK2410 Board  */

……

……

……

/*-----------------------------------------------------------------------

 * FLASH and environment organization

 */

 

#define CONFIG_AMD_LV400     1     /* uncomment this if you have a LV400 flash */

#if 0

#define CONFIG_AMD_LV800     1     /* uncomment this if you have a LV800 flash */

#endif

 

#define CFG_MAX_FLASH_BANKS     1     /* max number of memory banks */

#ifdef CONFIG_AMD_LV800

#define PHYS_FLASH_SIZE         0x00100000 /* 1MB */

#define CFG_MAX_FLASH_SECT       (19) /* max number of sectors on one chip */

#define CFG_ENV_ADDR            (CFG_FLASH_BASE + 0x0F0000) /* addr of environment */

#endif

#ifdef CONFIG_AMD_LV400

#define PHYS_FLASH_SIZE         0x00080000 /* 512KB */

#define CFG_MAX_FLASH_SECT       (11) /* max number of sectors on one chip */

#define CFG_ENV_ADDR            (CFG_FLASH_BASE + 0x070000) /* addr of environment */

#endif

 

/* timeout values are in ticks */

#define CFG_FLASH_ERASE_TOUT    (5*CFG_HZ) /* Timeout for Flash Erase */

#define CFG_FLASH_WRITE_TOUT   (5*CFG_HZ) /* Timeout for Flash Write */

 

#define     CFG_ENV_IS_IN_FLASH    1

#define CFG_ENV_SIZE        0x10000  /* Total Size of Environment Sector */

 

/*-----------------------------------------------------------------------

 *  NAND FLASH BOOT

 */

#define     CONFIG_S3C2410_NAND_BOOT      1

#define     STACK_BASE                     0x33f00000

#define     STACK_SIZE                   0x8000

 

 

#define     NAND_CTL_BASE                     0x4e000000

#define     bINT_CTL(Nb)                   _REG(INT_CTL_BASE+(Nb))

 

 

#define     oNFCONF                           0x00

#define     oNFCMD                            0x04

#define     oNFADDR                           0x08

#define     oNFDATA                           0x0c

#define     oNFSTAT                            0x10

#define     oNFECC                      0x14

 

/*-----------------------------------------------------------------------

 * NAND flash settings

 */

#define NAND_MAX_CHIPS              1

 

 

3. 在board/zj2410/中添加nand_read.c文件:

#include

#include "linux/mtd/mtd.h"

#include "linux/mtd/nand.h"

 

//#define LARGEPAGE_FLASH

 

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

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

#define NF_BASE        0x4e000000

#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 BUSY 1

inline void wait_idle(void) {

    int i;

 

    while(!(NFSTAT & BUSY))

      for(i=0; i<10; i++);

}

 

#ifndef LARGEPAGE_FLASH

#define NAND_SECTOR_SIZE        512

#else

#define NAND_SECTOR_SIZE        2048

#endif

#define NAND_BLOCK_MASK         (NAND_SECTOR_SIZE - 1)

 

/* low level nand read function */

int

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

{

    int i, j;

 

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

    //if ((start_addr & NAND_BLOCK_MASK) /*|| (size > SZ_1M)*/) {

        return -1;      /* invalid alignment */

    }

 

    /* chip Enable */

    NFCONF &= ~0x800;

    for(i=0; i<10; i++);

 

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

      /* READ0 */

      NFCMD = NAND_CMD_READ0;

 

      /* Write Address */

#ifndef LARGEPAGE_FLASH

      NFADDR = i & 0xff;

      NFADDR = (i >> 9) & 0xff;

      NFADDR = (i >> 17) & 0xff;

      NFADDR = (i >> 25) & 0xff;

#else

      NFADDR = i & 0xff;

      NFADDR = (i >> 8) & 0x07;

      NFADDR = (i >> 11) & 0xff;

      NFADDR = (i >> 19) & 0xff;

      NFADDR = (i >> 27) & 0x3;

     

      NFCMD = NAND_CMD_READSTART;

#endif

      wait_idle();

 

      for(j=0; j < NAND_SECTOR_SIZE; j++) {

        *buf = (NFDATA & 0xff);

        buf++;

      }

      i += NAND_SECTOR_SIZE;

    }

 

    /* chip Disable */

    NFCONF |= 0x800;    /* chip disable */

 

    return 0;

}

4. 修改board/zj2410/Makefile:

COBJS  := smdk2410.o flash.o nand_read.o    //添加nand_read.o

 

OK,这边就编译一下,就可以烧到NAND FLASH运行了。

 

阅读(862) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~