diff --git a/CMakeLists.txt b/CMakeLists.txt index 95b3ecc..d1975da 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -85,7 +85,7 @@ add_framework(photon STATIC SHARED HEADERS ${CMAKE_CURRENT_BINARY_DIR}/sysroot/usr/include/*) bundle_compile_options(photon PRIVATE -ffreestanding -nostdlib -fPIC -fPIE) -bundle_link_libraries(photon ${photon_platform_libs} -ffreestanding) +bundle_link_libraries(photon ${photon_platform_libs} -ffreestanding -nostdlib) bundle_link_frameworks(photon ${photon_platform_frameworks}) bundle_include_directories(photon PRIVATE diff --git a/photon/libc/sys/magenta/fio.c b/photon/libc/sys/magenta/fio.c index 59855d3..2b56c89 100644 --- a/photon/libc/sys/magenta/fio.c +++ b/photon/libc/sys/magenta/fio.c @@ -1,3 +1,4 @@ +#include #include #include "sys/types.h" #include "__fio.h" @@ -59,7 +60,8 @@ unsigned int __fio_read(struct __io_file *f, char *buf, unsigned int sz) unsigned int __fio_write(struct __io_file *f, const char *buf, unsigned int sz) { - return 0; + mx_console_write(buf, sz); + return sz; } int __fio_ungetc(struct __io_file *f, char c) diff --git a/photon/libc/sys/magenta/init.c b/photon/libc/sys/magenta/init.c index 613d2ff..644c827 100644 --- a/photon/libc/sys/magenta/init.c +++ b/photon/libc/sys/magenta/init.c @@ -1,11 +1,160 @@ +#include +#include +#include +#include +#include +#include +#include "sys/handles.h" #include "__init.h" #include "__heap.h" #include "__fio.h" +struct handles { + mx_handle_t task_self; + mx_handle_t task_vmar; + mx_handle_t exec_vmar; + mx_handle_t stack_vmo; + mx_handle_t vdso_vmo; + mx_handle_t exec_vmo; + mx_handle_t ldsvc; + mx_handle_t bootstrap; +}; + +static struct handles rt_handles; + extern int main(int, const char **); -/* TODO magenta/procargs.h protocol */ -int __crt_init(void *arg) +static void parse_args( + mx_bootstrap_msg_t *args, mx_handle_t *handles, + const char **argv, const char **envp, int hndc, struct handles *out) { - return main(0, 0); + if (args->args_num > 0) { + char *arg_buf = (char *)args + args->args_off; + int arg_i = 0; + int arg_off = 0; + + for (int i = 0; ; i++) { + if (arg_buf[i] == '\0') { + argv[arg_i++] = arg_buf + arg_off; + arg_off = i + 1; + } + + if (arg_i == (int)args->args_num) { + break; + } + } + } + + if (args->environ_num > 0) { + char *env_buf = (char *)args + args->environ_off; + int env_i = 0; + int env_off = 0; + + for (int i = 0; ; i++) { + if (env_buf[i] == '\0') { + envp[env_i++] = env_buf + env_off; + env_off = i + 1; + } + + if (env_i == (int)args->environ_num) { + break; + } + } + } + + uint32_t *hent = (uint32_t *)((char *)args + args->handle_info_off); + + for (int i = 0; i < hndc; i++) { + switch (MX_B_HND_TYPE(hent[i])) { + case MX_B_TASK_SELF: + out->task_self = handles[i]; + break; + case MX_B_VMO_VDSO: + out->vdso_vmo = handles[i]; + break; + case MX_B_VMO_STACK: + out->stack_vmo = handles[i]; + break; + case MX_B_VMAR_ROOT: + out->task_vmar = handles[i]; + break; + case MX_B_VMAR_EXEC: + out->exec_vmar = handles[i]; + break; + case MX_B_VMO_EXECUTABLE: + out->exec_vmo = handles[i]; + break; + case MX_B_TUNNEL_LDSVC: + out->ldsvc = handles[i]; + break; +#if 0 + case MX_B_VMO_BOOTDATA: + out->bootfs_vmo = handles[i]; + break; +#endif + default: + break; + } + } } + +static void hang() +{ + while (1) { + mx_nanosleep(mx_deadline_after(MX_SEC(1))); + } +} + +int __crt_init(mx_handle_t bootstrap) +{ + size_t msg_size = 0; + size_t nr_handles = 0; + mx_status_t status = mx_tunnel_read(bootstrap, NULL, 0, NULL, 0, &msg_size, &nr_handles); + + if (status != MX_OK) { + /* TODO replace with a better error handler */ + printf("error: cannot read bootstrap message from handle %lx (error %d)\n", + bootstrap, status); + hang(); + } + + unsigned char msg_buf[msg_size]; + mx_handle_t handles[nr_handles]; + mx_tunnel_read(bootstrap, msg_buf, msg_size, handles, nr_handles, &msg_size, &nr_handles); + + mx_bootstrap_msg_t *msg = (mx_bootstrap_msg_t *)msg_buf; + + const char *argv[msg->args_num]; + const char *envp[msg->environ_num]; + + parse_args(msg, handles, argv, envp, nr_handles, &rt_handles); + rt_handles.bootstrap = bootstrap; + + int ret = main(msg->args_num, argv); + mx_task_kill(rt_handles.task_self, ret); + + /* unreachable */ + hang(); + return 0; +} + +mx_handle_t m_get_handle(unsigned int type) +{ + switch (type) { + case M_HND_VMAR_ROOT: + return rt_handles.task_vmar; + case M_HND_VMAR_EXEC: + return rt_handles.exec_vmar; + case M_HND_VMO_EXEC: + return rt_handles.exec_vmo; + case M_HND_VMO_VDSO: + return rt_handles.vdso_vmo; + case M_HND_TNL_LDSVC: + return rt_handles.ldsvc; + case M_HND_TNL_BTSTP: + return rt_handles.bootstrap; + default: + return MX_NULL_HANDLE; + } +} + diff --git a/photon/libc/sys/magenta/machine/x86_64/crt0.s b/photon/libc/sys/magenta/machine/x86_64/crt0.s index 01f97e2..a5608c1 100644 --- a/photon/libc/sys/magenta/machine/x86_64/crt0.s +++ b/photon/libc/sys/magenta/machine/x86_64/crt0.s @@ -11,8 +11,7 @@ _start: mov %rsp, %rsi andq $-16, %rsp call __crt_init - movq %rax, %rdx - movq $1, %rsi /* MX_EXIT_ALL_THREADS */ - movq $0, %rdi /* MX_NULL_HANDLE */ - movq $1, %rax /* mx_process_kill() */ - syscall + + # unreachable; __crt_init() will call mx_task_kill() +.loop: + jmp .loop diff --git a/photon/libc/sys/magenta/sys/handles.h b/photon/libc/sys/magenta/sys/handles.h new file mode 100644 index 0000000..8df53d4 --- /dev/null +++ b/photon/libc/sys/magenta/sys/handles.h @@ -0,0 +1,15 @@ +#ifndef SYS_MAGENTA_SYS_HANDLES_H_ +#define SYS_MAGENTA_SYS_HANDLES_H_ + +#include + +#define M_HND_VMAR_ROOT 0x01u +#define M_HND_VMAR_EXEC 0x02u +#define M_HND_VMO_EXEC 0x03u +#define M_HND_VMO_VDSO 0x04u +#define M_HND_TNL_LDSVC 0x05u +#define M_HND_TNL_BTSTP 0x06u + +extern mx_handle_t m_get_handle(unsigned int type); + +#endif