diff --git a/src/kernel/boot/loader/Jamfile b/src/kernel/boot/loader/Jamfile index 5ee6614916..7fb46eb8a4 100644 --- a/src/kernel/boot/loader/Jamfile +++ b/src/kernel/boot/loader/Jamfile @@ -34,6 +34,7 @@ KernelStaticLibrary boot_loader : elf.cpp menu.cpp loader.cpp + kernel_args.cpp # utils list.c diff --git a/src/kernel/boot/loader/elf.cpp b/src/kernel/boot/loader/elf.cpp index 60cea362d8..65c139b685 100644 --- a/src/kernel/boot/loader/elf.cpp +++ b/src/kernel/boot/loader/elf.cpp @@ -1,5 +1,5 @@ /* -** Copyright 2002-2003, Axel Dörfler, axeld@pinc-software.de. All rights reserved. +** Copyright 2002-2004, Axel Dörfler, axeld@pinc-software.de. All rights reserved. ** Distributed under the terms of the OpenBeOS License. */ @@ -15,8 +15,8 @@ #include #include -#define TRACE_ELF 1 -#if TRACE_ELF +//#define TRACE_ELF +#ifdef TRACE_ELF # define TRACE(x) dprintf x #else # define TRACE(x) ; @@ -181,7 +181,7 @@ elf_load_image(Directory *directory, const char *path) if (fd < 0) return fd; - image = (preloaded_image *)malloc(sizeof(preloaded_image)); + image = (preloaded_image *)kernel_args_malloc(sizeof(preloaded_image)); if (image == NULL) { close(fd); return B_NO_MEMORY; @@ -195,7 +195,7 @@ elf_load_image(Directory *directory, const char *path) image->next = gKernelArgs.preloaded_images; gKernelArgs.preloaded_images = image; } else - free(image); + kernel_args_free(image); close(fd); return B_OK; diff --git a/src/kernel/boot/loader/kernel_args.cpp b/src/kernel/boot/loader/kernel_args.cpp new file mode 100644 index 0000000000..91f62d809b --- /dev/null +++ b/src/kernel/boot/loader/kernel_args.cpp @@ -0,0 +1,80 @@ +/* +** Copyright 2004, Axel Dörfler, axeld@pinc-software.de. All rights reserved. +** Distributed under the terms of the OpenBeOS License. +*/ + + +#include + +#include +#include + + +static const size_t kChunkSize = 16384; + +kernel_args gKernelArgs; + +static void *sFirstFree; +static void *sLast; +static size_t sFree = kChunkSize; + + +/** This function can be used to allocate memory that is going + * to be passed over to the kernel. For example, the preloaded_image + * structures are allocated this way. + * The boot loader heap doesn't make it into the kernel! + */ + +extern "C" void * +kernel_args_malloc(size_t size) +{ + if (sFirstFree != NULL && size <= sFree) { + // there is enough space in the current buffer + void *address = sFirstFree; + sFirstFree = (void *)((addr_t)sFirstFree + size); + sLast = address; + sFree -= size; + + return address; + } + + if (size > kChunkSize / 2 && sFree < size) { + // the block is so large, we'll allocate a new block for it + void *block = NULL; + if (platform_allocate_region(&block, size, B_READ_AREA | B_WRITE_AREA) != B_OK) + return NULL; + + return block; + } + + // just allocate a new block and "close" the old one + void *block = NULL; + if (platform_allocate_region(&block, kChunkSize, B_READ_AREA | B_WRITE_AREA) != B_OK) + return NULL; + + sFirstFree = (void *)((addr_t)block + size); + sLast = block; + sFree = kChunkSize - size; + + return block; +} + + +/** This function frees a block allocated via kernel_args_malloc(). + * It's very simple; it can only free the last allocation. It's + * enough for its current usage in the boot loader, though. + */ + +extern "C" void +kernel_args_free(void *block) +{ + if (sLast != block) { + // sorry, we're dumb + return; + } + + sFree = (addr_t)sFirstFree - (addr_t)sLast; + sFirstFree = block; + sLast = NULL; +} + diff --git a/src/kernel/boot/loader/loader.cpp b/src/kernel/boot/loader/loader.cpp index 47dd3ceda5..5d3e5d247f 100644 --- a/src/kernel/boot/loader/loader.cpp +++ b/src/kernel/boot/loader/loader.cpp @@ -26,6 +26,8 @@ // temp. VFS API extern Node *get_node_from(int fd); +addr_t gKernelEntry; + bool is_bootable(Directory *volume) diff --git a/src/kernel/boot/loader/main.cpp b/src/kernel/boot/loader/main.cpp index 6d39bf8eca..692ab45478 100644 --- a/src/kernel/boot/loader/main.cpp +++ b/src/kernel/boot/loader/main.cpp @@ -16,18 +16,14 @@ #include -#define TRACE_MAIN 0 -#if TRACE_MAIN +//#define TRACE_MAIN +#ifdef TRACE_MAIN # define TRACE(x) printf x #else # define TRACE(x) ; #endif -kernel_args gKernelArgs; -addr_t gKernelEntry; - - extern "C" int main(stage2_args *args) {