This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Multicore SMP using Linux kernel

Hi,

I am just trying to learn the linux kernel booting process for arm32 Cortex A9 multi core SOC. I had understood the concept of booting in linux, but I am confused about the section where secondary cores enabling from primary core. Can somebody briefly explains me about the assembly instructions in head.S for enabling the secondary cpus from primary cpu and which registers are actually involved during these assembly operations

adr r4, __secondary_data
ldmia   r4, {r5, r7, r12}
sub lr, r4, r5
add r3, r7, lr
ldrd    r4, [r3, #0]
ARM_BE8(eor r4, r4, r5)
ARM_BE8(eor r5, r4, r5)
ARM_BE8(eor r4, r4, r5)
ldr r8, [r3, #8]
badr    lr, __enable_mmu
mov r13, r12
ldr r12, [r10, #PROCINFO_INITFUNC]
add r12, r12, r10
ret r12

Thanks, manish

  • This code snippet extracts data from primary core and based on the info enable MMU, and eventually when the MMU is enabled it return to the __secondary_switched which in turn branches to secondary_start_kernel main C entry point for secondary CPUs. To dive in little bit deeper lets dry run this.

    At this time we have processor id in r9. Based on which the registers are populated as follows r3 has cpu_val and r4 cpu_mask and r5 has the pointer to the proc_info structure. For now let's assume everything was fine and we'll never run into an error. Then we load the secondary data in 1st instruction.

    Now the secondary data is populated usually by the boot processor/primary CPU and this contains the data such as info for MMU and initial stack to be used. After

    ldmia   r4, {r5, r7, r12}

    (Assuming we are using MMU not MPU) we have pointers for struct secondary_data in r4 we load its fields.  Now registers has

    r5-> Pointer to Page Directory

    r7-> Pointer to Swapper Page Directoryr12-> Pointer to initial stack

    Since MMU is not enabled right now we do the translation by ourselves, via these instructions

    sub lr, r4, r5
    add r3, r7, lr

    and we derefence pgdir in r4.
    ldrd    r4, [r3, #0]

    after this we swap this in BE mode via these instructions (pgdir is uint64)

    ARM_BE8(eor r4, r4, r5)
    ARM_BE8(eor r5, r4, r5)
    ARM_BE8(eor r4, r4, r5)

    Now we have in r4,r5 page driectory

    Next we load Swapper page directory

    ldr r8, [r3, #8]

    Now in r8 we have swapper page directory.

    now load address for __enable_mmu in r14.

    Move stack pointer to its right place with

    mov r13, r12

    Remember in r10 we have the pointer to proc_info_list, so we load the init function pointer to r12 and eventually jump to it initializing the processor. Now we have all pointer set we would just go through all flow described at start of answer.

    ldr r12, [r10, #PROCINFO_INITFUNC]
    add r12, r12, r10
    ret r12

    Hope this simplifies things for you.