kernel/head.S – __mmap_switched:

__mmap_switched:

/*
 * The following fragment of code is executed with the MMU on in MMU mode,
 * and uses absolute addresses; this is not position independent.
 *
 *  r0  = cp#15 control register
 *  r1  = machine ID
 *  r2  = atags/dtb pointer
 *  r9  = processor ID
 */
        __INIT
__mmap_switched:
        adr     r3, __mmap_switched_data

        ldmia   r3!, {r4, r5, r6, r7}
        cmp     r4, r5                          @ Copy data segment if needed
1:      cmpne   r5, r6
        ldrne   fp, [r4], #4
        strne   fp, [r5], #4
        bne     1b

        mov     fp, #0                          @ Clear BSS (and zero fp)
1:      cmp     r6, r7
        strcc   fp, [r6],#4
        bcc     1b

 ARM(   ldmia   r3, {r4, r5, r6, r7, sp})
 THUMB( ldmia   r3, {r4, r5, r6, r7}    )
 THUMB( ldr     sp, [r3, #16]           )
        str     r9, [r4]                        @ Save processor ID
        str     r1, [r5]                        @ Save machine type
        str     r2, [r6]                        @ Save atags pointer
        cmp     r7, #0
        strne   r0, [r7]                        @ Save control register values
        b       start_kernel
ENDPROC(__mmap_switched)
  • ldmia   r3!, {r4, r5, r6, r7}
    • r4: __data_loc <- 커널 데이터 섹션 시작 가상주소
    • r5: _sdata <- 위와 동일하지만 XIP 커널의 경우 RAM영역으로 바뀜
      • rpi2: 0x8000_8000 <- 커널빌드시 결정 (vmlinux.lds.S)
    • r6: __bss_start <- .bss 섹션 시작
    • r7: _end <- .bss 섹션 끝
  • __data_loc 와 _sdata의 주소가 다른 경우 데이터 섹션을 _sdata 주소로 옮긴다. 즉, XIP 커널이 동작중인 경우 데이터 영역을 kernel space의 시작부분 + TEXT_OFFSET 위치로 옮긴다. (data영역만 ROM -> RAM으로 옮긴다)
  • .bss 영역을 0으로 초기화한다.
  • start_kernel로 점프하기 전에 몇 개의 레지스터를 __mmap_switched_data 스트럭처의 5~7 번째 멤버가 가리키는 각 전역 변수 processor_id, __machine_arch_type 및 __atags_pointer에 저장한다.
  • 보조코프로세서 CP15가 사용되는 경우 __mmap_switched_data 스트럭처의 8번째 멤버가 가리키는 전역 변수 cr_alignment에 SCTLR 값을 가진 r0을 저장한다.
  • b start_kernel
    • 여기서 start_kernel 함수로 이동하여 C언어로 작성된 커널 설정 루틴을 동작시킨다.

 

__mmap_switched_data:

        .align  2
        .type   __mmap_switched_data, %object
__mmap_switched_data:
        .long   __data_loc                      @ r4
        .long   _sdata                          @ r5
        .long   __bss_start                     @ r6
        .long   _end                            @ r7
        .long   processor_id                    @ r4
        .long   __machine_arch_type             @ r5
        .long   __atags_pointer                 @ r6
#ifdef CONFIG_CPU_CP15
        .long   cr_alignment                    @ r7
#else
        .long   0                               @ r7
#endif
        .long   init_thread_union + THREAD_START_SP @ sp
        .size   __mmap_switched_data, . - __mmap_switched_data

 

댓글 남기기