From 39bdbadf398652d036208336af8c3b2f766d4514 Mon Sep 17 00:00:00 2001 From: Ingo Weinhold Date: Fri, 18 May 2007 17:33:21 +0000 Subject: [PATCH] If the boot code couldn't be found in makebootable's resources, it tries to load it from an attribute ("BootCode"). On Darwin we write the boot code into this attribute. This should solve the problem that writing resources into the makebootable file renders it not executable there. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@21170 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- .../platform/bios_ia32/makebootable.cpp | 102 +++++++++++------- .../makebootable/platform/bios_ia32/Jamfile | 12 ++- 2 files changed, 75 insertions(+), 39 deletions(-) diff --git a/src/bin/makebootable/platform/bios_ia32/makebootable.cpp b/src/bin/makebootable/platform/bios_ia32/makebootable.cpp index 8778556353..823d498513 100644 --- a/src/bin/makebootable/platform/bios_ia32/makebootable.cpp +++ b/src/bin/makebootable/platform/bios_ia32/makebootable.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2005-2006, Ingo Weinhold, bonefish@users.sf.net. + * Copyright 2005-2007, Ingo Weinhold, bonefish@users.sf.net. * Distributed under the terms of the MIT License. */ @@ -64,6 +64,7 @@ const char *kUsage = " -safe - Compatibility option. Fail when specified.\n" ; + // print_usage static void print_usage(bool error) @@ -85,6 +86,7 @@ print_usage(bool error) commandName); } + // print_usage_and_exit static void print_usage_and_exit(bool error) @@ -93,6 +95,62 @@ print_usage_and_exit(bool error) exit(error ? 1 : 0); } + +// read_boot_code_data +static uint8 * +read_boot_code_data(const char* programPath) +{ + // open our executable + BFile executableFile; + status_t error = executableFile.SetTo(programPath, B_READ_ONLY); + if (error != B_OK) { + fprintf(stderr, "Error: Failed to open my executable file (\"%s\": " + "%s\n", programPath, strerror(error)); + exit(1); + } + + uint8 *bootCodeData = new uint8[kBootCodeSize]; + + // open our resources + BResources resources; + error = resources.SetTo(&executableFile); + const void *resourceData = NULL; + if (error == B_OK) { + // read the boot block from the resources + size_t resourceSize; + resourceData = resources.LoadResource(B_RAW_TYPE, 666, &resourceSize); + + if (resourceData && resourceSize != (size_t)kBootCodeSize) { + resourceData = NULL; + printf("Warning: Something is fishy with my resources! The boot " + "code doesn't have the correct size. Trying the attribute " + "instead ...\n"); + } + } + + if (resourceData) { + // found boot data in the resources + memcpy(bootCodeData, resourceData, kBootCodeSize); + } else { + // no boot data in the resources; try the attribute + ssize_t bytesRead = executableFile.ReadAttr("BootCode", B_RAW_TYPE, + 0, bootCodeData, kBootCodeSize); + if (bytesRead < 0) { + fprintf(stderr, "Error: Failed to read boot code from resources " + "or attribute."); + exit(1); + } + if (bytesRead != kBootCodeSize) { + fprintf(stderr, "Error: Failed to read boot code from resources, " + "and the boot code in the attribute has the wrong size!"); + exit(1); + } + } + + return bootCodeData; +} + + // write_boot_code_part static void write_boot_code_part(const char *fileName, int fd, const uint8 *bootCodeData, @@ -111,6 +169,7 @@ write_boot_code_part(const char *fileName, int fd, const uint8 *bootCodeData, } } + // main int main(int argc, const char *const *argv) @@ -155,46 +214,15 @@ main(int argc, const char *const *argv) if (fileCount == 0) print_usage_and_exit(true); - // open our executable - BFile resourcesFile; - status_t error = resourcesFile.SetTo(argv[0], B_READ_ONLY); - if (error != B_OK) { - fprintf(stderr, "Error: Failed to open my resources: %s\n", - strerror(error)); + // read the boot code + uint8 *bootCodeData = read_boot_code_data(argv[0]); + if (!bootCodeData) { + fprintf(stderr, "Error: Failed to read "); exit(1); } - // open our resources - BResources resources; - error = resources.SetTo(&resourcesFile); - if (error != B_OK) { - fprintf(stderr, "Error: Failed to read my resources: %s\n", - strerror(error)); - exit(1); - } - - // read the boot block from the resources - size_t resourceSize; - const void *resourceData = resources.LoadResource(B_RAW_TYPE, 666, - &resourceSize); - if (!resourceData) { - fprintf(stderr, - "Error: Failed to read the boot block from my resources!\n"); - exit(1); - } - - if (resourceSize != (size_t)kBootCodeSize) { - fprintf(stderr, - "Error: Something is fishy with my resources! The boot code " - "doesn't have the correct size.\n"); - exit(1); - } - - // clone the boot code data, so that we can modify it - uint8 *bootCodeData = new uint8[kBootCodeSize]; - memcpy(bootCodeData, resourceData, kBootCodeSize); - // iterate through the files and make them bootable + status_t error; for (int i = 0; i < fileCount; i++) { const char *fileName = files[i]; BEntry entry; diff --git a/src/tools/makebootable/platform/bios_ia32/Jamfile b/src/tools/makebootable/platform/bios_ia32/Jamfile index 291fb3fe1d..46217e0942 100644 --- a/src/tools/makebootable/platform/bios_ia32/Jamfile +++ b/src/tools/makebootable/platform/bios_ia32/Jamfile @@ -17,11 +17,19 @@ if $(HOST_PLATFORM) = linux || $(HOST_PLATFORM) = freebsd { DEFINES += _USER_MODE ; } -# write the stage 1 boot loader into the makebootable resources -AddFileDataResource makebootable : RAWT:666:BootCode : stage1.bin ; +# Write the stage 1 boot loader into the makebootable resources. On Darwin +# resources don't seem to work; there we use an attribute instead. +if $(HOST_PLATFORM) != darwin { + AddFileDataResource makebootable : RAWT:666:BootCode : stage1.bin ; +} BuildPlatformMain makebootable : makebootable.cpp $(hostPlatformSources) : $(HOST_LIBBE) $(HOST_LIBSTDC++) $(HOST_LIBSUPC++) ; + +# on Darwin write the boot loader code into an attribute +if $(HOST_PLATFORM) = darwin { + AddFileDataAttribute makebootable : BootCode : raw : stage1.bin ; +}