本文基于Linux版本:linux-4.19.125 arm-V7架构
__mmap_switched
__mmap_switched位于arch/arm/kernel/head-common.S,其实现如下:
/*
* 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 (exc_ret for M-class)
* r1 = machine ID
* r2 = atags/dtb pointer
* r9 = processor ID
*/
__INIT
__mmap_switched:
mov r7, r1
mov r8, r2
mov r10, r0
adr r4, __mmap_switched_data
/* r4: __mmap_switched_data虚拟地址
*/
mov fp, #0
#if defined(CONFIG_XIP_DEFLATED_DATA) /*未开启,暂忽略 --start*/
ARM( ldr sp, [r4], #4 )
THUMB( ldr sp, [r4] )
THUMB( add r4, #4 )
bl __inflate_kernel_data @ decompress .data to RAM
teq r0, #0
bne __error
#elif defined(CONFIG_XIP_KERNEL)
ARM( ldmia r4!, {r0, r1, r2, sp} )
THUMB( ldmia r4!, {r0, r1, r2, r3} )
THUMB( mov sp, r3 )
sub r2, r2, r1
bl memcpy @ copy .data to RAM
#endif /*未开启,暂忽略 --end*/
ARM( ldmia r4!, {r0, r1, sp} )
THUMB( ldmia r4!, {r0, r1, r3} )
THUMB( mov sp, r3 )
/* r0: __bss_start
* r1: __bss_stop
* sp: 栈底(高地址)
*/
sub r2, r1, r0 /* r2: __bss_stop - __bss_start*/
mov r1, #0
bl memset @ clear .bss
ldmia r4, {r0, r1, r2, r3}
/* r0: processor_id
* r1: __machine_arch_type
* r2: __atags_pointer (DTB地址?)
/* r3: cr_alignment
*/
str r9, [r0] @ Save processor ID
str r7, [r1] @ Save machine type
str r8, [r2] @ Save atags pointer
cmp r3, #0
strne r10, [r3] @ Save control register values
mov lr, #0
b start_kernel /*跳入内核*/
ENDPROC(__mmap_switched)
总结下来,主要干了两件事情:
1. 清除.bss段
2. 保存process ID/Machine type/DTB地址
__mmap_switched_data
.align 2
.type __mmap_switched_data, %object
__mmap_switched_data:
#ifdef CONFIG_XIP_KERNEL
#ifndef CONFIG_XIP_DEFLATED_DATA
.long _sdata @ r0
.long __data_loc @ r1
.long _edata_loc @ r2
#endif
.long __bss_stop @ sp (temporary stack in .bss)
#endif
.long __bss_start @ r0
.long __bss_stop @ r1
.long init_thread_union + THREAD_START_SP @ sp
.long processor_id @ r0
.long __machine_arch_type @ r1
.long __atags_pointer @ r2
#ifdef CONFIG_CPU_CP15
.long cr_alignment @ r3
#else
M_CLASS(.long exc_ret) @ r3
AR_CLASS(.long 0) @ r3
#endif
.size __mmap_switched_data, . - __mmap_switched_data
__FINIT
.text