Working Init Channel
This commit is contained in:
parent
24c9fa55a9
commit
50c75ed361
@ -17,10 +17,15 @@
|
|||||||
|
|
||||||
#include <aos/aos.h>
|
#include <aos/aos.h>
|
||||||
|
|
||||||
|
// define some message types
|
||||||
|
#define RPC_MTYPE_CHILD_ENDPOINT 0UL
|
||||||
|
#define RPC_MTYPE_CHILD_ENDPOINT_OK 1UL
|
||||||
|
|
||||||
|
|
||||||
/* An RPC binding, which may be transported over LMP or UMP. */
|
/* An RPC binding, which may be transported over LMP or UMP. */
|
||||||
struct aos_rpc {
|
struct aos_rpc {
|
||||||
// TODO(M3): Add state
|
// TODO(M3): Add state
|
||||||
|
struct lmp_chan *chan;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@ -56,6 +56,8 @@ struct spawninfo {
|
|||||||
struct capref cspace_cap_vspace; // < The frame capability used to store the serialized vspace
|
struct capref cspace_cap_vspace; // < The frame capability used to store the serialized vspace
|
||||||
|
|
||||||
struct capref vspace_cap_l0_pagetable;
|
struct capref vspace_cap_l0_pagetable;
|
||||||
|
|
||||||
|
struct lmp_chan init_chan;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Start a child process using the multiboot command line. Fills in si.
|
// Start a child process using the multiboot command line. Fills in si.
|
||||||
|
|||||||
@ -152,7 +152,6 @@ time_t mktime(struct tm *);
|
|||||||
size_t strftime(char * __restrict, size_t, const char * __restrict,
|
size_t strftime(char * __restrict, size_t, const char * __restrict,
|
||||||
const struct tm * __restrict);
|
const struct tm * __restrict);
|
||||||
time_t time(time_t *);
|
time_t time(time_t *);
|
||||||
void time_wait_ms(unsigned long);
|
|
||||||
long time_to_ms(struct timespec tt);
|
long time_to_ms(struct timespec tt);
|
||||||
#if __POSIX_VISIBLE >= 200112
|
#if __POSIX_VISIBLE >= 200112
|
||||||
struct sigevent;
|
struct sigevent;
|
||||||
|
|||||||
@ -81,7 +81,12 @@ aos_rpc_process_get_all_pids(struct aos_rpc *rpc, domainid_t **pids,
|
|||||||
return SYS_ERR_OK;
|
return SYS_ERR_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// We are allowed to change the signature for this one
|
||||||
|
errval_t aos_rpc_init(struct aos_rpc *rpc)
|
||||||
|
{
|
||||||
|
// TODO!
|
||||||
|
return SYS_ERR_OK;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Returns the RPC channel to init.
|
* \brief Returns the RPC channel to init.
|
||||||
|
|||||||
@ -28,9 +28,11 @@
|
|||||||
|
|
||||||
#include "threads_priv.h"
|
#include "threads_priv.h"
|
||||||
#include "init.h"
|
#include "init.h"
|
||||||
|
#include <aos/aos_rpc.h>
|
||||||
|
|
||||||
/// Are we the init domain (and thus need to take some special paths)?
|
/// Are we the init domain (and thus need to take some special paths)?
|
||||||
static bool init_domain;
|
static bool init_domain;
|
||||||
|
static bool init_chan_initialized;
|
||||||
|
|
||||||
extern size_t (*_libc_terminal_read_func)(char *, size_t);
|
extern size_t (*_libc_terminal_read_func)(char *, size_t);
|
||||||
extern size_t (*_libc_terminal_write_func)(const char *, size_t);
|
extern size_t (*_libc_terminal_write_func)(const char *, size_t);
|
||||||
@ -81,6 +83,56 @@ static size_t dummy_terminal_read(char *buf, size_t len)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO rueegges: putting it here for now. Not sure how to do rcp abstraction yet
|
||||||
|
static int event_init_dispatch_thread(void *arg)
|
||||||
|
{
|
||||||
|
errval_t err;
|
||||||
|
while(true) {
|
||||||
|
err = event_dispatch(get_default_waitset());
|
||||||
|
if (err_is_fail(err)) {
|
||||||
|
USER_PANIC_ERR(err_push(err, LIB_ERR_EVENT_DISPATCH), "Failed to dispatch events");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO rueegges: putting it here for now. Not sure how to do rcp abstraction yet
|
||||||
|
static void handle_init_recv(void *arg)
|
||||||
|
{
|
||||||
|
errval_t err;
|
||||||
|
struct lmp_chan *init_chan = (struct lmp_chan *)arg;
|
||||||
|
|
||||||
|
struct lmp_recv_msg msg = LMP_RECV_MSG_INIT;
|
||||||
|
struct capref cap;
|
||||||
|
|
||||||
|
err = lmp_chan_recv(init_chan, &msg, &cap);
|
||||||
|
if (err_is_fail(err)) {
|
||||||
|
if (lmp_err_is_transient(err)) {
|
||||||
|
err = lmp_endpoint_register(init_chan->endpoint, get_default_waitset(), MKCLOSURE(handle_init_recv, init_chan));
|
||||||
|
if (err_is_fail(err)) {
|
||||||
|
USER_PANIC_ERR(err, "Could not reregister after failed init_chan cap receive");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
USER_PANIC_ERR(err, "Failure in child channel");
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch(msg.words[0]){
|
||||||
|
case RPC_MTYPE_CHILD_ENDPOINT_OK:
|
||||||
|
debug_printf("Received child init OK\n");
|
||||||
|
init_chan_initialized = true;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
USER_PANIC("Unknown rpc message type.");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
err = lmp_endpoint_register(init_chan->endpoint, get_default_waitset(), MKCLOSURE(handle_init_recv, init_chan));
|
||||||
|
if (err_is_fail(err)) {
|
||||||
|
USER_PANIC_ERR(err, "Could not reregister after failed init_chan cap receive");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Set libc function pointers */
|
/* Set libc function pointers */
|
||||||
void barrelfish_libc_glue_init(void)
|
void barrelfish_libc_glue_init(void)
|
||||||
{
|
{
|
||||||
@ -146,16 +198,48 @@ errval_t barrelfish_init_onthread(struct spawn_domain_params *params)
|
|||||||
lmp_endpoint_init();
|
lmp_endpoint_init();
|
||||||
|
|
||||||
// HINT: Use init_domain to check if we are the init domain.
|
// HINT: Use init_domain to check if we are the init domain.
|
||||||
|
// early exit for the init process
|
||||||
|
if(init_domain) {
|
||||||
|
return SYS_ERR_OK;
|
||||||
|
}
|
||||||
|
|
||||||
// TODO MILESTONE 3: register ourselves with init
|
// TODO MILESTONE 3: register ourselves with init
|
||||||
/* allocate lmp channel structure */
|
/* allocate lmp channel structure */
|
||||||
|
struct lmp_chan *init_chan = malloc(sizeof(struct lmp_chan));
|
||||||
/* create local endpoint */
|
/* create local endpoint */
|
||||||
|
err = endpoint_create(DEFAULT_LMP_BUF_WORDS, &init_chan->local_cap, &init_chan->endpoint);
|
||||||
|
if (err_is_fail(err)) {
|
||||||
|
return err_push(err, LIB_ERR_ENDPOINT_CREATE);
|
||||||
|
}
|
||||||
/* set remote endpoint to init's endpoint */
|
/* set remote endpoint to init's endpoint */
|
||||||
|
init_chan->remote_cap = cap_initep;
|
||||||
/* set receive handler */
|
/* set receive handler */
|
||||||
|
init_chan_initialized = false;
|
||||||
|
err = lmp_chan_register_recv(init_chan, get_default_waitset(), MKCLOSURE(handle_init_recv, init_chan));
|
||||||
/* send local ep to init */
|
/* send local ep to init */
|
||||||
|
err = lmp_chan_send0(init_chan, LMP_FLAG_YIELD | LMP_FLAG_SYNC, init_chan->local_cap);
|
||||||
|
if (err_is_fail(err)) {
|
||||||
|
// should never fail since init listens before invoking the dispatcher
|
||||||
|
return err_push(err, LIB_ERR_LMP_CHAN_SEND);
|
||||||
|
}
|
||||||
/* wait for init to acknowledge receiving the endpoint */
|
/* wait for init to acknowledge receiving the endpoint */
|
||||||
|
while(!init_chan_initialized) {
|
||||||
|
err = event_dispatch(get_default_waitset());
|
||||||
|
if (err_is_fail(err)) {
|
||||||
|
return err_push(err, LIB_ERR_EVENT_DISPATCH);
|
||||||
|
}
|
||||||
|
}
|
||||||
/* initialize init RPC client with lmp channel */
|
/* initialize init RPC client with lmp channel */
|
||||||
|
struct aos_rpc *init_rpc = malloc(sizeof(struct aos_rpc));
|
||||||
|
err = aos_rpc_init(init_rpc);
|
||||||
|
if (err_is_fail(err)){
|
||||||
|
return err_push(err, ERR_NOTIMP);
|
||||||
|
}
|
||||||
/* set init RPC client in our program state */
|
/* set init RPC client in our program state */
|
||||||
|
set_init_rpc(init_rpc);
|
||||||
|
|
||||||
|
// create thread to dispatch events
|
||||||
|
thread_create(event_init_dispatch_thread, NULL);
|
||||||
|
|
||||||
/* TODO MILESTONE 3: now we should have a channel with init set up and can
|
/* TODO MILESTONE 3: now we should have a channel with init set up and can
|
||||||
* use it for the ram allocator */
|
* use it for the ram allocator */
|
||||||
@ -176,7 +260,7 @@ errval_t barrelfish_init_onthread(struct spawn_domain_params *params)
|
|||||||
void barrelfish_init_disabled(dispatcher_handle_t handle, bool init_dom_arg);
|
void barrelfish_init_disabled(dispatcher_handle_t handle, bool init_dom_arg);
|
||||||
void barrelfish_init_disabled(dispatcher_handle_t handle, bool init_dom_arg)
|
void barrelfish_init_disabled(dispatcher_handle_t handle, bool init_dom_arg)
|
||||||
{
|
{
|
||||||
init_domain = init_dom_arg;
|
; init_domain = init_dom_arg;
|
||||||
disp_init_disabled(handle);
|
disp_init_disabled(handle);
|
||||||
thread_init_disabled(handle, init_dom_arg);
|
thread_init_disabled(handle, init_dom_arg);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -330,7 +330,7 @@ errval_t paging_init_state_foreign(struct paging_state *st, lvaddr_t start_vaddr
|
|||||||
errval_t paging_init_params(struct spawn_domain_params *params)
|
errval_t paging_init_params(struct spawn_domain_params *params)
|
||||||
{
|
{
|
||||||
errval_t err;
|
errval_t err;
|
||||||
debug_printf("paging_init\n");
|
// debug_printf("paging_init\n");
|
||||||
// (M2): Call paging_init_state for ¤t
|
// (M2): Call paging_init_state for ¤t
|
||||||
// TODO (M4): initialize self-paging handler
|
// TODO (M4): initialize self-paging handler
|
||||||
// TIP: use thread_set_exception_handler() to setup a page fault handler
|
// TIP: use thread_set_exception_handler() to setup a page fault handler
|
||||||
@ -351,8 +351,8 @@ errval_t paging_init_params(struct spawn_domain_params *params)
|
|||||||
if(params != NULL && params->vspace_buf != NULL) {
|
if(params != NULL && params->vspace_buf != NULL) {
|
||||||
current.l0_pt = **(struct pt_t **)params->vspace_buf;
|
current.l0_pt = **(struct pt_t **)params->vspace_buf;
|
||||||
current.vaddr_head = **(struct pt_vaddr_reg_t **)(params->vspace_buf + sizeof(struct pt_t *));
|
current.vaddr_head = **(struct pt_vaddr_reg_t **)(params->vspace_buf + sizeof(struct pt_t *));
|
||||||
debug_printf("Received initial paging state:\n");
|
// debug_printf("Received initial paging state:\n");
|
||||||
pt_print_state(¤t);
|
// pt_print_state(¤t);
|
||||||
}
|
}
|
||||||
|
|
||||||
set_current_paging_state(¤t);
|
set_current_paging_state(¤t);
|
||||||
|
|||||||
@ -8,15 +8,24 @@
|
|||||||
void do_test_spawn(void) {
|
void do_test_spawn(void) {
|
||||||
// spawn multiple processes
|
// spawn multiple processes
|
||||||
|
|
||||||
struct spawninfo si[PROCESS_COUNT];
|
struct spawninfo *si = malloc(PROCESS_COUNT * sizeof(struct spawninfo));
|
||||||
domainid_t pid[PROCESS_COUNT];
|
domainid_t *pid = malloc(PROCESS_COUNT * sizeof(domainid_t));
|
||||||
for(uint i = 0; i < PROCESS_COUNT; ++i) {
|
for(uint i = 0; i < PROCESS_COUNT; ++i) {
|
||||||
debug_printf("TEST_SPAWN: spawn %u\n", i);
|
debug_printf("TEST_SPAWN: spawn %u\n", i);
|
||||||
CHECK_ERR(spawn_load_by_name("hello", &(si[i]), &(pid[i])));
|
CHECK_ERR(spawn_load_by_name("hello", &(si[i]), &(pid[i])));
|
||||||
}
|
}
|
||||||
|
|
||||||
// wait for 10 seconds before continuing
|
// wait for 10 seconds but handle events in the mean time
|
||||||
time_wait_ms(10000);
|
struct waitset *default_ws = get_default_waitset();
|
||||||
|
struct timespec tt;
|
||||||
|
clock_gettime(CLOCK_REALTIME, &tt);
|
||||||
|
long start = time_to_ms(tt);
|
||||||
|
do {
|
||||||
|
if(err_is_ok(check_for_event(default_ws))){
|
||||||
|
CHECK_ERR(event_dispatch(default_ws));
|
||||||
|
}
|
||||||
|
clock_gettime(CLOCK_REALTIME, &tt);
|
||||||
|
} while(time_to_ms(tt) - start < 10000);
|
||||||
|
|
||||||
for(uint i = 0; i < PROCESS_COUNT; ++i) {
|
for(uint i = 0; i < PROCESS_COUNT; ++i) {
|
||||||
debug_printf("TEST_SPAWN: Killing %u\n", i);
|
debug_printf("TEST_SPAWN: Killing %u\n", i);
|
||||||
|
|||||||
@ -55,24 +55,3 @@ long
|
|||||||
time_to_ms(struct timespec tt) {
|
time_to_ms(struct timespec tt) {
|
||||||
return tt.tv_sec * 1000 + tt.tv_nsec / 1000 / 1000;
|
return tt.tv_sec * 1000 + tt.tv_nsec / 1000 / 1000;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* \brief Wait for ms milliseconds before returning.
|
|
||||||
*
|
|
||||||
* \param ms Duration to wait
|
|
||||||
*
|
|
||||||
* Very ugly and approximate but useful
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
time_wait_ms(unsigned long ms) {
|
|
||||||
struct timespec tt;
|
|
||||||
|
|
||||||
clock_gettime(CLOCK_REALTIME, &tt);
|
|
||||||
long start = time_to_ms(tt);
|
|
||||||
long now;
|
|
||||||
do {
|
|
||||||
clock_gettime(CLOCK_REALTIME, &tt);
|
|
||||||
now = time_to_ms(tt);
|
|
||||||
} while(start + ms > now);
|
|
||||||
}
|
|
||||||
@ -140,7 +140,7 @@ struct mem_region *multiboot_find_module(struct bootinfo *bi, const char *name)
|
|||||||
snprintf(pathname, len, "/armv8/sbin/%s", name);
|
snprintf(pathname, len, "/armv8/sbin/%s", name);
|
||||||
name = pathname;
|
name = pathname;
|
||||||
}
|
}
|
||||||
DEBUG_PRINTF("name is: %s\n", name);
|
// DEBUG_PRINTF("name is: %s\n", name);
|
||||||
for(size_t i = 0; i < bi->regions_length; i++) {
|
for(size_t i = 0; i < bi->regions_length; i++) {
|
||||||
struct mem_region *region = &bi->regions[i];
|
struct mem_region *region = &bi->regions[i];
|
||||||
const char *modname = multiboot_module_name(region);
|
const char *modname = multiboot_module_name(region);
|
||||||
|
|||||||
@ -47,9 +47,45 @@ static void armv8_set_registers(void *arch_load_info,
|
|||||||
disabled_area->regs[REG_OFFSET(PIC_REGISTER)] = got_base;
|
disabled_area->regs[REG_OFFSET(PIC_REGISTER)] = got_base;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void handle_child_recv(void *arg) {
|
||||||
|
errval_t err;
|
||||||
|
struct lmp_chan *init_chan = (struct lmp_chan *)arg;
|
||||||
|
|
||||||
|
struct lmp_recv_msg msg = LMP_RECV_MSG_INIT;
|
||||||
|
struct capref cap;
|
||||||
|
|
||||||
|
err = lmp_chan_recv(init_chan, &msg, &cap);
|
||||||
|
if (err_is_fail(err)) {
|
||||||
|
if (lmp_err_is_transient(err)) {
|
||||||
|
err = lmp_endpoint_register(init_chan->endpoint, get_default_waitset(), MKCLOSURE(handle_child_recv, init_chan));
|
||||||
|
if (err_is_fail(err)) {
|
||||||
|
USER_PANIC_ERR(err, "Could not reregister after failed init_chan cap receive");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
USER_PANIC_ERR(err, "Failure in child channel");
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch(msg.words[0]){
|
||||||
|
case RPC_MTYPE_CHILD_ENDPOINT:
|
||||||
|
debug_printf("SPAWN: Received child init_chan endpoint\n");
|
||||||
|
init_chan->remote_cap = cap;
|
||||||
|
err = lmp_chan_send1(init_chan, LMP_FLAG_YIELD | LMP_FLAG_SYNC, NULL_CAP, RPC_MTYPE_CHILD_ENDPOINT_OK);
|
||||||
|
if (err_is_fail(err)) {
|
||||||
|
USER_PANIC_ERR(err, "Failed to send RPC_MTYPE_CHILD_ENDPOINT_OK");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
USER_PANIC("Unknown rpc message type.");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
err = lmp_endpoint_register(init_chan->endpoint, get_default_waitset(), MKCLOSURE(handle_child_recv, init_chan));
|
||||||
|
if (err_is_fail(err)) {
|
||||||
|
USER_PANIC_ERR(err, "Could not reregister after failed init_chan cap receive");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
struct temp_mapping {
|
struct temp_mapping {
|
||||||
struct temp_mapping *next;
|
struct temp_mapping *next;
|
||||||
@ -276,7 +312,7 @@ static errval_t spawn_serialize_vspace(struct spawninfo *si, struct paging_state
|
|||||||
|
|
||||||
assert(curr_offset <= total_space);
|
assert(curr_offset <= total_space);
|
||||||
|
|
||||||
debug_printf("SPAWN: Passing vspace info at 0x%lx\n", vspace_buf_child);
|
// debug_printf("SPAWN: Passing vspace info at 0x%lx\n", vspace_buf_child);
|
||||||
domain_params->vspace_buf = vspace_buf_child;
|
domain_params->vspace_buf = vspace_buf_child;
|
||||||
domain_params->vspace_buf_len = total_space;
|
domain_params->vspace_buf_len = total_space;
|
||||||
|
|
||||||
@ -315,11 +351,11 @@ errval_t spawn_load_argv(int argc, char *argv[], struct spawninfo *si,
|
|||||||
// - Get the module from the multiboot image
|
// - Get the module from the multiboot image
|
||||||
// and map it (take a look at multiboot.c)
|
// and map it (take a look at multiboot.c)
|
||||||
|
|
||||||
debug_printf("[spawn_load_argv]: argc: %d, argv: ", argc);
|
// debug_printf("[spawn_load_argv]: argc: %d, argv: ", argc);
|
||||||
for (int i = 0; i < argc; ++i) {
|
// for (int i = 0; i < argc; ++i) {
|
||||||
printf("\"%s\", ", argv[i]);
|
// printf("\"%s\", ", argv[i]);
|
||||||
}
|
// }
|
||||||
printf("\n");
|
// printf("\n");
|
||||||
|
|
||||||
assert(argc > 0);
|
assert(argc > 0);
|
||||||
assert(argc < MAX_CMDLINE_ARGS);
|
assert(argc < MAX_CMDLINE_ARGS);
|
||||||
@ -405,9 +441,15 @@ errval_t spawn_load_argv(int argc, char *argv[], struct spawninfo *si,
|
|||||||
if (err_is_fail(err)) return err_push(err, LIB_ERR_CAP_COPY_FAIL);
|
if (err_is_fail(err)) return err_push(err, LIB_ERR_CAP_COPY_FAIL);
|
||||||
|
|
||||||
err = cap_retype(si->cspace_cap_selfep, si->cspace_cap_dispatcher, 0, ObjType_EndPointLMP, 0, 1);
|
err = cap_retype(si->cspace_cap_selfep, si->cspace_cap_dispatcher, 0, ObjType_EndPointLMP, 0, 1);
|
||||||
if (err_is_fail(err)) return err;
|
if (err_is_fail(err)) return err_push(err, SPAWN_ERR_CREATE_SELFEP);
|
||||||
err = cap_copy(si->cspace_cap_initep, cap_selfep);
|
|
||||||
|
// give the child an endpoint to talk to init
|
||||||
|
lmp_chan_init(&si->init_chan);
|
||||||
|
err = endpoint_create(DEFAULT_LMP_BUF_WORDS, &si->init_chan.local_cap, &si->init_chan.endpoint);
|
||||||
|
if (err_is_fail(err)) return err_push(err, LIB_ERR_ENDPOINT_CREATE);
|
||||||
|
err = cap_copy(si->cspace_cap_initep, si->init_chan.local_cap);
|
||||||
if (err_is_fail(err)) return err_push(err, LIB_ERR_CAP_COPY_FAIL);
|
if (err_is_fail(err)) return err_push(err, LIB_ERR_CAP_COPY_FAIL);
|
||||||
|
si->init_chan.remote_cap = NULL_CAP;
|
||||||
|
|
||||||
// - Setup the child's vspace
|
// - Setup the child's vspace
|
||||||
// afeer: create level 0 page table
|
// afeer: create level 0 page table
|
||||||
@ -441,8 +483,8 @@ errval_t spawn_load_argv(int argc, char *argv[], struct spawninfo *si,
|
|||||||
got_addr = got_shdr->sh_addr;
|
got_addr = got_shdr->sh_addr;
|
||||||
}
|
}
|
||||||
|
|
||||||
debug_printf("SPAWN: self paging state after loading:\n");
|
// debug_printf("SPAWN: self paging state after loading:\n");
|
||||||
pt_print_state(get_current_paging_state());
|
// pt_print_state(get_current_paging_state());
|
||||||
|
|
||||||
err = paging_unmap(get_current_paging_state(), elf_base);
|
err = paging_unmap(get_current_paging_state(), elf_base);
|
||||||
if (err_is_fail(err)) return err_push(err, LIB_ERR_PMAP_UNMAP);
|
if (err_is_fail(err)) return err_push(err, LIB_ERR_PMAP_UNMAP);
|
||||||
@ -454,8 +496,8 @@ errval_t spawn_load_argv(int argc, char *argv[], struct spawninfo *si,
|
|||||||
free(tm);
|
free(tm);
|
||||||
}
|
}
|
||||||
|
|
||||||
debug_printf("SPAWN: self paging state after unmapping:\n");
|
// debug_printf("SPAWN: self paging state after unmapping:\n");
|
||||||
pt_print_state(get_current_paging_state());
|
// pt_print_state(get_current_paging_state());
|
||||||
|
|
||||||
// - Setup the dispatcher
|
// - Setup the dispatcher
|
||||||
err = frame_create(si->cspace_cap_dispframe, DISPATCHER_FRAME_SIZE, NULL);
|
err = frame_create(si->cspace_cap_dispframe, DISPATCHER_FRAME_SIZE, NULL);
|
||||||
@ -569,6 +611,11 @@ errval_t spawn_load_argv(int argc, char *argv[], struct spawninfo *si,
|
|||||||
err = paging_unmap(get_current_paging_state(), arguments_page_in_self);
|
err = paging_unmap(get_current_paging_state(), arguments_page_in_self);
|
||||||
if (err_is_fail(err)) return err_push(err, LIB_ERR_PMAP_UNMAP);
|
if (err_is_fail(err)) return err_push(err, LIB_ERR_PMAP_UNMAP);
|
||||||
|
|
||||||
|
// Receive the child's endpoint for the init channel
|
||||||
|
lmp_chan_alloc_recv_slot(&si->init_chan);
|
||||||
|
err = lmp_endpoint_register(si->init_chan.endpoint, get_default_waitset(), MKCLOSURE(handle_child_recv, &si->init_chan));
|
||||||
|
if (err_is_fail(err)) return err;
|
||||||
|
|
||||||
// - Make the new dispatcher runnable
|
// - Make the new dispatcher runnable
|
||||||
err = invoke_dispatcher(
|
err = invoke_dispatcher(
|
||||||
si->dispatcher, cap_dispatcher,
|
si->dispatcher, cap_dispatcher,
|
||||||
|
|||||||
@ -16,9 +16,9 @@
|
|||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <time.h>
|
|
||||||
|
|
||||||
#include <aos/aos.h>
|
#include <aos/aos.h>
|
||||||
|
#include <aos/deferred.h>
|
||||||
|
|
||||||
#define HELLO_CATCH_COMMAND "catch"
|
#define HELLO_CATCH_COMMAND "catch"
|
||||||
|
|
||||||
@ -37,7 +37,7 @@ int main(int argc, char *argv[])
|
|||||||
while(1) {
|
while(1) {
|
||||||
printf("Catch me if you can! %d\n", iter);
|
printf("Catch me if you can! %d\n", iter);
|
||||||
// wait for 1 second
|
// wait for 1 second
|
||||||
time_wait_ms(1000);
|
barrelfish_usleep(1000000);
|
||||||
++iter;
|
++iter;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -53,6 +53,9 @@ bsp_main(int argc, char *argv[]) {
|
|||||||
|
|
||||||
// TODO: initialize mem allocator, vspace management here
|
// TODO: initialize mem allocator, vspace management here
|
||||||
|
|
||||||
|
err = cap_retype(cap_selfep, cap_dispatcher, 0, ObjType_EndPointLMP, 0, 1);
|
||||||
|
if (err_is_fail(err)) return err;
|
||||||
|
|
||||||
// Grading
|
// Grading
|
||||||
grading_test_early();
|
grading_test_early();
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user