Each guest will be built in a separate directory tree with its own makefile.
A simple guest
Below is a simple guest similar to the test program we used above to test gdb. It contains (1) a vector table, (2) startup code, and (3) a main program that runs in an infinite loop.
#include <stdint.h>
void dummyHandler();
void dummyguest();
void __start();
uint8_t dummyStack[1024] __attribute__ ((aligned (32)));
uint32_t *dummyVectorTable[] = {
(void*)dummyStack + sizeof(dummyStack),
(void*)__start,
(void*)dummyHandler,
(void*)dummyHandler,
(void*)dummyHandler,
(void*)dummyHandler,
(void*)dummyHandler,
(void*)dummyHandler,
(void*)dummyHandler,
(void*)dummyHandler,
(void*)dummyHandler,
(void*)dummyHandler,
(void*)dummyHandler,
(void*)dummyHandler,
(void*)dummyHandler,
(void*)dummyHandler };
void __start(){
asm("ldr r0,=dummyVectorTable\n\
ldr sp,[r0]" : : : "r0");
dummyguest();
}
void dummyHandler() {
while(1);
}
void dummyguest(){
uint16_t counter = 0;
while(1) {
counter++;
}
}
dummyStack is the 1-kB stack for this guest. Each guest must have its own stack, declared as a C-array. dummyVectorTable is the vector table for this guest. We have truncated it to 16 entries, but real apps should have complete vector tables. This should be filled out in exactly the same way as it would be if it were running on the bare metal (not in a hypervisor). __start is the guest's startup code, which initializes the guest's stack pointer and calls the main function.
# arm-none-eabi-gcc -o test.elf -mthumb -T hermes/src/devices/microchip/sam/same70q21.ld test.c -nostartfiles -g -Wl,-emain
Now start up gdb and load the test.elf binary
# arm-none-eabi-gdb a.out
(gdb) target remote localhost:3333
(gdb) load test.elf
You should be able to run this simple program now using standard gdb features. You can use layout asm
or layout src
to view assembly or source for the program as you're stepping through it. You can use layout regs
to view the registers.