forked from M-Labs/artiq
runtime: avoid race condition when running kernel.
Also, don't bother passing kernel name: entry point is already recorded in DT_INIT when the kernel is linked.
This commit is contained in:
parent
1a969aa9e4
commit
b5cf1e395d
|
@ -130,10 +130,9 @@ class CommGeneric:
|
||||||
if ty != _D2HMsgType.LOAD_COMPLETED:
|
if ty != _D2HMsgType.LOAD_COMPLETED:
|
||||||
raise IOError("Incorrect reply from device: "+str(ty))
|
raise IOError("Incorrect reply from device: "+str(ty))
|
||||||
|
|
||||||
def run(self, kname):
|
def run(self):
|
||||||
self._write_header(len(kname) + 9, _H2DMsgType.RUN_KERNEL)
|
self._write_header(9, _H2DMsgType.RUN_KERNEL)
|
||||||
self.write(bytes(kname, "ascii"))
|
logger.debug("running kernel")
|
||||||
logger.debug("running kernel: %s", kname)
|
|
||||||
|
|
||||||
def flash_storage_read(self, key):
|
def flash_storage_read(self, key):
|
||||||
self._write_header(9+len(key), _H2DMsgType.FLASH_READ_REQUEST)
|
self._write_header(9+len(key), _H2DMsgType.FLASH_READ_REQUEST)
|
||||||
|
|
|
@ -30,22 +30,29 @@ void kloader_start_bridge()
|
||||||
start_kernel_cpu(NULL);
|
start_kernel_cpu(NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int load_or_start_kernel(void *library, const char *kernel)
|
static int load_or_start_kernel(void *library, int run_kernel)
|
||||||
{
|
{
|
||||||
static struct dyld_info library_info;
|
static struct dyld_info library_info;
|
||||||
struct msg_load_request request = {
|
struct msg_load_request request = {
|
||||||
.library = library,
|
.library = library,
|
||||||
.library_info = &library_info,
|
.library_info = &library_info,
|
||||||
.kernel = kernel,
|
.run_kernel = run_kernel,
|
||||||
};
|
};
|
||||||
start_kernel_cpu(&request);
|
start_kernel_cpu(&request);
|
||||||
|
|
||||||
struct msg_load_reply *reply = mailbox_wait_and_receive();
|
struct msg_load_reply *reply = mailbox_wait_and_receive();
|
||||||
if(reply != NULL && reply->type == MESSAGE_TYPE_LOAD_REPLY) {
|
if(reply->type != MESSAGE_TYPE_LOAD_REPLY) {
|
||||||
log("cannot load/run kernel: %s", reply->error);
|
log("BUG: unexpected reply to load/run request");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(reply->error != NULL) {
|
||||||
|
log("cannot load kernel: %s", reply->error);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
mailbox_acknowledge();
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -56,12 +63,12 @@ int kloader_load_library(void *library)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return load_or_start_kernel(library, NULL);
|
return load_or_start_kernel(library, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
int kloader_start_kernel(const char *name)
|
void kloader_start_kernel()
|
||||||
{
|
{
|
||||||
return load_or_start_kernel(NULL, name);
|
load_or_start_kernel(NULL, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
int kloader_start_idle_kernel(void)
|
int kloader_start_idle_kernel(void)
|
||||||
|
@ -74,7 +81,7 @@ int kloader_start_idle_kernel(void)
|
||||||
if(length <= 0)
|
if(length <= 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
return load_or_start_kernel(buffer, "test.__modinit__");
|
return load_or_start_kernel(buffer, 1);
|
||||||
#else
|
#else
|
||||||
return 0;
|
return 0;
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -12,7 +12,7 @@ int kloader_load_library(void *code);
|
||||||
|
|
||||||
void kloader_start_bridge(void);
|
void kloader_start_bridge(void);
|
||||||
int kloader_start_idle_kernel(void);
|
int kloader_start_idle_kernel(void);
|
||||||
int kloader_start_kernel(const char *name);
|
void kloader_start_kernel(void);
|
||||||
void kloader_stop(void);
|
void kloader_stop(void);
|
||||||
|
|
||||||
int kloader_validate_kpointer(void *p);
|
int kloader_validate_kpointer(void *p);
|
||||||
|
|
|
@ -184,51 +184,37 @@ void exception_handler(unsigned long vect, unsigned long *regs,
|
||||||
int main(void);
|
int main(void);
|
||||||
int main(void)
|
int main(void)
|
||||||
{
|
{
|
||||||
struct msg_load_request *msg = mailbox_receive();
|
struct msg_load_request *request = mailbox_receive();
|
||||||
|
struct msg_load_reply load_reply = {
|
||||||
|
.type = MESSAGE_TYPE_LOAD_REPLY,
|
||||||
|
.error = NULL
|
||||||
|
};
|
||||||
|
|
||||||
if(msg == NULL) {
|
if(request == NULL) {
|
||||||
bridge_main();
|
bridge_main();
|
||||||
while(1);
|
while(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(msg->library != NULL) {
|
if(request->library != NULL) {
|
||||||
const char *error;
|
if(!dyld_load(request->library, KERNELCPU_PAYLOAD_ADDRESS,
|
||||||
if(!dyld_load(msg->library, KERNELCPU_PAYLOAD_ADDRESS,
|
resolve_runtime_export, request->library_info,
|
||||||
resolve_runtime_export, msg->library_info, &error)) {
|
&load_reply.error)) {
|
||||||
struct msg_load_reply msg = {
|
mailbox_send(&load_reply);
|
||||||
.type = MESSAGE_TYPE_LOAD_REPLY,
|
|
||||||
.error = error
|
|
||||||
};
|
|
||||||
mailbox_send(&msg);
|
|
||||||
while(1);
|
while(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void (*kernel)(void) = NULL;
|
if(request->run_kernel) {
|
||||||
if(msg->kernel != NULL) {
|
void (*kernel_init)() = request->library_info->init;
|
||||||
kernel = dyld_lookup(msg->kernel, msg->library_info);
|
|
||||||
if(kernel == NULL) {
|
|
||||||
char error[256];
|
|
||||||
snprintf(error, sizeof(error),
|
|
||||||
"kernel '%s' not found in library", msg->kernel);
|
|
||||||
struct msg_load_reply msg = {
|
|
||||||
.type = MESSAGE_TYPE_LOAD_REPLY,
|
|
||||||
.error = error
|
|
||||||
};
|
|
||||||
mailbox_send(&msg);
|
|
||||||
while(1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
mailbox_acknowledge();
|
mailbox_send_and_wait(&load_reply);
|
||||||
|
kernel_init();
|
||||||
|
|
||||||
if(kernel) {
|
struct msg_base finished_reply;
|
||||||
void (*run_closure)(void *) = msg->library_info->init;
|
finished_reply.type = MESSAGE_TYPE_FINISHED;
|
||||||
run_closure(kernel);
|
mailbox_send_and_wait(&finished_reply);
|
||||||
|
} else {
|
||||||
struct msg_base msg;
|
mailbox_send(&load_reply);
|
||||||
msg.type = MESSAGE_TYPE_FINISHED;
|
|
||||||
mailbox_send_and_wait(&msg);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
while(1);
|
while(1);
|
||||||
|
|
|
@ -39,7 +39,7 @@ struct msg_base {
|
||||||
struct msg_load_request {
|
struct msg_load_request {
|
||||||
void *library;
|
void *library;
|
||||||
struct dyld_info *library_info;
|
struct dyld_info *library_info;
|
||||||
const char *kernel;
|
int run_kernel;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct msg_load_reply {
|
struct msg_load_reply {
|
||||||
|
|
|
@ -184,21 +184,8 @@ static int process_input(void)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if((buffer_in_index + 1) > BUFFER_OUT_SIZE) {
|
|
||||||
log("Kernel name too long");
|
|
||||||
buffer_out[8] = REMOTEMSG_TYPE_KERNEL_STARTUP_FAILED;
|
|
||||||
submit_output(9);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
buffer_in[buffer_in_index] = 0;
|
|
||||||
|
|
||||||
watchdog_init();
|
watchdog_init();
|
||||||
if(!kloader_start_kernel((char *)&buffer_in[9])) {
|
kloader_start_kernel();
|
||||||
log("Failed to find kernel entry point '%s' in object", &buffer_in[9]);
|
|
||||||
buffer_out[8] = REMOTEMSG_TYPE_KERNEL_STARTUP_FAILED;
|
|
||||||
submit_output(9);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
user_kernel_state = USER_KERNEL_RUNNING;
|
user_kernel_state = USER_KERNEL_RUNNING;
|
||||||
break;
|
break;
|
||||||
|
|
Loading…
Reference in New Issue