0xe51ff004 = "ldr pc, [pc, #-4]"

    百万汉字注解 + 百篇博客分析 => 挖透鸿蒙内核源码
    https://weharmony.gitee.io
上级 f1fac04a
......@@ -121,28 +121,29 @@ reset_vector: //鸿蒙开机代码
bic r0, #(1<<12) @位清除指令,清除r0的第11
bic r0, #(1<<2 | 1<<0) @清除第02 ,禁止 MMU和缓存 0位:MMU enable/disable 2位:Cache enable/disable
mcr p15, 0, r0, c1, c0, 0 @c1=r0
@adr指令 寄存器小范围的转变,得到一个与PC有关的值,必定是个地址
/* r11: delta of physical address and virtual address */@物理地址和虚拟地址的增量
adr r11, pa_va_offset @将基于PC相对偏移的地址pa_va_offset值读取到寄存器R11
ldr r0, [r11] @R11的值给r0
ldr r0, [r11] @r0 = *r11
sub r11, r11, r0 @r11 = r11 - r0
mrc p15, 0, r12, c0, c0, 5 /* r12: get cpuid */ @获取CPUID
and r12, r12, #MPIDR_CPUID_MASK @r12经过掩码过滤
cmp r12, #0 @当前是否为0CPU
cmp r12, #0 @ cpu id 0 比较
bne secondary_cpu_init @不是0号主CPU则调用secondary_cpu_init
/* if we need to relocate to proper location or not */
adr r4, __exception_handlers /* r4: base of load address */ @r4获得加载基地址
ldr r5, =SYS_MEM_BASE /* r5: base of physical address */@r5获得物理基地址
subs r12, r4, r5 /* r12: delta of load address and physical address */ @r12=r4-r5 加载地址和物理地址的增量
/* if we need to relocate to proper location or not */ @如果需要重新安装到合适的位置
adr r4, __exception_handlers /* r4: base of load address */ @r4记录加载基地址,即:各异常的跳转指令
ldr r5, =SYS_MEM_BASE /* r5: base of physical address */@r5获得物理基地址 SYS_MEM_BASE = 0x80000000
@subs中的s表示把进位结果写入CPSR r12 = r4-r5
subs r12, r4, r5 /* r12: delta of load address and physical address */ @r12=r4-r5 加载地址和物理地址的增量
beq reloc_img_to_bottom_done /* if we load image at the bottom of physical address */@物理地址底部加载镜像
/* we need to relocate image at the bottom of physical address */
ldr r7, =__exception_handlers /* r7: base of linked address (or vm address) */
ldr r6, =__bss_start /* r6: end of linked address (or vm address) */
sub r6, r7 /* r6: delta of linked address (or vm address) */
add r6, r4 /* r6: end of load address */
/* we need to relocate image at the bottom of physical address */ @在物理地址的底部重新定位镜像
ldr r7, =__exception_handlers /* r7: base of linked address (or vm address) */ @链接地址基地址
ldr r6, =__bss_start /* r6: end of linked address (or vm address) */@链接地址结束地址
sub r6, r7 /* r6: delta of linked address (or vm address) */@链接地址范围
add r6, r4 /* r6: end of load address */@加载地址结束地址
reloc_img_to_bottom_loop:
ldr r7, [r4], #4
......@@ -155,7 +156,7 @@ reloc_img_to_bottom_loop:
reloc_img_to_bottom_done:
ldr r4, =g_firstPageTable /* r4: physical address of translation table and clear it */ @获取页面地址
add r4, r4, r11 @r4 = r4 + r11
add r4, r4, r11 @r4 = r4 + r11
bl page_table_clear @清除页表
@设置页表
PAGE_TABLE_SET SYS_MEM_BASE, KERNEL_VMM_BASE, KERNEL_VMM_SIZE, MMU_DESCRIPTOR_KERNEL_L1_PTE_FLAGS
......@@ -181,15 +182,15 @@ reloc_img_to_bottom_done:
rsb r7, r11, r6, lsl #20 /* r7: va */
str r12, [r4, r7, lsr #(20 - 2)] /* jumpTable[vaIndex] = pt entry */
bl _bootaddr_setup
bl _bootaddr_setup @安装引导地址
bl mmu_setup /* set up the mmu */
bl mmu_setup /* set up the mmu */@安装MMU
/* 清除中断和异常堆栈,并设置magic num来检查溢出 */
/* clear out the interrupt and exception stack and set magic num to check the overflow */
ldr r0, =__undef_stack
ldr r1, =__exc_stack_top
bl stack_init @初始化栈
@设置栈顶魔法数字
@设置各个栈顶魔法数字
STACK_MAGIC_SET __undef_stack, #OS_EXC_UNDEF_STACK_SIZE, OS_STACK_MAGIC_WORD
STACK_MAGIC_SET __abt_stack, #OS_EXC_ABT_STACK_SIZE, OS_STACK_MAGIC_WORD
STACK_MAGIC_SET __irq_stack, #OS_EXC_IRQ_STACK_SIZE, OS_STACK_MAGIC_WORD
......@@ -253,15 +254,15 @@ warm_reset: @初始化CPU各异常工作模式环境
cmp r12, #0 @是否为主CPU
bne cpu_start @跳转到cpu_start运行
clear_bss:
ldr r1, =__bss_start
ldr r2, =__bss_end
mov r0, #0
clear_bss: @清楚bss
ldr r1, =__bss_start @bbs开始地址
ldr r2, =__bss_end @bss结束地址
mov r0, #0 @r0 = 0
bss_loop:
cmp r1, r2
strlo r0, [r1], #4
blo bss_loop
bss_loop:
cmp r1, r2 @r1r2比较
strlo r0, [r1], #4 @ *r1 = r0 ,r1 = r1 +4 其实就是将r1慢慢清零
blo bss_loop @循环
#if defined(LOSCFG_CC_STACKPROTECTOR_ALL) || \
defined(LOSCFG_CC_STACKPROTECTOR_STRONG) || \
......@@ -275,23 +276,23 @@ bss_loop:
.word 0xe7ffdeff
#endif
bl main
bl main @LR的子程序跳转, LR = pc - 4 ,执行Cmain函数
_start_hang:
_start_hang: @悬停 ,相当于死循环,不再往下走了.
b _start_hang
mmu_setup: @启动MMU
mov r12, #0
mmu_setup: @安装MMU,初始化MMU操作
mov r12, #0 @ r12 = 0的目的是 c8设置为控制TLB,并将映射设置为无效
mcr p15, 0, r12, c8, c7, 0 /* Set c8 to control the TLB and set the mapping to invalid */
isb
isb @C8TLB控制,C7位高速缓存控制
mcr p15, 0, r12, c2, c0, 2 /* Initialize the c2 register */
isb
orr r12, r4, #MMU_TTBRx_FLAGS
isb @初始化C2 地址转换表基地址
orr r12, r4, #MMU_TTBRx_FLAGS @设置属性和设置临时页表
mcr p15, 0, r12, c2, c0, 0 /* Set attributes and set temp page table */
isb
isb @初始化C3 设置DACR0b0111
mov r12, #0x7 /* 0b0111 */
mcr p15, 0, r12, c3, c0, 0 /* Set DACR with 0b0111, client and manager domian */
isb
isb @辅助控制寄存器
mrc p15, 0, r12, c1, c0, 1 /* ACTLR, Auxlliary Control Register */
orr r12, r12, #(1 << 6) /* SMP, Enables coherent requests to the processor. */
orr r12, r12, #(1 << 2) /* Enable D-side prefetch */
......@@ -320,17 +321,17 @@ mmu_setup: @启动MMU
.global reset_platform
.type reset_platform,function
reset_platform:
reset_platform: @平台复位
#ifdef A7SEM_HAL_ROM_MONITOR
/* initialize CPSR (machine state register) */
mov r0, #(CPSR_IRQ_DISABLE|CPSR_FIQ_DISABLE|CPSR_SVC_MODE)
msr cpsr, r0
b warm_reset
mov r0, #(CPSR_IRQ_DISABLE|CPSR_FIQ_DISABLE|CPSR_SVC_MODE) @禁止中断和切换到SVC模式
msr cpsr, r0 @修改CPSR寄存器值
b warm_reset
#else
mov r0, #0
mov pc, r0 // Jump to reset vector
mov pc, r0 // Jump to reset vector @跳到重置向量表处
#endif
cpu_start: /* 启动次级CPU */
cpu_start: /* CPU 启动 */
ldr r4, =g_firstPageTable /* r4 = physical address of translation table and clear it */
add r4, r4, r11
orr r8, r4, #MMU_TTBRx_FLAGS
......@@ -342,7 +343,7 @@ cpu_start: /* 启动次级CPU */
bl mmu_setup /* 安装MMU */
bl secondary_cpu_start /* 启动次级CPU */
b .
b . //注意 b . 就会跳转到当前地址,相当死循环
secondary_cpu_init: /* 次级CPU初始化 */
#ifdef LOSCFG_TEE_ENABLE
......@@ -375,7 +376,7 @@ sp_set: /* 设置当前cpu 栈顶指针 ,r1是栈底 ,r0是栈大小,r12是cpuid
* r4: page table base address
* r5 and r6 will be used as variable
*/
page_table_clear:
page_table_clear: @清空页表,一页一页来
mov r5, #0
mov r6, #0
0:
......@@ -386,14 +387,14 @@ page_table_clear:
bx lr
/*
* r4: page table base address
* r6: physical address
* r7: virtual address
* r8: sizes
* r10: flags
* r9 and r12 will be used as variable
* r4: page table base address 页表基地址
* r6: physical address 物理地址
* r7: virtual address 虚拟地址
* r8: sizes 大小(4K)
* r10: flags 标签
* r9 and r12 will be used as variable 作为变量使用
*/
page_table_build:
page_table_build: @创建页面
mov r9, r6
bfc r9, #20, #12 /* r9: pa % MB */
add r8, r8, r9
......@@ -416,53 +417,53 @@ page_table_build_loop:
* init stack to initial value 初始化栈,前置条件:r0r1分别为栈顶和栈底
* r0 is stack mem start, r1 is stack mem end
*/
stack_init:
stack_init:@初始化栈,注意这里执行完 stack_init后会接着执行stack_init_loop,因为pc寄存器会一直往下走,直到有指令令它改变走向
ldr r2, =OS_STACK_INIT @魔法数字
ldr r3, =OS_STACK_INIT @魔法数字
/* Main loop sets 32 bytes at a time. */
stack_init_loop:
stack_init_loop:@循环初始化栈
.irp offset, #0, #8, #16, #24 @等价于 strd r2, r3, [r0, 0],...,strd r2, r3, [r0, 24]
strd r2, r3, [r0, \offset]
.endr
add r0, #32
cmp r0, r1
blt stack_init_loop
bx lr
bx lr @ mov pc lr 改变走向
pa_va_offset:
pa_va_offset:@物理地址和虚拟地址偏移量
.word .
/*
* set magic num to stack top for all cpu
* r0 is stack top, r1 is stack size, r2 is magic num
*/
excstack_magic:
mov r3, #0
excstack_magic_loop:
str r2, [r0]
add r0, r0, r1
add r3, r3, #1
cmp r3, #CORE_NUM
blt excstack_magic_loop
bx lr
excstack_magic: @开始设置魔法数字
mov r3, #0 @用作记录CPU id
excstack_magic_loop:@给所有CPU栈顶位置设置魔法数字
str r2, [r0] @栈顶设置魔法数字 ,等同于 *r0 = r2
add r0, r0, r1 @定位到栈底
add r3, r3, #1 @r3++
cmp r3, #CORE_NUM @比较cpu个数
blt excstack_magic_loop @循环来
bx lr @跳回 mov pc lr
/*
* 0xe51ff004 = "ldr pc, [pc, #-4]"
* next addr value will be the real booting addr
* 0xe51ff004 = "ldr pc, [pc, #-4]"
* next addr value will be the real booting addr 下一个addr将是真正的引导addr
*/
_bootaddr_setup:
mov r0, #0
ldr r1, =0xe51ff004
str r1, [r0]
ldr r1, =0xe51ff004 @等同于 MOV r1, #0xe51ff004 ,
str r1, [r0] @等同于 *r0 = r1
add r0, r0, #4
ldr r1, =SYS_MEM_BASE
str r1, [r0]
add r0, r0, #4 @r0 = r0 + 4
ldr r1, =SYS_MEM_BASE @r1 = 0x80000000 物理基地址 SYS_MEM_BASE = 0x80000000
str r1, [r0] @等同于 *r0 = r1
dsb
isb
dsb @数据同步
isb @指令同步
bx lr
bx lr @跳回调用处
init_done:
.long 0xDEADB00B
......
......@@ -149,7 +149,7 @@ LITE_OS_SEC_TEXT_INIT VOID release_secondary_cores(VOID)//调动次级CPU干活
#endif /* LOSCFG_KERNEL_SMP */
/******************************************************************************
内核入口函数,由汇编调用,见于reset_vector_up.S 和 reset_vector_mp.S
up指单核CPU, mp指多核CPU
up指单核CPU, mp指多核CPU bl main
******************************************************************************/
LITE_OS_SEC_TEXT_INIT INT32 main(VOID)//由主CPU执行,默认0号CPU 为主CPU
{
......
git add -A
git commit -m '上下文切换汇编代码注解
git commit -m '0xe51ff004 = "ldr pc, [pc, #-4]"
百万汉字注解 + 百篇博客分析 => 挖透鸿蒙内核源码
https://weharmony.gitee.io
'
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册