软件平台: Windows XP, Ubuntu

硬件平台: mini2440

软件: Source Insight、u-boot.2012.04.01 (官方下载源码)


一、uboot 启动分析

 1.set the cpu to SVC32 mode(start.S)

 2.turn off the watchdog

 3.mask all IRQs by setting all bits in the INTMR

 4.设置分频系数

 5.cpu_init_crit

        flush v4 I/D caches

        disable MMU stuff and caches

        lowlevel_init //setup RAM timing(lowlevel_init.S)

                设置BWSCON

        board_init_f //set sp, call board_init_f

                init_sequence (各种初始化)

                        ...

                        board_early_init_f

                        ...

                        serial_init

                        ...


二、尝试

make smdk2410_config

make

成功生成的u-boot.bin并不能让mini2440启动


三、修改

  1.修改根目录下boards.cfg在

  smdk2410                     arm         arm920t     -                   samsung        s3c24x0

  下添加一行

  mini2440                     arm         arm920t     -                   samsung        s3c24x0 


 2.make mini2440_config


 3.复制include\configs\smdk2410.h为include\configs\mini2440.h


 4.cp board\samsung\smdk2410到board\samsung\mini2440


 5.从start.S里可以看出,缺省认为60Mhz的HCLK来设置内存控制器,才设置系统时钟MPLL是有问题的。

     因为没设置时钟时,是以晶振的频率运行的

     注释掉(mini2440\smdk2410.c)int board_early_init_f(void)中的

                #if 0

                /* configure MPLL */

                writel((M_MDIV << 12) + (M_PDIV << 4) + M_SDIV,

                 &clk_power->mpllcon);

                #endif

     start.S修改分频设置

     ldr r0, =0x4C000014 /* FCLK提高到400Mhz,但HCLK不能超过133Mhz */

     mov r1, #5 /* FCLK:HCLK:PCLK = 1:4:8, HDIVN=10, PDIVN=1*/

     str r1, [r0]

     将MPLL的设置放到start.S

     在分频后加上

     /* 如果HDIVN非0,CPU的总线模式应该从“fast bus mode”变为“asynchronous bus mode” */

     mrc p15, 0, r1, c1, c0, 0 /* 读出控制寄存器 */ 

     orr r1, r1, #0xc0000000 /* 设置为“asynchronous bus mode” */

     mcr p15, 0, r1, c1, c0, 0 /* 写入控制寄存器 */


     #define S3C2440_MPLL_400MHZ     ((0x5c<<12)|(0x01<<4)|(0x01))


     /* MPLLCON = S3C2440_MPLL_200MHZ */

     ldr r0, =0x4c000004

     ldr r1, =S3C2440_MPLL_400MHZ

     str r1, [r0]


     /* 启动ICACHE */

     mrc p15, 0, r0, c1, c0, 0 @ read control reg

     orr r0, r0, #(1<<12)

     mcr p15, 0, r0, c1, c0, 0   @ write it back


    6.修改设置BWSCON的SMRDATA(lowlevel_init.S)

     /* BWSCON

     [31]ST7:0     [27]ST6:0

     [30]WS7:0     [26]WS6:0

     [29:28]DW7:10 [25:24]DW6:10

     only bank6 and bank7 for sdram

     [19]ST4:0

     [18]WS4:1

     [17:16]DW4:01

     bank4 for DM9000

     */

     .long 0x22050000 //BWSCON


     /* use the reset value */

     .long 0x00000700 //BANKCON0

     .long 0x00000700 //BANKCON1

     .long 0x00000700 //BANKCON2

     .long 0x00000700 //BANKCON3

     .long 0x00000700 //BANKCON4

     .long 0x00000700 //BANKCON5



     /* MT [16:15] Determine the memory type for bank6 and bank7

     = 11 SDRAM

     Trcd [3:2] RAS to CAS delay, HCLK = 400Mhz/4 = 100Mhz

     = 01 3 clocks (view HY57V561620.pdf)

     SCAN [1:0] Column address number

     = 01 9-bit (view HY57V561620.pdf)

     */

     .long 0x00018005 //BANKCON6

     .long 0x00018005 //BANKCON7

     /*

     REFEN [23] SDRAM Refresh Enable

     = 1 Enable (self or CBR/auto refresh)

     TREFMD [22] SDRAM Refresh Mode

     = 0 CBR/Auto Refresh

     Trp [21:20] SDRAM RAS pre-charge Time

     = 01 3 clocks (view HY57V561620.pdf)

     Tsrc [19:18] SDRAM Semi Row cycle time, Trc=Tsrc+Trp => Tsrc=Trc-Trp => 9-3 

     = 10 6 clocks (view HY57V561620.pdf)

     Refresh Counter [10:0] SDRAM refresh count value.

     Refresh period = (2^11-refresh_count+1)/HCLK

     refresh_count = 64/8192 ms = 7.8125us

     Rp = 2^11 + 1 - 135.75*7.8125 = 988 = 0x3dc

     */

     .long 0x009803dc //REFRESH


     /* BURST_EN [7] ARM core burst operation enable.

     = 1 Enable burst operation

     SCKE_EN [5] SDRAM power down mode enable control by SCKE

     = 1 SDRAM power down mode enable

     SCLK_EN [4]

     = 1 SCLK is active only during the access (recommended)

     BK76MAP [2:0] BANK6/7 memory map

      = 001 64MB/64MB

     */

     .long 0x000000B1 //BANKSIZE



     /* CL [6:4] CAS latency

     = 011 3 clocks

     */

     .long 0x00000030 //MRSRB6

     .long 0x00000030 //MRSRB7

     再次make,并烧写u-boot.bin到nor flash,启动后发现是乱码,应该是串口波特率问题,看看串口初始化


    u-boot2012.04.01移植到mini2440_#if


     7.board.c (z:\u-boot-2012.04.01\arch\arm\lib\Board.c)

               serial_init(z:\u-boot-2012.04.01\drivers\serial\Serial_s3c24x0.c)

                   serial_init_dev

                          _serial_setbrg

                                 get_PCLK(z:\u-boot-2012.04.01\arch\arm\cpu\arm920t\s3c24x0\Speed.c)

                                        get_HCLK

                                        发现没有定义CONFIG_S3C2440,它用2410的那套

     那么在config中的mini2440.h中去掉#define CONFIG_S3C2410改成#define CONFIG_S3C2440

    make发现多个错误

     s3c2410_nand.c: In function 's3c2410_hwcontrol':

     s3c2410_nand.c:57: warning: implicit declaration of function 's3c2410_get_base_nand'

     s3c2410_nand.c:57: warning: initialization makes pointer from integer without a cast

     s3c2410_nand.c:72: error: dereferencing pointer to incomplete type

     s3c2410_nand.c:72: error: dereferencing pointer to incomplete type

     s3c2410_nand.c:75: error: dereferencing pointer to incomplete type

     s3c2410_nand.c:75: error: dereferencing pointer to incomplete type

     s3c2410_nand.c: In function 's3c2410_dev_ready':

     s3c2410_nand.c:85: warning: initialization makes pointer from integer without a cast

     s3c2410_nand.c:87: error: dereferencing pointer to incomplete type

     s3c2410_nand.c: In function 'board_nand_init':

     s3c2410_nand.c:129: warning: initialization makes pointer from integer without a cast

     s3c2410_nand.c:150: error: dereferencing pointer to incomplete type

     s3c2410_nand.c:153: error: dereferencing pointer to incomplete type

     s3c2410_nand.c:154: error: dereferencing pointer to incomplete type、

     s3c2410_nand.c找错误,发现是因为更改了#define CONFIG_S3C2440后,s3c2410_nand未定义

   暂且先让串口输出正常看看,去掉nand支持。

     [root: u-boot-2012.04.01]# grep "s3c2410_nand.o" * -nR 

    drivers/mtd/nand/Makefile:61:COBJS-$(CONFIG_NAND_S3C2410) += s3c2410_nand.o

     drivers/mtd/nand/.depend.s3c2410_nand:1:s3c2410_nand.o: s3c2410_nand.c \

     drivers/mtd/nand/.depend:341:s3c2410_nand.o: s3c2410_nand.c \ 

   [root: u-boot-2012.04.01]# vi drivers/mtd/nand/Makefile 

     找到

    COBJS-$(CONFIG_NAND_S3C2410) += s3c2410_nand.o

   现取消CONFIG_NAND_S3C2410的定义,在mini2440.h中发现

   #ifdef CONFIG_CMD_NAND

   #define CONFIG_NAND_S3C2410

   #define CONFIG_SYS_S3C2410_NAND_HWECC

   #define CONFIG_SYS_MAX_NAND_DEVICE 1

   #define CONFIG_SYS_NAND_BASE 0x4E000000

   #endif

   则注释掉//#define CONFIG_CMD_NAND

   再编译提示

   fs/yaffs2/libyaffs2.o: In function `yaffs_StartUp':

   /home/profiles/u-boot-2012.04.01/fs/yaffs2/yaffscfg.c:210: undefined reference to `nand_info'

   还是在mini2440.h中先注释掉

   //#define CONFIG_YAFFS2

  再次make,并烧写u-boot.bin到nor flash,启动后发现Flash: *** failed ***,串口正常了,只是flash还有问题


    8.为了去掉原u-boot复杂的重定位代码,现自己写重定位代码,将init.c添加到board/samsung/mini2440下。修改

    board/samsung/mini2440/Makefile

    改COBJS   := smdk2410.o init.o

    init.c内容如下





点击(此处)折叠或打开


  1. #define NFCONF (*((volatile unsigned long *)0x4E000000))
  2. #define NFCONT (*((volatile unsigned long *)0x4E000004))
  3. #define NFCMMD (*((volatile unsigned char *)0x4E000008))    //注意是char* 不是long*,与下面保持一致
  4. #define NFADDR (*((volatile unsigned char *)0x4E00000C))
  5. #define NFDATA (*((volatile unsigned char *)0x4E000010))
  6. #define NFSTAT (*((volatile unsigned char *)0x4E000020))
  7. void nand_read_ll(unsigned int addr, unsigned char *buf, unsigned int len);

  8. static int isNor()
  9. {
  10.     volatile int *p = (volatile int *)0;
  11.     int val;


  12.     val = *p;
  13.     *p = 0xfdfdfdfd;
  14.     if(0xfdfdfdfd == *p)    //可写,证明是在SRAM中运行,即是从NAND启动
  15.     {
  16.         *p = val;
  17.         return 0;
  18.      }
  19.      else     //写NOR需要特定的命令时序
  20.     {
  21.         return 1;
  22.     }
  23. }

  24. void copy_to_sdram(unsigned char *src, unsigned char *dest, unsigned int len)
  25.     int i = 0;
  26.     /* 判断启动方式 */
  27.     if (isNor())
  28.     {
  29.         while(i < len)
  30.         {
  31.             dest[i] = src[i];    //直接读 NOR(view Figure 5-1. S3C2440A Memory Map after Reset)
  32.             i++;
  33.         }
  34.     }
  35.     else
  36.     {
  37.         nand_read_ll((unsigned int)src, dest, len);
  38.     } 
  39. }


  40. void clear_bss(void)
  41. {
  42.     extern int __bss_start, __bss_end__;
  43.     int *p = &__bss_start;


  44.     for(; p<=&__bss_end__; p++)
  45.     {
  46.         *p = 0;
  47.     }
  48. }


  49. void nand_init_ll(void)
  50. {
  51. /* NFCONF
  52. TACLS [13:12] CLE & ALE duration setting value (0~3)
  53. = 0 Duration = HCLK x TACLSHCLK x TACLS (view K9F1208.pdf)
  54. TWRPH0 [10:8] TWRPH0 duration setting value (0~7)
  55.           Duration = HCLK x ( TWRPH0 + 1 ) = 25ns (view K9F1208.pdf) 1/135.75 = 7ns 
  56. = 3 TWRPH0 >= 25 / 7 - 1 = 2.57
  57. TWRPH1 [6:4] TWRPH1 duration setting value (0~7)
  58.   Duration = HCLK x ( TWRPH1 + 1 ) = 10ns (view K9F1208.pdf)
  59. = 1     TWRPH1 >= 10 / 7 - 1 = 0.42
  60. */
  61.     #define TACLS 0
  62.     #define TWRPH0 3
  63.     #define TWRPH1 1
  64.  
  65.     NFCONF = (TACLS<<12) | (TWRPH0<<8) | (TWRPH1<<4);


  66. /* NFCONT
  67. InitECC [4] Initialize ECC decoder/encoder(Write-only)
  68. = 1 Initialize ECC decoder/encoder
  69. Reg_nCE [1] NAND Flash Memory nFCE signal control
  70. = 1 Force nFCE to high (Disable chip select)
  71. MODE [0] NAND flash controller operating mode
  72. = 1 NAND flash controller enable
  73.  */
  74.     NFCONT = (1<<4) | (0<<1) | (1<<0);
  75. }


  76. static void nand_select(void)
  77. {
  78.     NFCONT &= ~(1<<1); 
  79. }


  80. static void nand_deselect(void)
  81. {
  82.     NFCONT |= (1<<1); 
  83. }


  84. static void nand_cmd(unsigned char cmd)
  85. {
  86.     volatile int i;
  87.     NFCMMD = cmd;
  88.     for (i = 0; i < 10; i++);
  89. }


  90. static void nand_addr(unsigned int addr)
  91. {
  92. /* Address(5Cycle)
  93. Col Add.1,2 & Row Add.1,2,3
  94. */
  95.     int col = addr % 2048;
  96.     int row = addr / 2048;
  97.     volatile int i;


  98.     NFADDR = col & 0xff;
  99.     for(i=0; i<10; i++);


  100.     NFADDR = (col>>8) & 0xff;
  101.     for(i=0; i<10; i++);


  102.     NFADDR = row & 0xff;
  103.     for(i=0; i<10; i++);


  104.     NFADDR = (row>>8) & 0xff;
  105.     for(i=0; i<10; i++);


  106.     NFADDR = (row>>16) & 0xff;
  107.     for(i=0; i<10; i++);
  108. }


  109. static void nand_wait(void)
  110. {
  111.     while(!(NFSTAT&1));
  112. }


  113. void nand_read_ll(unsigned int addr, unsigned char *dest, unsigned int len)
  114. {
  115.     int col = addr % 2048, i = 0;
  116.     nand_select();
  117.     while(i < len)
  118.     {
  119.         /* view K9K8G08U0A.pdf */
  120.         nand_cmd(0x00);


  121.         nand_addr(addr);
  122.         nand_cmd(0x30);
  123.         nand_wait();
  124.         for(; col<2048 && i<len; col++)
  125.         {
  126.             dest[i] = NFDATA;
  127.             i++;
  128.             addr++;
  129.         }
  130.         col = 0;
  131.      }


  132.     nand_deselect();
  133. }


    修改start.S

    #ifndef CONFIG_SKIP_LOWLEVEL_INIT

    bl cpu_init_crit

    #endif


    ldr sp, =(CONFIG_SYS_INIT_SP_ADDR)

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


    bl nand_init_ll


    mov r0, #0

    //ldr r1, =_start

    ldr r1, _TEXT_BASE //CONFIG_SYS_TEXT_BASE = 0x33f00000

    ldr r2, _bss_start_ofs


    bl copy_to_sdram //copy_to_sdram(r0, r1, r2)

    bl clear_bss


    ldr pc, =call_board_init_f //远跳转


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

    call_board_init_f:


    ldr r0,=0x00000000

    bl board_init_f


    修改mini2440.h中#define CONFIG_SYS_TEXT_BASE 0x33f80000

   自己写了重定位,就去掉它写的重定位函数

    注释掉掉board.c中board_init_f中//relocate_code(addr_sp, id, addr);

    删掉start.S中下面不需要的代码





点击(此处)折叠或打开


  1. /*------------------------------------------------------------------                                                                                                                                        ------------*/
  2.                                                                                                                                         
  3.                                                                                                                                         
  4. /*                                                                                                                                        
  5.  * void relocate_code (addr_sp, gd, addr_moni)                                                                                                                                        
  6.  *                                                                                                                                        
  7.  * This "function" does not return, instead it continues in RAM                                                                                                                                        
  8.  * after relocating the monitor code.                                                                                                                                        
  9.  *                                                                                                                                        
  10.  */                                                                                                                                        
  11. .globl    relocate_code                                                                                                                                        
  12. relocate_code:                                                                                                                                        
  13. mov    r4, r0    /* save addr_sp */                                                                                                                                        
  14. mov    r5, r1    /* save addr of gd */                                                                                                                                        
  15. mov    r6, r2    /* save addr of destination */                                                                                                                                        
  16.                                                                                                                                         
  17.                                                                                                                                         
  18. /* Set up the stack     */                                                                                                                                        
  19. stack_setup:                                                                                                                                        
  20. mov    sp, r4                                                                                                                                        
  21.                                                                                                                                         
  22.                                                                                                                                         
  23. adr    r0, _start                                                                                                                                        
  24. cmp    r0, r6                                                                                                                                        
  25. beq    clear_bss     /* skip relocation */                                                                                                                                        
  26. mov    r1, r6     /* r1 <- scratch for copy_loop */                                                                                                                                        
  27. ldr    r3, _bss_start_ofs                                                                                                                                        
  28. add    r2, r0, r3     /* r2 <- source end address     */                                                                                                                                        
  29.                                                                                                                                         
  30.                                                                                                                                         
  31. copy_loop:                                                                                                                                        
  32. ldmia     {r9-r10}     /* copy from source address [r0] */                                                                                                                                        
  33. stmia     {r9-r10}     /* copy to target address [r1] */                                                                                                                                        
  34. cmp    r0, r2     /* until source end address [r2] */                                                                                                                                        
  35. blo    copy_loop                                                                                                                                        
  36.                                                                                                                                         
  37.                                                                                                                                         
  38. #ifndef CONFIG_SPL_BUILD                                                                                                                                        
  39. /*                                                                                                                                        
  40. * fix .rel.dyn relocations                                                                                                                                        
  41. */                                                                                                                                        
  42. ldr    r0, _TEXT_BASE     /* r0 <- Text base */                                                                                                                                        
  43. sub    r9, r6, r0     /* r9 <- relocation offset */                                                                                                                                        
  44. ldr    r10, _dynsym_start_ofs    /* r10 <- sym table ofs */                                                                                                                                        
  45. add    r10, r10, r0     /* r10 <- sym table in FLASH */                                                                                                                                        
  46. ldr    r2, _rel_dyn_start_ofs    /* r2 <- rel dyn start ofs */                                                                                                                                        
  47. add    r2, r2, r0     /* r2 <- rel dyn start in FLASH */                                                                                                                                        
  48. ldr    r3, _rel_dyn_end_ofs    /* r3 <- rel dyn end ofs */                                                                                                                                        
  49. add    r3, r3, r0     /* r3 <- rel dyn end in FLASH */                                                                                                                                        
  50. fixloop:                                                                                                                                        
  51. ldr    r0, [r2]     /* r0 <- location to fix up, IN */                                                                                                                                        
  52. add    r0, r0, r9     /* r0 <- location to fix up in RAM */                                                                                                                                        
  53. ldr    r1, [r2, #4]                                                                                                                                        
  54. and    r7, r1, #0xff                                                                                                                                        
  55. cmp    r7, #23     /* relative fixup? */                                                                                                                                        
  56. beq    fixrel                                                                                                                                        
  57. cmp    r7, #2     /* absolute fixup? */                                                                                                                                        
  58. beq    fixabs                                                                                                                                        
  59. /* ignore unknown type of fixup */                                                                                                                                        
  60. b    fixnext                                                                                                                                        
  61. fixabs:                                                                                                                                        
  62. /* absolute fix: set location to (offset) symbol value */                                                                                                                                        
  63. mov    r1, r1, LSR #4     /* r1 <- symbol index in .dynsym */                                                                                                                                        
  64. add    r1, r10, r1     /* r1 <- address of symbol in table */                                                                                                                                        
  65. ldr    r1, [r1, #4]     /* r1 <- symbol value */                                                                                                                                        
  66. add    r1, r1, r9     /* r1 <- relocated sym addr */                                                                                                                                        
  67. b    fixnext                                                                                                                                        
  68. fixrel:                                                                                                                                        
  69. /* relative fix: increase location by offset */                                                                                                                                        
  70. ldr    r1, [r0]                                                                                                                                        
  71. add    r1, r1, r9                                                                                                                                        
  72. fixnext:                                                                                                                                        
  73. str    r1, [r0]                                                                                                                                        
  74. add    r2, r2, #8     /* each rel.dyn entry is 8 bytes */                                                                                                                                        
  75. cmp    r2, r3                                                                                                                                        
  76. blo    fixloop                                                                                                                                        
  77. #endif                                                                                                                                        
  78.                                                                                                                                         

  79. clear_bss:
  80. #ifndef CONFIG_SPL_BUILD
  81. ldr    r0, _bss_start_ofs
  82. ldr    r1, _bss_end_ofs
  83. mov    r4, r6     /* reloc addr */
  84. add    r0, r0, r4
  85. add    r1, r1, r4
  86. mov    r2, #0x00000000     /* clear     */


  87. clbss_l:str    r2, [r0]     /* clear loop...     */
  88. add    r0, r0, #4
  89. cmp    r0, r1
  90. bne    clbss_l


  91. bl coloured_LED_init
  92. bl red_led_on
  93. #endif


    因为第二阶段函数board_init_f需要

    修改函数定义

    unsigned int board_init_f  (ulong);(common.h)

    unsigned int board_init_f(ulong bootflag) (arch/arm/lib/board.c)

    函数体最后加上

    return (unsigned int)id;

    返回后给start.S的第二阶段代码用

    在start.S

    ldr r0,=0x00000000

    bl board_init_f

    后加上

    //board_init_f的返回值在r0里面,刚好把id传给board_init_r

    ldr r1, _TEXT_BASE

    bl board_init_r


    vi arch/arm/config.mk 

    注释掉

     #LDFLAGS_u-boot += -pie

    修改

    arch/arm/cpu/u-boot.lds添加 board/samsung/mini2440/libmini2440.o (.text)

        .text :

        {

             __image_copy_start = .;

             CPUDIR/start.o (.text)

             board/samsung/mini2440/libmini2440.o (.text)

             *(.text)

        }

    修改board.c

    //addr -= gd->mon_len;

    //addr &= ~(4096 - 1); 

    addr = CONFIG_SYS_TEXT_BASE;

     make后烧写发现


u-boot2012.04.01移植到mini2440_#define_02


    9.在SI中搜索"Flash:“

    (z:\u-boot-2012.04.01\arch\arm\lib\Board.c)

    #if !defined(CONFIG_SYS_NO_FLASH)

    puts("Flash: ");

    继续看

    if (flash_size > 0) {

        ...

    }else {

        puts(failed); //输出*** failed ***

        hang(); //挂起

    }


    void hang(void)

    {

        puts("### ERROR ### Please RESET the board ###\n");

        for (;;); //死循环    

   }

    注释掉//hang();

    再次make,并烧写u-boot.bin到nor flash,发现uboot是启动起来了不过flash和nand都不识别



 u-boot2012.04.01移植到mini2440_#endif_03


    10.定义#define DEBUG (z:\u-boot-2012.04.01\include\configs\Mini2440.h)

    方便调试

    u-boot2012.04.01移植到mini2440_i++_04



    11.找nor的识别问题

    从图中JEDEC PROBE: ID 1 2249 0和代码(z:\u-boot-2012.04.01\drivers\mtd\Cfi_flash.c)

    debug("JEDEC PROBE: ID %x %x %x\n",

    info->manufacturer_id,

    info->device_id,

    info->device_id2); 

  可以看出manufacturer_id是1,device_id是2249,device_id2是0


    flash_init (z:\u-boot-2012.04.01\drivers\mtd\Cfi_flash.c)

        flash_detect_legacy

            // match jedec ids against table. If a match is found, fill flash_info entry

            jedec_flash_match (z:\u-boot-2012.04.01\drivers\mtd\Jedec_flash.c)

                if ((jedec_table[i].mfr_id & mask) == (info->manufacturer_id & mask) &&

                   (jedec_table[i].dev_id & mask) == (info->device_id & mask)) {

                        fill_info(info, &jedec_table[i], base);

                        ret = 1;

                        break;

                }

                可以看到manufacturer_id、device_id都要和jedec_table中的信息匹配。

                添加mini2440用的nor flash信息(需要查看芯片手册Am29LV160DB.pdf)

                {

                    .mfr_id = 1,

                    .dev_id = 0x2249,

                    .name = "Am29LV160DB",

                    .uaddr = {

                        [1] = MTD_UADDR_0x0555_0x02AA /* x16 */

                    },

                    .DevSize = SIZE_2MiB,

                    .CmdSet = CFI_CMDSET_AMD_LEGACY,

                    .NumEraseRegions = 4,

                    .regions = {

                        ERASEINFO(0x04000, 1),

                        ERASEINFO(0x02000, 2),

                        ERASEINFO(0x08000, 1),

                        ERASEINFO(0x10000, 31),

                    }

            },


   u-boot2012.04.01移植到mini2440_3c_05


    取消DEBUG定义(看之前的DEBUG信息足以),再次编译烧写


    12.提示Flash: ERROR: too many flash sectors

    搜索发现#define CONFIG_SYS_MAX_FLASH_SECT (19)  //(z:\u-boot-2012.04.01\include\configs\Mini2440.h)

    修改大一点#define CONFIG_SYS_MAX_FLASH_SECT (128)

    make烧写,Flash:2 MiB.

    u-boot2012.04.01移植到mini2440_#if_06


    13.修改栈指针

    start.S中加上

    .globl base_sp

    base_sp:

    .long 0 

    start_code:  

    .....


    ldr r1, _TEXT_BASE

   ldr sp, base_sp

    bl board_init_r 

    在board.c的board_init_f加上

    extern ulong base_sp;

    ...

    memcpy(id, (void *)gd, sizeof(gd_t));

    base_sp = addr_sp;

    //relocate_code(addr_sp, id, addr);


    14.加上nand的支持

    在mini2440.h中取消注释

    #define CONFIG_CMD_NAND

    make出错,拷贝drivers/mtd/nand/s3c2410_nand.c复制为s3c2440_nand.c

    修改mini2440.h

    #ifdef CONFIG_CMD_NAND


    #ifdef CONFIG_S3C2410

    #define CONFIG_NAND_S3C2410

    #define CONFIG_SYS_S3C2410_NAND_HWECC

    #else

    #define CONFIG_NAND_S3C2440

    #define CONFIG_SYS_S3C2440_NAND_HWECC

    #endif


    #define CONFIG_SYS_MAX_NAND_DEVICE 1

    #define CONFIG_SYS_NAND_BASE 0x4E000000

    #endif

    修改drivers/mtd/nand/Makefile

    加上

    COBJS-$(CONFIG_NAND_S3C2410) += s3c2410_nand.o

    COBJS-$(CONFIG_NAND_S3C2440) += s3c2440_nand.o


    修改s3c2440_nand.c中的s3c2410_nand为s3c2440_nand(除了宏)

    包括s3c2440_dev_ready、s3c2440_hwcontrol、s3c2440_get_base_nand


    从nand_init开始看

    nand_init_chip

            board_nand_init

                ...

                tacls = 4;

                twrph0 = 8;

                twrph1 = 8;

                #endif

                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);

  

                /* NFCONF

                TACLS [13:12] CLE & ALE duration setting value (0~3)

                = 0        Duration = HCLK x TACLSHCLK x TACLS (view K9F1208.pdf)

                TWRPH0 [10:8] TWRPH0 duration setting value (0~7)

                          Duration = HCLK x ( TWRPH0 + 1 ) = 25ns (view K9F1208.pdf) 1/135.75 = 7ns 

                = 3        TWRPH0 >= 25 / 7 - 1 = 2.57

                TWRPH1 [6:4] TWRPH1 duration setting value (0~7)

                  Duration = HCLK x ( TWRPH1 + 1 ) = 10ns (view K9F1208.pdf)

                = 1   TWRPH1 >= 10 / 7 - 1 = 0.42

                */

                cfg = ((tacls-1)<<12) | ((tacls-1)<<8) | ((tacls-1)<<4);

                writel(cfg, &nand_reg->nfconf);


                /* NFCONT

                InitECC [4] Initialize ECC decoder/encoder(Write-only)

                = 1 Initialize ECC decoder/encoder

                Reg_nCE [1] NAND Flash Memory nFCE signal control

                = 1 Force nFCE to high (Disable chip select)

                MODE [0] NAND flash controller operating mode

                = 1 NAND flash controller enable

                 */

                 writel((1<<4) | (0<<1) | (1<<0), &nand_reg->nfcont);

                 ...

                 nand->select_chip = NULL;

                 //修改为nand->select_chip = s3c2440_select_nand;

                  自己写

                                static void s3c2440_select_nand(struct mtd_info *mtd, int chipnr)

                                {

                                     struct s3c2440_nand *nand = s3c2440_get_base_nand();

                                     switch (chipnr) {

                                           case -1: //-1 for deselect

                                                 nand->nfcont |= 1<<1;

                                                 break;

                                           case 0: //0 for select

                                                 nand->nfcont &= ~(1<<1);

                                                 break;

                                           default:

                                                 BUG();

                                    }

                                 }

                      nand->cmd_ctrl = s3c2440_hwcontrol;

                                //修改s3c2410_hwcontrol,根据ctrl判断是发命令还是地址

                               static void s3c2410_hwcontrol(struct mtd_info *mtd, int dat, unsigned int ctrl)

                               {

                                     struct s3c2440_nand *nand = s3c2440_get_base_nand();

                                     debug("hwcontrol(): 0x%02x 0x%02x\n", dat, ctrl);

                                     if (ctrl & NAND_CLE)

                                     {

                                           writeb(dat, &nand->nfcmd);

                                     }

                                     else if (ctrl & NAND_ALE)

                                     {

                                           writeb(dat, &nand->nfaddr);

                                     }

                               }

                               ...

                            nand_scan

                                 nand_scan_ident

                                      nand_set_defaults

                                           if (chip->cmdfunc == NULL)

                                               chip->cmdfunc = nand_command; //static void nand_command(struct mtd_info *mtd, unsigned int command, int column, int page_addr)

                                           if (!chip->select_chip)

                                                chip->select_chip = nand_select_chip;

                                      nand_get_flash_type

                                           chip->select_chip(mtd, 0);

                                           chip->cmdfunc(mtd, NAND_CMD_READID, 0x00, -1);

                                           <=>nand_command

                                                  chip->cmd_ctrl(mtd, readcmd, ctrl);

                                                  <=>s3c2410_hwcontrol;

                     nand_register

                            add_mtd_device

     make后nand可以正常使用了


    15.mini2440用dm9000网卡,搜索drivers/net/Makefile 可以发现

    COBJS-$(CONFIG_DRIVER_DM9000) += dm9000x.o

    由mini2440.h中的宏CONFIG_DRIVER_DM9000控制,并且从上面结果可以看到,需要去掉cs8900的宏.

    #if 0

    #define CONFIG_CS8900 /* we have a CS8900 on-board */

    #define CONFIG_CS8900_BASE 0x19000300

    #define CONFIG_CS8900_BUS16 /* the Linux driver does accesses as shorts */

    #else


    #define CONFIG_DRIVER_DM9000


    #endif


    make看看结果

    dm9000x.c: In function 'dm9000_outblk_8bit':

    dm9000x.c:156: error: 'DM9000_DATA' undeclared (first use in this function)

    dm9000x.c:156: error: (Each undeclared identifier is reported only once

    dm9000x.c:156: error: for each function it appears in.)

    dm9000x.c: In function 'dm9000_outblk_16bit':

    dm9000x.c:165: error: 'DM9000_DATA' undeclared (first use in this function)

    dm9000x.c: In function 'dm9000_outblk_32bit':

    dm9000x.c:173: error: 'DM9000_DATA' undeclared (first use in this function)

    dm9000x.c: In function 'dm9000_inblk_8bit':

    dm9000x.c:180: error: 'DM9000_DATA' undeclared (first use in this function)

    dm9000x.c: In function 'dm9000_inblk_16bit':

    dm9000x.c:189: error: 'DM9000_DATA' undeclared (first use in this function)

    dm9000x.c: In function 'dm9000_inblk_32bit':

    dm9000x.c:197: error: 'DM9000_DATA' undeclared (first use in this function)

    dm9000x.c: In function 'dm9000_rx_status_32bit':

    dm9000x.c:204: error: 'DM9000_IO' undeclared (first use in this function)

    dm9000x.c:206: error: 'DM9000_DATA' undeclared (first use in this function)

    dm9000x.c: In function 'dm9000_rx_status_16bit':

    dm9000x.c:213: error: 'DM9000_IO' undeclared (first use in this function)

    dm9000x.c:215: error: 'DM9000_DATA' undeclared (first use in this function)

    dm9000x.c: In function 'dm9000_rx_status_8bit':

    dm9000x.c:221: error: 'DM9000_IO' undeclared (first use in this function)

    dm9000x.c:224: error: 'DM9000_DATA' undeclared (first use in this function)

    dm9000x.c: In function 'dm9000_probe':

    dm9000x.c:243: error: 'CONFIG_DM9000_BASE' undeclared (first use in this function)

    dm9000x.c: In function 'dm9000_send':

    dm9000x.c:420: error: 'DM9000_IO' undeclared (first use in this function)

    dm9000x.c: In function 'dm9000_rx':

    dm9000x.c:484: error: 'DM9000_DATA' undeclared (first use in this function)

    dm9000x.c: In function 'DM9000_ior':

    dm9000x.c:574: error: 'DM9000_IO' undeclared (first use in this function)

    dm9000x.c:575: error: 'DM9000_DATA' undeclared (first use in this function)

    dm9000x.c: In function 'DM9000_iow':

    dm9000x.c:584: error: 'DM9000_IO' undeclared (first use in this function)

    dm9000x.c:585: error: 'DM9000_DATA' undeclared (first use in this function)

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

    make[1]: Leaving directory `/home/profiles/u-boot-2012.04.01/drivers/net'

    make: *** [drivers/net/libnet.o] Error 2


    报错

    grep "DM9000_DATA" * -nR参考其他开发板

    include/configs/M5253DEMO.h:95:# define DM9000_DATA (CONFIG_DM9000_BASE + 4)

    定义了

     #   define CONFIG_DM9000_BASE   (CONFIG_SYS_CS1_BASE | 0x300)

     #   define DM9000_IO        CONFIG_DM9000_BASE

     #   define DM9000_DATA      (CONFIG_DM9000_BASE + 4)

    则在mini2440.h上加上这些宏,并把值参照原理图芯片手册,DM9000接片选4即bank4,由2440手册知0x20000000是bank4的基址修改过来为:

    #define CONFIG_DM9000_BASE   0x20000000

    #define DM9000_IO        CONFIG_DM9000_BASE

    #define DM9000_DATA      (CONFIG_DM9000_BASE + 4) //LADDR2开始接到DM9000上

    内存控制器初始化已经在lowlevel.S中设置过为

    SMRDATA:

    .long 0x22050000 //BWSCON


    make烧写从nor启动,发现Net:   No ethernet found.

u-boot2012.04.01移植到mini2440_#endif_07


    16.在source insight中搜索“No ethernet found.”找出原因

    eth_initialize (board.c)

        board_eth_init (mini2440/smdk2410.c)

             cs8900_initialize此处不合适,添加DM9000的函数


            #ifdef CONFIG_CS8900

            rc = cs8900_initialize(0, CONFIG_CS8900_BASE);

            #endif

            #ifdef CONFIG_DRIVER_DM9000

            rc = dm9000_initialize(bis);

            #endif

    再次make烧写来试验网络功能

    set ipaddr 169.254.252.201 (连上网线同自己要ping的机器在一个网段)

    set serverip 169.254.252.200

    set gatewayip 255.255.0.0  (同自己要ping的机器一致)

    set ethaddr 08:00:27:71:89:bb

    ping 169.254.252.200 通了

    u-boot2012.04.01移植到mini2440_#define_08

    自行测试下tftp的下载功能。

    tftp 30000000 uImage

    发面bootm 30000000后不能启动linux,在解压后停住了。应该是开发板型号没修改

    修改board_init(board.c)中

    gd->bd->bi_arch_number = MACH_TYPE_SMDK2410;为

    gd->bd->bi_arch_number = MACH_TYPE_MINI2440;

    再次tftp下载后bootm就启动了


    17.环境变量

    开发板烧写u-boot后,发现*** Warning - bad CRC, using default environment

    SI搜索一下。

    set_default_env

        default_environment

            #ifdef CONFIG_BOOTARGS

                "bootargs=" CONFIG_BOOTARGS "\0"

            #ifdef CONFIG_BOOTCOMMAND

                "bootcmd=" CONFIG_BOOTCOMMAND "\0"

    在mini2440.h中加上

    #define CONFIG_BOOTARGS "console=ttySAC0 root=/dev/mtdblock3"

    #define CONFIG_BOOTCOMMAND "nand read 30000000 0x60000 0x500000;bootm 30000000"

    修改

    #define CONFIG_NETMASK 255.255.0.0

    #define CONFIG_IPADDR 169.254.252.201

    #define CONFIG_SERVERIP 169.254.252.200

    加上

    #define CONFIG_ETHADDR 08:00:27:71:89:bb


    18.裁剪

    在mini2440.h找不需要的宏

    #if 0

    #define CONFIG_USB_OHCI

    #define CONFIG_USB_KEYBOARD

    #define CONFIG_USB_STORAGE

    #define CONFIG_DOS_PARTITION

    #endif

    //#define CONFIG_RTC_S3C24X0


    #if 0

    #define CONFIG_BOOTP_BOOTFILESIZE

    #define CONFIG_BOOTP_BOOTPATH

    #define CONFIG_BOOTP_GATEWAY

    #define CONFIG_BOOTP_HOSTNAME

    #endif

    //#define CONFIG_CMD_USB

    //#define CONFIG_CMD_DATE

    //#define CONFIG_CMD_DHCP


    #if 0

    #define CONFIG_CMD_FAT

    #define CONFIG_CMD_EXT2

    #define CONFIG_CMD_UBI

    #define CONFIG_CMD_UBIFS

    #define CONFIG_CMD_MTDPARTS

    #define CONFIG_MTD_DEVICE

    #define CONFIG_MTD_PARTITIONS

    #define CONFIG_YAFFS2

    #define CONFIG_RBTREE

    #endif

    裁剪后make发现

    u-boot.bin的大小为204344B小了很多



    19.环境变量默认存在nor,为了让u-boot里面的saveenv命令将环境变量保存到nand,且不能破坏内核,需要修改保存的位置。

    在SI中搜索"saveenv",找到env_nand.c文件,到Makefile中找寻它所依赖的宏.

    vi common/Makefile,发现它依赖于CONFIG_ENV_IS_IN_NAND

    (mini2440.h)修改

    #if 0

    #define CONFIG_ENV_ADDR (CONFIG_SYS_FLASH_BASE + 0x070000)

    #define CONFIG_ENV_IS_IN_FLASH

    #define CONFIG_ENV_SIZE 0x10000

    /* allow to overwrite serial and ethaddr */

    #define CONFIG_ENV_OVERWRITE

    #endif

    添加

    #define CONFIG_ENV_IS_IN_NAND

    在env_nand.c中找到宏CONFIG_ENV_OFFSET,这个制定存在nand的哪个地址

    需要看看原内核的分区。

    在我使用的2.6.32.2源代码中发现

    static struct mtd_partition friendly_arm_default_nand_part[] = {

        [0] = {

            .name = "supervivi",

            .size = 0x00040000,

            .offset = 0,

        },

        [1] = {

            .name = "param",

            .offset = 0x00040000,

            .size = 0x00020000,

        },

        [2] = {

            .name = "Kernel",

            .offset = 0x00060000,

            .size = 0x00500000,

        },

        [3] = {

            .name = "root",

            .offset = 0x00560000,

            .size = 1024 * 1024 * 1024, //

        },

        [4] = {

            .name = "nand",

            .offset = 0x00000000,

            .size = 1024 * 1024 * 1024, //

        }

    };

    (或者启动内核后发现)

u-boot2012.04.01移植到mini2440_#if_09

    参数存在0x40000开始的0x20000大小处

    则加定义(mini2440.h)

    #define CONFIG_ENV_OFFSET 0x40000

    #define CONFIG_ENV_SIZE 0x20000

    #define CONFIG_ENV_RANGE CONFIG_ENV_SIZE //擦除单位

    make后烧写nor

    此时还有*** Warning - bad CRC, using default environment

    在u-boot里执行save命令重启就行了

    u-boot倒计时5秒如果没有执行的话,就会执行我们设置的

    #define CONFIG_BOOTCOMMAND "nand read 30000000 0x60000 0x500000;bootm 30000000"

    即从nand flash 0x60000的地方读0x500000的数据(整个内核)到内存0x30000000的地方,然后从0x30000000启动内核。

     于是我们必须先将uImage烧写到0x60000的地方: 

    先下载tftp 30000000 uImage

    nand erase 60000 500000

    nand write 30000000 60000 500000 //这样60000的地方就有了可启动的内核

    下次重启开发板,5秒延时之后将自动读内核并加载运行


    20.代替繁琐的数字

    在board.c的board_init_r中加上

    run_command("mtdparts default", 0); //必须让uboot执行这条命令

    /* main_loop() can return to retry autoboot, if so just run it again. */

    for (;;) {

    main_loop();

     }

    在mini2440中定义宏

    #define CONFIG_CMD_MTDPARTS

    参照其它开发板再添加上

     #define CONFIG_MTD_DEVICE

    #define MTDIDS_DEFAULT "nand0=mini2440-0"

    #define MTDPARTS_DEFAULT "mtdparts=mini2440-0:256k(u-boot)," \

                                                       "128k(params)," \

                                                       "5m(kernel)," \

                                                       "-(rootfs)" \ //-余下的所有给rootfs

    make后提示发现drivers\mtd\mtdcore.c中的get_mtd_device_nm未定义。

    则可以直接去drivers\mtd\Makefile中查看哪个宏决定是否编译成mtdcore.o

    或者grep "mtdcore.o" * -nR发现是CONFIG_MTD_DEVICE控制的

    将宏添加到mini2440.h

    #define CONFIG_MTD_DEVICE

    再次make并烧写

    在uboot执行命令mtdparts

u-boot2012.04.01移植到mini2440_#define_10

    现在可以尝试用名字代替数字的分区表示,如

    tftp 30000000 uImage

    nand erase.part kernel

    nand write 30000000 kernel


    此版对于yaffs的一个小bug

    drivers/mtd/nand/nand_util.c (nand_write_skip_bad)中

    改为

    ops.len = pagesize;

    ops.ooblen = nand->oobsize;

    ops.mode = MTD_OOB_RAW;

   ops.ooboffs = 0;



    pages = write_size / pagesize_oob;

    for (page = 0; page < pages; page++) {

    WATCHDOG_RESET();



    ops.datbuf = p_buffer;

    ops.oobbuf = ops.datbuf + pagesize;



    rval = nand->write_oob(nand, offset, &ops);

    if (rval) 

   break;



    offset += pagesize;

    p_buffer += pagesize_oob;

    }

    if (!need_skip && !(flags & WITH_DROP_FFS)) {

    改为

    if (!need_skip && !(flags & WITH_DROP_FFS) && !(flags & WITH_YAFFS_OOB)) {


之前的内核都是用nfs文件系统。

如果想用jffs2或者yaffs应该执行下列命令

烧写JFFS2

tftp 30000000 fs.jffs2

nand erase.part rootfs

nand write.jffs2 30000000 0x00260000 5b89a8


set bootargs console=ttySAC0 root=/dev/mtdblock3 rootfstype=jffs2


烧写YAFFS(需要先在mini2440中重新#define CONFIG_CMD_NAND_YAFFS再编译)

tftp 30000000 fs.yaffs2

nand erase.part rootfs

nand write.yaffs 30000000 260000  889bc0 //文件大小


用uboot更新自身

tftp 30000000 u-boot_new.bin; protect off all; erase 0 3ffff; cp.b 30000000 0 40000


移植完后制作补丁

mv u-boot-2012.04.01 u-boot-2012.04.01_ok

tar xjf u-boot-2012.04.01.tar.bz2

diff -urN u-boot-2012.04.01 u-boot-2012.04.01_ok > u-boot-2012.04.01.patch