1. 程式人生 > >cortex A8處理器啟動過程二引導程式碼BL1

cortex A8處理器啟動過程二引導程式碼BL1

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:

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

檔案clock.S

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

檔案cpu_init.S

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

檔案uart.c:

  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. #define GPACON     (*((volatile unsigned long *)0xE0300000))  
  12. #define ENABLE_FIFO   
  13. void init_uart(void)  
  14. {  
  15.   GPACON &= ~0xffff;  
  16.   GPACON |= 0x2222;  
  17.   /* ULCON0 */  
  18.   ULCON0 = 0x3;  /* 資料位:8, 無較驗, 停止位: 1, 8n1 */  
  19.   UCON0  = 0x5;  /* 使能UART傳送、接收 */  
  20. #ifdef ENABLE_FIFO  
  21.   UFCON0 = 0x07; /* FIFO enable */  
  22. #else  
  23.   UFCON0 = 0x00; /* FIFO disable */  
  24. #endif  
  25.   UMCON0 = 0;  
  26.   /* 波特率 */  
  27.   /* DIV_VAL = (PCLK / (bps x 16 ) ) - 1   
  28.    * bps = 115200  
  29.    * DIV_VAL = (66500000 / (115200 x 16 ) ) - 1   
  30.    *         = 35.08  
  31.    */  
  32.   UBRDIV0   = 35;  
  33.   /* x/16 = 0.08  
  34.    * x = 1  
  35.    */  
  36.   UDIVSLOT0 = 3;  
  37.   UTXH0 = 0x4f4f4f4f;  
  38. }  
  39. #define ENABLE_FIFO   
  40. static void delay1(void)  
  41. {  
  42.   volatile int i = 10;  
  43.   while (i--);  
  44. }  
  45. unsigned char getc(void)  
  46. {  
  47. #ifdef ENABLE_FIFO  
  48.   while ((UFSTAT0 & (1<<6)) == 0 && (UFSTAT0 & 0x3f) == 0)delay1();  
  49. #else  
  50.   while ((UTRSTAT0 & (1<<0)) == 0);  
  51. #endif  
  52.   return URXH0;  
  53. }  
  54. int getc_nowait(unsigned char *pChar)  
  55. {  
  56. #ifdef ENABLE_FIFO  
  57.   if ((UFSTAT0 & (1<<6)) == 0 && (UFSTAT0 & 0x3f) == 0)  
  58. #else  
  59.     if ((UTRSTAT0 & (1<<0)) == 0)  
  60. #endif  
  61.       {  
  62.     return -1;  
  63.       }  
  64.     else  
  65.       {  
  66.     *pChar = URXH0;  
  67.     return 0;  
  68.       }  
  69. }  
  70. void putc(char c)  
  71. {  
  72. #ifdef ENABLE_FIFO  
  73.   if(c == '\r')  
  74.     {  
  75.       while (UFSTAT0 & (1<<14))delay1();  
  76.       UTXH0 = '\n';  
  77.     }  
  78.   if(c == '\n')  
  79.     {  
  80.       while (UFSTAT0 & (1<<14))delay1();  
  81.       UTXH0 = '\r';  
  82.     }  
  83.   //while(!(UTRSTAT0&(1<<1)));  
  84.   while (UFSTAT0 & (1<<14))delay1();  
  85. #else  
  86.   while ((UTRSTAT0 & (1<<2)) == 0);  
  87. #endif  
  88.   UTXH0 = c;  
  89. }  

檔案uart.h:

  1. void init_uart(void);  
  2. unsigned char getc(void);  
  3. int getc_nowait(unsigned char *pChar);  
  4. void putc(char c);  

檔案command.c:

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

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

檔案lib.c:

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

檔案lib.h

  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:

  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. void nand_read(unsigned int nand_start, unsigned int ddr_start, unsigned int len);  
  9. void copy_code_to_sdram(unsigned int src, unsigned int dest, unsigned int len)  
  10. {  
  11.   //int i = 0;  
  12.   /*如果是Nor啟動*/  <