当前位置: 首页 > 工具软件 > ARMboot > 使用案例 >

uboot 二 之start_armboot

符俊材
2023-12-01

   在分析start_armboot 之前先来解决上节遗留下来的两个问题。

   一、lowlevel_init 对哪些设备进行了初始化

   二、copy_uboot_to_ram 如何复制UBoot

   先上代码

  1. #include <config.h>  
  2. #include <version.h>  
  3.   
  4. #include <s3c6410.h>  
  5. #include "mini6410_val.h"  
  6.   
  7. _TEXT_BASE:  
  8.     .word   TEXT_BASE  
  9.   
  10.     .globl lowlevel_init  
  11. lowlevel_init:  
  12.     mov r12, lr  
  13.   
  14.     /* LED on only #8 */  
  15.     ldr r0, =ELFIN_GPIO_BASE  
  16.     ldr r1, =0x55540000  
  17.     str r1, [r0, #GPNCON_OFFSET]  
  18.   
  19.     ldr r1, =0x55555555  
  20.     str r1, [r0, #GPNPUD_OFFSET]  
  21.   
  22.     ldr r1, =0xf000  
  23.     str r1, [r0, #GPNDAT_OFFSET]  
  24.   
  25.     ldr r0, =ELFIN_GPIO_BASE  
  26.     ldr r1, =0x1  
  27.     str r1, [r0, #GPECON_OFFSET]  
  28.     ldr r1, =0x0  
  29.     str r1, [r0, #GPEDAT_OFFSET]  
  30.   
  31.     ldr r0, =ELFIN_GPIO_BASE  
  32.     ldr r1, =0x2A5AAAAA  
  33.     str r1, [r0, #GPPCON_OFFSET]  
  34.     ldr r1, =0x0  
  35.     str r1, [r0, #GPPDAT_OFFSET]  
  36.       
  37.   
  38.     ldr r1, =0x55555555  
  39.     str r1, [r0, #MEM1DRVCON_OFFSET]  
  40.   
  41.     /* Disable Watchdog */                                                          /*关看门狗*/  
  42.     ldr r0, =0x7e000000     @0x7e004000  
  43.     orr r0, r0, #0x4000  
  44.     mov r1, #0  
  45.     str r1, [r0]  
  46.   
  47.     @ External interrupt pending clear                                              /*清外部中断标志位*/  
  48.     ldr r0, =(ELFIN_GPIO_BASE+EINTPEND_OFFSET)  /*EINTPEND*/  
  49.     ldr r1, [r0]  
  50.     str r1, [r0]  
  51.   
  52.     ldr r0, =ELFIN_VIC0_BASE_ADDR   @0x71200000  
  53.     ldr r1, =ELFIN_VIC1_BASE_ADDR   @0x71300000  
  54.   
  55.     @ Disable all interrupts (VIC0 and VIC1)                                        /*禁用VIC0、VIC1*/  
  56.     mvn r3, #0x0  
  57.     str r3, [r0, #oINTMSK]  
  58.     str r3, [r1, #oINTMSK]  
  59.   
  60.     @ Set all interrupts as IRQ                                                     /*设置所有中断为IRQ*/  
  61.     mov r3, #0x0  
  62.     str r3, [r0, #oINTMOD]  
  63.     str r3, [r1, #oINTMOD]  
  64.   
  65.     @ Pending Interrupt Clear                                                       /*清中断标志位*/  
  66.     mov r3, #0x0  
  67.     str r3, [r0, #oVECTADDR]  
  68.     str r3, [r1, #oVECTADDR]  
  69.   
  70.     /* init system clock */                                                         /*初始化系统时钟*/  
  71.     bl system_clock_init  
  72.   
  73.     /* for UART */                                                                  /*串口初始化*/  
  74.     bl uart_asm_init  
  75.   
  76. #if defined(CONFIG_NAND)                                                                /*初始化NAND*/     
  77.     /* simple init for NAND */  
  78.     bl nand_asm_init  
  79. #endif  
  80.   
  81.   
  82.     bl  mem_ctrl_asm_init                                                       /*初始化DRAM*/  
  83.   
  84. #if 1  
  85.         ldr     r0, =(ELFIN_CLOCK_POWER_BASE+RST_STAT_OFFSET)                           /*RST_STAT Check*/  
  86.         ldr     r1, [r0]   
  87.         bic     r1, r1, #0xfffffff7  
  88.         cmp     r1, #0x8  
  89.         beq     wakeup_reset                                                            /*Reset by SLEEP mode wake-up */  
  90.   
  91. #endif  
  92.   
  93. 1:  
  94.     ldr r0, =ELFIN_UART_BASE                                                    /*输出 'K'*/  
  95.     ldr r1, =0x4b4b4b4b  
  96.     str r1, [r0, #UTXH_OFFSET]  
  97. //  ldr r0, =ELFIN_UART_BASE  
  98. //  ldr r1, =0x4b4b4b4b  
  99. //  str r1, [r0, #UTXH_OFFSET]  
  100.     mov lr, r12  
  101.     mov pc, lr                                                                  /*跳回start.s*/  
  102. #if 1  
  103. wakeup_reset:  
  104.   
  105.     /*Clear wakeup status register*/  
  106.     ldr r0, =(ELFIN_CLOCK_POWER_BASE+WAKEUP_STAT_OFFSET)  
  107.     ldr r1, [r0]  
  108.     str r1, [r0]  
  109.   
  110.         /*LED test*/  
  111.         ldr     r0, =ELFIN_GPIO_BASE  
  112.         ldr     r1, =0x3000  
  113.         str     r1, [r0, #GPNDAT_OFFSET]  
  114.   
  115.     /*Load return address and jump to kernel*/  
  116.     ldr r0, =(ELFIN_CLOCK_POWER_BASE+INF_REG0_OFFSET)  
  117.     ldr r1, [r0]    /* r1 = physical address of s3c6400_cpu_resume function*/  
  118.     mov pc, r1      /*Jump to kernel (sleep-s3c6400.S)*/  
  119.     nop  
  120.     nop  
  121. #endif  
  122. /* 
  123.  * system_clock_init: Initialize core clock and bus clock. 
  124.  * void system_clock_init(void) 
  125.  */  
  126. system_clock_init:  
  127.     ldr r0, =ELFIN_CLOCK_POWER_BASE @0x7e00f000  
  128.   
  129.   
  130.     ldr r1, [r0, #OTHERS_OFFSET]        @0x7e00f900  
  131.     mov r2, #0x40  
  132.     orr r1, r1, r2             
  133.     str r1, [r0, #OTHERS_OFFSET]        /*SYS CLOCK SELECT IN CMU  1 : DOUTAPLL*/  
  134.   
  135.     nop  
  136.     nop  
  137.     nop  
  138.     nop  
  139.     nop  
  140.   
  141.     ldr r2, =0x80  
  142.     orr r1, r1, r2  
  143.     str r1, [r0, #OTHERS_OFFSET]      /*SYNCMODEREQ to ARM 1: Synchronous mode  */  
  144.   
  145. check_syncack:  
  146.     ldr r1, [r0, #OTHERS_OFFSET]  
  147.     ldr r2, =0xf00  
  148.     and r1, r1, r2  
  149.     cmp r1, #0xf00  
  150.     bne check_syncack                /*SYNC mode acknowledge (Read Only) */  
  151.   
  152.   
  153.     mov r1, #0xff00  
  154.     orr r1, r1, #0xff  
  155.     str r1, [r0, #APLL_LOCK_OFFSET]  /*Required period to generate a stable clock output*/  
  156.     str r1, [r0, #MPLL_LOCK_OFFSET]  
  157.     str r1, [r0, #EPLL_LOCK_OFFSET]  
  158. /* CLKUART(=66.5Mhz) = CLKUART_input(532/2=266Mhz) / (UART_RATIO(3)+1) */  
  159. /* CLKUART(=50Mhz) = CLKUART_input(400/2=200Mhz) / (UART_RATIO(3)+1) */  
  160. /* Now, When you use UART CLK SRC by EXT_UCLK1, We support 532MHz & 400MHz value */  
  161.   
  162. #if defined(CONFIG_CLKSRC_CLKUART)  
  163.     ldr     r1, [r0, #CLK_DIV2_OFFSET]  
  164.     bic r1, r1, #0x70000  
  165.     orr r1, r1, #0x30000  
  166.     str r1, [r0, #CLK_DIV2_OFFSET]  
  167. #endif  
  168.   
  169.   
  170.     ldr     r1, [r0, #CLK_DIV0_OFFSET]  /*Set Clock Divider*/  
  171.     bic r1, r1, #0x30000  
  172.     bic r1, r1, #0xff00  
  173.     bic r1, r1, #0xff  
  174.     ldr r2, =CLK_DIV_VAL  
  175.     orr r1, r1, r2  
  176.     str r1, [r0, #CLK_DIV0_OFFSET]  
  177.   
  178.     ldr r1, =APLL_VAL  
  179.     str r1, [r0, #APLL_CON_OFFSET]  
  180.     ldr r1, =MPLL_VAL  
  181.     str r1, [r0, #MPLL_CON_OFFSET]  
  182.   
  183.     ldr r1, =0x80200203         /* FOUT of EPLL is 96MHz */  
  184.     str r1, [r0, #EPLL_CON0_OFFSET]  
  185.     ldr r1, =0x0  
  186.     str r1, [r0, #EPLL_CON1_OFFSET]  
  187.   
  188.     ldr r1, [r0, #CLK_SRC_OFFSET]   /* APLL, MPLL, EPLL select to Fout */  
  189.   
  190. #if defined(CONFIG_CLKSRC_CLKUART)  
  191.     ldr r2, =0x2007  
  192. #else  
  193.     ldr r2, =0x7  
  194. #endif  
  195.     orr r1, r1, r2  
  196.   
  197.     str r1, [r0, #CLK_SRC_OFFSET]  
  198.   
  199.     /* wait at least 200us to stablize all clock */  
  200.     mov r1, #0x10000  
  201. 1:  subs    r1, r1, #1  
  202.     bne 1b  
  203.   
  204.   
  205. #ifdef CONFIG_SYNC_MODE             /* Synchronization for VIC port */  
  206.     ldr r1, [r0, #OTHERS_OFFSET]  
  207.     orr r1, r1, #0x20  
  208.     str r1, [r0, #OTHERS_OFFSET]  
  209.   
  210.     mov pc, lr  
  211.   
  212.   
  213. /* 
  214.  * uart_asm_init: Initialize UART in asm mode, 115200bps fixed. 
  215.  * void uart_asm_init(void) 
  216.  */  
  217. uart_asm_init:  
  218.     /* set GPIO to enable UART */  
  219.     @ GPIO setting for UART  
  220.     ldr r0, =ELFIN_GPIO_BASE  
  221.     ldr r1, =0x22222222  
  222.     str     r1, [r0, #GPACON_OFFSET]  
  223.     ldr r1, =0x2222  
  224.     str     r1, [r0, #GPBCON_OFFSET]  
  225.   
  226.     ldr r0, =ELFIN_UART_CONSOLE_BASE        @0x7F005000  
  227.     mov r1, #0x0  
  228.     str r1, [r0, #UFCON_OFFSET]  
  229.     str r1, [r0, #UMCON_OFFSET]  
  230.   
  231.     mov r1, #0x3                    @was 0.  
  232.     str r1, [r0, #ULCON_OFFSET]  
  233.   
  234. #if defined(CONFIG_CLKSRC_CLKUART)  
  235.     ldr r1, =0xe45          /* UARTCLK SRC = 11 => EXT_UCLK1*/  
  236. #else  
  237.     ldr r1, =0x245          /* UARTCLK SRC = x0 => PCLK */  
  238. #endif  
  239.   
  240.     str r1, [r0, #UCON_OFFSET]  
  241.   
  242. #if defined(CONFIG_UART_50)  
  243.     ldr r1, =0x1A  
  244. #elif defined(CONFIG_UART_66)  
  245.     ldr r1, =0x22  
  246. #else  
  247.     ldr r1, =0x1A  
  248. #endif  
  249.     str r1, [r0, #UBRDIV_OFFSET]  
  250.   
  251. #if defined(CONFIG_UART_50)  
  252.     ldr r1, =0x3  
  253. #elif defined(CONFIG_UART_66)  
  254.     ldr r1, =0x1FFF  
  255. #else  
  256.     ldr r1, =0x3  
  257. #endif  
  258.     str r1, [r0, #UDIVSLOT_OFFSET]  
  259.   
  260.     ldr r1, =0x4f4f4f4f  
  261.     str r1, [r0, #UTXH_OFFSET]      @'O'  /*串口输出'O'*/  
  262.   
  263.     mov pc, lr  
  264.   
  265. /* 
  266.  * Nand Interface Init for SMDK6400 */  
  267. nand_asm_init:                                     /*NAND Flash Configuration register*/  
  268.     ldr r0, =ELFIN_NAND_BASE  
  269.     ldr r1, [r0, #NFCONF_OFFSET]  
  270.     orr r1, r1, #0x70  
  271.     orr r1, r1, #0x7700  
  272.     str     r1, [r0, #NFCONF_OFFSET]  
  273.   
  274.     ldr r1, [r0, #NFCONT_OFFSET]  
  275.     orr r1, r1, #0x03  
  276.     str     r1, [r0, #NFCONT_OFFSET]  
  277.   
  278.     mov pc, lr  
  279.   
  280. #ifdef CONFIG_ENABLE_MMU  
  281.   
  282. /* 
  283.  * MMU Table for SMDK6400 
  284.  */  
  285.   
  286.     /* form a first-level section entry */  
  287. .macro FL_SECTION_ENTRY base,ap,d,c,b  
  288.     .word (\base << 20) | (\ap << 10) | \  
  289.           (\d << 5) | (1<<4) | (\c << 3) | (\b << 2) | (1<<1)  
  290. .endm  
  291. .section .mmudata, "a"  
  292.     .align 14  
  293.     // the following alignment creates the mmu table at address 0x4000.  
  294.     .globl mmu_table  
  295. mmu_table:  
  296.     .set __base,0  
  297.     // 1:1 mapping for debugging  
  298.     .rept 0xA00  
  299.     FL_SECTION_ENTRY __base,3,0,0,0  
  300.     .set __base,__base+1  
  301.     .endr  
  302.   
  303.     // access is not allowed.  
  304.     .rept 0xC00 - 0xA00  
  305.     .word 0x00000000  
  306.     .endr  
  307.   
  308.     // 128MB for SDRAM 0xC0000000 -> 0x50000000  
  309.     .set __base, 0x500  
  310.     .rept 0xC80 - 0xC00  
  311.     FL_SECTION_ENTRY __base,3,0,1,1  
  312.     .set __base,__base+1  
  313.     .endr  
  314.   
  315.     // access is not allowed.  
  316.     .rept 0x1000 - 0xc80  
  317.     .word 0x00000000  
  318.     .endr  
  319.   
  320. #endif  
   进行了一些最主要初始化包括系统时钟、串口、nandflash、DRAM。
   

   下面来看另一个代码   copy_uboot_to_ram

  1. int copy_uboot_to_ram (void)  
  2. {  
  3.     int large_block = 0;  
  4.     int i;  
  5.     vu_char id;  
  6.       
  7.         NAND_ENABLE_CE();                                                    /*Enable nandchip select*/  
  8.         NFCMD_REG = NAND_CMD_READID;                                         /*read id*/  
  9.         NFADDR_REG =  0x00;  
  10.   
  11.     /* wait for a while */  
  12.         for (i=0; i<200; i++);  
  13.     id = NFDATA8_REG;  
  14.     id = NFDATA8_REG;  
  15.   
  16.     if (id > 0x80)  
  17.         large_block = 1;  
  18.     /* read NAND Block. 
  19.      * 128KB ->240KB because of U-Boot size increase. by scsuh 
  20.      * So, read 0x3c000 bytes not 0x20000(128KB). 
  21.      */  
  22.     return nandll_read_blocks(CFG_PHY_UBOOT_BASE, UBOOTBINSIZE, large_block); /** Read data from NAND.*/  
  23.   
  24. }                                                                                                                                                         static int nandll_read_blocks (ulong dst_addr, ulong size, int large_block)  
  25. {  
  26.         uchar *buf = (uchar *)dst_addr;  
  27.         int i;  
  28. <span style="white-space: pre; ">   </span>uint page_shift = 9;                                                        /* 512bytes/page */  
  29.   
  30.   
  31. <span style="white-space: pre; ">   </span>if (large_block)  
  32. <span style="white-space: pre; ">       </span>page_shift = 11;                                                    /* 2k/page */   
  33.   
  34.   
  35.         /* Read pages */  
  36.         for (i = 0; i < (UBOOTBINSIZE>>page_shift); i++, buf+=(1<<page_shift)) {  
  37.  //       for (i = 0; i < (0x3c000>>page_shift); i++, buf+=(1<<page_shift)) {  
  38.                 nandll_read_page(buf, i, large_block);  
  39.         }  
  40.   
  41.   
  42.         return 0;  

 类似资料: