Chinaunix首页 | 论坛 | 博客
  • 博客访问: 40982
  • 博文数量: 10
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 22
  • 用 户 组: 普通用户
  • 注册时间: 2014-04-05 23:29
文章分类
文章存档

2016年(10)

我的朋友

分类: 嵌入式

2016-06-05 22:36:52

原文地址:u-boot2012.04.01移植到mini2440 作者:angrad

软件平台: 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,启动后发现是乱码,应该是串口波特率问题,看看串口初始化

    

     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. {
  26.     int i = 0;
  27.     /* 判断启动方式 */
  28.     if (isNor())
  29.     {
  30.         while(i < 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 *p = &__bss_start;


  45.     for(; p<=&__bss_end__; p++)
  46.     {
  47.         *p = 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 (i = 0; i < 10; i++);
  90. }


  91. static void nand_addr(unsigned int addr)
  92. {
  93. /* Address(5Cycle)
  94. Col Add.1,2 & 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(i < 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后烧写发现



    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都不识别


 

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


    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_id1device_id2249device_id20

    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),
                    }
            },

   

    取消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.
    

    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_readys3c2440_hwcontrols3c2440_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.


    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 通了
    
    自行测试下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, //
        }
    };
    (或者启动内核后发现)

    参数存在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

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

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

编译新uboot
make mini2440_config
make



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