// TODO: Every subfunction have a return value. hvmm_status_t khypervisor_init() { hvmm_status_t status; __malloc_init(); memory_init(); if ((status = interrupt_init()) == HVMM_STATUS_UNKNOWN_ERROR) { printf("[%s] interrupt initialization failed\n", __func__); return status; } setup_timer(); if ((status = timer_init(_timer_irq)) == HVMM_STATUS_UNKNOWN_ERROR) { printf("[%s] timer initialization failed\n", __func__); return status; } if ((status = vdev_init()) == HVMM_STATUS_UNKNOWN_ERROR) { printf("[%s] vdev initialization failed\n", __func__); return status; } // FIXME: Currently, testing routines for vdev are failed if ((status = basic_tests_run(PLATFORM_BASIC_TESTS)) == HVMM_STATUS_UNKNOWN_ERROR) { printf("[%s] basic testing failed\n", __func__); //return status; status = HVMM_STATUS_SUCCESS; } return status; }
void __main(void *pcb_ptr) { /* Initialize user task run-time environment */ __malloc_init(); __async_init(); fibril_t *fibril = fibril_setup(); if (fibril == NULL) abort(); __tcb_set(fibril->tcb); /* Save the PCB pointer */ __pcb = (pcb_t *) pcb_ptr; /* The basic run-time environment is setup */ env_setup = true; int argc; char **argv; #ifdef __IN_SHARED_LIBC__ if (__pcb != NULL && __pcb->rtld_runtime != NULL) { runtime_env = (runtime_env_t *) __pcb->rtld_runtime; } #endif /* * Get command line arguments and initialize * standard input and output */ if (__pcb == NULL) { argc = 0; argv = NULL; __stdio_init(0); } else { argc = __pcb->argc; argv = __pcb->argv; __stdio_init(__pcb->filc); (void) chdir(__pcb->cwd); } /* * Run main() and set task return value * according the result */ int retval = main(argc, argv); exit(retval); }
/* * Copyright (c) 2007 Open Kernel Labs, Inc. (Copyright Holder). * All rights reserved. * * 1. Redistribution and use of OKL4 (Software) in source and binary * forms, with or without modification, are permitted provided that the * following conditions are met: * * (a) Redistributions of source code must retain this clause 1 * (including paragraphs (a), (b) and (c)), clause 2 and clause 3 * (Licence Terms) and the above copyright notice. * * (b) Redistributions in binary form must reproduce the above * copyright notice and the Licence Terms in the documentation and/or * other materials provided with the distribution. * * (c) Redistributions in any form must be accompanied by information on * how to obtain complete source code for: * (i) the Software; and * (ii) all accompanying software that uses (or is intended to * use) the Software whether directly or indirectly. Such source * code must: * (iii) either be included in the distribution or be available * for no more than the cost of distribution plus a nominal fee; * and * (iv) be licensed by each relevant holder of copyright under * either the Licence Terms (with an appropriate copyright notice) * or the terms of a licence which is approved by the Open Source * Initative. For an executable file, "complete source code" * means the source code for all modules it contains and includes * associated build and other files reasonably required to produce * the executable. * * 2. THIS SOFTWARE IS PROVIDED ``AS IS'' AND, TO THE EXTENT PERMITTED BY * LAW, ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR * PURPOSE, OR NON-INFRINGEMENT, ARE DISCLAIMED. WHERE ANY WARRANTY IS * IMPLIED AND IS PREVENTED BY LAW FROM BEING DISCLAIMED THEN TO THE * EXTENT PERMISSIBLE BY LAW: (A) THE WARRANTY IS READ DOWN IN FAVOUR OF * THE COPYRIGHT HOLDER (AND, IN THE CASE OF A PARTICIPANT, THAT * PARTICIPANT) AND (B) ANY LIMITATIONS PERMITTED BY LAW (INCLUDING AS TO * THE EXTENT OF THE WARRANTY AND THE REMEDIES AVAILABLE IN THE EVENT OF * BREACH) ARE DEEMED PART OF THIS LICENCE IN A FORM MOST FAVOURABLE TO * THE COPYRIGHT HOLDER (AND, IN THE CASE OF A PARTICIPANT, THAT * PARTICIPANT). IN THE LICENCE TERMS, "PARTICIPANT" INCLUDES EVERY * PERSON WHO HAS CONTRIBUTED TO THE SOFTWARE OR WHO HAS BEEN INVOLVED IN * THE DISTRIBUTION OR DISSEMINATION OF THE SOFTWARE. * * 3. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR ANY OTHER PARTICIPANT BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include <compat/c.h> #include <stdint.h> #include <stdlib.h> #include <threadstate.h> #include <okl4/env.h> #include <okl4/init.h> #include <okl4/types.h> extern void __thread_state_init(void *); void __malloc_init(uintptr_t head_base, uintptr_t heap_end); void __sys_entry(void * env); void __sys_thread_entry(void); int main(int argc, char **argv); #ifdef THREAD_SAFE static struct thread_state __ts; #endif #if defined(OKL4_KERNEL_MICRO) void *_okl4_forced_symbols = &okl4_forced_symbols; #endif /* OKL4_KERNEL_MICRO */ void __sys_entry(void *env) { okl4_env_segment_t *heap; okl4_env_args_t *args; int argc = 0; char **argv = NULL; int result; #if defined(OKL4_KERNEL_MICRO) /* Ensure forced symbols are linked into final binary. * * GCC is too smart for its own good, and compiles away any trivial * reference to 'forced_symbols'. Thus, we need to perform this next * bit of trickiness to confuse the compiler sufficiently to emit * the symbol. */ if ((int)&_okl4_forced_symbols == 1) { for (;;); } #endif /* OKL4_KERNEL_MICRO */ /* Setup environment. */ __okl4_environ = env; /* Get the heap address and size from the environment. */ heap = okl4_env_get_segment("MAIN_HEAP"); assert(heap != NULL); /* Get the command line arguments from the environment. */ args = OKL4_ENV_GET_ARGS("MAIN_ARGS"); if (args != NULL) { argc = args->argc; argv = &args->argv; } /* Initialise heap. */ __malloc_init(heap->virt_addr, heap->virt_addr + heap->size); #ifdef THREAD_SAFE __thread_state_init(&__ts); #endif result = main(argc, argv); exit(result); }
void libc_init() { __malloc_init(&__begin_heap, &__end_heap); __libc_putc = (__fputc_p) &serial_putc; __libc_getc = (__fgetc_p) &serial_getc; }
void libSystem_initializer(int argc, const char* argv[], const char* envp[], const char* apple[], const struct ProgramVars* vars) { static const struct _libkernel_functions libkernel_funcs = { .version = 1, .dlsym = dlsym, .malloc = malloc, .free = free, .realloc = realloc, ._pthread_exit_if_canceled = _pthread_exit_if_canceled, }; static const struct _libpthread_functions libpthread_funcs = { .version = 1, .exit = exit, }; __libkernel_init(&libkernel_funcs, envp, apple, vars); bootstrap_init(); __libplatform_init(NULL, envp, apple, vars); __pthread_init(&libpthread_funcs, envp, apple, vars); __libc_init(vars, libSystem_atfork_prepare, libSystem_atfork_parent, libSystem_atfork_child, apple); // TODO: Move __malloc_init before __libc_init after breaking malloc's upward link to Libc __malloc_init(apple); _dyld_initializer(); libdispatch_init(); _libxpc_initializer(); __stack_logging_early_finished(); /* <rdar://problem/11588042> * C99 standard has the following in section 7.5(3): * "The value of errno is zero at program startup, but is never set * to zero by any library function." */ errno = 0; } /* * libSystem_atfork_{prepare,parent,child}() are called by libc when we fork, then we deal with running fork handlers * for everyone else. */ void libSystem_atfork_prepare(void) { _libSC_info_fork_prepare(); xpc_atfork_prepare(); dispatch_atfork_prepare(); _pthread_fork_prepare(); _malloc_fork_prepare(); } void libSystem_atfork_parent(void) { _malloc_fork_parent(); _pthread_fork_parent(); dispatch_atfork_parent(); xpc_atfork_parent(); _libSC_info_fork_parent(); }
/* * malloc itself. */ void * malloc(size_t size) { struct mheader *mh; uintptr_t i; size_t rightprevblock; if (__heapbase==0) { __malloc_init(); } if (__heapbase==0 || __heaptop==0 || __heapbase > __heaptop) { warnx("malloc: Internal error - local data corrupt"); errx(1, "malloc: heapbase 0x%lx; heaptop 0x%lx", (unsigned long) __heapbase, (unsigned long) __heaptop); } #ifdef MALLOCDEBUG warnx("malloc: about to allocate %lu (0x%lx) bytes", (unsigned long) size, (unsigned long) size); __malloc_dump(); #endif /* Round size up to an integral number of blocks. */ size = ((size + MBLOCKSIZE - 1) & ~(size_t)(MBLOCKSIZE-1)); /* * First-fit search algorithm for available blocks. * Check to make sure the next/previous sizes all agree. */ rightprevblock = 0; for (i=__heapbase; i<__heaptop; i += M_NEXTOFF(mh)) { mh = (struct mheader *) i; if (!M_OK(mh)) { errx(1, "malloc: Heap corrupt; header at 0x%lx" " has bad magic bits", (unsigned long) i); } if (mh->mh_prevblock != rightprevblock) { errx(1, "malloc: Heap corrupt; header at 0x%lx" " has bad previous-block size %lu " "(should be %lu)", (unsigned long) i, (unsigned long) mh->mh_prevblock << MBLOCKSHIFT, (unsigned long) rightprevblock << MBLOCKSHIFT); } rightprevblock = mh->mh_nextblock; /* Can't allocate a block that's in use. */ if (mh->mh_inuse) { continue; } /* Can't allocate a block that isn't big enough. */ if (M_SIZE(mh) < size) { continue; } /* Try splitting block. */ __malloc_split(mh, size); /* * Now, allocate. */ mh->mh_inuse = 1; #ifdef MALLOCDEBUG warnx("malloc: allocating at %p", M_DATA(mh)); __malloc_dump(); #endif return M_DATA(mh); } if (i!=__heaptop) { errx(1, "malloc: Heap corrupt; ran off end"); } /* * Didn't find anything. Expand the heap. */ mh = __malloc_sbrk(size + MBLOCKSIZE); if (mh == NULL) { return NULL; } mh->mh_prevblock = rightprevblock; mh->mh_magic1 = MMAGIC; mh->mh_magic2 = MMAGIC; mh->mh_pad = 0; mh->mh_inuse = 1; mh->mh_nextblock = M_MKFIELD(size + MBLOCKSIZE); #ifdef MALLOCDEBUG warnx("malloc: allocating at %p", M_DATA(mh)); __malloc_dump(); #endif return M_DATA(mh); }