当前位置: 首页 > 工具软件 > RK Boot > 使用案例 >

(ROC-RK3568-PC) 裸机9_bootrom代码分析

韦胜泫
2023-12-01

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核心是主核,然后跳到 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

将内在 0x000000e0 处的32位数据写成1
然后就 wfe => Wait for event,即让当前核心进入 low-power standby state 模式,
直到被事件唤醒,请参考 ARM WFI和WFE指令_自由的天空-CSDN博客_arm wfi
如果wfe失败,就判断内在 0x000000e0 处是否为0xf0,如果不是就继续跳到1c处,
继续wfe,如果 0x000000e0 处为 0xf0,就从内存 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 代码分析。

 类似资料: