Chinaunix首页 | 论坛 | 博客
  • 博客访问: 2603245
  • 博文数量: 877
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 5920
  • 用 户 组: 普通用户
  • 注册时间: 2013-12-05 12:25
个人简介

技术的乐趣在于分享,欢迎多多交流,多多沟通。

文章分类

全部博文(877)

文章存档

2021年(2)

2016年(20)

2015年(471)

2014年(358)

2013年(26)

分类: 嵌入式

2014-03-06 09:57:38

移植U-Boot-2010.03到友善之臂mini2440(二)

2.1 修改cpu/arm920t/start.S

(1)删除AT91RM9200使用的LED代码,117118行,关闭LED代码。

 

start_code:

    /*

     * set the cpu to SVC32 mode

     */

    mrs r0,cpsr

    bic r0,r0,#0x1f

    orr r0,r0,#0xd3

    msr cpsr,r0

    //bl coloured_LED_init

    //bl red_LED_on

 

(2)修改编译条件支持s3c2440,修改寄存器地址定义,修改 CPU频率初始化设置

 

#ifdef  (CONFIG_S3C24X0)

        /* turn off the watchdog */

# if defined(CONFIG_S3C2400)

#  define pWTCON           0x15300000

#  define INTMSK           0x14400008      /* Interupt-Controller base addresses */

#  define CLKDIVN          0x14800014      /* clock divisor register */

#else

#  define pWTCON           0x53000000

#  define INTMSK           0x4A000008      /* Interupt-Controller base addresses */

#  define INTSUBMSK        0x4A00001C

#  define CLKDIVN           0x4C000014      /* clock divisor register */

# endif

修改 CPU频率初始化设置147

//xujun

#define CLK_CTL_BASE 0x4C000000

#define MDIV_405 0x7f << 12

#define PSDIV_405 0x21

#define MDIV_200 0xa1 <<12

#define PSDIV_200 0x31

 

(3)修改中断禁止部分

165行修改0x3ff0x7ff

#if defined(CONFIG_S3C2410)

    ldr r1, =0x7ff /*根据2410芯片手册,INTSUBMSK11位可用*/

    ldr r0, =INTSUBMSK

    str r1, [r0]

#endif

170行添加

#if defined(CONFIG_S3C2440)

    ldr r1, =0x7fff

    ldr r0, =INTSUBMSK

    str r1, [r0]

#endif

(4)修改时钟设置(2440的主频为405MHz。)175

 

//xujun

#if defined(CONFIG_S3C2440)

     /* FCLK:HCLK:PCLK = 1:4:8 */

ldr r0,=CLKDIVN

    mov r1,#5

    str r1,[r0]

 

    mrc p15,0,r1,c1,c0,0

    orr r1,r1,#0xc0000000

    mcr p15,0,r1,c1,c0,0

 

    mov r1,#CLK_CTL_BASE

    mov r2,#MDIV_405

    add r2,r2,#PSDIV_405

    str r2,[r1,#0x04]

#else

 

        /* FCLK:HCLK:PCLK = 1:2:4 */

        /* default FCLK is 120 MHz ! */

        ldr     r0, =CLKDIVN

        mov     r1, #3

        str     r1, [r0]

//xujun

    mrc p15,0,r1,c1,c0,0

    orr r1,r1,#0xc0000000

    mcr p15,0,r1,c1,c0,0

 

    mov r1,#CLK_CTL_BASE

    mov r2,#MDIV_200

    add r2,r2,#PSDIV_200

    str r2,[r2,#0x04]

#endif

#endif /* CONFIG_S3C24X0 */

(5)将从自动识别从NAND Flash启动还是从Nor flash启动

代码原理:在启动的时候,用程序将0x400000000x40001000中的某些位置清零,如果回读0x000000000x00001000中的相应位置后为零,说明是Nand boot,如果是原来的数据(一定要选非零的位置)就是Nor boot。判断完后如果是nand boot,还要恢复被改动的数据,再进入自拷贝阶段。
   只要检测的位置合理,这方法是可行的。现在的关键是选什么位置的数据最好呢?经过查看源码,我选择了在start.S文件开头,全局中断向量之后的:

    .balignl 16,0xdeadbeef

选这个数据作为检测位置的理由如下:
1)他是非零数,而且数据是确定的:0xdeadbeef
2)他的位置是固定的:0x0000003c0x4000003c);
3)他在检测程序之前,不会影响程序的向下运行;
4)他不属于程序,他是一个程序中的魔数(Magic Number),用魔数来检测也比较合理
所以最后的检测步骤是:
在启动的时候,将0x4000003c位置开始的四个字节清零,然后读取0x0000003c位置开始的四个字节。如果回读的结果为零,说明是nand boot,否则就是Nor boot(为了保险还可以判断是否为0xdeadbeef,不是的话就说明有未知错误,死循环!)。但是最后有一点很重要:如果是Nand boot,必须要复原清零的数据。原因是:在nand boot过后,会核对内部SRAM中的4K程序,和从Nand中拷贝到SDRAM的前4K程序是否一致,如果不一致会进入死循

 

218行将原来转移nor  flash启动的代码修改为:

1)判断当前代码位置,如果在内存,直接跳到stack_setup

/***************** CHECK_CODE_POSITION **********************************/

  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

/***************** CHECK_CODE_POSITION ************************************/

2)如果不是在代码当前位置不在内存中,就判断启动的FlashNand 或者Nor

/***************** CHECK_BOOT_FLASH *************************************/

  ldr  r1, =( (4<<28)|(3<<4)|(3<<2) )           /* address of Internal SRAM  0x4000003C*/

  mov      r0, #0             /* r0 = 0 */  //0x4000003C所指向的4个字节40

  str  r0, [r1]

 

  mov      r1, #0x3c              /* address of men  0x0000003C*/

  ldr  r0, [r1]

  cmp      r0, #0  //判断0x0000003C所指向的4个字节是否被清0

  bne       relocate     //如果0x0000003C所指向的4个字节没有被清0,就是在Nor Flash中启动,则跳到Nor Flash的重定向代码处relocate

 

 

 

  /* recovery  */

  ldr  r0, =(0xdeadbeef) //如果0x0000003C所指向的4个字节被清0,就是在Nand Flash中启动

ldr   r1, =( (4<<28)|(3<<4)|(3<<2) ) //先恢复0x4000003C指向的4字节的数据0xdeadbeef

  str  r0, [r1]

/***************** CHECK_BOOT_FLASH ***********************************/

 

3)如果判断是在Nand Flash中启动的话,那么nand  Flash搬移代码如下:

 

定义u-bootnand flash中存放的长度为#define LENGTH_UBOOT 0x60000,可以方便修改u-boot因为裁剪和增添大小的改变而占的长度。

 

// copy U-Boot to RAM  form   Nand Flash

 

/***************** NAND_BOOT *******************************************/

 

#define LENGTH_UBOOT 0x60000

#define NAND_CTL_BASE 0x4E000000

 

#ifdef CONFIG_S3C2440

/* Offset */

#define oNFCONF 0x00

#define oNFCONT 0x04

#define oNFCMD 0x08

#define oNFSTAT 0x20

 

  @ reset NAND

  mov      r1, #NAND_CTL_BASE

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

  str  r2, [r1, #oNFCONF]

  ldr  r2, [r1, #oNFCONF]

 

  ldr  r2, =( (1<<4)|(0<<1)|(1<<0) )      @ Active low CE Control

  str  r2, [r1, #oNFCONT]

  ldr  r2, [r1, #oNFCONT]

 

  ldr  r2, =(0x6)      @ RnB Clear

  str  r2, [r1, #oNFSTAT]

  ldr  r2, [r1, #oNFSTAT]

 

  mov      r2, #0xff @ RESET command

  strb       r2, [r1, #oNFCMD]

 

  mov      r3, #0      @ wait

nand1:

  add       r3, r3, #0x1

  cmp      r3, #0xa

  blt  nand1

 

nand2:

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

  tst  r2, #0x4

  beq       nand2

 

 

  ldr  r2, [r1, #oNFCONT]

  orr r2, r2, #0x2    @ Flash Memory Chip Disable

  str  r2, [r1, #oNFCONT]

 

  @ get read to call C functions (for nand_read())

  ldr  sp, DW_STACK_START      @ setup stack pointer

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

 

  @ copy U-Boot to RAM

  ldr  r0, =TEXT_BASE

  mov      r1, #0x0

  mov      r2, #LENGTH_UBOOT

  bl   nand_read_ll

  tst  r0, #0x0

  beq       ok_nand_read

 

bad_nand_read:

loop2:

  b    loop2      @ 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       stack_setup

  bne       go_next

 

notmatch:

loop3:

  b    loop3      @ infinite loop

#endif

 

#ifdef      CONFIG_S3C2410

 

/* Offset */

#define oNFCONF 0x00

#define oNFCMD 0x04

#define oNFSTAT 0x10

 

  @ 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

nand1:

  add       r3, r3, #0x1

  cmp      r3, #0xa

  blt  nand1

 

nand2:

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

  tst  r2, #0x1

  beq       nand2

 

  ldr  r2, [r1, #oNFCONF]

  orr r2, r2, #0x800 @ disable chip

  str  r2, [r1, #oNFCONF]

 

  @ get read to call C functions (for nand_read())

  ldr  sp, DW_STACK_START      @ setup stack pointer

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

 

  @ copy U-Boot to RAM

  ldr  r0, =TEXT_BASE

  mov      r1, #0x0

  mov      r2, #LENGTH_UBOOT

  bl   nand_read_ll

  tst  r0, #0x0

  beq       ok_nand_read

 

bad_nand_read:

loop2:

  b    loop2      @ 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       stack_setup

  bne       go_next

 

notmatch:

loop3:

  b    loop3      @ infinite loop

 

#endif

/*************** NAND_BOOT *******************************/

(4)  如果判断是在Nor  Flash中启动的话,那么nor  Flash搬移代码如下

 

// copy U-Boot to RAM  form   Nor  Flash

 

//#ifndef CONFIG_SKIP_RELOCATE_UBOOT

/***************** NOR_BOOT *************************************************/

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

      /*********** CHECK_FOR_MAGIC_NUMBER***************/

  ldr  r1, =(0xdeadbeef)

  cmp      r0, r1

  bne       loop3

      /*********** CHECK_FOR_MAGIC_NUMBER***************/

  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

/***************** NOR_BOOT *************************************************/

//#endif /* CONFIG_SKIP_RELOCATE_UBOOT */

 

 

ldr    pc, _start_armboot之后加入LED代码:

       ldr     pc, _start_armboot

#if defined(CONFIG_MINI2440_LED)

   mov  r1, #GPIO_CTL_BASE

   add  r1, r1, #oGPIO_B

   ldr  r2,=0x156aa

   str  r2, [r1, #oGPIO_CON]

   mov  r2, #0xff

   str  r2, [r1, #oGPIO_UP]

   mov  r2, #0x1c0

   str  r2, [r1, #oGPIO_DAT]

#endif

_start_armboot: .word start_armboot

 

  _start_armboot:    .word start_armboot  后加入

_start_armboot: .word start_armboot

#define STACK_BASE 0x33f00000

#define STACK_SIZE 0x10000

        .align  2

DW_STACK_START: .word   STACK_BASE+STACK_SIZE-4

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