u-boot2012.04.01移植到mini2440

软件平台: 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 0x000 000B1 //BANKSIZE


      /* CL [6:4] CAS latency
      = 011 3 clocks
      */
      .long 0x00000030 //MRSRB6
      .long 0x00000030 //MRSRB7
      再次 make ,并烧写u-boot.bin到nor flash,启动后发现是乱码,应该是串口波特率问题,看看串口初始化

    

      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:  erro r: 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 *= (volatile int *)0;
  11.     int val;


  12.     val = *p;
  13.     *= 0xfdfdfdfd;
  14.     if(0xfdfdfdfd == *p)    //可写,证明是在SRAM中运行,即是从NAND启动
  15.     {
  16.         *= 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. { 
  26.     int i = 0;
  27.     /* 判断启动方式 */
  28.     if (isNor())
  29.     {
  30.         while(< len)
  31.         {
  32.             dest[i] = src[i];    //直接读 NOR(view Figure 5-1. S3C2440A Memory Map after Reset)
  33.             i++;
  34.         }
  35.     }
  36.     else
  37.     {
  38.         nand_read_ll((unsigned int)src, dest, len);
  39.     } 
  40. }


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


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


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


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


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


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


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


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


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


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


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


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


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


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


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


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


  133.     nand_deselect();
  134. }

    修改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_第1张图片

     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_第2张图片

     10.定义#define DEBUG (z:\u-boot-2012.04.01\include\configs\Mini2440.h)
     方便调试
     u-boot2012.04.01移植到mini2440_第3张图片


     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_第4张图片

     取消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_第5张图片

     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_第6张图片

     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_第7张图片
     自行测试下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中搜索 "saveen v ",找到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, //
         }
     };
     (或者启动内核后发现)

     参数存在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_第8张图片

     现在可以尝试用名字代替数字的分区表示,如
     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 ( rva l)  
   
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

打补丁
cd u-boot-2012.04.01
patch -p1 < ../u-boot-2012.04.01.patch    //因为现在所在u-boot-2012.04.01目录,-p1 数字表示忽略第一个斜杠
[email protected]

编译新uboot
make mini2440_config
make

你可能感兴趣的:(嵌入式linux开发)