U-부팅 첫 번째 단계의 시작

삼성 기반으로 엑시 노스 4412

링크 U-부팅에서 U-boot.lds 스크립트, 우리는이 start.s에서 문서의 편집이다 시작 알 수 있도록 확실히 여기에서 첫 번째 U-부팅 부팅의 위상과에서, CPU / arm_cortexa9 / 폴더에이 파일 다음, 문서에 따라 U-부팅 부팅의 첫 번째 단계의 단계 분석에 의한하자의 단계.

#include <config.h>
#include <version.h>
#if defined(CONFIG_ENABLE_MMU)
#include <asm/proc/domain.h>
#endif
#if defined(CONFIG_S5PV310)
#include <s5pv310.h>
#endif
#if defined(CONFIG_S5PC210)
#include <s5pc210.h>
#endif

위의 코드는 필요한 헤더 파일이 포함되어 있습니다.

    .word 0x2000
    .word 0x0
    .word 0x0
    .word 0x0

프로그램 16 바이트 패리티 헤더의 시작 부분에 정의 Uboot의 공간을 채우기 블록의 헤더 체크섬 값이 나중에 기록된다.

.globl _start
_start: b   reset
    ldr pc, _undefined_instruction
    ldr pc, _software_interrupt
    ldr pc, _prefetch_abort
    ldr pc, _data_abort
    ldr pc, _not_used
    ldr pc, _irq
    ldr pc, _fiq

_undefined_instruction:
    .word undefined_instruction
_software_interrupt:
    .word software_interrupt
_prefetch_abort:
    .word prefetch_abort
_data_abort:
    .word data_abort
_not_used:
    .word not_used
_irq:
    .word irq
_fiq:
    .word fiq

인터럽트 벡터 테이블의 정의는, 우리가 리셋 레이블을 참조하지만, 같은 장소에서 다른 벡터 인터럽트 벡터 테이블처럼 아니지만, 점프 시작에 의해 달성했다. 여기에서 우리는 다시 분석

#if 0
    /*
     * set the cpu to SVC32 mode and IRQ & FIQ disable
     */
    mrs r0, cpsr
    bic r0, r0, #0x3f
    orr r0, r0, #0xd3
    msr cpsr, r0
#else//*****ly
    mrs r0, cpsr
    bic r0, r0, #0x1f
    orr r0, r0, #0xd3
    msr cpsr,r0
#endif

위의 코드는 CPU의 동작 모드 관리 모드를 설정하고, 차폐 IRQ와 FIQ 인터럽트됩니다.

#if 1 //*****ly
cache_init:
    mrc p15, 0, r0, c0, c0, 0   @ read main ID register
    and r1, r0, #0x00f00000 @ variant
    and r2, r0, #0x0000000f @ revision
    orr r2, r2, r1, lsr #20-4   @ combine variant and revision
    cmp r2, #0x30
    mrceq   p15, 0, r0, c1, c0, 1   @ read ACTLR
    orreq   r0, r0, #0x6        @ Enable DP1(2), DP2(1)
    mcreq   p15, 0, r0, c1, c0, 1   @ write ACTLR
    /*
     * Invalidate L1 I/D
     */
    mov r0, #0          @ set up for MCR
    mcr p15, 0, r0, c8, c7, 0   @ invalidate TLBs
    mcr p15, 0, r0, c7, c5, 0   @ invalidate icache

    /*
     * disable MMU stuff and caches
     */
    mrc p15, 0, r0, c1, c0, 0
    bic r0, r0, #0x00002000 @ clear bits 13 (--V-)
    bic r0, r0, #0x00000007 @ clear bits 2:0 (-CAM)
    orr r0, r0, #0x00001000 @ set bit 12 (---I) Icache
    orr r0, r0, #0x00000002 @ set bit 1  (--A-) Align
    orr r0, r0, #0x00000800 @ set bit 11 (Z---) BTB
    mcr p15, 0, r0, c1, c0, 0
#endif

닫기 캐시와 MMU, 캐시 및 MMU가 코 프로세서 CP15에 의해 관리되고, CP15 때문에 적절한 레지스터를 설정하려면

    /* Read booting information */
    ldr r0, =POWER_BASE
    ldr r1, [r0,#OMR_OFFSET]
    bic r2, r1, #0xffffffc1

    cmp     r2, #0xA
    moveq   r3, #BOOT_ONENAND

    /* SD/MMC BOOT */
    cmp     r2, #0x4
        moveq   r3, #BOOT_MMCSD 

    /* eMMC4.3 BOOT */
    cmp     r2, #0x6
    moveq   r3, #BOOT_EMMC43

    /* eMMC441 BOOT */
    cmp     r2, #0x28
    moveq   r3, #BOOT_EMMC441
    
    ldr r0, =INF_REG_BASE
    str r3, [r0, #INF_REG3_OFFSET]   

미디어가 처음부터 시작이 무엇인지 결정하기 위해 부트 정보를 읽고

    bl  lowlevel_init   /* go setup pll,mux,memory */

이 개발 보드와 관련이 있기 때문에 보드가이 폴더 내부에 배치되도록, 우리는 lowlevel_init 입력 여기에 초기화 lowlevel_init로 이동

lowlevel_init:
#if 1//*****ly
    /* use iROM stack in bl2 */
    ldr sp, =0x02060000
#endif
    push    {lr}

    /* check reset status  */
    ldr     r0, =(INF_REG_BASE + INF_REG1_OFFSET)
        ldr     r1, [r0]

    /* AFTR wakeup reset */
    ldr r2, =S5P_CHECK_DIDLE
    cmp r1, r2
    beq exit_wakeup

    /* Sleep wakeup reset */
    ldr r2, =S5P_CHECK_SLEEP
    cmp r1, r2
    beq wakeup_reset

        /* PS-Hold high */
        ldr r0, =0x1002330c
        ldr r1, [r0]
        orr r1, r1, #0x300
        str r1, [r0]

        ldr     r0, =0x11000c08
        ldr r1, =0x0
        str r1, [r0]

        /* Clear  MASK_WDT_RESET_REQUEST  */
        ldr r0, =0x1002040c
        ldr r1, =0x00
        str r1, [r0]
        
#ifdef check_mem /*liyang 20110822*/
    /* when we already run in ram, we don't need to relocate U-Boot.
     * and actually, memory controller must be configured before U-Boot
     * is running in ram.
     */
    ldr r0, =0xff000fff
    bic r1, pc, r0      /* r0 <- current base addr of code */
    ldr r2, _TEXT_BASE      /* r1 <- original base addr in ram */
    bic r2, r2, r0      /* r0 <- current base addr of code */
    cmp     r1, r2                  /* compare r0, r1                  */
    beq     1f          /* r0 == r1 then skip sdram init   */
#endif
    /* add by cym 20130218 */
    /* init system clock */
    bl system_clock_init_scp
    
    /* Memory initialize */
    bl mem_ctrl_asm_init_ddr3

    /* end add */
    

    bl tzpc_init
    
    b   1f
    1:

#ifdef CONFIG_EVT1___
    /* store DMC density information in DRAM */
    /* mem_ctrl_asm_init returns dmc_density in r6 */
    ldr r0, =CFG_UBOOT_BASE
    sub r0, r0, #4
    str r6, [r0]
#endif
#if 0 //test for mt6620 turn off GPC1(0)
    /*wenpin.cui: headphone and sw uart switch init*/
    ldr r0, =0x11000C44
    ldr r1, [r0]
    and r1, r1, #0x4    
    cmp r1, #0x4    /*uart*/    
    beq out 

    ldr     r0, =0x11400084  /* GPC1(0)  */
    ldr     r1, [r0]    /* read GPC1DAT status*/
    orr r1, r1, #0x1    /* GPC1(0) output high  */
    str     r1, [r0]

    ldr     r0, =0x11400080  /* GPC1(0)  */
    ldr r1, [r0]
    and r1, r1, #0xfffffff0
    orr     r1, r1, #0x1    /* GPC1(0) output  */
    str     r1, [r0]
#endif
out:
    /* for UART */
    bl uart_asm_init

그것은 상관이 중요한 것은 : 다시 시작하려면, 메모리의 코드 (U-부팅이 이미 메모리에 있다면, 다음 3 단계를 생략) 여부를 시스템 클럭 초기화, 메모리 초기화, tzpc 초기화, 마지막으로 시리얼 포트 초기화를 결정하는 .S 파일

    ldr r0, =0x1002330C  /* PS_HOLD_CONTROL register */
    ldr r1, =0x00005300  /* PS_HOLD output high */
    str r1, [r0]

개발 보드 전원은 래치 구비

    /* get ready to call C functions */
    ldr sp, _TEXT_PHY_BASE  /* setup temp stack pointer */
    sub sp, sp, #12
    mov fp, #0          /* no previous frame, so fp=0 */

메모리 기능 C의 다음 세트의 스택

    ldr r0, =0xff000fff
    bic r1, pc, r0      /* r0 <- current base addr of code */
    ldr r2, _TEXT_BASE      /* r1 <- original base addr in ram */
    bic r2, r2, r0      /* r0 <- current base addr of code */
    cmp     r1, r2                  /* compare r0, r1                  */
    beq     after_copy      /* r0 == r1 then skip flash copy   */

현재 코드는 SDRAM에서 실행중인 경우 SDRAM의 현재 코드를 실행할지 여부를 결정, 코드 재배치를 건너 뜁니다.

    ldr r0, =INF_REG_BASE
    ldr r1, [r0, #INF_REG3_OFFSET]
    cmp r1, #BOOT_NAND      /* 0x0 => boot device is nand */
    beq     nand_boot
    
    cmp r1, #BOOT_ONENAND   /* 0x1 => boot device is onenand */
    beq     onenand_boot
    
    cmp     r1, #BOOT_EMMC441
    beq     emmc441_boot
    
    cmp     r1, #BOOT_EMMC43
    beq     emmc_boot
    
    cmp     r1, #BOOT_MMCSD
    beq     mmcsd_boot
    
    cmp     r1, #BOOT_NOR
    beq     nor_boot
    
    cmp     r1, #BOOT_SEC_DEV
    beq     mmcsd_boot

심판의 시작 모드

nand_boot:
    mov r0, #0x1000
    bl  copy_from_nand
    b   after_copy

onenand_boot:
    bl  onenand_bl2_copy  /*goto 0x1010*/
    b   after_copy
//ly
second_mmcsd_boot:
    ldr   r3, =BOOT_MMCSD   
    ldr r0, =INF_REG_BASE
    str r3, [r0, #INF_REG3_OFFSET]
    
mmcsd_boot:
#ifdef CONFIG_CLK_1000_400_200
    ldr r0, =CMU_BASE
    ldr r2, =CLK_DIV_FSYS2_OFFSET
    ldr r1, [r0, r2]
    orr r1, r1, #0xf
    str r1, [r0, r2]
#endif
    bl      movi_uboot_copy
    b       after_copy

emmc_boot:
#if defined(CONFIG_CLK_1000_400_200) || defined(CONFIG_CLK_1000_200_200) || defined(CONFIG_CLK_800_400_200)
    ldr r0, =CMU_BASE
    ldr r2, =CLK_DIV_FSYS1_OFFSET
    ldr r1, [r0, r2]
    orr r1, r1, #0x3
    str r1, [r0, r2]
#endif
    bl      emmc_uboot_copy
    b   after_copy

emmc441_boot:
#if defined(CONFIG_CLK_1000_400_200) || defined(CONFIG_CLK_1000_200_200) || defined(CONFIG_CLK_800_400_200)
    ldr r0, =CMU_BASE
    ldr r2, =CLK_DIV_FSYS3_OFFSET
    ldr r1, [r0, r2]
    orr r1, r1, #0x3
    str r1, [r0, r2]
#endif
    bl      emmc441_uboot_copy
//ly 20110824
    ldr   r0, =0x43e00000
    ldr   r1, [r0]
    ldr   r2, =0x2000
    cmp r1, r2
    bne  second_mmcsd_boot
    b   after_copy


nor_boot:
@   bl  read_hword
    b   after_copy

다른 부트 부트 코드에 해당하는 코드의이 부분이 U 자 부팅 메모리에없는 수행 될 경우에만 있습니다

#if defined(CONFIG_ENABLE_MMU)
enable_mmu:
    /* enable domain access */
    ldr r5, =0x0000ffff
    mcr p15, 0, r5, c3, c0, 0       @load domain access register

    /* Set the TTB register */
    ldr r0, _mmu_table_base
    ldr r1, =CFG_PHY_UBOOT_BASE
    ldr r2, =0xfff00000
    bic r0, r0, r2
    orr r1, r0, r1
    mcr p15, 0, r1, c2, c0, 0

    /* Enable the MMU */
mmu_on:
    mrc p15, 0, r0, c1, c0, 0
    orr r0, r0, #1
    mcr p15, 0, r0, c1, c0, 0
    nop
    nop
    nop
    nop
#endif

설정 MMU, 가능 MMU

stack_setup:
#if defined(CONFIG_MEMORY_UPPER_CODE)
    ldr sp, =(CFG_UBOOT_BASE + CFG_UBOOT_SIZE - 0x1000)
#else
    ldr r0, _TEXT_BASE      /* upper 128 KiB: relocated uboot   */
    sub r0, r0, #CONFIG_SYS_MALLOC_LEN  /* malloc area                      */
    sub r0, r0, #CFG_GBL_DATA_SIZE /* bdinfo                        */
#if defined(CONFIG_USE_IRQ)
    sub r0, r0, #(CONFIG_STACKSIZE_IRQ+CONFIG_STACKSIZE_FIQ)
#endif
    sub sp, r0, #12     /* leave 3 words for abort-stack    */

#endif

메모리에 스택 메모리 전체 이용 계획, 적절한 장소를 설정하여

clear_bss:
    ldr r0, _bss_start      /* find start of bss segment        */
    ldr r1, _bss_end        /* stop here                        */
    mov     r2, #0x00000000     /* clear                            */

clbss_l:
    str r2, [r0]        /* clear loop...                    */
    add r0, r0, #4
    cmp r0, r1
    ble clbss_l
    
    ldr pc, _start_armboot

_start_armboot:
    .word start_armboot

클리어 BSS 섹션 start_armboot 실행에 점프, U-부팅 첫 번째 단계가 완료 시작합니다.

다음 요약하는 것, U-부팅 일들이 무엇을해야하는지의 첫 단계 :

  1. 다만 예외 벡터 (예외 벡터)
  2. 닫기 IRQ, FIQ, SVC 모드 설정
  3. 닫기 캐시, MMU
  4. 시작 모드를 결정
  5. lowlevel_init (주로 시스템 클럭, SDRAM 초기화 직렬 포트의 초기화 등의 초기화를 위해)
  6. 개발 보드 전원은 래치 구비
  7. 설정 메모리 스택
  8. EMMC에 메모리에서 복사 Uboot
  9. 설정 및 개방 MMU
  10. 메모리에 스택 메모리 전체 이용 계획, 적절한 장소를 설정하여
  11. 삭제 BSS 섹션, start_armboot에 멀리 점프를 실행 u는 부팅 첫 단계를 수행

추천

출처www.cnblogs.com/YinShijia/p/12021621.html