当前位置: 代码迷 >> WinCE >> 关于启动内核函数void Launch(DWORD dwLaunchAddr)的疑问,该怎么处理
  详细解决方案

关于启动内核函数void Launch(DWORD dwLaunchAddr)的疑问,该怎么处理

热度:380   发布时间:2016-04-28 13:48:17.0
关于启动内核函数void Launch(DWORD dwLaunchAddr)的疑问
void Launch(DWORD dwLaunchAddr)这个函数是在SMDK2440A\Src\Bootloader\Eboot\util.s(32)实现的
;******************************************************************************

  INCLUDE kxarm.h

PHY_RAM_START EQU 0x30000000
VIR_RAM_START EQU 0x80000000

TEXTAREA

LEAF_ENTRY Launch

ldr r2, = PhysicalStart
ldr r3, = (VIR_RAM_START - PHY_RAM_START)

sub r2, r2, r3

mov r1, #0x0070 ; Disable MMU
mcr p15, 0, r1, c1, c0, 0
nop
mov pc, r2 ; Jump to PStart
nop

; MMU & caches now disabled.

PhysicalStart

mov r2, #0
mcr p15, 0, r2, c8, c7, 0 ; Flush the TLB
mov pc, r0 ; Jump to program we are launching.
根据C语言中void Launch(DWORD dwLaunchAddr),只有一个参数以及C和汇编函数调用的参数传递规则。
这个DWORD dwLaunchAddr应该传递给汇编中的r0。
但是我搞不明白这东西是怎么启动起来的。并且这个启动方法和优龙的有很大差别。
根据config.bib中的设置,这个内核开始的物理地址应该是)0x30200000
按照道理应该是直接运行PhysicalStart这个汇编段才能运行起来,但是怎么会在前面横插下面的代码呢?
ldr r2, = PhysicalStart
ldr r3, = (VIR_RAM_START - PHY_RAM_START)

sub r2, r2, r3

mov r1, #0x0070 ; Disable MMU
mcr p15, 0, r1, c1, c0, 0
nop
mov pc, r2 ; Jump to PStart

还有一个疑问,为什么eboot要在nboot之后开启MMU,但是在启动内核的时候又关闭MMU,不能在eboot把MMU都关闭吗?
这样做有什么好处?


------解决方案--------------------
问题的关键是在Disable MMU后必须在2条指令内执行mov pc操作,否则程序就跑飞
但是在真正跳转到NK地址前,还需要flush cache等操作
所以就先跳到PhysicalStart处,做完其他操作再跳到NK入口
------解决方案--------------------
Assembly code
                TEXTAREA    LEAF_ENTRY Launch    mov        r10, r0         ; r0 : mov physical launch address    bl        INTERRUPTS_OFF    ldr        r1, =g_oalAddressTable    ldr        r0, =PhysicalStart    mov        r4, r0    bl        PaFromVa     ; find physical address of PhysicalStart    cmp        r0, #-1         ; found?    movne    r4, r0             ; yes, save real address    mov     r1, #0x0070          ; Disable MMU    mcr        p15, 0, r1, c1, c0, 0    ; MMU & caches now disabled. // excute    nop                    ; // decode    mov        pc, r4            ; Jump to PStart // patch    nopPhysicalStart    mov        r1, #0    mcr        p15, 0, r1, c8, c7, 0    ; Flush the TLB    mov        pc, r10            ; Jump to program we are launching.    ENTRY_END
  相关解决方案