OPERATING MODE REGISTER (OMR, R, ADDRESS = 0XE000_0004)

Field Bit Description Reset Value

Reserved [31:18] Read as zero 0x0

Reserved [17] Read as one 1

Reserved [16] Read as one 1

Reserved [15:14] Read as zero 0x0

NFMOD [13:8] The value of the XNFMOD[5:0] pad Pin value

Reserved [7:5] Read as zero 0x0

OM [4:0] The value of the XOM[4:0] pad Pin value

 

 

OM[4]:

0 = normal mode, 1 = test mode

 

OM[3]:

0 = 1st boot loader in iROM , 1 = reserved

 

OM[2:1] :

00 = 2nd boot loader in NAND flash

01 = 2nd boot loader in OneNAND

10 = 2nd boot loader in MMC

11 = Reserved

 

OM[0] : APLL/MPLL input selection

0 = XXTI

1 = XusbXTI


< hkdkc100\config.mk 파일에서 >
ifndef TEXT_BASE
//TEXT_BASE = 0xc7e00000
TEXT_BASE = 0x27e00000
endif

< hkdkc100.h(45) 파일에서>
#define CONFIG_S5PC100_EVT2
#define BOOT_ONENAND        0x1
#define BOOT_NAND              0x2
#define BOOT_MMCSD          0x3

#undef CONFIG_ENABLE_MMU
#define CONFIG_MEMORY_UPPER_CODE
#undef CONFIG_USE_IRQ                /* we don't need IRQ/FIQ stuff */

< cpu/s5pc1xx/start.s 파일에서 >

///////////////////////////////////////////////////////////////
        /* Read booting information *
        ldr        r0, =PRO_ID_BASE        ; PRO_ID_BASE = 0XE000_000
        ldr        r1, [r0,#OMR_OFFSET] ; OMR_OFFSET = 0x04
        bic       r2, r1, #0xfffffff9

        cmp      r2, #0x0
        moveq   r3, #BOOT_NAND

        cmp      r2, #0x2
        moveq   r3, #BOOT_ONENAND

        cmp       r2, #0x4
        moveq    r3, #BOOT_MMCSD

    ldr    r0, =INF_REG_BASE
    str    r3, [r0, #INF_REG3_OFFSET]    
     
    /*
     * Go setup Memory and board specific bits prior to relocation.
     */
    bl    lowlevel_init    /* go setup pll,mux,memory */

    /* 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     after_copy        /* r0 == r1 then skip flash copy   */

    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_MMCSD
    beq     mmcsd_boot

출처 : http://blog.naver.com/serimo/50091184494
< cpu/s5pc1xx/start.s 파일에서 >
       /*
        * 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, #0x00000002     @ set bit 1 (--A-) Align
        orr    r0, r0, #0x00000800     @ set bit 12 (Z---) BTB
        mcr     p15, 0, r0, c1, c0, 0

출처 : http://blog.naver.com/serimo/50091184301

<MCR|MRC>{cond}p#,<expression1>,Rd,cRn,cRm{,<expression2>}

MRC : coprocessor registerCPU register로 이동 (L=1)

MCR : CPU register coprocessor register로 이동 (L=0)

{cond} : Two character condition mnemonic

p# : coprocessor 번호

<opcode_1> : coprocessor-specific opcode. <opcode_1> 은 항상 0 이다.

Rd : CPU register number

cRn and cRm : coprocessor register numbers

<opcode_2> : coprocessor-specific opcode. 이 필드는 생략 할 수 있다.


< cpu/s5pc1xx/start.s 파일에서 >

/*
 *************************************************************************
 *
 * CPU_init_critical registers
 *
 * setup important registers
 * setup memory timing
 *
 *************************************************************************
 */
         /*
         * we do sys-critical inits only at reboot,
         * not when booting from ram!
         */
cpu_init_crit:
        /*
        * Invalidate L1 I/D
        */
        mov    r0, #0                      @ set up for MCR

        mcr    p15, 0, r0, c8, c7, 0   @ invalidate TLBs
// 1. 변환 참조 버퍼(Transition Lockaside Buffer: TLB)를 무효화

        mcr    p15, 0, r0, c7, c5, 0   @ invalidate icache
// 2. 명령어 캐시(instruction cache: I-cache) 무효화

출처 : http://blog.naver.com/serimo/50091160857

ARM에 리셋 신호가 입력이 되면 리셋 예외처리가 발생한다. 리셋은 전원을 처음 연결하거나 리셋 스위치를 누를 경우 발생한다.

1.     ARM 상태로 전환( CPRS[5] = 0 )

2.     인터럽트 중지 ( FIQ disable : CPRS[6] = 1, IRQ disable : CPRS[7] = 1)

3.     SVC 모드로 전환( CPRS[4:0] = 10011 )

4.     어드레스 0x0 번지로 분기하여 리셋 핸들러를 처리한다.

따라서 시스템의 0x0 번지는 Linker script file( U-boot.lds)의 Entry point에서 선언된 '_start'가 되고 여기서 부터 코드가 실행되어 reset으로 분기, 시스템의 부팅 처리를 수행한다.

다음은 부트로더의 reset 핸들 러에서 처리하는 코드이다.

< cpu/s5pc1xx/start.s 파일에서 >

/*
 *************************************************************************
 *
 * Jump vector table as in table 3.1 in [1]
 *
 *************************************************************************
 */

.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
_pad:
    .word 0x12345678 /* now 16*4=64 */
.global _end_vect
_end_vect:

    .balignl 16,0xdeadbeef


/*
 * the actual reset code
 */

reset:
    /*
     * set the cpu to SVC32 mode and IRQ & FIQ disable
     */

    mrs      r0, cpsr           

    bic       r0, r0, #0x1F      @ r0 레지스터의 0x1F 비트들을 비트 클리어한다.

    orr       r0, r0, #0xD3     @ 1101 0011 : ARM상태전환, 인터럽트 중지, SVC모드전환

                                   @ 0xD3 비트를 OR 한다.

    msr      cpsr, r0

 
* ARM의 상태 레지스터(PSR)

상태 레지스터는 1개 의 CPSR 5개의 SPSR로 구성되어 있고 내부 구조는 서로 동일하다.


비 트

명 칭

분 류

의 미

CPSR[4:0]

모드비트

컨트롤 비트

프로세서의 동작모드를 의미한다.

10000   User 모드

10001   FIQ 모드

10010   IRQ 모드

10011   SVC 모드

10111   Abort 모드

11011   Undefined 모드

11111   System 모드

CPSR[5]

상태비트( T )

ARM 아키텍쳐에서 16비트 명령인 Thumb 명령을 실행할 수 있는 상태인 경우를 1 Thumb상태, 0인 경우는 ARM 상태를 의미한다

CPSR[6]

FIQ

비트가 1로 설정되어 있으면 disable, 0이면 Enable

CPSR[7]

IRQ

비트가 1로 설정되어 있으면 disable, 0이면 Enable

CPSR[24]

J bit

컨디션코드 플래그

새로운 ARM 아키텍쳐에서 JAVA 바이트 코드 명령이 가능한데 JAVA 명령 실행 상태이면 설정된다

CPSR[27]

Q flag(Q)

새로운 ARM 아키텍쳐에서 추가된 포화 연산 명령의 수행결과 포화상태가 발생하면 설정된다. 사용후 반드시 클리어를 해 주어야 한다

CPSR[28]

Overflow( V )

연산결과가 오버플로우가 되었을 때 설정된다

CPSR[29]

Carry flag( C )

자리올림이나 내림이 발생한 경우, Shift 연 산에서 캐리가 발생한

경우에 설정된다

CPSR[30]

Zero( Z )

연산결과가 0인 경우에 설정된다

CPSR[31]

Negative( N )

연산 결과가 값인 경우에 설정된다


상태 레지스터(PSR) 전송 명령어

상태 레지스터(PSR)CPSRSPSR 2 종류가 있다. PSR 전송명령이란 이 2종류의 레지스터와 범용 레지스터들( R0 ~ R15 )과 의 데이터 전송을 하는 명령이다.


CPSR User모드에서는 컨디션코드 플래그만 쓰기가 가능하고 그 외 모든 특권모드에서는 모든 필드에 쓰기가 가능하다.

SPSR User 모드에서는 정의되어 있지 않고 각 특권 모드의 해당 SPSR만 엑세스가 가능하다.


MRS 명령

CPRS SPRS 레지스터 값을 ARM의 범용 레지스터로 읽어오는 명령이다.

MRS r0, cpsr   @ CPSRr0에 전송한다.

 

MSR 명령

ARM의 범용 레지스터나 상수값을 CPRS SPRS 레지스터에 쓰는 명령이다.

MSR cpsr, r0   @ r0CPSR에 전송한다.

출처 : http://blog.naver.com/serimo/50091044696

U-Boot , 부트로더는 보통 NORNAND 플래시의 가장 앞부분 즉, 어드레스 0번지에 저장이 된다. ARM CPU에서 리셋이 걸리면 PC값이 0번지로 초기화되는데 이는 메모리맵에서

어드레스 0번지가 시작된다는 의미이다. 그러나 NOR 플래시와는 다르게 NAND플래시의 경우에는 읽기 동작시 블록단위로 동작을 하기 때문에 순차적인 실행 즉, 부팅 동작을 할 수 없다.

 

따라서 최신 CPU들은 이러한 NAND플래시 부팅을 지원하기 위해 별도의 기능들을 추가했다. 2410 CPU의 경우 리셋이 걸리면 DMA제어에 의해 4KB만큼 내부 SRAM으로 복사되고 SRAM의 시작 주소를 0번지로 할당하여 부팅동작을 하게한다. 하지만 U-Boot의 크기는 보통 160KB 정도 되는데 4KB를 훨씬 넘는 크기이다. 이러한 문제를 해결하기 위해 부트코드의 4KB 이내 코드의 동작은 아주 중요한 기본동작만 하고, 나머지는 시스템의 주메모리 즉, SDRAM에서 동작하게 PC(Program Count)의 위치를 SDRAM 메모리 영역으로 넘겨준다.

 

이렇게 하기 위해서 우선, 부트코드는 두 가지 방식으로 분리된다.

 

1.     시스템의 기본동작을 위한 초기화를 하고, NAND 플래시에 저장된 U-Boot의 전체 이미지를 SDRAM으로 복사한다. 이 동작은 간단하게 어셈블러 언어의 리터럴 풀(상수값 지정) 동작방식으로 메모리 접근이 가능하다.

 

2.     주메모리로 복사된 후 PC SDRAM으로 넘겨줄 때는 주로 복잡한 부팅기능을 지원하기 위해 C 프로그램으로 작성되어 실행이 되는데 이때는 자동변수를 위한 스택과 전역변수 그리고 다양한 라이브러리들이 링크될 수 있는 선형적인 메모리 접근이 용이하도록 절대주소방식을 사용한다.

 

따라서 메모리 용량이 작은 SRAM에서의 초기 부팅처리는 어셈블러로 코딩이 이루어져 있고 그 뒤 SDRAM으로 복사된 후의 복잡한 처리는 C프로그램으로 작성되어 있다.

 

어셈블러로 작성된 start.S의 코드는 CPU의 동작을 위해 비교적 간단하면서도 중요한 초기화 과정을 처리하고 있다. 먼저, CPU동작 모드를 유저모드에서 수퍼바이저(SVC32)모드로 전환하고 동작에 영향을 미칠 수 있는 인터럽트와 기타 하드웨어 기능을 중지하고 시스템 클럭을 설정한다. 또한 메모리 컨트롤러를 설정하고 NAND 플래시에 존재하는 부트코드를 SDRAM의 부트영역으로 복사하고 PC를 넘겨준다. C 프로그램의 실행을 위해 필요한 스택에 대한 설정이 이루어지고 나면 C로 구현된 부트로더의 시작함수를 호출한다.

출처 : http://blog.naver.com/serimo/50090962508

+ Recent posts