int checkboard(void) { puts("Board: iMX8QM MEK\n"); build_info(); print_bootinfo(); return 0; }
static void _sos_init(seL4_CPtr* ipc_ep, seL4_CPtr* async_ep){ seL4_Word dma_addr; seL4_Word low, high; int err; /* Retrieve boot info from seL4 */ _boot_info = seL4_GetBootInfo(); conditional_panic(!_boot_info, "Failed to retrieve boot info\n"); if(verbose > 0){ print_bootinfo(_boot_info); } /* Initialise the untyped sub system and reserve memory for DMA */ err = ut_table_init(_boot_info); conditional_panic(err, "Failed to initialise Untyped Table\n"); /* DMA uses a large amount of memory that will never be freed */ dma_addr = ut_steal_mem(DMA_SIZE_BITS); conditional_panic(dma_addr == 0, "Failed to reserve DMA memory\n"); /* find available memory */ ut_find_memory(&low, &high); /* Initialise the untyped memory allocator */ ut_allocator_init(low, high); /* Initialise the cspace manager */ err = cspace_root_task_bootstrap(ut_alloc, ut_free, ut_translate, malloc, free); conditional_panic(err, "Failed to initialise the c space\n"); /* Initialise DMA memory */ err = dma_init(dma_addr, DMA_SIZE_BITS); conditional_panic(err, "Failed to intiialise DMA memory\n"); /* Initialise IPC */ _sos_ipc_init(ipc_ep, async_ep); /* Initialise frame table */ err = frame_init(); conditional_panic(err, "Failed to initialise frame table\n"); }
int main(void) { int error; /* give us a name: useful for debugging if the thread faults */ name_thread(seL4_CapInitThreadTCB, "hello-2"); /* get boot info */ info = seL4_GetBootInfo(); /* print out bootinfo */ print_bootinfo(info); /* get our cspace root cnode */ seL4_CPtr cspace_cap; //cspace_cap = simple_get_cnode(&simple); cspace_cap = seL4_CapInitThreadCNode; /* get our vspace root page diretory */ seL4_CPtr pd_cap; pd_cap = seL4_CapInitThreadPD; seL4_CPtr tcb_cap; /* TODO 1: Set tcb_cap to a free cap slot index. * hint: The bootinfo struct contains a range of free cap slot indices. */ seL4_CPtr untyped; /* TODO 2: Obtain a cap to an untyped which is large enough to contain a tcb. * * hint 1: determine the size of a tcb object. * (look in libs/libsel4/arch_include/x86/sel4/arch/types.h) * hint 2: an array of untyped caps, and a corresponding array of untyped sizes * can be found in the bootinfo struct */ /* TODO 3: Retype the untyped into a tcb, storing a cap in tcb_cap * * hint 1: int seL4_Untyped_Retype(seL4_Untyped service, int type, int size_bits, seL4_CNode root, int node_index, int node_depth, int node_offset, int num_objects) * hint 2: use a depth of 32 * hint 3: use cspace_cap for the root cnode AND the cnode_index * (bonus question: What property of the calling thread's cspace must hold for this to be ok?) */ /* initialise the new TCB */ error = seL4_TCB_Configure(tcb_cap, seL4_CapNull, seL4_MaxPrio, cspace_cap, seL4_NilData, pd_cap, seL4_NilData, 0, 0); assert(error == 0); /* give the new thread a name */ name_thread(tcb_cap, "hello-2: thread_2"); uintptr_t thread_2_stack_top = (uintptr_t)thread_2_stack + sizeof(thread_2_stack); assert(thread_2_stack_top % (sizeof(seL4_Word) * 2) == 0); seL4_UserContext regs; /* TODO 4: Set up regs to contain the desired stack pointer and instruction pointer * hint 1: libsel4/arch_include/x86/sel4/arch/types.h: * ... typedef struct seL4_UserContext_ { seL4_Word eip, esp, eflags, eax, ebx, ecx, edx, esi, edi, ebp; seL4_Word tls_base, fs, gs; } seL4_UserContext; */ /* TODO 5: Write the registers in regs to the new thread * * hint 1: int seL4_TCB_WriteRegisters(seL4_TCB service, seL4_Bool resume_target, seL4_Uint8 arch_flags, seL4_Word count, seL4_UserContext *regs); * hint 2: the value of arch_flags is ignored on x86 and arm */ /* start the new thread running */ error = seL4_TCB_Resume(tcb_cap); assert(error == 0); /* we are done, say hello */ printf("main: hello world\n"); return 0; }
int main(void) { int error; /* give us a name: useful for debugging if the thread faults */ name_thread(seL4_CapInitThreadTCB, "hello-3"); /* get boot info */ info = seL4_GetBootInfo(); /* print out bootinfo */ print_bootinfo(info); /* get our cspace root cnode */ seL4_CPtr cspace_cap; cspace_cap = seL4_CapInitThreadCNode; /* get our vspace root page directory */ seL4_CPtr pd_cap; pd_cap = seL4_CapInitThreadPD; /* TODO 1: Find free cap slots for the caps to the: * - tcb * - ipc frame * - endpoint * - badged endpoint * - page table * hint: The bootinfo struct contains a range of free cap slot indices. */ /* decide on slots to use based on what is free */ seL4_CPtr tcb_cap = ???; seL4_CPtr ipc_frame_cap = ???; ep_cap = ???; badged_ep_cap = ???; seL4_CPtr page_table_cap = ???; /* get an untyped to retype into all the objects we will need */ seL4_CPtr untyped; /* TODO 2: Obtain a cap to an untyped which is large enough to contain: * - tcb * - ipc frame * - endpoint * - badged endpoint * - page table * * hint 1: determine the size of each object * (look in libs/libsel4/arch_include/x86/sel4/arch/types.h) * hint 2: an array of untyped caps, and a corresponding array of untyped sizes * can be found in the bootinfo struct * hint 3: a single untyped cap can be retyped multiple times. Each time, an appropriately sized chunk * of the object is "chipped off". For simplicity, find a cap to an untyped which is large enough * to contain all required objects. */ /* TODO 3: Using the untyped, create the required objects, storing their caps in the roottask's root cnode. * * hint 1: int seL4_Untyped_Retype(seL4_Untyped service, int type, int size_bits, seL4_CNode root, int node_index, int node_depth, int node_offset, int num_objects) * hint 2: use a depth of 32 * hint 3: use cspace_cap for the root cnode AND the cnode_index */ /* * map the frame into the vspace at ipc_buffer_vaddr. * To do this we first try to map it in to the root page directory. * If there is already a page table mapped in the appropriate slot in the * page diretory where we can insert this frame, then this will succeed. * Otherwise we first need to create a page table, and map it in to * the page`directory, before we can map the frame in. */ seL4_Word ipc_buffer_vaddr; ipc_buffer_vaddr = IPCBUF_VADDR; error = seL4_IA32_Page_Map(ipc_frame_cap, pd_cap, ipc_buffer_vaddr, seL4_AllRights, seL4_IA32_Default_VMAttributes); if (error != 0) { /* TODO 4: Retype the untyped into page table (if this was done in TODO 3, ignore this). */ error = seL4_IA32_PageTable_Map(page_table_cap, pd_cap, ipc_buffer_vaddr, seL4_IA32_Default_VMAttributes); assert(error == 0); /* then map the frame in */ error = seL4_IA32_Page_Map(ipc_frame_cap, pd_cap, ipc_buffer_vaddr, seL4_AllRights, seL4_IA32_Default_VMAttributes); assert(error == 0); } /* set the IPC buffer's virtual address in a field of the IPC buffer */ seL4_IPCBuffer *ipcbuf = (seL4_IPCBuffer*)ipc_buffer_vaddr; ipcbuf->userData = ipc_buffer_vaddr; /* TODO 5: Mint a copy of the endpoint cap into our cspace, using the badge EP_BADGE * hint: int seL4_CNode_Mint(seL4_CNode service, seL4_Word dest_index, seL4_Uint8 dest_depth, seL4_CNode src_root, seL4_Word src_index, seL4_Uint8 src_depth, seL4_CapRights rights, seL4_CapData_t badge); */ /* initialise the new TCB */ error = seL4_TCB_Configure(tcb_cap, seL4_CapNull, seL4_MaxPrio, cspace_cap, seL4_NilData, pd_cap, seL4_NilData, ipc_buffer_vaddr, ipc_frame_cap); assert(error == 0); /* give the new thread a name */ name_thread(tcb_cap, "hello-3: thread_2"); /* set start up registers for the new thread */ size_t regs_size = sizeof(seL4_UserContext) / sizeof(seL4_Word); /* check that stack is aligned correctly */ uintptr_t thread_2_stack_top = (uintptr_t)thread_2_stack + sizeof(thread_2_stack); assert(thread_2_stack_top % (sizeof(seL4_Word) * 2) == 0); /* set instruction pointer, stack pointer and gs register (used for thread local storage) */ seL4_UserContext regs = { .eip = (seL4_Word)thread_2, .esp = (seL4_Word)thread_2_stack_top, .gs = IPCBUF_GDT_SELECTOR }; /* actually write the TCB registers. */ error = seL4_TCB_WriteRegisters(tcb_cap, 0, 0, regs_size, ®s); assert(error == 0); /* start the new thread running */ error = seL4_TCB_Resume(tcb_cap); assert(error == 0); /* we are done, say hello */ printf("main: hello world\n"); /* * now send a message to the new thread, and wait for a reply */ seL4_Word msg; seL4_MessageInfo_t tag; /* set the data to send. We send it in the first message register */ tag = seL4_MessageInfo_new(0, 0, 0, 1); seL4_SetMR(0, MSG_DATA); /* send and wait for a reply */ tag = seL4_Call(badged_ep_cap, tag); /* check that we got the expected repy */ assert(seL4_MessageInfo_get_length(tag) == 1); msg = seL4_GetMR(0); assert(msg == ~MSG_DATA); printf("main: got a reply: %#x\n", msg); return 0; }