zoukankan      html  css  js  c++  java
  • uboot 2013.01 代码简析(2)第一阶段初始化

    uboot执行"make smdk2410_config"之后就可以进行编译了,可以执行make命令进行编译,

    因为整个输出太长,我仅仅列出部分最关键的输出(部分我不关心的内容直接用......代替):

    arm-linux-gcc ....... < u-boot-2013.01.01/arch/arm/cpu/u-boot.lds >u-boot.lds

    arm-linux-ld  -pie -T u-boot.lds -Bstatic -Ttext 0x0 $UNDEF_LST arch/arm/cpu/arm920t/start.o --start-group api/libapi.o arch/arm/cpu/arm920t/libarm920t.o arch/arm/cpu/arm920t/s3c24x0/libs3c24x0.o arch/arm/lib/libarm.o board/samsung/common/libsamsung.o common/libcommon.o disk/libdisk.o drivers/bios_emulator/libatibiosemu.o drivers/block/libblock.o drivers/dfu/libdfu.o drivers/dma/libdma.o drivers/fpga/libfpga.o drivers/gpio/libgpio.o drivers/hwmon/libhwmon.o drivers/i2c/libi2c.o drivers/input/libinput.o drivers/misc/libmisc.o drivers/mmc/libmmc.o drivers/mtd/libmtd.o drivers/mtd/nand/libnand.o drivers/mtd/onenand/libonenand.o drivers/mtd/spi/libspi_flash.o drivers/mtd/ubi/libubi.o drivers/net/libnet.o drivers/net/phy/libphy.o drivers/pci/libpci.o drivers/pcmcia/libpcmcia.o drivers/power/battery/libbattery.o drivers/power/fuel_gauge/libfuel_gauge.o drivers/power/libpower.o drivers/power/pmic/libpmic.o drivers/rtc/librtc.o drivers/serial/libserial.o drivers/sound/libsound.o drivers/spi/libspi.o drivers/twserial/libtws.o drivers/usb/eth/libusb_eth.o drivers/usb/gadget/libusb_gadget.o drivers/usb/host/libusb_host.o drivers/usb/musb-new/libusb_musb-new.o drivers/usb/musb/libusb_musb.o drivers/usb/phy/libusb_phy.o drivers/usb/ulpi/libusb_ulpi.o drivers/video/libvideo.o drivers/watchdog/libwatchdog.o fs/cbfs/libcbfs.o fs/cramfs/libcramfs.o fs/ext4/libext4fs.o fs/fat/libfat.o fs/fdos/libfdos.o fs/jffs2/libjffs2.o fs/libfs.o fs/reiserfs/libreiserfs.o fs/ubifs/libubifs.o fs/yaffs2/libyaffs2.o fs/zfs/libzfs.o lib/libfdt/libfdt.o lib/libgeneric.o lib/lzma/liblzma.o lib/lzo/liblzo.o lib/zlib/libz.o net/libnet.o post/libpost.o test/libtest.o board/samsung/smdk2410/libsmdk2410.o --end-group /home/host/prac/u-boot-2013.01.01/arch/arm/lib/eabi_compat.o  -L /home/host/soft/FriendlyARM/toolschain/4.4.3/bin/../lib/gcc/arm-none-linux-gnueabi/4.4.3 -lgcc -Map u-boot.map -o u-boot

     从这两行输出可以知道,先由arch/arm/cpu/u-boot.lds在当前文件夹下生成u-boot.lds,然后在用生成的u-boot.lds对前面编译过程中生成的目标文件和静态库进行链接。

    另外还需要注意的是arm-linux-ld的一些选项的含义:

    -pie 用于生成“位置无关代码”
    -T u-boot.lds 使用u-boot.lds来作为链接脚本
    -Bsharable  生成共享库
    -Ttext 0x0 指定代码段的初始地址为0
    --start-group和--end-group 用于标志一个组的开始和结束(用于多个目标文件和库文件中都存在相互依赖关系,可以多次执行依赖查找)
    -Map u-boot.map 生成Map文件,其名称为u-boot.map

    生成的u-boot.lds内容如下:

     1 OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
     2 OUTPUT_ARCH(arm)
     3 ENTRY(_start)
     4 SECTIONS
     5 {
     6  . = 0x00000000;
     7  . = ALIGN(4);
     8  .text :
     9  {
    10   __image_copy_start = .;
    11   arch/arm/cpu/arm920t/start.o (.text*)
    12   *(.text*)
    13  }
    14  . = ALIGN(4);
    15  .rodata : { *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*))) }
    16  . = ALIGN(4);
    17  .data : {
    18   *(.data*)
    19  }
    20  . = ALIGN(4);
    21  . = .;
    22  . = ALIGN(4);
    23  .u_boot_list : {
    24 _u_boot_list__start = .;
    25 _u_boot_list_cmd__start = .;
    26 *(SORT(.u_boot_list.cmd.*));
    27 _u_boot_list_cmd__end = .;
    28 _u_boot_list_env_clbk__start = .;
    29 *(SORT(.u_boot_list.env_clbk.*));
    30 _u_boot_list_env_clbk__end = .;
    31 *(SORT(.u_boot_list.*));
    32 _u_boot_list__end = .;
    33  }
    34  . = ALIGN(4);
    35  __image_copy_end = .;
    36  .rel.dyn : {
    37   __rel_dyn_start = .;
    38   *(.rel*)
    39   __rel_dyn_end = .;
    40  }
    41  .dynsym : {
    42   __dynsym_start = .;
    43   *(.dynsym)
    44  }
    45  _end = .;
    46  . = ALIGN(4096);
    47  .mmutable : {
    48   *(.mmutable)
    49  }
    50  .bss __rel_dyn_start (OVERLAY) : {
    51   __bss_start = .;
    52   *(.bss*)
    53    . = ALIGN(4);
    54   __bss_end__ = .;
    55  }
    56  /DISCARD/ : { *(.dynstr*) }
    57  /DISCARD/ : { *(.dynamic*) }
    58  /DISCARD/ : { *(.plt*) }
    59  /DISCARD/ : { *(.interp*) }
    60  /DISCARD/ : { *(.gnu*) }
    61 }

    从这个链接脚本可以知道,代码段中最开始是arch/arm/cpu/arm920t/start.o(由arch/arm/cpu/arm920t/start.S编译而成),
    start.o之后才是其他的目标文件对应的代码。

    arch/arm/cpu/arm920t/start.S内容如下:

      1 /*
      2  *  armboot - Startup Code for ARM920 CPU-core
      3  *
      4  *  Copyright (c) 2001    Marius Gröger <mag@sysgo.de>
      5  *  Copyright (c) 2002    Alex Züpke <azu@sysgo.de>
      6  *  Copyright (c) 2002    Gary Jennejohn <garyj@denx.de>
      7  *
      8  * See file CREDITS for list of people who contributed to this
      9  * project.
     10  *
     11  * This program is free software; you can redistribute it and/or
     12  * modify it under the terms of the GNU General Public License as
     13  * published by the Free Software Foundation; either version 2 of
     14  * the License, or (at your option) any later version.
     15  *
     16  * This program is distributed in the hope that it will be useful,
     17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
     18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     19  * GNU General Public License for more details.
     20  *
     21  * You should have received a copy of the GNU General Public License
     22  * along with this program; if not, write to the Free Software
     23  * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
     24  * MA 02111-1307 USA
     25  */
     26 
     27 #include <asm-offsets.h>
     28 #include <common.h>
     29 #include <config.h>
     30 
     31 /*
     32  *************************************************************************
     33  *
     34  * Jump vector table as in table 3.1 in [1]
     35  *
     36  *************************************************************************
     37  */
     38 
     39 
     40 .globl _start
     41 _start:    b    start_code
     42     ldr    pc, _undefined_instruction
     43     ldr    pc, _software_interrupt
     44     ldr    pc, _prefetch_abort
     45     ldr    pc, _data_abort
     46     ldr    pc, _not_used
     47     ldr    pc, _irq
     48     ldr    pc, _fiq
     49 
     50 _undefined_instruction:    .word undefined_instruction
     51 _software_interrupt:    .word software_interrupt
     52 _prefetch_abort:    .word prefetch_abort
     53 _data_abort:        .word data_abort
     54 _not_used:        .word not_used
     55 _irq:            .word irq
     56 _fiq:            .word fiq
     57 
     58     .balignl 16,0xdeadbeef
     59 
     60 
     61 /*
     62  *************************************************************************
     63  *
     64  * Startup Code (called from the ARM reset exception vector)
     65  *
     66  * do important init only if we don't start from memory!
     67  * relocate armboot to ram
     68  * setup stack
     69  * jump to second stage
     70  *
     71  *************************************************************************
     72  */
     73 
     74 .globl _TEXT_BASE
     75 _TEXT_BASE:
     76     .word    CONFIG_SYS_TEXT_BASE
     77 
     78 /*
     79  * These are defined in the board-specific linker script.
     80  * Subtracting _start from them lets the linker put their
     81  * relative position in the executable instead of leaving
     82  * them null.
     83  */
     84 .globl _bss_start_ofs
     85 _bss_start_ofs:
     86     .word __bss_start - _start
     87 
     88 .globl _bss_end_ofs
     89 _bss_end_ofs:
     90     .word __bss_end__ - _start
     91 
     92 .globl _end_ofs
     93 _end_ofs:
     94     .word _end - _start
     95 
     96 #ifdef CONFIG_USE_IRQ
     97 /* IRQ stack memory (calculated at run-time) */
     98 .globl IRQ_STACK_START
     99 IRQ_STACK_START:
    100     .word    0x0badc0de
    101 
    102 /* IRQ stack memory (calculated at run-time) */
    103 .globl FIQ_STACK_START
    104 FIQ_STACK_START:
    105     .word 0x0badc0de
    106 #endif
    107 
    108 /* IRQ stack memory (calculated at run-time) + 8 bytes */
    109 .globl IRQ_STACK_START_IN
    110 IRQ_STACK_START_IN:
    111     .word    0x0badc0de
    112 
    113 /*
    114  * the actual start code
    115  */
    116 
    117 start_code:
    118     /*
    119      * set the cpu to SVC32 mode
    120      */
    121     mrs    r0, cpsr
    122     bic    r0, r0, #0x1f
    123     orr    r0, r0, #0xd3
    124     msr    cpsr, r0
    125 
    126 #if    defined(CONFIG_AT91RM9200DK) || defined(CONFIG_AT91RM9200EK)
    127     /*
    128      * relocate exception table
    129      */
    130     ldr    r0, =_start
    131     ldr    r1, =0x0
    132     mov    r2, #16
    133 copyex:
    134     subs    r2, r2, #1
    135     ldr    r3, [r0], #4
    136     str    r3, [r1], #4
    137     bne    copyex
    138 #endif
    139 
    140 #ifdef CONFIG_S3C24X0
    141     /* turn off the watchdog */
    142 
    143 # if defined(CONFIG_S3C2400)
    144 #  define pWTCON    0x15300000
    145 #  define INTMSK    0x14400008    /* Interrupt-Controller base addresses */
    146 #  define CLKDIVN    0x14800014    /* clock divisor register */
    147 #else
    148 #  define pWTCON    0x53000000
    149 #  define INTMSK    0x4A000008    /* Interrupt-Controller base addresses */
    150 #  define INTSUBMSK    0x4A00001C
    151 #  define CLKDIVN    0x4C000014    /* clock divisor register */
    152 # endif
    153 
    154     ldr    r0, =pWTCON
    155     mov    r1, #0x0
    156     str    r1, [r0]
    157 
    158     /*
    159      * mask all IRQs by setting all bits in the INTMR - default
    160      */
    161     mov    r1, #0xffffffff
    162     ldr    r0, =INTMSK
    163     str    r1, [r0]
    164 # if defined(CONFIG_S3C2410)
    165     ldr    r1, =0x3ff
    166     ldr    r0, =INTSUBMSK
    167     str    r1, [r0]
    168 # endif
    169 
    170     /* FCLK:HCLK:PCLK = 1:2:4 */
    171     /* default FCLK is 120 MHz ! */
    172     ldr    r0, =CLKDIVN
    173     mov    r1, #3
    174     str    r1, [r0]
    175 #endif    /* CONFIG_S3C24X0 */
    176 
    177     /*
    178      * we do sys-critical inits only at reboot,
    179      * not when booting from ram!
    180      */
    181 #ifndef CONFIG_SKIP_LOWLEVEL_INIT
    182     bl    cpu_init_crit
    183 #endif
    184 
    185     bl    _main
    186 
    187 /*------------------------------------------------------------------------------*/
    188 
    189 /*
    190  * void relocate_code (addr_sp, gd, addr_moni)
    191  *
    192  * This "function" does not return, instead it continues in RAM
    193  * after relocating the monitor code.
    194  *
    195  */
    196     .globl    relocate_code
    197 relocate_code:
    198     mov    r4, r0    /* save addr_sp */
    199     mov    r5, r1    /* save addr of gd */
    200     mov    r6, r2    /* save addr of destination */
    201 
    202     adr    r0, _start
    203     cmp    r0, r6
    204     moveq    r9, #0        /* no relocation. relocation offset(r9) = 0 */
    205     beq    relocate_done        /* skip relocation */
    206     mov    r1, r6            /* r1 <- scratch for copy_loop */
    207     ldr    r3, _bss_start_ofs
    208     add    r2, r0, r3        /* r2 <- source end address        */
    209 
    210 copy_loop:
    211     ldmia    r0!, {r9-r10}        /* copy from source address [r0]    */
    212     stmia    r1!, {r9-r10}        /* copy to   target address [r1]    */
    213     cmp    r0, r2            /* until source end address [r2]    */
    214     blo    copy_loop
    215 
    216 #ifndef CONFIG_SPL_BUILD
    217     /*
    218      * fix .rel.dyn relocations
    219      */
    220     ldr    r0, _TEXT_BASE        /* r0 <- Text base */
    221     sub    r9, r6, r0        /* r9 <- relocation offset */
    222     ldr    r10, _dynsym_start_ofs    /* r10 <- sym table ofs */
    223     add    r10, r10, r0        /* r10 <- sym table in FLASH */
    224     ldr    r2, _rel_dyn_start_ofs    /* r2 <- rel dyn start ofs */
    225     add    r2, r2, r0        /* r2 <- rel dyn start in FLASH */
    226     ldr    r3, _rel_dyn_end_ofs    /* r3 <- rel dyn end ofs */
    227     add    r3, r3, r0        /* r3 <- rel dyn end in FLASH */
    228 fixloop:
    229     ldr    r0, [r2]        /* r0 <- location to fix up, IN FLASH! */
    230     add    r0, r0, r9        /* r0 <- location to fix up in RAM */
    231     ldr    r1, [r2, #4]
    232     and    r7, r1, #0xff
    233     cmp    r7, #23            /* relative fixup? */
    234     beq    fixrel
    235     cmp    r7, #2            /* absolute fixup? */
    236     beq    fixabs
    237     /* ignore unknown type of fixup */
    238     b    fixnext
    239 fixabs:
    240     /* absolute fix: set location to (offset) symbol value */
    241     mov    r1, r1, LSR #4        /* r1 <- symbol index in .dynsym */
    242     add    r1, r10, r1        /* r1 <- address of symbol in table */
    243     ldr    r1, [r1, #4]        /* r1 <- symbol value */
    244     add    r1, r1, r9        /* r1 <- relocated sym addr */
    245     b    fixnext
    246 fixrel:
    247     /* relative fix: increase location by offset */
    248     ldr    r1, [r0]
    249     add    r1, r1, r9
    250 fixnext:
    251     str    r1, [r0]
    252     add    r2, r2, #8        /* each rel.dyn entry is 8 bytes */
    253     cmp    r2, r3
    254     blo    fixloop
    255 #endif
    256 
    257 relocate_done:
    258 
    259     mov    pc, lr
    260 
    261 _rel_dyn_start_ofs:
    262     .word __rel_dyn_start - _start
    263 _rel_dyn_end_ofs:
    264     .word __rel_dyn_end - _start
    265 _dynsym_start_ofs:
    266     .word __dynsym_start - _start
    267 
    268     .globl    c_runtime_cpu_setup
    269 c_runtime_cpu_setup:
    270 
    271     mov    pc, lr
    272 
    273 /*
    274  *************************************************************************
    275  *
    276  * CPU_init_critical registers
    277  *
    278  * setup important registers
    279  * setup memory timing
    280  *
    281  *************************************************************************
    282  */
    283 
    284 
    285 #ifndef CONFIG_SKIP_LOWLEVEL_INIT
    286 cpu_init_crit:
    287     /*
    288      * flush v4 I/D caches
    289      */
    290     mov    r0, #0
    291     mcr    p15, 0, r0, c7, c7, 0    /* flush v3/v4 cache */
    292     mcr    p15, 0, r0, c8, c7, 0    /* flush v4 TLB */
    293 
    294     /*
    295      * disable MMU stuff and caches
    296      */
    297     mrc    p15, 0, r0, c1, c0, 0
    298     bic    r0, r0, #0x00002300    @ clear bits 13, 9:8 (--V- --RS)
    299     bic    r0, r0, #0x00000087    @ clear bits 7, 2:0 (B--- -CAM)
    300     orr    r0, r0, #0x00000002    @ set bit 2 (A) Align
    301     orr    r0, r0, #0x00001000    @ set bit 12 (I) I-Cache
    302     mcr    p15, 0, r0, c1, c0, 0
    303 
    304     /*
    305      * before relocating, we have to setup RAM timing
    306      * because memory timing is board-dependend, you will
    307      * find a lowlevel_init.S in your board directory.
    308      */
    309     mov    ip, lr
    310 
    311     bl    lowlevel_init
    312 
    313     mov    lr, ip
    314     mov    pc, lr
    315 #endif /* CONFIG_SKIP_LOWLEVEL_INIT */
    316 
    317 /*
    318  *************************************************************************
    319  *
    320  * Interrupt handling
    321  *
    322  *************************************************************************
    323  */
    324 
    325 @
    326 @ IRQ stack frame.
    327 @
    328 #define S_FRAME_SIZE    72
    329 
    330 #define S_OLD_R0    68
    331 #define S_PSR        64
    332 #define S_PC        60
    333 #define S_LR        56
    334 #define S_SP        52
    335 
    336 #define S_IP        48
    337 #define S_FP        44
    338 #define S_R10        40
    339 #define S_R9        36
    340 #define S_R8        32
    341 #define S_R7        28
    342 #define S_R6        24
    343 #define S_R5        20
    344 #define S_R4        16
    345 #define S_R3        12
    346 #define S_R2        8
    347 #define S_R1        4
    348 #define S_R0        0
    349 
    350 #define MODE_SVC    0x13
    351 #define I_BIT        0x80
    352 
    353 /*
    354  * use bad_save_user_regs for abort/prefetch/undef/swi ...
    355  * use irq_save_user_regs / irq_restore_user_regs for IRQ/FIQ handling
    356  */
    357 
    358     .macro    bad_save_user_regs
    359     sub    sp, sp, #S_FRAME_SIZE
    360     stmia    sp, {r0 - r12}            @ Calling r0-r12
    361     ldr    r2, IRQ_STACK_START_IN
    362     ldmia    r2, {r2 - r3}            @ get pc, cpsr
    363     add    r0, sp, #S_FRAME_SIZE        @ restore sp_SVC
    364 
    365     add    r5, sp, #S_SP
    366     mov    r1, lr
    367     stmia    r5, {r0 - r3}            @ save sp_SVC, lr_SVC, pc, cpsr
    368     mov    r0, sp
    369     .endm
    370 
    371     .macro    irq_save_user_regs
    372     sub    sp, sp, #S_FRAME_SIZE
    373     stmia    sp, {r0 - r12}            @ Calling r0-r12
    374     add    r7, sp, #S_PC
    375     stmdb    r7, {sp, lr}^            @ Calling SP, LR
    376     str    lr, [r7, #0]            @ Save calling PC
    377     mrs    r6, spsr
    378     str    r6, [r7, #4]            @ Save CPSR
    379     str    r0, [r7, #8]            @ Save OLD_R0
    380     mov    r0, sp
    381     .endm
    382 
    383     .macro    irq_restore_user_regs
    384     ldmia    sp, {r0 - lr}^            @ Calling r0 - lr
    385     mov    r0, r0
    386     ldr    lr, [sp, #S_PC]            @ Get PC
    387     add    sp, sp, #S_FRAME_SIZE
    388     /* return & move spsr_svc into cpsr */
    389     subs    pc, lr, #4
    390     .endm
    391 
    392     .macro get_bad_stack
    393     ldr    r13, IRQ_STACK_START_IN        @ setup our mode stack
    394 
    395     str    lr, [r13]            @ save caller lr / spsr
    396     mrs    lr, spsr
    397     str    lr, [r13, #4]
    398 
    399     mov    r13, #MODE_SVC            @ prepare SVC-Mode
    400     @ msr    spsr_c, r13
    401     msr    spsr, r13
    402     mov    lr, pc
    403     movs    pc, lr
    404     .endm
    405 
    406     .macro get_irq_stack            @ setup IRQ stack
    407     ldr    sp, IRQ_STACK_START
    408     .endm
    409 
    410     .macro get_fiq_stack            @ setup FIQ stack
    411     ldr    sp, FIQ_STACK_START
    412     .endm
    413 
    414 /*
    415  * exception handlers
    416  */
    417     .align  5
    418 undefined_instruction:
    419     get_bad_stack
    420     bad_save_user_regs
    421     bl    do_undefined_instruction
    422 
    423     .align    5
    424 software_interrupt:
    425     get_bad_stack
    426     bad_save_user_regs
    427     bl    do_software_interrupt
    428 
    429     .align    5
    430 prefetch_abort:
    431     get_bad_stack
    432     bad_save_user_regs
    433     bl    do_prefetch_abort
    434 
    435     .align    5
    436 data_abort:
    437     get_bad_stack
    438     bad_save_user_regs
    439     bl    do_data_abort
    440 
    441     .align    5
    442 not_used:
    443     get_bad_stack
    444     bad_save_user_regs
    445     bl    do_not_used
    446 
    447 #ifdef CONFIG_USE_IRQ
    448 
    449     .align    5
    450 irq:
    451     get_irq_stack
    452     irq_save_user_regs
    453     bl    do_irq
    454     irq_restore_user_regs
    455 
    456     .align    5
    457 fiq:
    458     get_fiq_stack
    459     /* someone ought to write a more effiction fiq_save_user_regs */
    460     irq_save_user_regs
    461     bl    do_fiq
    462     irq_restore_user_regs
    463 
    464 #else
    465 
    466     .align    5
    467 irq:
    468     get_bad_stack
    469     bad_save_user_regs
    470     bl    do_irq
    471 
    472     .align    5
    473 fiq:
    474     get_bad_stack
    475     bad_save_user_regs
    476     bl    do_fiq
    477 
    478 #endif

    40行是代码的入口:

    .globl _start
    _start:    b    start_code

    然后跳转到start_code处:

    start_code:
        /*
         * set the cpu to SVC32 mode
         */
        mrs    r0, cpsr
        bic    r0, r0, #0x1f
        orr    r0, r0, #0xd3
        msr    cpsr, r0
    
    #if    defined(CONFIG_AT91RM9200DK) || defined(CONFIG_AT91RM9200EK)
        /*
         * relocate exception table
         */
        ldr    r0, =_start
        ldr    r1, =0x0
        mov    r2, #16
    copyex:
        subs    r2, r2, #1
        ldr    r3, [r0], #4
        str    r3, [r1], #4
        bne    copyex
    #endif
    
    #ifdef CONFIG_S3C24X0
        /* turn off the watchdog */
    
    # if defined(CONFIG_S3C2400)
    #  define pWTCON    0x15300000
    #  define INTMSK    0x14400008    /* Interrupt-Controller base addresses */
    #  define CLKDIVN    0x14800014    /* clock divisor register */
    #else
    #  define pWTCON    0x53000000
    #  define INTMSK    0x4A000008    /* Interrupt-Controller base addresses */
    #  define INTSUBMSK    0x4A00001C
    #  define CLKDIVN    0x4C000014    /* clock divisor register */
    # endif
    
        ldr    r0, =pWTCON
        mov    r1, #0x0
        str    r1, [r0]
    
        /*
         * mask all IRQs by setting all bits in the INTMR - default
         */
        mov    r1, #0xffffffff
        ldr    r0, =INTMSK
        str    r1, [r0]
    # if defined(CONFIG_S3C2410)
        ldr    r1, =0x3ff
        ldr    r0, =INTSUBMSK
        str    r1, [r0]
    # endif
    
        /* FCLK:HCLK:PCLK = 1:2:4 */
        /* default FCLK is 120 MHz ! */
        ldr    r0, =CLKDIVN
        mov    r1, #3
        str    r1, [r0]
    #endif    /* CONFIG_S3C24X0 */
    
        /*
         * we do sys-critical inits only at reboot,
         * not when booting from ram!
         */
    #ifndef CONFIG_SKIP_LOWLEVEL_INIT
        bl    cpu_init_crit
    #endif
    
        bl    _main

    前面几行代码将切换到svc32模式。

    之后会判断是否配置了CONFIG_AT91RM9200DK或者CONFIG_AT91RM9200EK,

    而从include/configs/smdk2410.h文件中没有这样的配置,所以这几行代码不被执行。

    然后会判断是否定义了CONFIG_S3C24X0(smdk2410确实配置了这个选项),

    然后根据是否定义了CONFIG_S3C2400(smdk2410没有配置这个选项)来确定pWTCON、INTMSKCLKDIVN等寄存器的地址。

    接下来关闭看门狗:

        ldr     r0, =pWTCON
        mov     r1, #0x0
        str     r1, [r0]

    接着设置中断屏蔽寄存器的值为0xffffffff:

        mov    r1, #0xffffffff
        ldr    r0, =INTMSK
        str    r1, [r0]

    接着配置副中断屏蔽寄存器的值为0x3ff(总共有11个有效位,所以0x3ff表示第11位未屏蔽)

    # if defined(CONFIG_S3C2410)
        ldr    r1, =0x3ff
        ldr    r0, =INTSUBMSK
        str    r1, [r0]
    # endif

    然后对分频进行设置:

    而CLKDIVN最低位为0(CLKDIVN[0])时表示PCLK与HCLK相同,为1表示PCLK等于HCLK的1/2。

    而CLKDIVN次低两位(CLKDIVN[2:1])为0时表示HCLK等于FCLK,为1时表示HCLK等于FCLK的1/2.

        /* FCLK:HCLK:PCLK = 1:2:4 */
        /* default FCLK is 120 MHz ! */
        ldr    r0, =CLKDIVN
        mov    r1, #3
        str    r1, [r0]

     因为没有定义CONFIG_SKIP_LOWLEVEL_INIT,所以接下来会跳转到cpu_init_crit:

    #ifndef CONFIG_SKIP_LOWLEVEL_INIT
        bl    cpu_init_crit
    #endif

    cpu_init_crit代码如下:

    #ifndef CONFIG_SKIP_LOWLEVEL_INIT
    cpu_init_crit:
        /*
         * flush v4 I/D caches
         */
        mov    r0, #0
        mcr    p15, 0, r0, c7, c7, 0    /* flush v3/v4 cache */
        mcr    p15, 0, r0, c8, c7, 0    /* flush v4 TLB */
    
        /*
         * disable MMU stuff and caches
         */
        mrc    p15, 0, r0, c1, c0, 0
        bic    r0, r0, #0x00002300    @ clear bits 13, 9:8 (--V- --RS)
        bic    r0, r0, #0x00000087    @ clear bits 7, 2:0 (B--- -CAM)
        orr    r0, r0, #0x00000002    @ set bit 2 (A) Align
        orr    r0, r0, #0x00001000    @ set bit 12 (I) I-Cache
        mcr    p15, 0, r0, c1, c0, 0
    
        /*
         * before relocating, we have to setup RAM timing
         * because memory timing is board-dependend, you will
         * find a lowlevel_init.S in your board directory.
         */
        mov    ip, lr
    
        bl    lowlevel_init
    
        mov    lr, ip
        mov    pc, lr
    #endif /* CONFIG_SKIP_LOWLEVEL_INIT */

    cpu_init_crit功能先flush Cache和TLB,然后禁止MMU和Cache,然后会跳转到lowlevel_init执行。

    lowlevel_init位于board/samsung/smdk2410/lowlevel_init.S文件,代码如下:

    _TEXT_BASE:
        .word    CONFIG_SYS_TEXT_BASE

    .globl lowlevel_init
    lowlevel_init: /* memory control configuration */ /* make r0 relative the current location so that it */ /* reads SMRDATA out of FLASH rather than memory ! */ ldr r0, =SMRDATA ldr r1, _TEXT_BASE sub r0, r0, r1 ldr r1, =BWSCON /* Bus Width Status Controller */ add r2, r0, #13*4 0: ldr r3, [r0], #4 str r3, [r1], #4 cmp r2, r0 bne 0b /* everything is fine now */ mov pc, lr

        .ltorg
    /* the literal pools origin */

    SMRDATA:
        .word (0+(B1_BWSCON<<4)+(B2_BWSCON<<8)+(B3_BWSCON<<12)+(B4_BWSCON<<16)+(B5_BWSCON<<20)+(B6_BWSCON<<24)+(B7_BWSCON<<28))
        .word ((B0_Tacs<<13)+(B0_Tcos<<11)+(B0_Tacc<<8)+(B0_Tcoh<<6)+(B0_Tah<<4)+(B0_Tacp<<2)+(B0_PMC))
        .word ((B1_Tacs<<13)+(B1_Tcos<<11)+(B1_Tacc<<8)+(B1_Tcoh<<6)+(B1_Tah<<4)+(B1_Tacp<<2)+(B1_PMC))
        .word ((B2_Tacs<<13)+(B2_Tcos<<11)+(B2_Tacc<<8)+(B2_Tcoh<<6)+(B2_Tah<<4)+(B2_Tacp<<2)+(B2_PMC))
        .word ((B3_Tacs<<13)+(B3_Tcos<<11)+(B3_Tacc<<8)+(B3_Tcoh<<6)+(B3_Tah<<4)+(B3_Tacp<<2)+(B3_PMC))
        .word ((B4_Tacs<<13)+(B4_Tcos<<11)+(B4_Tacc<<8)+(B4_Tcoh<<6)+(B4_Tah<<4)+(B4_Tacp<<2)+(B4_PMC))
        .word ((B5_Tacs<<13)+(B5_Tcos<<11)+(B5_Tacc<<8)+(B5_Tcoh<<6)+(B5_Tah<<4)+(B5_Tacp<<2)+(B5_PMC))
        .word ((B6_MT<<15)+(B6_Trcd<<2)+(B6_SCAN))
        .word ((B7_MT<<15)+(B7_Trcd<<2)+(B7_SCAN))
        .word ((REFEN<<23)+(TREFMD<<22)+(Trp<<20)+(Trc<<18)+(Tchr<<16)+REFCNT)
        .word 0x32
        .word 0x30
        .word 0x30

    lowlevel_init用于初始化SDRAM,对2410的bank0-bank7都进行初始化。寄存器含义可以查看http://www.embedu.org/Column/Column169.htm

    接下来就是执行“bl _main”跳转到_main函数,这属于第二阶段初始化的内容,在下一篇博文中再进行讲述。

    总之,第一阶段初始化内容如下:

    (1)进入SVC32模式

    (2)关闭看门狗,屏蔽中断

    (3)设置分频(FCLK:HCLK:PCLK = 1:2:4)

    (4)Flush Cache和TLB, 禁止MMU和Cache

    (5)初始化SDRAM(即配置Bank0-Bank7)

  • 相关阅读:
    CentOS7配置VIP
    Linux定时任务crontab命令
    zabbix安装部署
    ansible部署EFK
    Python中参数的冒号与箭头表示注释
    pycharm 进行远程服务器修改与调试
    判别模型与生成模型
    写Python机器学习时的一些注意事项
    numpy基本操作
    手写神经网络
  • 原文地址:https://www.cnblogs.com/qiaoqiao2003/p/3726958.html
Copyright © 2011-2022 走看看