rk3568 的 bootrom在 0xffff0000处,hexdump出来一段。
0000000000000000 <.data>: 0: d53800a0 mrs x0, mpidr_el1 4: 92403c00 and x0, x0, #0xffff 8: f100001f cmp x0, #0x0 c: 540001a0 b.eq 0x40 10: 58000680 ldr x0, 0xe0 14: 52800021 mov w1, #0x1 // #1 18: b9000001 str w1, [x0] 1c: d503205f wfe 20: 18000682 ldr w2, 0xf0 24: 580005e0 ldr x0, 0xe0 28: b9400001 ldr w1, [x0] 2c: 6b02003f cmp w1, w2 30: 54ffff61 b.ne 0x1c 34: 580005a1 ldr x1, 0xe8 38: b9400020 ldr w0, [x1] 3c: d61f0000 br x0 40: aa1f03e0 mov x0, xzr 44: aa1f03e1 mov x1, xzr 48: aa1f03e2 mov x2, xzr 4c: aa1f03e3 mov x3, xzr 50: aa1f03e4 mov x4, xzr 54: aa1f03e5 mov x5, xzr 58: aa1f03e6 mov x6, xzr 5c: aa1f03e7 mov x7, xzr 60: aa1f03e8 mov x8, xzr 64: aa1f03e9 mov x9, xzr 68: aa1f03ea mov x10, xzr ...
通过 mpidr_el1判断主从核心, 低16位为0,表明当前CPU核心是主核,然后跳到 0x继续运行40个代码。 否则说明目前的核心是从核,操作如下说明: 10: 58000680 ldr x0, 0xe0 14: 52800021 mov w1, #0x1 // #1 18: b9000001 str w1, [x0] 1c: d503205f wfe 20: 18000682 ldr w2, 0xf0 24: 580005e0 ldr x0, 0xe0 28: b9400001 ldr w1, [x0] 2c: 6b02003f cmp w1, w2 30: 54ffff61 b.ne 0x1c 34: 580005a1 ldr x1, 0xe8 38: b9400020 ldr w0, [x1] 3c: d61f0000 br x0 将内在 0x000000e0 32位数据写成1 然后就 wfe =>Wait for event,即让当前的核心进入low-power standby state模式, 直到被事件唤醒,请参考ARM WFI和WFE指令_自由的天空-CSDN博客_arm wfi 如果wfe失败,判断内在0x000000e0 处是否为0xf如果没有,继续跳到1c处, 继续wfe,如果 0x000000e0处为 xf0,就从内存 0x000000e8 处取目标地址, 并用 br 指令跳转过去运行。
dfsdf主核心跳到 0x40 处后执行流程: 首先就是把 31 个通用寄存器清0,
......... ac: aa1f03fb mov x27, xzr b0: aa1f03fc mov x28, xzr b4: aa1f03fd mov x29, xzr b8: aa1f03fe mov x30, xzr bc: 580000a0 ldr x0, 0xd0 c0: 9100001f mov sp, x0 c4: 580000a0 ldr x0, 0xd8 c8: d51ec000 msr vbar_el3, x0 cc: 14000567 b 0x1668 d0: fdcc1000 .inst 0xfdcc1000 ; undefined d4: 00000000 .inst 0x00000000 ; undefined d8: ffff7800 .inst 0xffff7800 ; undefined dc: 00000000 .inst 0x00000000 ; undefined e0: fdcc0004 .inst 0xfdcc0004 ; undefined e4: 00000000 .inst 0x00000000 ; undefined e8: fdcc0008 .inst 0xfdcc0008 ; undefined ec: 00000000 .inst 0x00000000 ; undefined f0: deadbeaf .inst 0xdeadbeaf ; undefined f4: 00000000 .inst 0x00000000 ; undefined
然后设置栈寄存器:取 0xd0 处的 unsigned int 做为 sp 其后设置 vbar_el3(el3 的 vertor base addr)为 0xFFFF7800, 然后 b 0x1668 跳到 0x1668 处继续运行。
1668: f81f0ffe str x30, [sp,#-16]! 166c: f0fee668 adrp x8, 0xfffffffffdcd0000 1670: 528794a9 mov w9, #0x3ca5 // #15525 1674: f0fee66a adrp x10, 0xfffffffffdcd0000 1678: 1280000b mov w11, #0xffffffff // #-1 167c: f0fee66c adrp x12, 0xfffffffffdcd0000 1680: f0fee66d adrp x13, 0xfffffffffdcd0000 1684: b9000d09 str w9, [x8,#12] 1688: b902714b str w11, [x10,#624] 168c: f0fee668 adrp x8, 0xfffffffffdcd0000 1690: 3900f19f strb wzr, [x12,#60] 1694: 3900d1bf strb wzr, [x13,#52] 1698: b900111f str wzr, [x8,#16] 169c: 321d07e0 orr w0, wzr, #0x18 16a0: 94000dfb bl 0x4e8c 16a4: 94000dfd bl 0x4e98 16a8: 94000cb8 bl 0x4988
mem@0xfdcd000c = 0x3ca5 mem@0xfdcd0270 = 0xffffffff // #-1 mem@0xfdcd003c = 0 (byte) mem@0xfdcd0034 = 0 (byte) mem@0xfdcd0010 = 0 (byte)
都是PMU_SRAM 内存( 0xFDCD0000 8KB) 然后 bl 0x4e8c
因为只dump了前19kb的bootrom, 暂时看不到 0x4e8c 处的代码。 汇编也不是强项, 放弃 bootrom 代码分析。