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
This commit is contained in:
parent
c033041c9f
commit
39bdbadf39
@ -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;
|
||||
|
@ -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 <build>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 <build>makebootable : RAWT:666:BootCode : stage1.bin ;
|
||||
}
|
||||
|
||||
BuildPlatformMain <build>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 <build>makebootable : BootCode : raw : stage1.bin ;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user