cortex A8处理器启动过程二引导代码BL1

本博客转载于:http://blog.csdn.net/u010216127/article/details/9321489


BL1相当于u-boot的第一阶段代码,主要完成如下工作:1.初始化硬件:关看门狗、设置串口、SDRAM、初始化Flash;2.重定位,将代码重定位到SDRAM;3.引导u-boot第二阶段代码。其实如果它能引导内核,就相当于一个bootlaoder,这里先实现上面3个功能。代码有点多,我还是贴出来吧,懒得看,需要编译好的源码包留个邮箱我发你。

系统:ubuntu 10.04.4
单板:s5pc100(CES-C100)
编译器:arm-linux-gcc-4.3.2
搭建开发环境详见ubuntu 10.04.4开发环境配置。

一、编写代码

文件start.S:

[plain] view plain copy
  1. .global  
  2.   
  3. _start:  
  4.     /*1. Disable Watchdog */  
  5.     /*1.关看门狗*/  
  6.     ldr r0, =0xEA200000  
  7.     mov r1, #0  
  8.     str r1, [r0]  
  9.   
  10.     bl  clock_init  
  11.     //bl    test  
  12.     bl  mp1_x_drive_strength_init  
  13.     bl  mem_ctrl_asm_init  
  14.     ldr sp, =0xD0038000  
  15.     bl  init_uart  
  16.     bl  nand_init  
  17.     //bl    test  
  18.     ldr r0, =0x0  
  19.     ldr r1, =0x21000000  
  20.     ldr r2, =bss_start  
  21.     sub r2, r2, r1  
  22.     bl  copy_code_to_sdram  
  23.     //bl    test  
  24.     //b main  
  25.   
  26. clean_bss:  
  27.     ldr r0, =bss_start  
  28.     ldr r1, =bss_end  
  29.     mov r3, #0  
  30.     cmp r0, r1  
  31.     ldreq pc, =on_ddr  
  32.       
  33. clean_loop:  
  34.     str r3, [r0], #4  
  35.     cmp r0, r1  
  36.     bne clean_loop  
  37.     ldr pc, =on_ddr  
  38.   
  39. on_ddr:  
  40.     ldr sp, =0x21800000    /* ÖØгõÊŒ»¯Õ»£¬ÖžÏòÄÚŽæ */  
  41.     //bl  test  
  42.     ldr pc, =main  

文件clock.S

[plain] view plain copy
  1. .globl clock_init  
  2.   
  3. clock_init:  
  4.       
  5.     /* 1.设置LOCK_TIME */  
  6.     ldr r0, =0xe0100000     //CLOCK_POWER_BASE  
  7.     mov r1, #0xe00  
  8.     orr r1, r1, #0x10  
  9.     str r1, [r0, #0x0]      /* APLL_LOCK */  
  10.     str r1, [r0, #0x4]   /* MPLL_LOCK */  
  11.     str r1, [r0, #0x8]   /* EPLL_LOCK */  
  12.     str r1, [r0, #0x0c] //HPLL_LOCK  
  13.   
  14.       
  15. //#define OTHERS        0x7e00f900  
  16. //  @ set async mode  /* 当CPU时钟 != HCLK时,要设为异步模式 */  
  17. //  ldr r0, =OTHERS  
  18. //  ldr r1, [r0]  
  19. //  bic r1, r1, #0xc0   /* 1100,0000 */       
  20. //  str r1, [r0]  
  21.   
  22. //loop1:                /* 等待,直到CPU进入异步模式 */  
  23. //  ldr r0, =OTHERS  
  24. //  ldr r1, [r0]  
  25. //  and r1, r1, #0xf00                    
  26. //  cmp r1, #0  
  27. //  bne loop1         
  28.       
  29.     /* SYNC667 */  
  30.     /* MISC_CON[19] = 0 */  
  31.   
  32. //#define ARM_RATIO    0   /* ARMCLK = DOUTAPLL / (ARM_RATIO + 1)    */  
  33. //#define HCLKX2_RATIO 1   /* HCLKX2 = HCLKX2IN / (HCLKX2_RATIO + 1) */  
  34. //#define HCLK_RATIO   1   /* HCLK = HCLKX2 / (HCLK_RATIO + 1)       */  
  35. //#define PCLK_RATIO   3   /* PCLK   = HCLKX2 / (PCLK_RATIO + 1)     */  
  36. //#define MPLL_RATIO   0   /* DOUTMPLL = MOUTMPLL / (MPLL_RATIO + 1)     */  
  37. //  ldr r0, =0x7E00F020  /* CLK_DIV0 */  
  38. //  ldr r1, =(ARM_RATIO) | (MPLL_RATIO << 4) | (HCLK_RATIO << 8) | (HCLKX2_RATIO << 9) | (PCLK_//RATIO << 12)  
  39. //  str r1, [r0]  
  40. /* CLK_DIV0 */  
  41. #define APLL_RATIO  0  
  42. #define ARM_RATIO   4  
  43. #define D0_BUS_RATIO    8  
  44. #define PCLKD0_RATIO    12  
  45. #define SECSS_RATIO 16  
  46.       
  47.     ldr r1, [r0, #0x300]    //CLK_DIV0 Clock divider  
  48.     ldr r2, =0x3fff  
  49.     bic r1, r1, r2  
  50.   
  51.     ldr r2, =(1<<APLL_RATIO) | (0<<ARM_RATIO) | (4<<D0_BUS_RATIO) | (1<<PCLKD0_RATIO) | (1<<SECSS_RATIO)  
  52.     orr r1, r1, r2  
  53.     str r1, [r0, #0x300]    //CLK_DIV0  
  54.   
  55.     ldr r2, =((1<<16) | (1<<12) | (1<<8) | (1<<4))  
  56.     orr r1 ,r1, r2  
  57.     str r1, [r0, #0x304]    //CLD_DIV1  
  58.     /* 2.配置时钟 */  
  59.     /* 2.1 配置APLL */  
  60.     /* 2.1.1 设置APLL  
  61.      * 2.1.2 MUXAPLL  
  62.      * 2.1.3 SYNC667  
  63.      * 2.1.4 DIVAPLL  
  64.      */  
  65. //#define APLL_CON_VAL  ((1<<31) | (266 << 16) | (3 << 8) | (1))  
  66. //  ldr r0, =0x7E00F00C  
  67. //  ldr r1, =APLL_CON_VAL  
  68. //  str r1, [r0]        /* APLL_CON, FOUTAPL = MDIV * Fin / (PDIV*2^SDIV) = 266*12/(3*2^1) = 532MHz  */  
  69. #define APLL_VAL  ((1<<31) | (417 << 16) | (3 << 8) | (0))      
  70.     //ldr r0, =0xe0100100   //APLL_CON  
  71.     ldr r1, =APLL_VAL  
  72.     str r1, [r0, #0x100]        /* MPLL_CON, FOUTMPL = MDIV * Fin / (PDIV*2^SDIV) = 266*12/(3*2^1) = 532MHz  */  
  73.     /* 2.2 配置MPLL */  
  74.     /* 2.2.1 设置MPLL  
  75.      * 2.2.2 MUXMPLL  
  76.      * 2.2.3 SYNCMUX  
  77.      * 2.2.4 SYNC667  
  78.      * 2.2.5 HCLKX2_RATIO  
  79.      * 2.2.6 PCLK_RATIO  
  80.      */  
  81. //#define MPLL_CON_VAL  ((1<<31) | (266 << 16) | (3 << 8) | (1))  
  82. //CONFIG_CLK_833_166_66  
  83. #define MPLL_VAL  ((1<<31) | (89 << 16) | (2 << 8) | (1))  
  84. #define EPLL_VAL  ((1<<31) | (135 << 16) | (3 << 8) | (3))  
  85. #define HPLL_VAL  ((1<<31) | (96 << 16) | (6 << 8) | (3))  
  86.   
  87.     ldr r1, =MPLL_VAL  
  88.     str r1, [r0, #0x104]  
  89.   
  90.     ldr r1, =EPLL_VAL  
  91.     str r1, [r0, #0x108]  
  92.   
  93.     ldr r1, =HPLL_VAL  
  94.     str r1, [r0, #0x10c]  
  95.       
  96.     /* 3.选择PLL的输出作为时钟源 */  
  97.     ldr r1, [r0, #0x200]    //CLK_SRC0 0xe0100200  
  98.     ldr r2, =0x1111  
  99.     orr r1, r1, r2  
  100.     str r1, [r0, #0x200]    //FOUT: APLL MPLL EPLL HPLL  
  101.   
  102.     mov     r1, #0x10000  
  103. 1:  subs    r1, r1, #1  
  104.     bne 1b  
  105.   
  106.     mov pc, lr  

文件cpu_init.S

[plain] view plain copy
  1. //#include "s5pc100.h"  
  2. /* Port Group MP1_X Drive Strength Control */  
  3. #define MP1_0DRV_OFFSET         0x03CC  
  4. #define MP1_1DRV_OFFSET         0x03EC  
  5. #define MP1_2DRV_OFFSET         0x040C  
  6. #define MP1_3DRV_OFFSET         0x042C  
  7. #define MP1_4DRV_OFFSET         0x044C  
  8. #define MP1_5DRV_OFFSET         0x046C  
  9. #define MP1_6DRV_OFFSET         0x048C  
  10. #define MP1_7DRV_OFFSET         0x04AC  
  11. #define MP1_8DRV_OFFSET         0x04CC  
  12.   
  13. /*  
  14.  * Bus Matrix  
  15.  */  
  16. #define ELFIN_MEM_SYS_CFG       0x7e00f120  
  17.   
  18. /*  
  19.  * Memory controller  
  20.  */  
  21. #define ELFIN_SROM_BASE         0xE7000000  
  22.   
  23. #define SROM_BW_REG         __REG(ELFIN_SROM_BASE+0x0)  
  24. #define SROM_BC0_REG            __REG(ELFIN_SROM_BASE+0x4)  
  25. #define SROM_BC1_REG            __REG(ELFIN_SROM_BASE+0x8)  
  26. #define SROM_BC2_REG            __REG(ELFIN_SROM_BASE+0xC)  
  27. #define SROM_BC3_REG            __REG(ELFIN_SROM_BASE+0x10)  
  28. #define SROM_BC4_REG            __REG(ELFIN_SROM_BASE+0x14)  
  29. #define SROM_BC5_REG            __REG(ELFIN_SROM_BASE+0x18)  
  30.   
  31. /*  
  32.  * SDRAM Controller  
  33.  */  
  34. #define APB_DMC_BASE            0xE6000000  
  35.   
  36. #define DMC_CONCONTROL          0x00  
  37. #define DMC_MEMCONTROL          0x04  
  38. #define DMC_MEMCONFIG0          0x08  
  39. #define DMC_MEMCONFIG1          0x0C  
  40. #define DMC_DIRECTCMD           0x10  
  41. #define DMC_PRECHCONFIG         0x14  
  42. #define DMC_PHYCONTROL0         0x18  
  43. #define DMC_PHYCONTROL1         0x1C  
  44. #define DMC_PHYCONTROL2         0x20  
  45. #define DMC_PWRDNCONFIG         0x28  
  46. #define DMC_TIMINGAREF          0x30  
  47. #define DMC_TIMINGROW           0x34  
  48. #define DMC_TIMINGDATA          0x38  
  49. #define DMC_TIMINGPOWER         0x3C  
  50. #define DMC_PHYSTATUS0          0x40  
  51. #define DMC_PHYSTATUS1          0x44  
  52. #define DMC_CHIP0STATUS         0x48  
  53. #define DMC_CHIP1STATUS         0x4C  
  54. #define DMC_AREFSTATUS          0x50  
  55. #define DMC_MRSTATUS            0x54  
  56. #define DMC_PHYTEST0            0x58  
  57. #define DMC_PHYTEST1            0x5C  
  58. #define DMC_QOSCONTROL0         0x60  
  59. #define DMC_QOSCONFIG0          0x64  
  60. #define DMC_QOSCONTROL1         0x68  
  61. #define DMC_QOSCONFIG1          0x6C  
  62. #define DMC_QOSCONTROL2         0x70  
  63. #define DMC_QOSCONFIG2          0x74  
  64. #define DMC_DMC_QOSCONTROL3         0x78  
  65. #define DMC_QOSCONFIG3          0x7C  
  66. #define DMC_QOSCONTROL4         0x80  
  67. #define DMC_QOSCONFIG4          0x84  
  68. #define DMC_QOSCONTROL5         0x88  
  69. #define DMC_QOSCONFIG5          0x8C  
  70. #define DMC_QOSCONTROL6         0x90  
  71. #define DMC_QOSCONFIG6          0x94  
  72. #define DMC_QOSCONTROL7         0x98  
  73. #define DMC_QOSCONFIG7          0x9C  
  74.   
  75. /*  
  76. * Memory Chip direct command  
  77. */  
  78. #define PRO_ID_BASE         0xE0000000  
  79. #define PRO_ID_OFFSET           0x00  
  80. #define OMR_OFFSET          0x04  
  81.   
  82. /*  
  83.  * GPIO  
  84.  */  
  85. #define ELFIN_GPIO_BASE         0xE0300000  
  86.   
  87.   
  88. .globl  mp1_x_drive_strength_init  
  89. /*  
  90.  * Init MP1_X Driver Strength for SDRAM  
  91.  * void mp1_x_drive_strength_init(void)  
  92.  */  
  93.  mp1_x_drive_strength_init:  
  94.    
  95.     ldr r0, =ELFIN_GPIO_BASE  
  96.     ldr r1, =0xaaaa  
  97.     str     r1, [r0, #MP1_0DRV_OFFSET]  
  98.     str     r1, [r0, #MP1_1DRV_OFFSET]  
  99.     str     r1, [r0, #MP1_2DRV_OFFSET]  
  100.     str     r1, [r0, #MP1_3DRV_OFFSET]  
  101.     str     r1, [r0, #MP1_4DRV_OFFSET]  
  102.     str     r1, [r0, #MP1_5DRV_OFFSET]  
  103.     str     r1, [r0, #MP1_6DRV_OFFSET]    
  104.     str     r1, [r0, #MP1_7DRV_OFFSET]  
  105.     str     r1, [r0, #MP1_8DRV_OFFSET]    
  106.       
  107.     mov pc, lr  
  108.   
  109.     .globl mem_ctrl_asm_init  
  110. mem_ctrl_asm_init:  
  111.   
  112.     ldr r0, =APB_DMC_BASE           @APB_DMC_BASE 0xE6000000  
  113.   
  114.     ldr r1, =PRO_ID_BASE  
  115.     ldr r2, [r1, #PRO_ID_OFFSET]  
  116.     bic r2, #0xfffffdff  
  117.     mov r2, r2, lsr #9  
  118.     cmp r2, #0x1  
  119.     beq onenand_pop  
  120.   
  121. single:  
  122.   
  123. /************ delay loop *************/  
  124.   
  125. #if 0  
  126.     ldr     r1, =0x10000000  
  127.     mov         r2, #0  
  128. loop1:  
  129.   
  130.     cmp     r2, r1  
  131.     addne   r2, r2, #0x1  
  132.     bne loop1  
  133. #endif  
  134.   
  135. /************ DLL initialization *************/  
  136.         
  137.         ldr     r1, =0x6A101000             @ Phycontrol0 DLL parameter setting  
  138.         str     r1, [r0, #DMC_PHYCONTROL0]  
  139.   
  140.         ldr     r1, =0x000084F4                          @Phycontrol1 DLL parameter setting  
  141.         str     r1, [r0, #DMC_PHYCONTROL1]  
  142.   
  143.         ldr     r1, =0x00000000                          @Phycontrol2 DLL parameter setting  
  144.         str     r1, [r0, #DMC_PHYCONTROL2]  
  145.   
  146.         ldr     r1, =0x6A101002                   @DLL on  
  147.         str     r1, [r0, #DMC_PHYCONTROL0]  
  148.   
  149.         ldr     r1, =0x6A101003             @Dll start  
  150.         str     r1, [r0, #DMC_PHYCONTROL0]  
  151.   
  152.   
  153.   
  154.     ldr r2, = 0xE6000040        @DMC_PHYSTATUS0  
  155.   
  156. loop1:  
  157.   
  158.     ldr r1, [r2]                @Check DLL lock  
  159.     ands    r1, r1, #4  
  160.     beq loop1  
  161.   
  162.     ldr r1, [r2]  
  163.     mov r1, r1,  LSR #(0x6)  
  164.     and r1, r1, #(0xff)  
  165.     mov r1, r1, LSL  #(0x18)  
  166.     ldr     r2,  = 0xE6000018           @DMC_PHYCONTROL0  
  167.     ldr r3, [r2]  
  168.     bic r3,  r3, #(0xff000000)  
  169.     orr r1, r3, r2  
  170.     str r1, [r2]  
  171.   
  172.   
  173.   
  174.         ldr     r1, =0x6A101003         @Force Value locking  
  175.         str     r1, [r0, #DMC_PHYCONTROL0]  
  176.   
  177.         ldr     r1, =0x6A101009         @Dll off  
  178.         str     r1, [r0, #DMC_PHYCONTROL0]  
  179.   
  180.   
  181.   
  182. #if 0  
  183.         ldr     r1, =0x6A101000             @ Phycontrol0 DLL parameter setting  
  184.         str     r1, [r0, #DMC_PHYCONTROL0]  
  185.   
  186.         ldr     r1, =0x00008484                             @Phycontrol1 DLL parameter setting  
  187.         str     r1, [r0, #DMC_PHYCONTROL1]  
  188.   
  189.         ldr     r1, =0x00000000                             @Phycontrol2 DLL parameter setting  
  190.         str     r1, [r0, #DMC_PHYCONTROL2]  
  191.   
  192. #endif  
  193. /************ DLL initialization - END *************/  
  194.   
  195.   
  196.   
  197.   
  198.         ldr     r1, =0x0FF01010                         @auto refresh off  
  199.         str     r1, [r0, #DMC_CONCONTROL]  
  200.   
  201.         ldr     r1, =0x00202400                         @ BL=4 , 1 chip , DDR2  
  202.         str     r1, [r0, #DMC_MEMCONTROL]  
  203.   
  204. #if 1   // add xxs 256MB enable  
  205.         ldr     r1, =0x20F01323  
  206.         str     r1, [r0, #DMC_MEMCONFIG0]  
  207.   
  208.         ldr     r1, =0x40F00323  
  209.         str     r1, [r0, #DMC_MEMCONFIG1]  
  210. #else   // 128MB enable  
  211.         ldr     r1, =0x20F81313                       
  212.         str     r1, [r0, #DMC_MEMCONFIG0]  
  213.   
  214.         ldr     r1, =0x40F80313  
  215.         str     r1, [r0, #DMC_MEMCONFIG1]  
  216. #endif  
  217.     
  218.         ldr     r1, =0x20000000       
  219.         str     r1, [r0, #DMC_PRECHCONFIG]  
  220.   
  221.   
  222.         ldr     r1, =0x00100004         @ PwrdnConfig  
  223.         str     r1, [r0, #DMC_PWRDNCONFIG]  
  224.   
  225. #ifdef  CONFIG_HCLKD0_222  
  226.     ldr     r1, =0x000006c3                         @7.8us*222MHz=0x6c3, 7.8us*166MHz=1294(0x50E)  
  227.        str     r1, [r0, #DMC_TIMINGAREF]  
  228.     /* T-rfc   127.5nS/5ns  64 */  
  229.        ldr     r1, =0x202332C8                              @TimingRow      @222MHz  
  230.        str     r1, [r0, #DMC_TIMINGROW]  
  231.   
  232.        ldr     r1, =0x24450304                          @CL=5  
  233.        str     r1, [r0, #DMC_TIMINGDATA]  
  234.   
  235.  #else  
  236.   
  237.   
  238.         ldr     r1, =0x0000050E       
  239.         str     r1, [r0, #DMC_TIMINGAREF]  
  240.   
  241.         ldr  r1, =0x16233297                         @TimingRow      @166MHz  
  242.         str     r1, [r0, #DMC_TIMINGROW]  
  243.   
  244. @;      ldr  r1, =0x24250304                         @CL=5  
  245.         ldr  r1, =0x23230000                         @CL=3  
  246.         str     r1, [r0, #DMC_TIMINGDATA]  
  247.  #endif  
  248.   
  249.         ldr     r1, =0x07c80232                        @ Timing Power  
  250.         str     r1, [r0, #DMC_TIMINGPOWER]  
  251.   
  252. /* Direct Command for DDR2 */  
  253.         ldr     r1, =0x07000000                         @chip0 Deselect  
  254.         str     r1, [r0, #DMC_DIRECTCMD]  
  255.   
  256.         ldr     r1, =0x01000000                        @chip0 PALL  
  257.         str     r1, [r0, #DMC_DIRECTCMD]  
  258.   
  259.         ldr     r1, =0x00020000                         @chip0 EMRS2  
  260.         str     r1, [r0, #DMC_DIRECTCMD]  
  261.   
  262.         ldr     r1, =0x00030000                         @chip0 EMRS3  
  263.         str     r1, [r0, #DMC_DIRECTCMD]  
  264.   
  265.         ldr     r1, =0x00010400                         @chip0 EMRS1 (MEM DLL on = DQS# disable)  
  266.         str     r1, [r0, #DMC_DIRECTCMD]  
  267.   
  268. @;      ldr     r1, =0x00000552                         @chip0 MRS (MEM DLL reset) CL=5, Burst Length=4  
  269.         ldr     r1, =0x00000532                         @chip0 MRS (MEM DLL reset) CL=3, Burst Length=4  
  270.         str     r1, [r0, #DMC_DIRECTCMD]  
  271.   
  272.         ldr     r1, =0x01000000                         @chip0 PALL  
  273.         str     r1, [r0, #DMC_DIRECTCMD]  
  274.   
  275.         ldr     r1, =0x05000000                         @chip0 REFA  
  276.         str     r1, [r0, #DMC_DIRECTCMD]  
  277.   
  278.         ldr     r1, =0x05000000                         @chip0 REFA  
  279.         str     r1, [r0, #DMC_DIRECTCMD]  
  280.   
  281. @;      ldr     r1, =0x00000452                         @chip0 MRS (MEM DLL unreset) , BL=4 , CL=5  
  282.         ldr     r1, =0x00000432                         @chip0 MRS (MEM DLL unreset) , BL=4 , CL=3   
  283.         str     r1, [r0, #DMC_DIRECTCMD]  
  284.   
  285.         ldr     r1, =0x00010780                         @chip0 EMRS1 (OCD default)  
  286.         str     r1, [r0, #DMC_DIRECTCMD]  
  287.   
  288.   
  289. //      ldr     r1, =0x00010400                         @chip0 EMRS1 (OCD exit)  
  290.         ldr     r1, =0x00010402                         @chip0 EMRS1 (OCD exit)  Reduced Strength  
  291. //      ldr     r1, =0x00010000                         @chip0 EMRS1 (OCD exit)  ODT Disabled  
  292.         str     r1, [r0, #DMC_DIRECTCMD]  
  293.   
  294.   
  295. /* Direct Command for LPDDR  - END */  
  296.    
  297.     ldr     r1, =0x00FF20B0         @ConControl auto refresh on  
  298.         str     r1, [r0, #DMC_CONCONTROL]  
  299.   
  300. #if 0  
  301.         ldr     r1, =0x001000FF         @ PwrdnConfig  
  302.         str     r1, [r0, #DMC_PWRDNCONFIG]  
  303. #endif  
  304.   
  305.         ldr     r1, =0x00212413             @ MemControl  
  306.         str     r1, [r0, #DMC_MEMCONTROL]  
  307.   
  308.         b   exit_cpu_init  
  309.   
  310.   
  311. onenand_pop:  
  312.     ldr r1, =0x50101000             @Phycontrol0 DLL parameter setting  
  313.     str r1, [r0, #DMC_PHYCONTROL0]  
  314.   
  315.     ldr r1, =0x000000F4             @Phycontrol1 DLL parameter setting  
  316.     str r1, [r0, #DMC_PHYCONTROL1]  
  317.   
  318.     ldr r1, =0x00000000             @Phycontrol2 DLL parameter setting  
  319.     str r1, [r0, #DMC_PHYCONTROL2]  
  320.   
  321.     ldr r1, =0x50101002             @Dll on  
  322.     str r1, [r0, #DMC_PHYCONTROL0]  
  323.   
  324.     ldr r1, =0x50101003             @dll start  
  325.     str r1, [r0, #DMC_PHYCONTROL0]  
  326.   
  327.     ldr r1, =0x50101003             @Force Value locking  
  328.     str r1, [r0, #DMC_PHYCONTROL0]  
  329.   
  330.     ldr r1, =0x50101001             @Dll off  
  331.     str r1, [r0, #DMC_PHYCONTROL0]  
  332.   
  333.     ldr r1, =0xFF001010             @auto refresh off  
  334.     str r1, [r0, #DMC_CONCONTROL]  
  335.   
  336.     ldr r1, =0x00212100             @Dll off  
  337.     str r1, [r0, #DMC_MEMCONTROL]  
  338.   
  339. @;  ldr r1, =0x28F80222  
  340.     ldr r1, =0x28F00222  
  341.     str r1, [r0, #DMC_MEMCONFIG0]  
  342.   
  343.     ldr r1, =0x20F80222  
  344.     str r1, [r0, #DMC_MEMCONFIG1]  
  345.   
  346.     ldr r1, =0x20000000  
  347.     str r1, [r0, #DMC_PRECHCONFIG]  
  348.   
  349.     ldr r1, =0x0000050E  
  350.     str r1, [r0, #DMC_TIMINGAREF]  
  351.   
  352.     ldr r1, =0x0C233287             @TimingRow  @133MHz  
  353.     str r1, [r0, #DMC_TIMINGROW]  
  354.   
  355.     ldr r1, =0x32330303  
  356.     str r1, [r0, #DMC_TIMINGDATA]  
  357.   
  358.     ldr r1, =0x04141433             @Timing Power  
  359.     str r1, [r0, #DMC_TIMINGPOWER]  
  360.   
  361.     ldr r1, =0x07000000             @chip0 Deselect  
  362.     str r1, [r0, #DMC_DIRECTCMD]  
  363.   
  364.     ldr r1, =0x01000000             @chip0 PALL  
  365.     str r1, [r0, #DMC_DIRECTCMD]  
  366.   
  367.     ldr r1, =0x05000000             @chip0 REFA  
  368.     str r1, [r0, #DMC_DIRECTCMD]  
  369.   
  370.     ldr r1, =0x05000000             @chip0 REFA  
  371.     str r1, [r0, #DMC_DIRECTCMD]  
  372.   
  373.     ldr r1, =0x00000032             @chip0 MRS  
  374.     str r1, [r0, #DMC_DIRECTCMD]  
  375.   
  376.     ldr r1, =0x07100000             @chip1 Deselect  
  377.     str r1, [r0, #DMC_DIRECTCMD]  
  378.   
  379.     ldr r1, =0x01100000             @chip1 PALL  
  380.     str r1, [r0, #DMC_DIRECTCMD]  
  381.   
  382.     ldr r1, =0x05100000             @chip1 REFA  
  383.     str r1, [r0, #DMC_DIRECTCMD]  
  384.   
  385.     ldr r1, =0x05100000             @chip1 REFA  
  386.     str r1, [r0, #DMC_DIRECTCMD]  
  387.   
  388.     ldr r1, =0x00100032             @chip1 MRS  
  389.     str r1, [r0, #DMC_DIRECTCMD]  
  390.   
  391.     ldr r1, =0xFF002030             @ConControl auto refresh on  
  392.     str r1, [r0, #DMC_CONCONTROL]  
  393.   
  394.     ldr r1, =0x00100002             @PwrdnConfig  
  395.     str r1, [r0, #DMC_PWRDNCONFIG]  
  396.   
  397. @;  ldr r1, =0xFF212113             @MemControl  
  398.     ldr r1, =0xFF212100             @MemControl  
  399.     str r1, [r0, #DMC_MEMCONTROL]  
  400.   
  401.     b   exit_cpu_init  
  402.   
  403. exit_cpu_init:  
  404.     mov pc, lr  

文件uart.c:

[plain] view plain copy
  1. #define ULCON0     (*((volatile unsigned long *)0xEC000000))  
  2. #define UCON0      (*((volatile unsigned long *)0xEC000004))  
  3. #define UFCON0     (*((volatile unsigned long *)0xEC000008))  
  4. #define UMCON0     (*((volatile unsigned long *)0xEC00000C))  
  5. #define UTRSTAT0   (*((volatile unsigned long *)0xEC000010))  
  6. #define UFSTAT0    (*((volatile unsigned long *)0xEC000018))  
  7. #define UTXH0      (*((volatile unsigned char *)0xEC000020))  
  8. #define URXH0      (*((volatile unsigned char *)0xEC000024))  
  9. #define UBRDIV0    (*((volatile unsigned long *)0xEC000028))  
  10. #define UDIVSLOT0  (*((volatile unsigned long *)0xEC00002C))  
  11.   
  12. #define GPACON     (*((volatile unsigned long *)0xE0300000))  
  13.   
  14. #define ENABLE_FIFO   
  15.   
  16. void init_uart(void)  
  17. {  
  18.   GPACON &= ~0xffff;  
  19.   GPACON |= 0x2222;  
  20.     
  21.   /* ULCON0 */  
  22.   ULCON0 = 0x3;  /* 数据位:8, 无较验, 停止位: 1, 8n1 */  
  23.   UCON0  = 0x5;  /* 使能UART发送、接收 */  
  24. #ifdef ENABLE_FIFO  
  25.   UFCON0 = 0x07; /* FIFO enable */  
  26. #else  
  27.   UFCON0 = 0x00; /* FIFO disable */  
  28. #endif  
  29.   UMCON0 = 0;  
  30.     
  31.   /* 波特率 */  
  32.   /* DIV_VAL = (PCLK / (bps x 16 ) ) - 1   
  33.    * bps = 115200  
  34.    * DIV_VAL = (66500000 / (115200 x 16 ) ) - 1   
  35.    *         = 35.08  
  36.    */  
  37.   UBRDIV0   = 35;  
  38.   
  39.   /* x/16 = 0.08  
  40.    * x = 1  
  41.    */  
  42.   UDIVSLOT0 = 3;  
  43.     
  44.   UTXH0 = 0x4f4f4f4f;  
  45. }  
  46. #define ENABLE_FIFO   
  47. static void delay1(void)  
  48. {  
  49.   volatile int i = 10;  
  50.   while (i--);  
  51. }  
  52.   
  53. unsigned char getc(void)  
  54. {  
  55. #ifdef ENABLE_FIFO  
  56.   while ((UFSTAT0 & (1<<6)) == 0 && (UFSTAT0 & 0x3f) == 0)delay1();  
  57. #else  
  58.   while ((UTRSTAT0 & (1<<0)) == 0);  
  59. #endif  
  60.     
  61.   return URXH0;  
  62. }  
  63.   
  64. int getc_nowait(unsigned char *pChar)  
  65. {  
  66. #ifdef ENABLE_FIFO  
  67.   if ((UFSTAT0 & (1<<6)) == 0 && (UFSTAT0 & 0x3f) == 0)  
  68. #else  
  69.     if ((UTRSTAT0 & (1<<0)) == 0)  
  70. #endif  
  71.       {  
  72.     return -1;  
  73.       }  
  74.     else  
  75.       {  
  76.     *pChar = URXH0;  
  77.     return 0;  
  78.       }  
  79. }  
  80.   
  81. void putc(char c)  
  82. {  
  83. #ifdef ENABLE_FIFO  
  84.   if(c == '\r')  
  85.     {  
  86.       while (UFSTAT0 & (1<<14))delay1();  
  87.       UTXH0 = '\n';  
  88.     }  
  89.   if(c == '\n')  
  90.     {  
  91.       while (UFSTAT0 & (1<<14))delay1();  
  92.       UTXH0 = '\r';  
  93.     }  
  94.   //while(!(UTRSTAT0&(1<<1)));  
  95.   while (UFSTAT0 & (1<<14))delay1();  
  96. #else  
  97.   while ((UTRSTAT0 & (1<<2)) == 0);  
  98. #endif  
  99.   UTXH0 = c;  
  100. }  

文件uart.h:

[plain] view plain copy
  1. void init_uart(void);  
  2. unsigned char getc(void);  
  3. int getc_nowait(unsigned char *pChar);  
  4. void putc(char c);  

文件command.c:

[plain] view plain copy
  1. #include "lib.h"  
  2. #include "nand.h"  
  3. #include "setup.h"  
  4.   
  5. int help(int argc, char * argv[])  
  6. {  
  7.     printf("do_command <%s> \n", argv[0]);  
  8.     printf("help message: \n");  
  9.     printf("md - memory dispaly \n");  
  10.     printf("mw - memory write \n");  
  11.     printf("nand read - nand read sdram_addr nand_addr size\n");  
  12.     printf("nand write - nand write sdram_addr nand_addr size\n");  
  13.     printf("bootm - boot zImage\n");  
  14.   
  15.     return 0;  
  16. }  
  17.   
  18. int md(int argc, char * argv[])  
  19. {     
  20.     unsigned long *p = (unsigned long *)0;  
  21.     int i, j;  
  22.   
  23.     printf("do_command <%s> \n", argv[0]);  
  24.   
  25.     if (argc <= 1) {  
  26.         printf ("Usage:\n%s\n", "md address");  
  27.         return 1;  
  28.     }  
  29.       
  30.     if (argc >= 2)  
  31.         p = (unsigned long *)atoi(argv[1]);  
  32.           
  33.     for (j = 0; j < 16; j++)  
  34.     {     
  35.         printf("%x: ", p);  
  36.         for (i = 0; i < 4; i++)  
  37.           printf("%x ", *p++);    
  38.         puts("\n");  
  39.     }  
  40.           
  41.     return 0;  
  42. }  
  43.   
  44. int mw(int argc, char * argv[])  
  45. {     
  46.     unsigned long *p = (unsigned long *)0;  
  47.     int v = 0;  
  48.   
  49.     printf("do_command <%s> \n", argv[0]);  
  50.   
  51.     if (argc <= 2) {  
  52.         printf ("Usage:\n%s\n", "md address data");  
  53.         return 1;  
  54.     }  
  55.       
  56.     if (argc >= 2)  
  57.         p = (unsigned long *)atoi(argv[1]);  
  58.           
  59.     if (argc >= 3)  
  60.         v = atoi(argv[2]);  
  61.           
  62.     *p = v;  
  63.     printf("do_command mw finished!\n");  
  64.     return 0;  
  65. }  
  66. int nand(int argc, char *argv[])  
  67. {  
  68.   unsigned int nand_addr, sdram_addr;  
  69.   unsigned int size;  
  70.   char *cmd;  
  71.   if (argc < 5)  
  72.     {  
  73.       printf("nand read nand_addr sdram_addr size\n");  
  74.       printf("nand write nand_addr sdram_addr size\n");  
  75.       return 0;  
  76.     }  
  77.   nand_addr = atoi(argv[2]);  
  78.   sdram_addr = atoi(argv[3]);  
  79.   size = atoi(argv[4]);  
  80.   //cmd = argv[1];  
  81.   //putc(*cmd);  
  82.   //printf("*cmd = %x\n", *cmd);  
  83.   //printf("do_command <%s> \n", argv[0]);  
  84.   //printf("nand <%s> \n", argv[1]);  
  85.   puts("\n");  
  86.   printf("nand_addr = %x, sdram_addr = %x, size = %x\n", nand_addr, sdram_addr, size);  
  87.   if (strcmp(argv[1], "read") == 0)  
  88.   {  
  89.     nand_read_dis(nand_addr, sdram_addr, size);  
  90.     printf("nand <%s> \n", argv[1]);  
  91.   }  
  92.   if (strcmp(cmd, "write") == 0)  
  93.     nand_write_dat(nand_addr, (unsigned char *)sdram_addr, size);  
  94.   printf("nand %s finished!\n", argv[1]);  
  95.   return 0;  
  96. }  
  97.   
  98. //const char cmd[] = "root=/dev/nfs nfsroot=192.168.1.104:/work/nfs_root/wy_fs ip=192.168.1.17 cons//ole=ttySAC0";  
  99. const char cmd[] = "root=/dev/mtdblock2 rw rootfstype=yaffs2 mem=256m init=/init console=ttySAC0,115200 androidboot.console=s3c2410_serial0";  
  100.   
  101. void init_tag(int addr)  
  102. {  
  103.   struct tag * p;  
  104.   int i;  
  105.   p = (struct tag*) addr;  
  106.   p->hdr.tag  =  ATAG_CORE;  
  107.   p->hdr.size = tag_size(tag_core);  
  108.   p->u.core.flags = 0;//1;  
  109.   p->u.core.pagesize = 0;//4096;  
  110.   p->u.core.rootdev = 0x00000000;  
  111.   p = tag_next(p);  
  112.   p->hdr.tag = ATAG_CMDLINE;  
  113.   p->hdr.size =  (sizeof (cmd) + sizeof(struct tag_header) + 3) >>2;  
  114.   for(i=0; i< sizeof (cmd); i++)  
  115.     p->u.cmdline.cmdline[i] = cmd[i];  
  116.   p = tag_next(p);  
  117.   p->hdr.tag = ATAG_MEM;  
  118.   p->hdr.size = tag_size(tag_mem32);  
  119.   p->u.mem.start = 0x20000000;  
  120.   p->u.mem.size = 256*1024*1024;  
  121.   p = tag_next(p);  
  122.   p->hdr.tag = ATAG_NONE;  
  123.   p->hdr.size = 0;  
  124. }  
  125. int bootm(int argc, char * argv[])  
  126. {  
  127.   int addr = 0x20008000;  
  128.   void (*fp)(int, int, int);  
  129.   int taglist_mem_address = 0x20000100;  
  130.   printf("loading linux from 0x100000 to 0x20008000...\n");  
  131.   nand_read(0x100000, 0x20008000, 0x200000);  
  132.   fp = (void (*)(int, int, int))addr;  
  133.   init_tag(taglist_mem_address);  
  134.   printf("boot linux ...\n");  
  135.   fp(0, 1826, taglist_mem_address);  
  136.   printf("boot linux error!\n");  
  137.   return 0;  
  138. }  
  139. void run_command(int argc, char * argv[])  
  140. {  
  141.   switch(argc){  
  142.   case 0:  
  143.   case 1:  
  144.     if (strcmp(argv[0], "help") == 0)  
  145.     {  
  146.         help(argc, argv);  
  147.         return;  
  148.     }  
  149.       
  150.     else if (strcmp(argv[0], "bootm") == 0)  
  151.       {  
  152.         bootm(argc, argv);  
  153.         return;  
  154.       }  
  155.     else //(argc >= 1)  
  156.             printf("Unknown command '%s' - try 'help' \n",argv[0]);  
  157.   case 2:  
  158.   
  159.     if (strcmp(argv[0], "md") == 0)  
  160.     {  
  161.         md(argc, argv);  
  162.         return;  
  163.     }  
  164.       
  165.     else if (strcmp(argv[0], "mw") == 0)  
  166.     {  
  167.         mw(argc, argv);  
  168.         return;  
  169.     }  
  170.     else //(argc >= 1)  
  171.             printf("Unknown command '%s' - try 'help' \n",argv[0]);  
  172.   default:  
  173.     /*    if (strcmp(argv[1], "read") == 0)  
  174.       {  
  175.         nand(argc, argv);  
  176.         return;  
  177.       }  
  178.     else if (strcmp(argv[1], "write") == 0)  
  179.       {  
  180.         nand(argc, argv);  
  181.         return;  
  182.       }  
  183.     */  
  184.     if (argc == 5)  
  185.       {  
  186.       nand(argc, argv);  
  187.       return;  
  188.       }  
  189.     else //(argc >= 1)  
  190.         printf("Unknown command '%s' - try 'help' \n",argv[0]);  
  191.   
  192.     return;  
  193.   }  
  194. }  
  195.   
  196.   
  197. 文件command.h:  

void run_command(int argc, char * argv[]);

文件lib.c:

[plain] view plain copy
  1. #include "uart.h"  
  2.   
  3. int getchar(void)  
  4. {  
  5.   int c;  
  6.   c = (int)getc();  
  7.   if (c == '\r')  
  8.     return '\n';  
  9.   return c;  
  10. }  
  11.   
  12.   
  13. void puts(char *str)  
  14. {  
  15.   int i = 0;  
  16.   while (str[i])  
  17.     {  
  18.       putc(str[i]);  
  19.       i++;  
  20.     }  
  21. }  
  22. char * gets(char * s)  
  23. {  
  24.   char * p = s;  
  25.   while ((*p = getchar()) != '\n')  
  26.     {  
  27.       if (*p != '\b')  
  28.     putc(*p++);  
  29.       else  
  30.     if (p > s)  
  31.       {  
  32.         puts ("\b \b");  
  33.         p--;  
  34.       }  
  35.     }  
  36.   *p = '\0';  
  37.   putc('\n');  
  38.   return s;  
  39. }  
  40.   
  41. void test()  
  42. {  
  43.   puts("init: OK\n\r");  
  44. }  
  45. void puthex(unsigned int val)  
  46. {  
  47.   // 0x1234abcd   
  48.   int i;  
  49.   int j;  
  50.   
  51.   puts("0x");  
  52.   
  53.   for (i = 0; i < 8; i++)  
  54.     {  
  55.       j = (val >> ((7-i)*4)) & 0xf;  
  56.       if ((j >= 0) && (j <= 9))  
  57.     putc('0' + j);  
  58.       else  
  59.     putc('A' + j - 0xa);  
  60.     }  
  61. }  
  62.   
  63. void putbyte(unsigned char val)  
  64. {  
  65.   /* 0x1234abcd */  
  66.   int i;  
  67.   int j;  
  68.   
  69.   puts("0x");  
  70.   
  71.   for (i = 0; i < 2; i++)  
  72.     {  
  73.       j = (val >> ((1-i)*4)) & 0xf;  
  74.       if ((j >= 0) && (j <= 9))  
  75.     putc('0' + j);  
  76.       else  
  77.     putc('A' + j - 0xa);  
  78.     }  
  79. }  
  80.   
  81. char * itoa(int a, char * buf)  
  82.   
  83. {  
  84.   int num = a;  
  85.   int i = 0;  
  86.   int len = 0;  
  87.   do   
  88.     {  
  89.       buf[i++] = num % 10 + '0';  
  90.       num /= 10;  
  91.     } while (num);  
  92.   
  93.   buf[i] = '\0';  
  94.   len = i;  
  95.   for (i = 0; i < len/2; i++)  
  96.     {  
  97.       char tmp;  
  98.       tmp = buf[i];  
  99.       buf[i] = buf[len-i-1];  
  100.       buf[len-i-1] = tmp;  
  101.     }  
  102.   return buf;  
  103. }  
  104. int strlen(char *str)  
  105. {  
  106.   int i = 0;  
  107.   while (str[i])  
  108.     {  
  109.       i++;  
  110.     }  
  111.   return i;  
  112. }  
  113.   
  114. int strcmp(const char * s1, const char * s2)  
  115. {  
  116.   while (*s1 == *s2)  
  117.     {  
  118.       //putc(*s1);  
  119.       if (*s1 == '\0')  
  120.     {  
  121.       //s1 -= strlen(s2);  
  122.       return 0;  
  123.     }  
  124.       //putc(*s2);  
  125.       s1++;  
  126.       s2++;  
  127.     }  
  128.   //putc(*s1);  
  129.   //putc(*s2);  
  130.   return *s1 - *s2;  
  131. }  
  132.   
  133.  /*int strcmp(const char * cs,const char * ct)  
  134. {  
  135.   register signed char __res;  
  136.   
  137.   while (1) {  
  138.     if ((__res = *cs - *ct++) != 0 || !*cs++)  
  139.       break;  
  140.   }  
  141.   
  142.   return __res;  
  143.   }*/  
  144. int atoi(char * buf)  
  145. {  
  146.   int value = 0;  
  147.   int base = 10;  
  148.   int i = 0;  
  149.   if (buf[0] == '0' && buf[1] == 'x')  
  150.     {  
  151.       base = 16;  
  152.       i = 2;  
  153.     }  
  154.   // 123 = (1 * 10 + 2) * 10 + 3  
  155.   // 0x1F = 1 * 16 + F(15)  
  156.   while (buf[i])  
  157.     {  
  158.       int tmp;  
  159.       if (buf[i] <= '9' && buf[i] >= '0')   
  160.     tmp = buf[i] - '0';  
  161.       else  
  162.     tmp = buf[i] - 'a' + 10;  
  163.       value = value * base + tmp;  
  164.       i++;  
  165.     }  
  166.   return value;  
  167. }  
  168.   
  169. typedef int * va_list;  
  170. #define va_start(ap, A)(ap = (int *)&(A) + 1)  
  171. #define va_arg(ap, T)(*(T *)ap++)  
  172. #define va_end(ap)((void)0)  
  173.   
  174. int printf(const char * format, ...)  
  175. {  
  176.   char c;  
  177.   va_list ap;  
  178.   va_start(ap, format);  
  179.   
  180.   while ((c = *format++) != '\0')  
  181.     {  
  182.       switch (c)  
  183.     {  
  184.     case '%':  
  185.       c = *format++;  
  186.         
  187.       switch (c)  
  188.         {  
  189.           char ch;  
  190.           char * p;  
  191.           int a;  
  192.           char buf[100];  
  193.          
  194.         case 'c':  
  195.           ch = va_arg(ap, int);  
  196.           putc(ch);  
  197.           break;  
  198.         case 's':  
  199.           p = va_arg(ap, char *);  
  200.           puts(p);  
  201.           break;  
  202.         case 'x':  
  203.           a = va_arg(ap, int);  
  204.           puthex(a);  
  205.           break;  
  206.         case 'd':  
  207.           a = va_arg(ap, int);  
  208.           itoa(a, buf);  
  209.           puts(buf);  
  210.           break;          
  211.         default:  
  212.   
  213.           break;  
  214.         }  
  215.       break;  
  216.        
  217.     default:  
  218.       putc(c);  
  219.       break;  
  220.     }  
  221.     }  
  222.   return 0;  
  223. }  
  224.   
  225. void delay(void)  
  226.   
  227. {  
  228.   volatile int i = 0x200000;  
  229.   while (i--);  
  230. }  

文件lib.h

[plain] view plain copy
  1. void delay(void);  
  2. void puts(char *str);  
  3. //int puts(const char * s);  
  4. void test();  
  5. void puthex(unsigned int val);  
  6. int getchar(void);  
  7. char * gets(char * s);  
  8. //void puthex(int a);  
  9. void putbyte(unsigned char val);  
  10. char * itoa(int a, char * buf);  
  11. int strlen(char *str);  
  12. int strcmp(const char * s1, const char * s2);  
  13. int atoi(char * buf);  
  14. int printf(const char * format, ...);  

文件nand.c:

[plain] view plain copy
  1. //#define MEM_SYS_CFG     (*((volatile unsigned long *)0x7E00F120))  
  2. #define NFCONF          (*((volatile unsigned long *)0xE7200000))  
  3. #define NFCONT          (*((volatile unsigned long *)0xE7200004))  
  4. #define NFCMMD          (*((volatile unsigned long *)0xE7200008))  
  5. #define NFADDR          (*((volatile unsigned long *)0xE720000C))  
  6. #define NFDATA          (*((volatile unsigned char *)0xE7200010))  
  7. #define NFSTAT          (*((volatile unsigned long *)0xE7200028))  
  8.   
  9. void nand_read(unsigned int nand_start, unsigned int ddr_start, unsigned int len);  
  10.   
  11. void copy_code_to_sdram(unsigned int src, unsigned int dest, unsigned int len)  
  12. {  
  13.   //int i = 0;  
  14.   /*如果是Nor启动*/  
  15.   // unsigned char *src_start = (unsigned char *)src;  
  16.   //unsigned char *dest_start = (unsigned char *)dest;  
  17.   /*if(isBootFromNorFlash())  
  18.     {  
  19.       while (i < len)  
  20.         {  
  21.           dest_start[i] = src_start[i];  
  22.           i++;  
  23.         }  
  24.     }  
  25.   else  
  26.     {  
  27.       //nand_init();                                                                                  
  28.       //nand_resd(src, dest, len)                                                                     
  29.       nand_read(src, dest, len);  
  30.       }*/  
  31.   nand_read(src, dest, len);  
  32. }  
  33.   
  34. void nand_select(void)  
  35. {  
  36.   NFCONT &= ~(1<<1);  
  37. }  
  38.   
  39. void nand_deselect(void)  
  40. {  
  41.   NFCONT |= (1<<1);  
  42. }  
  43.   
  44.   
  45. void nand_cmd(unsigned char cmd)  
  46. {  
  47.   NFCMMD = cmd;  
  48. }  
  49.   
  50. void nand_addr(unsigned char addr)  
  51. {  
  52.   NFADDR = addr;  
  53. }  
  54.   
  55. unsigned char nand_get_data(void)  
  56. {  
  57.   return NFDATA;  
  58. }  
  59.   
  60. void nand_send_data(unsigned char data)  
  61. {  
  62.   NFDATA = data;  
  63. }  
  64.   
  65. void wait_ready(void)  
  66. {  
  67.   while ((NFSTAT & 0x1) == 0);  
  68. }  
  69.   
  70.   
  71. void nand_reset(void)  
  72. {  
  73.   /* 选中 */  
  74.   nand_select();  
  75.   
  76.   /* 发出0xff命令 */  
  77.   nand_cmd(0xff);  
  78.   
  79.   /* 等待就绪 */  
  80.   wait_ready();  
  81.   
  82.   /* 取消选中 */  
  83.   nand_deselect();  
  84. }  
  85.   
  86. /*void clear_bss(void)  
  87. {  
  88.   extern int __bss_start, __bss_end;  
  89.   int *p = &__bss_start;  
  90.   
  91.   for (; p < &__bss_end; p++)  
  92.     *p = 0;  
  93. }  
  94. */  
  95. void nand_init(void)  
  96. {  
  97.   /* 让xm0csn2用作nand flash cs0 片选引脚 */  
  98.   //MEM_SYS_CFG &= ~(1<<1);  
  99.   
  100.   /* 设置时间参数 */  
  101. #define TACLS     7  
  102. #define TWRPH0    7  
  103. #define TWRPH1    7  
  104.   NFCONF &= ~((1<<30) | (7<<12) | (7<<8) | (7<<4));  
  105.   NFCONF |= ((TACLS<<12) | (TWRPH0<<8) | (TWRPH1<<4));  
  106.   
  107.   /* 使能nand flash controller */  
  108.   NFCONT |= 1;  
  109.   NFCONT &= ~(1<<16); /* 森止soft lock */  
  110.   
  111.   nand_reset();  
  112. }  
  113.   
  114. void nand_send_addr(unsigned int addr)  
  115. {  
  116. #if 1  
  117.   unsigned int page   = addr / 2048;  
  118.   //unsigned int colunm = addr & (2048 - 1);  
  119.   unsigned int colunm = addr % 2048;  
  120.   volatile int i;  
  121.   /* 这两个地址表示从页内哪里开始 */  
  122.   nand_addr(colunm & 0xff);  
  123.   for (i = 0; i < 10; i++);  
  124.   nand_addr((colunm >> 8) & 0xff);  
  125.   for (i = 0; i < 10; i++);  
  126.   /* 下面三个地址表示哪一页 */  
  127.   nand_addr(page & 0xff);  
  128.   for (i = 0; i < 10; i++);  
  129.   nand_addr((page >> 8) & 0xff);  
  130.   for (i = 0; i < 10; i++);  
  131.   nand_addr((page >> 16) & 0xff);  
  132.   for (i = 0; i < 10; i++);  
  133. #else  
  134.   nand_addr(addr & 0xff);         /* a0~a7 */  
  135.   nand_addr((addr >> 8) & 0x0f);   /* 程序的角度: a8~a11 */  
  136.   
  137.   nand_addr((addr >> 12) & 0xff); /* 程序的角度: a12~a19 */  
  138.   nand_addr((addr >> 20) & 0xff); /* 程序的角度: a20~a27 */  
  139.   nand_addr((addr >> 28) & 0x7); /* 程序的角度: a28 ~a30 */  
  140.     
  141. #endif  
  142. }  
  143.   
  144. void nand_read(unsigned int nand_start, unsigned int ddr_start, unsigned int len)  
  145. {  
  146.   unsigned int addr = nand_start;  
  147.   int i = nand_start % 2048;  
  148.   int left = i;  
  149.   int count = 0;  
  150.   unsigned char *dest = (unsigned char *)ddr_start;  
  151.   unsigned char data = 0;  
  152.     
  153.   /* 选中芯片 */  
  154.   nand_select();  
  155.   
  156.   while (count < len)  
  157.     {  
  158.       /* 发出命令0x00 */  
  159.       nand_cmd(0x00);  
  160.   
  161.       /* 发出地址 */  
  162.       nand_send_addr(addr);  
  163.   
  164.       /* 发出命令0x30 */  
  165.       nand_cmd(0x30);  
  166.   
  167.       /* 等待就绪 */  
  168.       wait_ready();  
  169.   
  170.       /* 读数据 */  
  171.       //for (; i < (4096-left) && count < len; i++)//从某页的i处开始读  
  172.       for (; i < (2048-left) && count < len; i++)//从某页的i处开始读  
  173.     {  
  174.       data = nand_get_data();  
  175.       /*(addr<16384)//前4页每次只能写2K  
  176.         {  
  177.           if(i<(2048-left))  
  178.         {  
  179.           dest[count++] = data;  
  180.         }  
  181.         }  
  182.       else  
  183.         {  
  184.           dest[count++] = data;  
  185.           }*/  
  186.       dest[count++] = data;  
  187.       addr++;  
  188.     }  
  189.   
  190.       i = 0;  
  191.       left = i;  
  192.     }  
  193.   
  194.   /* 取消片选 */  
  195.   nand_deselect();  
  196.   // return 0;  
  197. }  
  198.   
  199. void nand_erase_block(unsigned long addr)  
  200. {  
  201.   int page = addr / 2048;  
  202.     
  203.   nand_select();  
  204.   nand_cmd(0x60);  
  205.     
  206.   nand_addr(page & 0xff);  
  207.   nand_addr((page >> 8) & 0xff);  
  208.   nand_addr((page >> 16) & 0xff);  
  209.   
  210.   nand_cmd(0xd0);  
  211.   wait_ready();  
  212.   
  213.   nand_deselect();  
  214. }  
  215.   
  216.   
  217. void nand_write(unsigned int nand_start, unsigned char * buf, unsigned int len)  
  218. {  
  219.   unsigned long count = 0;  
  220.   unsigned long addr  = nand_start;  
  221.   int i = nand_start % 2048;  
  222.   //int left = i;  
  223.     
  224.   nand_select();  
  225.   while (count < len)  
  226.     {  
  227.       nand_cmd(0x80);  
  228.       nand_send_addr(addr);  
  229.       //for (; i < (2048-left) && count < len; i++)  
  230.       for (; i < 2048 && count < len; i++)  
  231.     {  
  232.       /*if(addr<16384)//写前2K  
  233.         {  
  234.           if(i<(2048-left))//前2页每页只能写2K  
  235.         {  
  236.           nand_send_data(buf[count++]);  
  237.         }  
  238.         }  
  239.       else  
  240.         {  
  241.           nand_send_data(buf[count++]);  
  242.           }*/  
  243.       nand_send_data(buf[count++]);  
  244.       addr++;  
  245.     }  
  246.   
  247.       nand_cmd(0x10);  
  248.       wait_ready();  
  249.       i = 0;  
  250.       //left = i;  
  251.     }  
  252.   
  253.   nand_deselect();  
  254.     
  255. }  
  256.   
  257. void nand_read_dis(unsigned int nand_start, unsigned int ddr_start, unsigned int len)  
  258.   
  259. {  
  260.   int i;  
  261.   //char buf[100];  
  262.   unsigned char *buf = (unsigned char *)ddr_start;  
  263.   //unsigned long addr;  
  264.   //unsigned long size;  
  265.    
  266.   // puts("\n enter the start address: 0x80000");  
  267.   
  268.   //scanf("%s", buf);  
  269.   
  270.   //addr = strtoul(buf, NULL, 0);  
  271.   //addr = 0x80000;  
  272.   //puts("read addr = 0x%x\n\r", addr);  
  273.   
  274.   //puts("enter the size: 0x60");  
  275.   
  276.   //scanf("%s", buf);  
  277.   //size = strtoul(buf, NULL, 0);  
  278.   //size = 0x60;  
  279.   
  280.   //if (size > 100)  
  281.   //{  
  282.   //  puts("the max size is 100\r");  
  283.   //  size = 100;  
  284.   //}  
  285.   nand_read(nand_start, buf, len);  
  286.   
  287.   puts("datas: \n");  
  288.   for (i = 0; i < len; i++)  
  289.     {  
  290.       // printf("%02x ", buf[i]);  
  291.       putbyte(*buf);  
  292.       puts("\t");  
  293.       if ((i+1) % 8 == 0)  
  294.     {  
  295.       puts("\n");  
  296.     }  
  297.       buf++;  
  298.     }  
  299.   puts("\n");  
  300. }  
  301. void nand_write_dat(unsigned int nand_start, unsigned char * buf, unsigned int len)  
  302. {  
  303.   //char buf[20] = {"abcd1234ABCD"};  
  304.   //unsigned long addr;  
  305.   //unsigned long size;  
  306.     
  307.   //puts("enter the start address:0x80000 ");  
  308.   //scanf("%s", buf);  
  309.   //addr = strtoul(buf, NULL, 0);  
  310.   //addr = 0x80000;  
  311.   //puts("enter the string:abcd1234ABCD ");  
  312.   //scanf("%s", buf);  
  313.   len = strlen(buf) + 1;  
  314.   //puts(" size= ");  
  315.   //puthex(size);  
  316.   //puts("\r");  
  317.   nand_write(nand_start, buf, len);  
  318.   puts("nand write sucessful!\n");  
  319. }  
  320. void nand_erase_dat(unsigned long erase_addr, unsigned int len)  
  321. {  
  322.   //char buf[100];  
  323.   //unsigned long addr;  
  324.     
  325.   //puts("enter the start address:0x80000 ");  
  326.   //scanf("%s", buf);  
  327.   //addr = strtoul(buf, NULL, 0);  
  328.   //addr = 0x80000;  
  329.   //puts("erase addr = ");  
  330.   //puthex(addr);  
  331.   //puts("\n");  
  332.       /* 烧写到nand flash block 0 */  
  333.   if(erase_addr % 0x20000 == 0)  
  334.     {  
  335.       for (erase_addr; erase_addr < ((len + 0x1FFFF) & ~0x1FFFF); erase_addr += 0x20000)  
  336.     {  
  337.       nand_erase_block(erase_addr);  
  338.       puts("erase a block sucessful\n");  
  339.     }  
  340.     }  
  341.   else  
  342.     puts("error erase addr\n");  
  343.       //nand_erase_block(addr);  
  344.     
  345. }  

文件nand.h:

[plain] view plain copy
  1. void nand_read(unsigned int nand_start, unsigned int ddr_start, unsigned int len);  
  2. void nand_erase_block(unsigned long addr);  
  3. void nand_write(unsigned int nand_start, unsigned char * buf, unsigned int len);  
  4. void nand_read_dis(unsigned int nand_start, unsigned int ddr_start, unsigned int len);  
  5. void nand_write_dat(unsigned int nand_start, unsigned char * buf, unsigned int len);  
  6. void nand_erase_dat(unsigned long erase_addr, unsigned int len);  
  7. void copy_code_to_sdram(unsigned int src, unsigned int dest, unsigned int len);  

文件setup.h:

[plain] view plain copy
  1. /*  
  2.  *  linux/include/asm/setup.h  
  3.  *  
  4.  *  Copyright (C) 1997-1999 Russell King  
  5.  *  
  6.  * This program is free software; you can redistribute it and/or modify  
  7.  * it under the terms of the GNU General Public License version 2 as  
  8.  * published by the Free Software Foundation.  
  9.  *  
  10.  *  Structure passed to kernel to tell it about the  
  11.  *  hardware it's running on.  See linux/Documentation/arm/Setup  
  12.  *  for more info.  
  13.  *  
  14.  * NOTE:  
  15.  *  This file contains two ways to pass information from the boot  
  16.  *  loader to the kernel. The old struct param_struct is deprecated,  
  17.  *  but it will be kept in the kernel for 5 years from now  
  18.  *  (2001). This will allow boot loaders to convert to the new struct  
  19.  *  tag way.  
  20.  */  
  21. #ifndef __ASMARM_SETUP_H  
  22. #define __ASMARM_SETUP_H  
  23.   
  24. #define u8  unsigned char  
  25. #define u16 unsigned short  
  26. #define u32 unsigned long  
  27.   
  28. /*  
  29.  * Usage:  
  30.  *  - do not go blindly adding fields, add them at the end  
  31.  *  - when adding fields, don't rely on the address until  
  32.  *    a patch from me has been released  
  33.  *  - unused fields should be zero (for future expansion)  
  34.  *  - this structure is relatively short-lived - only  
  35.  *    guaranteed to contain useful data in setup_arch()  
  36.  */  
  37. #define COMMAND_LINE_SIZE 1024  
  38.   
  39. /* This is the old deprecated way to pass parameters to the kernel */  
  40. struct param_struct {  
  41.     union {  
  42.     struct {  
  43.         unsigned long page_size;        /*  0 */  
  44.         unsigned long nr_pages;     /*  4 */  
  45.         unsigned long ramdisk_size;     /*  8 */  
  46.         unsigned long flags;        /* 12 */  
  47. #define FLAG_READONLY   1  
  48. #define FLAG_RDLOAD 4  
  49. #define FLAG_RDPROMPT   8  
  50.         unsigned long rootdev;      /* 16 */  
  51.         unsigned long video_num_cols;   /* 20 */  
  52.         unsigned long video_num_rows;   /* 24 */  
  53.         unsigned long video_x;      /* 28 */  
  54.         unsigned long video_y;      /* 32 */  
  55.         unsigned long memc_control_reg; /* 36 */  
  56.         unsigned char sounddefault;     /* 40 */  
  57.         unsigned char adfsdrives;       /* 41 */  
  58.         unsigned char bytes_per_char_h; /* 42 */  
  59.         unsigned char bytes_per_char_v; /* 43 */  
  60.         unsigned long pages_in_bank[4]; /* 44 */  
  61.         unsigned long pages_in_vram;    /* 60 */  
  62.         unsigned long initrd_start;     /* 64 */  
  63.         unsigned long initrd_size;      /* 68 */  
  64.         unsigned long rd_start;     /* 72 */  
  65.         unsigned long system_rev;       /* 76 */  
  66.         unsigned long system_serial_low;    /* 80 */  
  67.         unsigned long system_serial_high;   /* 84 */  
  68.         unsigned long mem_fclk_21285;       /* 88 */  
  69.     } s;  
  70.     char unused[256];  
  71.     } u1;  
  72.     union {  
  73.     char paths[8][128];  
  74.     struct {  
  75.         unsigned long magic;  
  76.         char n[1024 - sizeof(unsigned long)];  
  77.     } s;  
  78.     } u2;  
  79.     char commandline[COMMAND_LINE_SIZE];  
  80. };  
  81.   
  82.   
  83. /*  
  84.  * The new way of passing information: a list of tagged entries  
  85.  */  
  86.   
  87. /* The list ends with an ATAG_NONE node. */  
  88. #define ATAG_NONE   0x00000000  
  89.   
  90. struct tag_header {  
  91.     u32 size;  
  92.     u32 tag;  
  93. };  
  94.   
  95. /* The list must start with an ATAG_CORE node */  
  96. #define ATAG_CORE   0x54410001  
  97.   
  98. struct tag_core {  
  99.     u32 flags;      /* bit 0 = read-only */  
  100.     u32 pagesize;  
  101.     u32 rootdev;  
  102. };  
  103.   
  104. /* it is allowed to have multiple ATAG_MEM nodes */  
  105. #define ATAG_MEM    0x54410002  
  106.   
  107. struct tag_mem32 {  
  108.     u32 size;  
  109.     u32 start;  /* physical start address */  
  110. };  
  111.   
  112. /* VGA text type displays */  
  113. #define ATAG_VIDEOTEXT  0x54410003  
  114.   
  115. struct tag_videotext {  
  116.     u8      x;  
  117.     u8      y;  
  118.     u16     video_page;  
  119.     u8      video_mode;  
  120.     u8      video_cols;  
  121.     u16     video_ega_bx;  
  122.     u8      video_lines;  
  123.     u8      video_isvga;  
  124.     u16     video_points;  
  125. };  
  126.   
  127. /* describes how the ramdisk will be used in kernel */  
  128. #define ATAG_RAMDISK    0x54410004  
  129.   
  130. struct tag_ramdisk {  
  131.     u32 flags;  /* bit 0 = load, bit 1 = prompt */  
  132.     u32 size;   /* decompressed ramdisk size in _kilo_ bytes */  
  133.     u32 start;  /* starting block of floppy-based RAM disk image */  
  134. };  
  135.   
  136. /* describes where the compressed ramdisk image lives (virtual address) */  
  137. /*  
  138.  * this one accidentally used virtual addresses - as such,  
  139.  * its depreciated.  
  140.  */  
  141. #define ATAG_INITRD 0x54410005  
  142.   
  143. /* describes where the compressed ramdisk image lives (physical address) */  
  144. #define ATAG_INITRD2    0x54420005  
  145.   
  146. struct tag_initrd {  
  147.     u32 start;  /* physical start address */  
  148.     u32 size;   /* size of compressed ramdisk image in bytes */  
  149. };  
  150.   
  151. /* board serial number. "64 bits should be enough for everybody" */  
  152. #define ATAG_SERIAL 0x54410006  
  153.   
  154. struct tag_serialnr {  
  155.     u32 low;  
  156.     u32 high;  
  157. };  
  158.   
  159. /* board revision */  
  160. #define ATAG_REVISION   0x54410007  
  161.   
  162. struct tag_revision {  
  163.     u32 rev;  
  164. };  
  165.   
  166. /* initial values for vesafb-type framebuffers. see struct screen_info  
  167.  * in include/linux/tty.h  
  168.  */  
  169. #define ATAG_VIDEOLFB   0x54410008  
  170.   
  171. struct tag_videolfb {  
  172.     u16     lfb_width;  
  173.     u16     lfb_height;  
  174.     u16     lfb_depth;  
  175.     u16     lfb_linelength;  
  176.     u32     lfb_base;  
  177.     u32     lfb_size;  
  178.     u8      red_size;  
  179.     u8      red_pos;  
  180.     u8      green_size;  
  181.     u8      green_pos;  
  182.     u8      blue_size;  
  183.     u8      blue_pos;  
  184.     u8      rsvd_size;  
  185.     u8      rsvd_pos;  
  186. };  
  187.   
  188. /* command line: \0 terminated string */  
  189. #define ATAG_CMDLINE    0x54410009  
  190.   
  191. struct tag_cmdline {  
  192.     char    cmdline[1]; /* this is the minimum size */  
  193. };  
  194.   
  195. /* acorn RiscPC specific information */  
  196. #define ATAG_ACORN  0x41000101  
  197.   
  198. struct tag_acorn {  
  199.     u32 memc_control_reg;  
  200.     u32 vram_pages;  
  201.     u8 sounddefault;  
  202.     u8 adfsdrives;  
  203. };  
  204.   
  205. /* footbridge memory clock, see arch/arm/mach-footbridge/arch.c */  
  206. #define ATAG_MEMCLK 0x41000402  
  207.   
  208. struct tag_memclk {  
  209.     u32 fmemclk;  
  210. };  
  211.   
  212. #define ATAG_MTDPART    0x41001099//add  
  213.   
  214. struct tag_mtdpart {             //add  
  215.   u32 mtd_part_size[3];  
  216. };  
  217.   
  218. struct tag {  
  219.     struct tag_header hdr;  
  220.     union {  
  221.         struct tag_core     core;  
  222.         struct tag_mem32    mem;  
  223.         struct tag_videotext    videotext;  
  224.         struct tag_ramdisk  ramdisk;  
  225.         struct tag_initrd   initrd;  
  226.         struct tag_serialnr serialnr;  
  227.         struct tag_revision revision;  
  228.         struct tag_videolfb videolfb;  
  229.         struct tag_cmdline  cmdline;  
  230.   
  231.         /*  
  232.          * Acorn specific  
  233.          */  
  234.         struct tag_acorn    acorn;  
  235.   
  236.         /*  
  237.          * DC21285 specific  
  238.          */  
  239.         struct tag_memclk   memclk;  
  240.   
  241.       struct tag_mtdpart      mtdpart_info;//add  
  242.     } u;  
  243. };  
  244.   
  245. struct tagtable {  
  246.     u32 tag;  
  247.     int (*parse)(const struct tag *);  
  248. };  
  249.   
  250. #define __tag __attribute__((unused, __section__(".taglist")))//add  
  251. #define __tagtable(tag, fn) \  
  252.   static struct tagtable __tagtable_##fn __tag = { tag, fn }//add  
  253.   
  254. #define tag_member_present(tag,member)              \  
  255.     ((unsigned long)(&((struct tag *)0L)->member + 1)    \  
  256.         <= (tag)->hdr.size * 4)  
  257.   
  258. #define tag_next(t) ((struct tag *)((u32 *)(t) + (t)->hdr.size))  
  259. #define tag_size(type)  ((sizeof(struct tag_header) + sizeof(struct type)) >> 2)  
  260.   
  261. #define for_each_tag(t,base)        \  
  262.     for (t = base; t->hdr.size; t = tag_next(t))  
  263.   
  264. /*  
  265.  * Memory map description  
  266.  */  
  267. #define NR_BANKS 8  
  268.   
  269. struct meminfo {  
  270.     int nr_banks;  
  271.     unsigned long end;  
  272.     struct {  
  273.         unsigned long start;  
  274.         unsigned long size;  
  275.         int           node;  
  276.     } bank[NR_BANKS];  
  277. };  
  278.   
  279. extern struct meminfo meminfo;  
  280.   
  281. #endif  

文件mani.c:

[plain] view plain copy
  1. #include "uart.h"  
  2. #include "lib.h"  
  3. #include "command.h"  
  4. #include "nand.h"  
  5.   
  6. #define CFG_PROMPT "WY_BOOT # "/* Monitor Command Prompt*/  
  7. #define CFG_CBSIZE 256/* Console I/O Buffer Size*/  
  8.   
  9. #define GPH1CON (*(volatile unsigned int *)0xe0300C20)  
  10. #define GPH1DAT (*(volatile unsigned int *)0xe0300c24)  
  11. void led_water(void);  
  12. void led_init();  
  13.   
  14.   
  15. //extern void clock_init(void);  
  16.   
  17. char *argv[10];  
  18. int readline (const char *const prompt)  
  19. {  
  20.   char console_buffer[CFG_CBSIZE];/* console I/O buffer*/  
  21.   char *buf = console_buffer;  
  22.   int argc = 0;  
  23.   int state = 0;  
  24.   int i = 0;  
  25.   puts(prompt);  
  26.   gets(console_buffer);  
  27.   while (*buf)  
  28.     {  
  29.       if (*buf != ' ' && state == 0)  
  30.     {  
  31.       argv[argc++] = buf;  
  32.       state = 1;  
  33.     }  
  34.       if (*buf == ' ' && state == 1)  
  35.     {  
  36.       *buf = '\0';  
  37.       state = 0;  
  38.     }  
  39.       buf++;  
  40.     }  
  41.   //for(i=0;i<2;i++)  
  42.   //printf("argv[%d] = %s, argc = %d\n",i,argv[i],argc);  
  43.   //for(i = 2;i < argc;i++)  
  44.   //printf("argv[%d] = %x, argc = %d\n",i,atoi(argv[i]),argc);  
  45.     
  46.   return argc;  
  47. }  
  48. void message(void)  
  49. {  
  50.   printf("This bootloader support some command to test peripheral:\n");  
  51.   printf("Such as: LCD, IIS, BUZZER \n");  
  52.   printf("Try 'help' to learn them \n");  
  53. }  
  54.   
  55. void nand_write_test(void)  
  56. {  
  57.   char buf[20] = {"abcd1234ABCD"};  
  58.   unsigned long addr;  
  59.   unsigned long size;  
  60.     
  61.   puts("enter the start address:0x20000 ");  
  62.   //scanf("%s", buf);  
  63.   //addr = strtoul(buf, NULL, 0);  
  64.   addr = 0x20000;  
  65.   puts("enter the string:abcd1234ABCD ");  
  66.   //scanf("%s", buf);  
  67.   size = strlen(buf) + 1;  
  68.   puts(" size= ");  
  69.   puthex(size);  
  70.   puts("\r");  
  71.   nand_write(addr, buf, size);  
  72.     
  73. }  
  74.   
  75. void nand_read_test(void)  
  76.   
  77. {  
  78.   int i;  
  79.   char buf[100];  
  80.   unsigned long addr;  
  81.   unsigned long size;  
  82.    
  83.   puts("\n enter the start address: 0x20000");  
  84.   
  85.   //scanf("%s", buf);  
  86.   
  87.   //addr = strtoul(buf, NULL, 0);  
  88.   addr = 0x20000;  
  89.   //puts("read addr = 0x%x\n\r", addr);  
  90.   
  91.   puts("enter the size: 0x60");  
  92.   
  93.   //scanf("%s", buf);  
  94.   //size = strtoul(buf, NULL, 0);  
  95.   size = 0x60;  
  96.   
  97.   if (size > 100)  
  98.     {  
  99.       puts("the max size is 100\r");  
  100.       size = 100;  
  101.     }  
  102.   nand_read(addr, buf, size);  
  103.   
  104.   puts("datas: \n");  
  105.   for (i = 0; i < size; i++)  
  106.     {  
  107.       // printf("%02x ", buf[i]);  
  108.       putbyte(buf[i]);  
  109.       puts("\t");  
  110.       if ((i+1) % 8 == 0)  
  111.     {  
  112.       puts("\n");  
  113.     }  
  114.     }  
  115.   puts("\n");  
  116. }  
  117.   
  118. void nand_erase_test(void)  
  119. {  
  120.   //char buf[100];  
  121.   unsigned long addr;  
  122.     
  123.   puts("enter the start address:0x20000 ");  
  124.   //scanf("%s", buf);  
  125.   //addr = strtoul(buf, NULL, 0);  
  126.   addr = 0x20000;  
  127.   puts("erase addr = ");  
  128.   puthex(addr);  
  129.   puts("\n");  
  130.   nand_erase_block(addr);  
  131.     
  132. }  
  133.   
  134. void update_program(void)  
  135. {  
  136.   unsigned char *buf = (unsigned char *)0x22000000;  
  137.   //unsigned char *buf = (unsigned char *)0xD0036000;  
  138.   unsigned long len = 0;  
  139.   int have_begin = 0;  
  140.   int nodata_time = 0;  
  141.   unsigned long erase_addr;  
  142.   char c;  
  143.   int i;  
  144.   
  145.   /* 读串口获得数据 */  
  146.   puts("\n\ruse V2.2.exe/gtkterm to send file\r");  
  147.   while (1)  
  148.     {  
  149.       if (getc_nowait(&buf[len]) == 0)  
  150.     {  
  151.       have_begin = 1;  
  152.       nodata_time = 0;  
  153.       len++;  
  154.     }  
  155.       else  
  156.     {  
  157.       if (have_begin)  
  158.         {  
  159.           nodata_time++;  
  160.         }  
  161.     }  
  162.   
  163.       if (nodata_time == 1000)  
  164.     {  
  165.       break;  
  166.     }  
  167.     }  
  168.   puts("\nhave get data:");  
  169.   puthex(len);  
  170.   puts(" bytes\n");  
  171.   puts("the first 16 bytes data: \n\r");  
  172.   for (i = 0; i < 16; i++)  
  173.     {  
  174.       // put("%02x ", buf[i]);  
  175.       putbyte(buf[i]);  
  176.       puts("\t");  
  177.       if ((i+1) % 8 == 0)  
  178.     {  
  179.       puts("\n");  
  180.     }  
  181.     }  
  182.   puts("\n");  
  183.   
  184.   puts("Press Y to program the flash: \n\r");  
  185.   
  186.   c = getc();  
  187.   putc(c);  
  188.   puts("\n");  
  189.   if (c == 'y' || c == 'Y')  
  190.     {  
  191.       /* 烧写到nand flash block 0 */  
  192.       for (erase_addr = 0; erase_addr < ((len + 0x1FFFF) & ~0x1FFFF); erase_addr += 0x20000)  
  193.     {  
  194.       nand_erase_block(erase_addr);  
  195.     }  
  196.       nand_write(0, buf, len);  
  197.         
  198.       puts("update program successful\n\r");  
  199.     }  
  200.   else  
  201.     {  
  202.       puts("Cancel program!\n\r");  
  203.     }  
  204. }  
  205.   
  206. void run_program(void)  
  207. {  
  208.   unsigned char *buf = (unsigned char *)0x27e00000;  
  209.   //unsigned char *buf = (unsigned char *)0xD0036000;  
  210.   unsigned long len = 0;  
  211.   int have_begin = 0;  
  212.   int nodata_time = 0;  
  213.   void (*theProgram)(void);  
  214.   int i;  
  215.   /* 读串口获得数据 */  
  216.   puts("\n use gtkterm to send file\r");  
  217.   while (1)  
  218.     {  
  219.       if (getc_nowait(&buf[len]) == 0)  
  220.     {  
  221.       have_begin = 1;  
  222.       nodata_time = 0;  
  223.       len++;  
  224.     }  
  225.       else  
  226.     {  
  227.       if (have_begin)  
  228.         {  
  229.           nodata_time++;  
  230.         }  
  231.     }  
  232.   
  233.       if (nodata_time == 10000)  
  234.     {  
  235.       break;  
  236.     }  
  237.     }  
  238.   //printf("have get %d bytes data\n\r", len);  
  239.   puts("\n have get data:");  
  240.   puthex(len);  
  241.   puts(" bytes\n");  
  242.   puts("the first 16 bytes data: \n");  
  243.   for (i = 0; i < 16; i++)  
  244.     {  
  245.       // put("%02x ", buf[i]);                                                                       
  246.       putbyte(buf[i]);  
  247.       puts("\t");  
  248.       //putc('\0');  
  249.     }  
  250.   puts("\n");  
  251.   puts("jump to 0x27e00000 to run it\n");  
  252.     
  253.   theProgram = (void (*)(void))0x27e00000;  
  254.   
  255.   theProgram();  
  256. }  
  257.   
  258. void download_bl2(void)  
  259. {  
  260.   unsigned char *buf = (unsigned char *)0x22000000;  
  261.   //unsigned char *buf = (unsigned char *)0xD0036000;  
  262.   unsigned long len = 0;  
  263.   int have_begin = 0;  
  264.   int nodata_time = 0;  
  265.   unsigned long erase_addr;  
  266.   char c;  
  267.   int i;  
  268.   
  269.   /* 读串口获得数据 */  
  270.   puts("\n\ruse V2.2.exe/gtkterm to send file\r");  
  271.   while (1)  
  272.     {  
  273.       if (getc_nowait(&buf[len]) == 0)  
  274.     {  
  275.       have_begin = 1;  
  276.       nodata_time = 0;  
  277.       len++;  
  278.     }  
  279.       else  
  280.     {  
  281.       if (have_begin)  
  282.         {  
  283.           nodata_time++;  
  284.         }  
  285.     }  
  286.   
  287.       if (nodata_time == 1000)  
  288.     {  
  289.       break;  
  290.     }  
  291.     }  
  292.   puts("\nhave get data:");  
  293.   puthex(len);  
  294.   puts(" bytes\n");  
  295.   puts("the first 16 bytes data: \n\r");  
  296.   for (i = 0; i < 16; i++)  
  297.     {  
  298.       // put("%02x ", buf[i]);  
  299.       putbyte(buf[i]);  
  300.       puts("\t");  
  301.       if ((i+1) % 8 == 0)  
  302.     {  
  303.       puts("\n");  
  304.     }  
  305.     }  
  306.   puts("\n");  
  307.   
  308.   puts("Press Y to program the flash: \n\r");  
  309.   
  310.   c = getc();  
  311.   putc(c);  
  312.   puts("\n");  
  313.   if (c == 'y' || c == 'Y')  
  314.     {  
  315.       /* 烧写到nand flash block 0 */  
  316.       for (erase_addr = 0x20000; erase_addr < ((len + 0x1FFFF) & ~0x1FFFF); erase_addr += 0x20000)  
  317.     {  
  318.       nand_erase_block(erase_addr);  
  319.     }  
  320.       nand_write(0x20000, buf, len);  
  321.         
  322.       puts("download bl2 program successful\n\r");  
  323.     }  
  324.   else  
  325.     {  
  326.       puts("Cancel program!\n\r");  
  327.     }  
  328. }  
  329.   
  330. void load_bl2(void)  
  331. {  
  332.   unsigned char *buf = (unsigned char *)0x27e00000;  
  333.   char c;  
  334.   //unsigned char *buf = (unsigned char *)0xD0036000;  
  335.   //unsigned long len = 0;  
  336.   //int have_begin = 0;  
  337.   //int nodata_time = 0;  
  338.   void (*theProgram)(void);  
  339.   //int i;  
  340.   /* 读串口获得数据 */  
  341.   puts("\n start load bl2 code\r");  
  342.   copy_code_to_sdram(0x20000, 0x27e00000, 0x40000);  
  343.   
  344.   puts("Press Y jump to run it \n\r");  
  345.   
  346.   c = getc();  
  347.   putc(c);  
  348.   puts("\n");  
  349.   if (c == 'y' || c == 'Y')  
  350.   {  
  351.     puts("jump to 0x27e00000 to run it\n");  
  352.     theProgram = (void (*)(void))0x27e00000;    
  353.     theProgram();  
  354.   }  
  355.   else  
  356.   {  
  357.      puts("Cancel run it!\n\r");  
  358.   }  
  359. }  
  360.   
  361. int main()  
  362. {  
  363.   char c;  
  364.   int argc = 0;  
  365.   int i = 0;  
  366.   volatile unsigned long *mem = (volatile unsigned long *)0x22000000;  
  367.   volatile unsigned long *tmem = (volatile unsigned long *)0x21000010;  
  368.   volatile unsigned long *tsram = (volatile unsigned long *)0xD0034010;  
  369.   *mem = 0xDB134653;  
  370.   led_init();  
  371.   //clock_init();  
  372.   //init_uart();  
  373.   printf("the 2012 hex value:%x\n",2012);  
  374.   printf("the mem hex value:%x\n",*mem);  
  375.   *mem = 0x11122212;  
  376.   printf("\n********************************\r");  
  377.   printf("                   wy_bootloader\r");  
  378.   printf("                   vars: %d \r",2012);  
  379.   printf("********************************\r");  
  380.   printf("the mem hex value:%x\n",*mem);  
  381.   printf("[0x21000010] = %x\n",*tmem);  
  382.   printf("[0xD0034010] = %x\n",*tsram);  
  383.   while (1)  
  384.     {  
  385.       puts("[w] write the nand flash\n");  
  386.       puts("[r] read the nand flash\n");  
  387.       puts("[e] erase the nand flash\n");  
  388.       puts("[g] get file, and write to nand flash 0 block\n");  
  389.       puts("[x] get file to ddr(0x27e00000), run it\n");  
  390.       puts("[b] boot the Kernel\n");  
  391.       puts("[l] load bl2 code to sdram,and run bl2\n");  
  392.       puts("[d] download bl2 code to nand flash\n");  
  393.       puts("[s] reset the programe\n");  
  394.       do {  
  395.     argc = readline (CFG_PROMPT);  
  396.     if(argc == 0 && i ==0)  
  397.       {  
  398.         message();  
  399.         i=1;  
  400.       }  
  401.     else  
  402.       run_command(argc, argv);  
  403.     c = getc();  
  404.     if (c == '\n' || c == '\r')  
  405.       {  
  406.         puts("\n\r");  
  407.       }  
  408.     else  
  409.       {  
  410.         putc(c);  
  411.       }  
  412.     led_water();  
  413.   
  414.       } while (c == '\n' || c == '\r');  
  415.         
  416.       switch (c)  
  417.     {  
  418.     case 'w':  
  419.     case 'W':  
  420.       {  
  421.         nand_write_test();  
  422.         break;  
  423.       }  
  424.   
  425.     case 'r':  
  426.     case 'R':  
  427.       {  
  428.         nand_read_test();  
  429.         break;  
  430.       }  
  431.   
  432.     case 'e':  
  433.     case 'E':  
  434.       {  
  435.         nand_erase_test();  
  436.         break;  
  437.       }  
  438.   
  439.     case 'g':  
  440.     case 'G':  
  441.       {  
  442.         update_program();  
  443.         break;  
  444.       }  
  445.   
  446.     case 'x':  
  447.     case 'X':  
  448.       {  
  449.         run_program();  
  450.         break;  
  451.       }  
  452.   
  453.     case 'b':  
  454.     case 'B':  
  455.       {  
  456.         //boot_kernel();  
  457.         break;  
  458.       }  
  459.     case 'l':  
  460.     case 'L':  
  461.       {  
  462.         //boot_kernel();  
  463.         load_bl2();  
  464.         break;  
  465.       }  
  466.     case 'd':  
  467.     case 'D':  
  468.       {  
  469.         download_bl2();  
  470.         break;  
  471.       }  
  472.   
  473.     case 's':  
  474.     case 'S':  
  475.       {  
  476.         //volatile unsigned long *mcode = (volatile unsigned long *)0x21000010;  
  477.         void (*theProgram)(void);  
  478.         //printf("the 0x21000010 value:%x\n\r",*mcode);  
  479.         theProgram = (void (*)(void))0xD0034010;  
  480.         theProgram();  
  481.   
  482.         break;  
  483.       }  
  484.       
  485.     }  
  486.     }  
  487.   
  488.   return 0;  
  489. }  
  490. void led_init()  
  491. {  
  492.   GPH1CON = 0x11110000;  
  493.   
  494. }  
  495. void led_water(void)  
  496. {  
  497.   /*  int i;  
  498.   while (1)  
  499.   {  
  500.   GPH1DAT = (i << 4;  
  501.       i++;  
  502.       if (i == 16)  
  503.     i = 0;  
  504.       delay();  
  505.       }*/  
  506.   GPH1DAT = 0x0000;  
  507.   delay();  
  508.   GPH1DAT = 0xffff;  
  509.   delay();  
  510. }  

文件bootloader.lds:

[plain] view plain copy
  1. SECTIONS {  
  2.     . = 0x21000010;  
  3.   
  4.     .text : {  
  5.         * (.text)  
  6.     }  
  7.   
  8.     . = ALIGN(4);  
  9.     .rodata : {  
  10.         * (.rodata)  
  11.     }  
  12.       
  13.     . = ALIGN(4);  
  14.     .data : {  
  15.         * (.data)  
  16.     }  
  17.   
  18.     . = ALIGN(4);  
  19.     bss_start = .;  
  20.     .bss  : { *(.bss)  *(COMMON) }  
  21.     bss_end = .;  
  22. }  

文件Makefile:

[plain] view plain copy
  1. boot.bin:start.S clock.S cpu_init.S nand.c main.c uart.c lib.c command.c  
  2.     arm-linux-gcc -c start.S -o start.o  
  3.     arm-linux-gcc -c clock.S -o clock.o  
  4.     arm-linux-gcc -c cpu_init.S -o cpu_init.o   
  5.     arm-linux-gcc -c main.c -o main.o  
  6.     arm-linux-gcc -c nand.c -o nand.o  
  7.     arm-linux-gcc -c uart.c -o uart.o  
  8.     arm-linux-gcc -c lib.c -o lib.o   
  9.     arm-linux-gcc -c command.c -o command.o   
  10.     arm-linux-ld -T bootloader.lds start.o clock.o cpu_init.o nand.o main.o uart.o lib.o command.o -o boot_elf  
  11.     arm-linux-objcopy -O binary -S boot_elf boot.bin  
  12. clean:  
  13.     rm -rf *.o *.bin boot_elf *.dis  

终于贴完了,基本上是按调用的顺序贴的,都是我反复修改、调试后,能用的代码。很多代码都有注释,有问题一起讨论。

二、编译

change@change:~$ cd 9_bl1/
change@change:~/9_bl1$ ls
bootloader.lds  command.c  cpu_init.S  lib.h   Makefile  nand.h        setup.h  uart.c  wy_mktools.exe
clock.S         command.h  lib.c       main.c  nand.c    newtools.exe  start.S  uart.h
change@change:~/9_bl1$ make
arm-linux-gcc -c start.S -o start.o
arm-linux-gcc -c clock.S -o clock.o
arm-linux-gcc -c cpu_init.S -o cpu_init.o
arm-linux-gcc -c main.c -o main.o
In file included from main.c:1:
uart.h:5: warning: conflicting types for built-in function 'putc'
In file included from main.c:2:
lib.h:3: warning: conflicting types for built-in function 'puts'
main.c: In function 'readline':
main.c:25: warning: passing argument 1 of 'puts' discards qualifiers from pointer target type
main.c: In function 'nand_read_test':
main.c:102: warning: passing argument 2 of 'nand_read' makes integer from pointer without a cast
arm-linux-gcc -c nand.c -o nand.o
nand.c: In function 'nand_read_dis':
nand.c:286: warning: passing argument 2 of 'nand_read' makes integer from pointer without a cast
nand.c: In function 'nand_write_dat':
nand.c:314: warning: incompatible implicit declaration of built-in function 'strlen'
arm-linux-gcc -c uart.c -o uart.o
uart.c: In function 'init_uart':
uart.c:45: warning: large integer implicitly truncated to unsigned type
uart.c: At top level:
uart.c:82: warning: conflicting types for built-in function 'putc'
arm-linux-gcc -c lib.c -o lib.o
In file included from lib.c:1:
uart.h:5: warning: conflicting types for built-in function 'putc'
lib.c:13: warning: conflicting types for built-in function 'puts'
arm-linux-gcc -c command.c -o command.o
In file included from command.c:1:
lib.h:3: warning: conflicting types for built-in function 'puts'
arm-linux-ld -T bootloader.lds start.o clock.o cpu_init.o nand.o main.o uart.o lib.o command.o -o boot_elf
arm-linux-objcopy -O binary -S boot_elf boot.bin
change@change:~/9_bl1$ ./newtools boot.bin boots.bin
-bash: ./newtools: No such file or directory
change@change:~/9_bl1$ newtools boot.bin boots.bin
newtools: command not found
change@change:~/9_bl1$ sudo chmod 777 -R newtools.exe
[sudo] password for change:
change@change:~/9_bl1$ ./newtools boot.bin boots.bin
-bash: ./newtools: No such file or directory
change@change:~/9_bl1$ newtools boot.bin boots.bin
newtools: command not found
change@change:~/9_bl1$ ./newtools.exe boot.bin boots.bin
change@change:~/9_bl1$ ls
boot.bin        boots.bin  command.c  cpu_init.o  lib.h   main.o    nand.h        setup.h  uart.c  wy_mktools.exe
boot_elf        clock.o    command.h  cpu_init.S  lib.o   Makefile  nand.o        start.o  uart.h
bootloader.lds  clock.S    command.o  lib.c       main.c  nand.c    newtools.exe  start.S  uart.o
change@change:~/9_bl1$
make后生成boot.bin,使用./newtools.exe boot.bin boots.bin,即给boot.bin增加头部。因为BL0代码跳到BL1是会根据头部检验程序的合法性,上一篇也有说明。上面的程序我测试过,基本上都OK,测试留在下篇,引导u-boot第二阶段代码BL2.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值