AMP with Raspberry Pi: Step 3 - Life Control Mangement for remote process

Running Bare Metal App
When Linux kernel boots all non asigned cpus (here Core 3) remain in a loop looking it's mailbox 3 for non-zero value, with an address where to jump (read more here). Writting to that mailbox (Core3_MBOX3_SET register = 0x400000BC) the value 0x20000000 makes Core 3 to jump to the executable that we loaded at that possition.
For physical memory read/write from Linux I used devmem, so get it from

Now start the loaded blinking app writing 0x20000000 to Core 3 MailBox3:

./devmem 0x400000bc w 0x20000000

Connect a LED to GPIO16.

Brian's tutorials include an C-startup assembler file "armc-0x-start.S" that is the first code to be executed.

For that armc-0x-start.S include this label:
.section ".text.startup"
That label is the first in the used linker script: rpi.x

In that examples we loose control over execution, as the used C-startup funcion start.S branches to kernel_main function and never return.

In order to have control over bare-metal execution the some changes were made to armc-0x-start.S:

.section ".text.startup"

.global _start
.global _get_stack_pointer

// Clear CORE3_MBOX3
    ldr r1,=0x400000FC
    ldr r3,=0xffffffff
    str r3, [r1]

    // Set the stack pointer, which progresses downwards through memory
    // Set it at 64MB which we know our application will not crash into
    // and we also know will be available to the ARM CPU. No matter what
    // settings we use to split the memory between the GPU and ARM CPU
    ldr     sp, =(768 * 1024 * 1024) //SP to 0x3000000

    // Run the c startup function - should not return and will call kernel_main
     bl       _cstartup
     bl       kernel_main              //changed from b to bl

// Check CORE3_MBOX3 for jump address (not zero)
ldr r1,=0x400000FC
 ldr r1, [r1]
mov r3, #0
cmp r1, r3
beq _check_loop
bx  r1

    // Return the stack pointer value
    str     sp, [sp]
    ldr     r0, [sp]

    // Return from the function
    mov     pc, lr

Replacing the "b" kernel_main branch with "bl"  (branch with link) kernel_main can return.
When kernel_main returns the core loops (_check_loop) looking for a non-zero value in mailbox 3.
Previously (when this code start) mailbox 3 is cleared.

For a tentative LCM implementation see this example.

A serious LCM requires interrups or any exception mechanism in order to take the control.

No hay comentarios:

Publicar un comentario