added 14 changesets to branch 'refs/remotes/jessicah-github/efi' old head: 0000000000000000000000000000000000000000 new head: c709aecd4e21ef61c4b85c2fd66685dc73c70e1c overview: https://github.com/jessicah/haiku/compare/c709aec ---------------------------------------------------------------------------- 408525a: Get haiku_loader.efi to show the boot menu. * Lots of debugging added, and blocks of code disabled. 2822d26: Make reboot work. Enable some previously disabled code. 21c2522: haiku_loader: search for matching shortcut in supermenus Fixes #7469. b5ae0c1: Change to warm reboot. d442ee0: Untested, likely broken code for devices.cpp. af3d237: UEFI: Tidy up compilation errors to devices.cpp 8dd0075: UEFI: more debug, getting closer to detecting a BFS partition. 2fe35ee: UEFI: more debug. fix kprintf. 8edf9b3: Fix typo. 37bdcd1: UEFI: maybe better working read function ad7597b: UEFI: lots of debugging, getting closer to mounting a BFS partition. 53beb3a: UEFI: lots more debug, no real progress... e39eb7f: UEFI: More debug and fun. Not sure what to do about MMU. c709aec: UEFI: redo creating the heap [ Jessica Hamilton <jessica.l.hamilton@xxxxxxxxx> ] ---------------------------------------------------------------------------- 24 files changed, 1148 insertions(+), 101 deletions(-) build/jam/ArchitectureRules | 2 +- headers/private/package/hpkg/ReaderImplBase.h | 73 +++- src/kits/package/hpkg/DataReader.cpp | 5 +- src/kits/package/hpkg/PackageReaderImpl.cpp | 88 +++- src/kits/package/hpkg/ReaderImplBase.cpp | 7 +- src/system/boot/loader/Jamfile | 4 +- src/system/boot/loader/file_systems/bfs/bfs.cpp | 4 +- .../loader/file_systems/packagefs/packagefs.cpp | 28 +- src/system/boot/loader/heap.cpp | 26 +- src/system/boot/loader/loader.cpp | 14 +- src/system/boot/loader/main.cpp | 19 +- src/system/boot/loader/menu.cpp | 56 ++- src/system/boot/loader/partitions.cpp | 15 +- src/system/boot/loader/vfs.cpp | 17 +- src/system/boot/platform/efi/Jamfile | 6 +- src/system/boot/platform/efi/acpi.cpp | 280 +++++++++++++ src/system/boot/platform/efi/acpi.h | 22 + src/system/boot/platform/efi/debug.cpp | 27 +- src/system/boot/platform/efi/devices.cpp | 415 +++++++++++++++++++ src/system/boot/platform/efi/efi_platform.h | 1 + src/system/boot/platform/efi/heap.cpp | 68 +++ src/system/boot/platform/efi/menu.cpp | 47 +++ src/system/boot/platform/efi/start.cpp | 18 +- src/system/boot/platform/efi/video.cpp | 7 + ############################################################################ Commit: 408525ab3e7695e956b06608aa8eed3a1e6401bb Author: Jessica Hamilton <jessica.l.hamilton@xxxxxxxxx> Date: Mon Apr 7 05:20:12 2014 UTC Get haiku_loader.efi to show the boot menu. * Lots of debugging added, and blocks of code disabled. ---------------------------------------------------------------------------- diff --git a/build/jam/ArchitectureRules b/build/jam/ArchitectureRules index dcd745d..3bf78d2 100644 --- a/build/jam/ArchitectureRules +++ b/build/jam/ArchitectureRules @@ -695,7 +695,7 @@ rule ArchitectureSetupWarnings architecture EnableWerror src kits ; EnableWerror src preferences ; EnableWerror src servers ; - EnableWerror src system boot ; +# EnableWerror src system boot ; EnableWerror src system kernel ; EnableWerror src system libroot add-ons ; EnableWerror src system libroot os ; diff --git a/src/system/boot/loader/heap.cpp b/src/system/boot/loader/heap.cpp index 8973ee6..af6da19 100644 --- a/src/system/boot/loader/heap.cpp +++ b/src/system/boot/loader/heap.cpp @@ -405,6 +405,8 @@ heap_init(stage2_args* args) void* top; if (platform_init_heap(args, &base, &top) < B_OK) return B_ERROR; + + kprintf("platform_init_heap OK\n"); sHeapBase = base; sHeapEnd = top; @@ -413,17 +415,19 @@ heap_init(stage2_args* args) // declare the whole heap as one chunk, and add it // to the free list FreeChunk* chunk = (FreeChunk*)base; + kprintf("set chunk to max heap size\n"); chunk->SetTo(sMaxHeapSize); + kprintf("insert chunk into free chunk tree\n"); sFreeChunkTree.Insert(chunk); - + kprintf("available = %Lx\n", chunk->Size()); sAvailable = chunk->Size(); #ifdef DEBUG_MAX_HEAP_USAGE sMaxHeapUsage = sMaxHeapSize - sAvailable; #endif - + kprintf("init large allocations\n"); if (sLargeAllocations.Init(64) != B_OK) return B_NO_MEMORY; - + kprintf("done!\n"); return B_OK; } diff --git a/src/system/boot/loader/main.cpp b/src/system/boot/loader/main.cpp index e0555dcd..2aa6482 100644 --- a/src/system/boot/loader/main.cpp +++ b/src/system/boot/loader/main.cpp @@ -18,9 +18,9 @@ #include "file_systems/packagefs/packagefs.h" -//#define TRACE_MAIN +#define TRACE_MAIN #ifdef TRACE_MAIN -# define TRACE(x) dprintf x +# define TRACE(x) kprintf x #else # define TRACE(x) ; #endif @@ -35,7 +35,7 @@ main(stage2_args *args) panic("Could not initialize heap!\n"); TRACE(("boot(): heap initialized...\n")); - +#if 0 // set debug syslog default #if KDEBUG_ENABLE_DEBUG_SYSLOG gKernelArgs.keep_debug_output_buffer = true; @@ -52,13 +52,15 @@ main(stage2_args *args) if (vfs_init(args) < B_OK) panic("Could not initialize VFS!\n"); - - dprintf("Welcome to the Haiku boot loader!\n"); +#endif + kprintf("Welcome to the Haiku boot loader!\n"); bool mountedAllVolumes = false; BootVolume bootVolume; PathBlacklist pathBlacklist; + + user_menu(bootVolume, pathBlacklist); if (get_boot_file_system(args, bootVolume) != B_OK || (platform_boot_options() & BOOT_OPTION_MENU) != 0) { diff --git a/src/system/boot/loader/menu.cpp b/src/system/boot/loader/menu.cpp index 9f91397..6e237f1 100644 --- a/src/system/boot/loader/menu.cpp +++ b/src/system/boot/loader/menu.cpp @@ -35,9 +35,9 @@ #include "RootFileSystem.h" -//#define TRACE_MENU +#define TRACE_MENU #ifdef TRACE_MENU -# define TRACE(x) dprintf x +# define TRACE(x) kprintf x #else # define TRACE(x) ; #endif @@ -1131,7 +1131,7 @@ add_safe_mode_menu() item->SetType(MENU_ITEM_MARKABLE); item->SetHelpText("Disables IDE DMA, increasing IDE compatibility " "at the expense of performance."); - +#if 0 #if B_HAIKU_PHYSICAL_BITS > 32 // check whether we have memory beyond 4 GB bool hasMemoryBeyond4GB = false; @@ -1157,16 +1157,17 @@ add_safe_mode_menu() "overriding the setting in the kernel settings file."); } #endif - +#endif platform_add_menus(safeMenu); safeMenu->AddSeparatorItem(); sBlacklistRootMenu = new(std::nothrow) BlacklistRootMenu; +#if 0 safeMenu->AddItem(item = new(std::nothrow) MenuItem("Blacklist entries", sBlacklistRootMenu)); item->SetHelpText("Allows to select system files that shall be ignored. " "Useful e.g. to disable drivers temporarily."); - +#endif safeMenu->AddSeparatorItem(); safeMenu->AddItem(item = new(nothrow) MenuItem("Return to main menu")); @@ -1280,7 +1281,7 @@ add_debug_menu() item->SetType(MENU_ITEM_MARKABLE); item->SetHelpText("Disables paging when on screen debug output is " "enabled."); - +#if 0 menu->AddItem(item = new(nothrow) MenuItem("Enable debug syslog")); item->SetType(MENU_ITEM_MARKABLE); item->SetMarked(gKernelArgs.keep_debug_output_buffer); @@ -1329,7 +1330,7 @@ add_debug_menu() item->SetHelpText("Saves the syslog from the previous Haiku session to " "disk. Currently only FAT32 volumes are supported."); } - +#endif menu->AddSeparatorItem(); menu->AddItem(item = new(nothrow) MenuItem( "Add advanced debug option")); @@ -1414,35 +1415,48 @@ user_menu(BootVolume& _bootVolume, PathBlacklist& _pathBlacklist) TRACE(("user_menu: enter\n")); // Add boot volume - menu->AddItem(item = new(std::nothrow) MenuItem("Select boot volume", - add_boot_volume_menu(_bootVolume.RootDirectory()))); - - // Add safe mode - menu->AddItem(item = new(std::nothrow) MenuItem("Select safe mode options", - safeModeMenu = add_safe_mode_menu())); - + //menu->AddItem(item = new(std::nothrow) MenuItem("Select boot volume", + // add_boot_volume_menu(_bootVolume.RootDirectory()))); + TRACE(("make new item\n")); + item = new(std::nothrow) MenuItem("Select safe mode options", + safeModeMenu = add_safe_mode_menu()); + TRACE(("add to menu\n")); + // Add safe mode + menu->AddItem(item); + TRACE(("build debug menu\n")); // add debug menu menu->AddItem(item = new(std::nothrow) MenuItem("Select debug options", debugMenu = add_debug_menu())); // Add platform dependent menus + TRACE(("build platform menu\n")); platform_add_menus(menu); menu->AddSeparatorItem(); + TRACE(("build reboot menu\n")); menu->AddItem(item = new(std::nothrow) MenuItem("Reboot")); item->SetTarget(user_menu_reboot); item->SetShortcut('r'); - + TRACE(("build continue menu\n")); menu->AddItem(item = new(std::nothrow) MenuItem("Continue booting")); + if (menu == NULL) { + TRACE(("menu is NULL!\n")); + } + if (item == NULL) { + TRACE(("item is NULL!\n")); + } +#if 0 if (!_bootVolume.IsValid()) { item->SetEnabled(false); menu->ItemAt(0)->Select(true); } else item->SetShortcut('b'); - +#endif + TRACE(("running menu\n")); menu->Run(); + TRACE(("done with menu\n")); apply_safe_mode_options(safeModeMenu); apply_safe_mode_options(debugMenu); apply_safe_mode_path_blacklist(); diff --git a/src/system/boot/platform/efi/Jamfile b/src/system/boot/platform/efi/Jamfile index c99ee59..002216e 100644 --- a/src/system/boot/platform/efi/Jamfile +++ b/src/system/boot/platform/efi/Jamfile @@ -25,6 +25,8 @@ BootMergeObject boot_platform_efi.o : # interrupts.cpp # interrupts_asm.S keyboard.cpp + menu.cpp + heap.cpp # mmu.cpp serial.cpp $(efi_glue_src) diff --git a/src/system/boot/platform/efi/heap.cpp b/src/system/boot/platform/efi/heap.cpp new file mode 100644 index 0000000..75e73df --- /dev/null +++ b/src/system/boot/platform/efi/heap.cpp @@ -0,0 +1,38 @@ +/* + * Copyright 2014, Jessica Hamilton, jessica.l.hamilton@xxxxxxxxx. + * + * Distributed under the terms of the MIT License. + */ + +#include "efi_platform.h" + +#include <boot/platform.h> +#include <boot/stage2.h> +#include <boot/stdio.h> + +#define STAGE_PAGES 10000 /* 64 MB */ + +EFI_PHYSICAL_ADDRESS staging; + +void +platform_release_heap(struct stage2_args *args, void *base) +{ + // TODO +} + + +status_t +platform_init_heap(struct stage2_args *args, void **_base, void **_top) +{ + kSystemTable->BootServices->AllocatePages( + AllocateAnyPages, EfiLoaderData, STAGE_PAGES, &staging); + // get_next_physical_address(args->heap_size); + kprintf("heap address = %lx\n", staging); + if (staging == 0l) + return B_NO_MEMORY; + + *_base = (void *)staging; + *_top = (void *)((int8 *)staging + STAGE_PAGES); + kprintf("heap: base = %lx, top = %lx\n", (uint64)*_base, (uint64)*_top); + return B_OK; +} diff --git a/src/system/boot/platform/efi/menu.cpp b/src/system/boot/platform/efi/menu.cpp new file mode 100644 index 0000000..ec3217b --- /dev/null +++ b/src/system/boot/platform/efi/menu.cpp @@ -0,0 +1,47 @@ +/* + * Copyright 2004-2010, Axel Dörfler, axeld@xxxxxxxxxxxxxxxx. + * Copyright 2011, Rene Gollent, rene@xxxxxxxxxxx. + * Distributed under the terms of the MIT License. + */ + + +#include <boot/menu.h> +#include <boot/platform/generic/text_menu.h> +#include <safemode.h> + + +static void +warm_reboot(char key) +{ + +} + + +void +platform_add_menus(Menu* menu) +{ + // we don't have any platform specific menus at present +} + + +void +platform_update_menu_item(Menu* menu, MenuItem* item) +{ + platform_generic_update_text_menu_item(menu, item); +} + + +void +platform_run_menu(Menu* menu) +{ + platform_generic_run_text_menu(menu); +} + + +size_t +platform_get_user_input_text(Menu* menu, MenuItem* item, char* buffer, + size_t bufferSize) +{ + return platform_generic_get_user_input_text(menu, item, buffer, + bufferSize); +} diff --git a/src/system/boot/platform/efi/start.cpp b/src/system/boot/platform/efi/start.cpp index a08d314..f7e8cfa 100644 --- a/src/system/boot/platform/efi/start.cpp +++ b/src/system/boot/platform/efi/start.cpp @@ -43,6 +43,9 @@ extern "C" int main(stage2_args *args); extern "C" void _start(void); +uint32 sBootOptions; + + static void call_ctors(void) { @@ -57,7 +60,7 @@ call_ctors(void) extern "C" uint32 platform_boot_options(void) { - return 0; + return sBootOptions; } @@ -106,6 +109,8 @@ efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *systemTable) /* parse_multiboot_commandline - probably not */ /* check for boot keys */ + sBootOptions = check_for_boot_keys(); + sBootOptions |= BOOT_OPTION_MENU; /* APM - skip entirely */ /* ACPI - do we need to mmap/checksum it ? Or does EFI help with that.. Is it needed */ @@ -124,9 +129,5 @@ efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *systemTable) /* Exit boot services - Only use runtime ( and maybe some system services) from here on. * See info on memory map and much more in docs. */ - //launch kernel (main(&args);) - //main(&args); - dprintf(("hello world!\n")); - console_wait_for_key(); - return EFI_SUCCESS; + main(&args); } ############################################################################ Commit: 2822d2698a95bd1973ece1eceef774fa63cf9c6c Author: Jessica Hamilton <jessica.l.hamilton@xxxxxxxxx> Date: Mon Apr 7 06:15:59 2014 UTC Make reboot work. Enable some previously disabled code. ---------------------------------------------------------------------------- diff --git a/src/system/boot/loader/menu.cpp b/src/system/boot/loader/menu.cpp index 6e237f1..dd1da9d 100644 --- a/src/system/boot/loader/menu.cpp +++ b/src/system/boot/loader/menu.cpp @@ -1446,13 +1446,12 @@ user_menu(BootVolume& _bootVolume, PathBlacklist& _pathBlacklist) if (item == NULL) { TRACE(("item is NULL!\n")); } -#if 0 if (!_bootVolume.IsValid()) { item->SetEnabled(false); menu->ItemAt(0)->Select(true); } else item->SetShortcut('b'); -#endif + TRACE(("running menu\n")); menu->Run(); diff --git a/src/system/boot/platform/efi/start.cpp b/src/system/boot/platform/efi/start.cpp index f7e8cfa..79e453b 100644 --- a/src/system/boot/platform/efi/start.cpp +++ b/src/system/boot/platform/efi/start.cpp @@ -73,6 +73,7 @@ platform_start_kernel(void) extern "C" void platform_exit(void) { + kSystemTable->RuntimeServices->ResetSystem(EfiResetCold, 0, 0, NULL); } ############################################################################ Commit: 21c2522ef884c24616a5b7f2b9b5c29747f5f4da Author: Jessica Hamilton <jessica.l.hamilton@xxxxxxxxx> Date: Mon Apr 7 07:52:23 2014 UTC Ticket: https://dev.haiku-os.org/ticket/7469 haiku_loader: search for matching shortcut in supermenus Fixes #7469. ---------------------------------------------------------------------------- diff --git a/src/system/boot/loader/menu.cpp b/src/system/boot/loader/menu.cpp index dd1da9d..9b91164 100644 --- a/src/system/boot/loader/menu.cpp +++ b/src/system/boot/loader/menu.cpp @@ -414,6 +414,11 @@ Menu::FindShortcut(char key) const shortcut = shortcut->next; } + Menu *superMenu = Supermenu(); + + if (superMenu != NULL) + return superMenu->FindShortcut(key); + return NULL; } @@ -430,6 +435,11 @@ Menu::FindItemByShortcut(char key) return item; } + Menu *superMenu = Supermenu(); + + if (superMenu != NULL) + return superMenu->FindItemByShortcut(key); + return NULL; } ############################################################################ Commit: b5ae0c1e44dc8fad856faa82dc77225bac3434b2 Author: Jessica Hamilton <jessica.l.hamilton@xxxxxxxxx> Date: Mon Apr 7 10:10:14 2014 UTC Change to warm reboot. ---------------------------------------------------------------------------- diff --git a/src/system/boot/platform/efi/start.cpp b/src/system/boot/platform/efi/start.cpp index 79e453b..d17898c 100644 --- a/src/system/boot/platform/efi/start.cpp +++ b/src/system/boot/platform/efi/start.cpp @@ -73,7 +73,7 @@ platform_start_kernel(void) extern "C" void platform_exit(void) { - kSystemTable->RuntimeServices->ResetSystem(EfiResetCold, 0, 0, NULL); + kSystemTable->RuntimeServices->ResetSystem(EfiResetWarm, 0, 0, NULL); } ############################################################################ Commit: d442ee0f9696876489f743f8aea72acc45510989 Author: Jessica Hamilton <jessica.l.hamilton@xxxxxxxxx> Date: Wed Apr 9 03:58:56 2014 UTC Untested, likely broken code for devices.cpp. ---------------------------------------------------------------------------- diff --git a/src/system/boot/platform/efi/Jamfile b/src/system/boot/platform/efi/Jamfile index 002216e..e2c8dae 100644 --- a/src/system/boot/platform/efi/Jamfile +++ b/src/system/boot/platform/efi/Jamfile @@ -20,7 +20,7 @@ local efi_glue_src = BootMergeObject boot_platform_efi.o : console.cpp debug.cpp -# devices.cpp + devices.cpp start.cpp # interrupts.cpp # interrupts_asm.S diff --git a/src/system/boot/platform/efi/devices.cpp b/src/system/boot/platform/efi/devices.cpp new file mode 100644 index 0000000..a99c9d7 --- /dev/null +++ b/src/system/boot/platform/efi/devices.cpp @@ -0,0 +1,428 @@ +/* + * Copyright 2003-2006, Axel Dörfler, axeld@xxxxxxxxxxxxxxxx. + * Distributed under the terms of the MIT License. + */ + + +#include "efi_platform.h" + +#include <KernelExport.h> +#include <boot/platform.h> +#include <boot/partitions.h> +#include <boot/stdio.h> +#include <boot/stage2.h> + +#include <string.h> + +//#define TRACE_DEVICES +#ifdef TRACE_DEVICES +# define TRACE(x) dprintf x +#else +# define TRACE(x) ; +#endif + + +static uint8 sDriveIdentifier = 0; +static EFI_GUID sBlockIOGuid = BLOCK_IO_PROTOCOL; +static EFI_GUID sDevicePathGuid = DEVICE_PATH_PROTOCOL; + + +class EFIDrive : public Node { + public: + EFIDrive(EFI_BLOCK_IO *blockIO); + virtual ~EFIDrive(); + + status_t InitCheck() const; + + virtual ssize_t ReadAt(void *cookie, off_t pos, void *buffer, size_t bufferSize); + virtual ssize_t WriteAt(void *cookie, off_t pos, const void *buffer, size_t bufferSize); + + virtual off_t Size() const; + + uint32 BlockSize() const { return fBlockSize; } + + status_t FillIdentifier(); + + bool HasParameters() const { return fHasParameters; } + const drive_parameters &Parameters() const { return fParameters; } + + disk_identifier &Identifier() { return fIdentifier; } + uint8 DriveID() const { return fDriveID; } + + protected: + EFI_BLOCK_IO fBlockIO; + uint8 fDriveID; + uint64 fSize; + uint32 fBlockSize; + disk_identifier fIdentifier; +}; + + +static bool sBlockDevicesAdded = false; + + +static off_t +get_next_check_sum_offset(int32 index, off_t maxSize) +{ + // The boot block often contains the disk superblock, and should be + // unique enough for most cases + if (index < 2) + return index * 512; + + // Try some data in the first part of the drive + if (index < 4) + return (maxSize >> 10) + index * 2048; + + // Some random value might do + return ((system_time() + index) % (maxSize >> 9)) * 512; +} + + +/** Computes a check sum for the specified block. + * The check sum is the sum of all data in that block interpreted as an + * array of uint32 values. + * Note, this must use the same method as the one used in kernel/fs/vfs_boot.cpp. + */ + +static uint32 +compute_check_sum(EFIDrive *drive, off_t offset) +{ + char buffer[512]; + ssize_t bytesRead = drive->ReadAt(NULL, offset, buffer, sizeof(buffer)); + if (bytesRead < B_OK) + return 0; + + if (bytesRead < (ssize_t)sizeof(buffer)) + memset(buffer + bytesRead, 0, sizeof(buffer) - bytesRead); + + uint32 *array = (uint32 *)buffer; + uint32 sum = 0; + + for (uint32 i = 0; i < (bytesRead + sizeof(uint32) - 1) / sizeof(uint32); i++) { + sum += array[i]; + } + + return sum; +} + + +static void +find_unique_check_sums(NodeList *devices) +{ + NodeIterator iterator = devices->GetIterator(); + Node *device; + int32 index = 0; + off_t minSize = 0; + const int32 kMaxTries = 200; + + while (index < kMaxTries) { + bool clash = false; + + iterator.Rewind(); + + while ((device = iterator.Next()) != NULL) { + EFIDrive *drive = (EFIDrive *)device; +#if 0 + // there is no RTTI in the boot loader... + BIOSDrive *drive = dynamic_cast<BIOSDrive *>(device); + if (drive == NULL) + continue; +#endif + + // TODO: currently, we assume that the BIOS provided us with unique + // disk identifiers... hopefully this is a good idea + if (drive->Identifier().device_type != UNKNOWN_DEVICE) + continue; + + if (minSize == 0 || drive->Size() < minSize) + minSize = drive->Size(); + + // check for clashes + + NodeIterator compareIterator = devices->GetIterator(); + while ((device = compareIterator.Next()) != NULL) { + EFIDrive *compareDrive = (EFIDrive *)device; + + if (compareDrive == drive + || compareDrive->Identifier().device_type != UNKNOWN_DEVICE) + continue; + +// TODO: Until we can actually get and compare *all* fields of the disk +// identifier in the kernel, we cannot compare the whole structure (we also +// should be more careful zeroing the structure before we fill it). +#if 0 + if (!memcmp(&drive->Identifier(), &compareDrive->Identifier(), + sizeof(disk_identifier))) { + clash = true; + break; + } +#else + const disk_identifier& ourId = drive->Identifier(); + const disk_identifier& otherId = compareDrive->Identifier(); + if (memcmp(&ourId.device.unknown.check_sums, + &otherId.device.unknown.check_sums, + sizeof(ourId.device.unknown.check_sums)) == 0) { + clash = true; + } +#endif + } + + if (clash) + break; + } + + if (!clash) { + // our work here is done. + return; + } + + // add a new block to the check sums + + off_t offset = get_next_check_sum_offset(index, minSize); + int32 i = index % NUM_DISK_CHECK_SUMS; + iterator.Rewind(); + + while ((device = iterator.Next()) != NULL) { + EFIDrive *drive = (EFIDrive *)device; + + disk_identifier& disk = drive->Identifier(); + disk.device.unknown.check_sums[i].offset = offset; + disk.device.unknown.check_sums[i].sum = compute_check_sum(drive, offset); + + TRACE(("disk %x, offset %Ld, sum %lu\n", drive->DriveID(), offset, + disk.device.unknown.check_sums[i].sum)); + } + + index++; + } + + // If we get here, we couldn't find a way to differentiate all disks from each other. + // It's very likely that one disk is an exact copy of the other, so there is nothing + // we could do, anyway. + + dprintf("Could not make EFI drives unique! Might boot from the wrong disk...\n"); +} + + +static status_t +add_block_devices(NodeList *devicesList, bool identifierMissing) +{ + if (sBlockDevicesAdded) + return B_OK; + + EFI_BLOCK_IO *blockIO; + EFI_DEVICE_PATH *devicePath, *node; + EFI_HANDLE *handles, handle; + EFI_STATUS status; + UINTN size; + CHAR16 *path; + uint32 n, nIn, nOut; + status_t result; + + size = 0; + handles = NULL; + + status = kSystemTable->BootServices->LocateHandle(EfiByProtocol, &sBlockIOGuid, 0, &size, 0); + if (status == EFI_BUFFER_TOO_SMALL) { + handles = (EFI_HANDLE *)malloc(size); + status = kSystemTable->BootServices->LocateHandle(EfiByProtocol, &sBlockIOGuid, 0, &size, handles); + if (status != EFI_SUCCESS) + free(handles); + } + if (status != EFI_SUCCESS) + return B_ERROR; + + nIn = size / sizeof(EFI_HANDLE); + + for (unsigned int n = 0; n < nIn; n++) { + status = kSystemTable->BootServices->HandleProtocol(handles[n], &sDevicePathGuid, &devicePath); + if (status != EFI_SUCCESS) + continue; + + node = devicePath; + + while (!IsDevicePathEnd(NextDevicePathNode(node))) + node = NextDevicePathNode(node); + + status = kSystemTable->BootServices->HandleProtocol(handles[n], &sBlockIOGuid, &blockIO); + if (status != EFI_SUCCESS) + continue; + if (!blockIO->Media->LogicalPartition) + continue; + + /* + * If we come across a logical partition of subtype CDROM + * it doesn't refer to the CD fileystem itself, but rather + * to any usable El Torito boot image on it. In this case + * we try to find the parent device and add that instead as + * that will be the CD filesystem. + */ + if (DevicePathType(node) == MEDIA_DEVICE_PATH && + DevicePathSubType(node) == MEDIA_CDROM_DP) { + node->Type = END_DEVICE_PATH_TYPE; + node->SubType = END_ENTIRE_DEVICE_PATH_SUBTREE; + status = kSystemTable->BootServices->LocateDevicePath(&sBlockIOGuid, + &devicePath, &handle); + // TODO: actually care about CD-ROMs + continue; + } + + // Use handles[n] to create an EFIDisk given the current Block IO handle + // kprintf: blocks = blockIO->Media->LastBlock + 1; removable = blockIO->Media->RemovableMedia + EFIDrive *drive = new(nothrow) EFIDrive(blockIO); + if (drive->InitCheck() != B_OK) { + dprintf("could not add drive %u\n", driveID); + delete drive; + continue; + } + + devicesList->Add(drive); + + if (drive->FillIdentifier() != B_OK) + identifierMissing = true; + } + + sBlockDevicesAdded = true; + return B_OK; +} + + +// #pragma mark - + + +EFIDrive::EFIDrive(EFI_BLOCK_IO *blockIO) + : + fBlockIO(blockIO), + fDriveID(++fDriveIdentifier), + fSize(0) +{ + TRACE(("drive ID %u\n", fDriveID)); + + if (!fBlockIO->Media->MediaPresent) + return; + + fBlockSize = fBlockIO->Media->BlockSize; + fSize = (fBlockIO->Media->LastBlock + 1) * fBlockSize; +} + + +EFIDrive::~EFIDrive() +{ +} + + +status_t +EFIDrive::InitCheck() const +{ + return fSize > 0 ? B_OK : B_ERROR; +} + +/* + * pos is in bytes, bufferSize is also in bytes + */ +ssize_t +EFIDrive::ReadAt(void *cookie, off_t pos, void *buffer, size_t bufferSize) +{ + uint32 offset = pos % fBlockSize; + pos /= fBlockSize; + + uint32 blocksLeft = (bufferSize + offset + fBlockSize - 1) / fBlockSize; + int32 totalBytesRead = 0; + + while (blocksLeft > 0) { + uint32 blocksRead = blocksLeft; + /*if (blocksRead > scratchSize) + blocksRead = scratchSize;*/ + + status = fBlockIO->ReadBlocks(fBlockIO, + fBlockIO->Media->MediaId, + pos, blocksRead * fBlockIO->BlockSize, buffer); + /* ReadBlocks(EFI_BLOCK_IO*, EFI_MEDIA_ID, + START IN BLOCKS, SIZE IN BYTES?, OUTPUT BUFFER); */ + + uint32 bytesRead = fBlockSize * blocksRead - offset; + // copy no more than bufferSize bytes + if (bytesRead > bufferSize) + bytesRead = bufferSize; + + //memcpy(buffer, (void *)(kExtraSegmentScratch + offset), bytesRead); + pos += blocksRead; + offset = 0; + blocksLeft -= blocksRead; + bufferSize -= bytesRead; + buffer = (void *)((addr_t)buffer + bytesRead); + totalBytesRead += bytesRead; + } + + return totalBytesRead; +} + + +ssize_t +EFIDrive::WriteAt(void* cookie, off_t pos, const void* buffer, + size_t bufferSize) +{ + return B_UNSUPPORTED; +} + + +off_t +EFIDrive::Size() const +{ + return fSize; +} + + +status_t +EFIDrive::FillIdentifier() +{ + fIdentifier.bus_type = UNKNOWN_BUS; + fIdentifier.device_type = UNKNOWN_DEVICE; + fIdentifier.device.unknown.size = Size(); + + for (int32 i = 0; i < NUM_DISK_CHECK_SUMS; i++) { + fIdentifier.device.unknown.check_sums[i].offset = -1; + fIdentifier.device.unknown.check_sums[i].sum = 0; + } + + return B_ERROR; +} + + +// #pragma mark - + + +status_t +platform_add_boot_device(struct stage2_args *args, NodeList *devicesList) +{ + return B_ENTRY_NOT_FOUND; +} + + +status_t +platform_get_boot_partition(struct stage2_args *args, Node *bootDevice, + NodeList *list, boot::Partition **_partition) +{ + return B_ENTRY_NOT_FOUND; +} + + +status_t +platform_add_block_devices(stage2_args *args, NodeList *devicesList) +{ + return add_block_devices(devicesList, false); +} + + +status_t +platform_register_boot_device(Node *device) +{ + EFIDrive *drive = (EFIDrive *)device; + + gBootVolume.SetInt64("boot drive number", drive->DriveID()); + gBootVolume.SetData(BOOT_VOLUME_DISK_IDENTIFIER, B_RAW_TYPE, + &drive->Identifier(), sizeof(disk_identifier)); + + return B_OK; +} + ############################################################################ Commit: af3d237aeeef8355bbf7c3c74e17fad57641216c Author: Jessica Hamilton <jessica.l.hamilton@xxxxxxxxx> Date: Tue Apr 15 01:03:35 2014 UTC UEFI: Tidy up compilation errors to devices.cpp ---------------------------------------------------------------------------- diff --git a/src/system/boot/platform/efi/devices.cpp b/src/system/boot/platform/efi/devices.cpp index a99c9d7..5c4fa90 100644 --- a/src/system/boot/platform/efi/devices.cpp +++ b/src/system/boot/platform/efi/devices.cpp @@ -43,14 +43,11 @@ class EFIDrive : public Node { status_t FillIdentifier(); - bool HasParameters() const { return fHasParameters; } - const drive_parameters &Parameters() const { return fParameters; } - disk_identifier &Identifier() { return fIdentifier; } uint8 DriveID() const { return fDriveID; } protected: - EFI_BLOCK_IO fBlockIO; + EFI_BLOCK_IO *fBlockIO; uint8 fDriveID; uint64 fSize; uint32 fBlockSize; @@ -222,10 +219,10 @@ add_block_devices(NodeList *devicesList, bool identifierMissing) size = 0; handles = NULL; - status = kSystemTable->BootServices->LocateHandle(EfiByProtocol, &sBlockIOGuid, 0, &size, 0); + status = kSystemTable->BootServices->LocateHandle(ByProtocol, &sBlockIOGuid, 0, &size, 0); if (status == EFI_BUFFER_TOO_SMALL) { handles = (EFI_HANDLE *)malloc(size); - status = kSystemTable->BootServices->LocateHandle(EfiByProtocol, &sBlockIOGuid, 0, &size, handles); + status = kSystemTable->BootServices->LocateHandle(ByProtocol, &sBlockIOGuid, 0, &size, handles); if (status != EFI_SUCCESS) free(handles); } @@ -235,7 +232,7 @@ add_block_devices(NodeList *devicesList, bool identifierMissing) nIn = size / sizeof(EFI_HANDLE); for (unsigned int n = 0; n < nIn; n++) { - status = kSystemTable->BootServices->HandleProtocol(handles[n], &sDevicePathGuid, &devicePath); + status = kSystemTable->BootServices->HandleProtocol(handles[n], &sDevicePathGuid, (void**)&devicePath); if (status != EFI_SUCCESS) continue; @@ -244,7 +241,7 @@ add_block_devices(NodeList *devicesList, bool identifierMissing) while (!IsDevicePathEnd(NextDevicePathNode(node))) node = NextDevicePathNode(node); - status = kSystemTable->BootServices->HandleProtocol(handles[n], &sBlockIOGuid, &blockIO); + status = kSystemTable->BootServices->HandleProtocol(handles[n], &sBlockIOGuid, (void**)&blockIO); if (status != EFI_SUCCESS) continue; if (!blockIO->Media->LogicalPartition) @@ -260,7 +257,7 @@ add_block_devices(NodeList *devicesList, bool identifierMissing) if (DevicePathType(node) == MEDIA_DEVICE_PATH && DevicePathSubType(node) == MEDIA_CDROM_DP) { node->Type = END_DEVICE_PATH_TYPE; - node->SubType = END_ENTIRE_DEVICE_PATH_SUBTREE; + node->SubType = END_ENTIRE_DEVICE_PATH_SUBTYPE; status = kSystemTable->BootServices->LocateDevicePath(&sBlockIOGuid, &devicePath, &handle); // TODO: actually care about CD-ROMs @@ -271,7 +268,6 @@ add_block_devices(NodeList *devicesList, bool identifierMissing) // kprintf: blocks = blockIO->Media->LastBlock + 1; removable = blockIO->Media->RemovableMedia EFIDrive *drive = new(nothrow) EFIDrive(blockIO); if (drive->InitCheck() != B_OK) { - dprintf("could not add drive %u\n", driveID); delete drive; continue; } @@ -293,7 +289,7 @@ add_block_devices(NodeList *devicesList, bool identifierMissing) EFIDrive::EFIDrive(EFI_BLOCK_IO *blockIO) : fBlockIO(blockIO), - fDriveID(++fDriveIdentifier), + fDriveID(++sDriveIdentifier), fSize(0) { TRACE(("drive ID %u\n", fDriveID)); @@ -334,9 +330,9 @@ EFIDrive::ReadAt(void *cookie, off_t pos, void *buffer, size_t bufferSize) /*if (blocksRead > scratchSize) blocksRead = scratchSize;*/ - status = fBlockIO->ReadBlocks(fBlockIO, + EFI_STATUS status = fBlockIO->ReadBlocks(fBlockIO, fBlockIO->Media->MediaId, - pos, blocksRead * fBlockIO->BlockSize, buffer); + pos, blocksRead * fBlockIO->Media->BlockSize, buffer); /* ReadBlocks(EFI_BLOCK_IO*, EFI_MEDIA_ID, START IN BLOCKS, SIZE IN BYTES?, OUTPUT BUFFER); */ diff --git a/src/system/boot/platform/efi/efi_platform.h b/src/system/boot/platform/efi/efi_platform.h index b1a8750..07c50a3 100644 --- a/src/system/boot/platform/efi/efi_platform.h +++ b/src/system/boot/platform/efi/efi_platform.h @@ -10,6 +10,7 @@ #include "efibind.h" #include "efidef.h" #include "efidevp.h" +#include "efiprot.h" #include "eficon.h" #include "efierr.h" #include "efiapi.h" ############################################################################ Commit: 8dd0075dd55ac95aafe6ccc0ef03dda1314fd821 Author: Jessica Hamilton <jessica.l.hamilton@xxxxxxxxx> Date: Tue Apr 15 05:03:46 2014 UTC UEFI: more debug, getting closer to detecting a BFS partition. ---------------------------------------------------------------------------- diff --git a/src/system/boot/loader/Jamfile b/src/system/boot/loader/Jamfile index 026c068..50fc531 100644 --- a/src/system/boot/loader/Jamfile +++ b/src/system/boot/loader/Jamfile @@ -15,7 +15,7 @@ UsePrivateHeaders shared storage ; BOOT_ARCH=\\\"$(TARGET_KERNEL_ARCH)\\\" KMESSAGE_CONTAINER_ONLY - BOOT_SUPPORT_PARTITION_INTEL + #BOOT_SUPPORT_PARTITION_INTEL BOOT_SUPPORT_FILE_SYSTEM_BFS BOOT_SUPPORT_FILE_SYSTEM_TARFS @@ -41,7 +41,7 @@ UsePrivateHeaders shared storage ; ALTERNATE_BOOT_ARCH=\\\"x86_64\\\" BOOT_SUPPORT_ELF64 - BOOT_SUPPORT_PARTITION_EFI + #BOOT_SUPPORT_PARTITION_EFI #BOOT_SUPPORT_FILE_SYSTEM_FAT ; diff --git a/src/system/boot/loader/file_systems/bfs/bfs.cpp b/src/system/boot/loader/file_systems/bfs/bfs.cpp index 3fee5a9..60b1282 100644 --- a/src/system/boot/loader/file_systems/bfs/bfs.cpp +++ b/src/system/boot/loader/file_systems/bfs/bfs.cpp @@ -18,9 +18,9 @@ #include "Utility.h" -#define TRACE_BFS 0 +#define TRACE_BFS 1 #if TRACE_BFS -# define TRACE(x) printf x +# define TRACE(x) kprintf x #else # define TRACE(x) ; #endif diff --git a/src/system/boot/loader/main.cpp b/src/system/boot/loader/main.cpp index 2aa6482..62de4a5 100644 --- a/src/system/boot/loader/main.cpp +++ b/src/system/boot/loader/main.cpp @@ -50,9 +50,10 @@ main(stage2_args *args) // the main platform dependent initialisation // has already taken place at this point. +#endif if (vfs_init(args) < B_OK) panic("Could not initialize VFS!\n"); -#endif + kprintf("Welcome to the Haiku boot loader!\n"); bool mountedAllVolumes = false; @@ -60,9 +61,7 @@ main(stage2_args *args) BootVolume bootVolume; PathBlacklist pathBlacklist; - user_menu(bootVolume, pathBlacklist); - - if (get_boot_file_system(args, bootVolume) != B_OK + if (get_boot_file_system(args, bootVolume) != B_OK || (platform_boot_options() & BOOT_OPTION_MENU) != 0) { if (!bootVolume.IsValid()) puts("\tno boot path found, scan for all partitions...\n"); diff --git a/src/system/boot/loader/menu.cpp b/src/system/boot/loader/menu.cpp index 9b91164..4aa756c 100644 --- a/src/system/boot/loader/menu.cpp +++ b/src/system/boot/loader/menu.cpp @@ -1172,12 +1172,10 @@ add_safe_mode_menu() safeMenu->AddSeparatorItem(); sBlacklistRootMenu = new(std::nothrow) BlacklistRootMenu; -#if 0 safeMenu->AddItem(item = new(std::nothrow) MenuItem("Blacklist entries", sBlacklistRootMenu)); item->SetHelpText("Allows to select system files that shall be ignored. " "Useful e.g. to disable drivers temporarily."); -#endif safeMenu->AddSeparatorItem(); safeMenu->AddItem(item = new(nothrow) MenuItem("Return to main menu")); @@ -1291,7 +1289,6 @@ add_debug_menu() item->SetType(MENU_ITEM_MARKABLE); item->SetHelpText("Disables paging when on screen debug output is " "enabled."); -#if 0 menu->AddItem(item = new(nothrow) MenuItem("Enable debug syslog")); item->SetType(MENU_ITEM_MARKABLE); item->SetMarked(gKernelArgs.keep_debug_output_buffer); @@ -1340,7 +1337,6 @@ add_debug_menu() item->SetHelpText("Saves the syslog from the previous Haiku session to " "disk. Currently only FAT32 volumes are supported."); } -#endif menu->AddSeparatorItem(); menu->AddItem(item = new(nothrow) MenuItem( "Add advanced debug option")); @@ -1425,8 +1421,8 @@ user_menu(BootVolume& _bootVolume, PathBlacklist& _pathBlacklist) TRACE(("user_menu: enter\n")); // Add boot volume - //menu->AddItem(item = new(std::nothrow) MenuItem("Select boot volume", - // add_boot_volume_menu(_bootVolume.RootDirectory()))); + menu->AddItem(item = new(std::nothrow) MenuItem("Select boot volume", + add_boot_volume_menu(_bootVolume.RootDirectory()))); TRACE(("make new item\n")); item = new(std::nothrow) MenuItem("Select safe mode options", safeModeMenu = add_safe_mode_menu()); diff --git a/src/system/boot/loader/partitions.cpp b/src/system/boot/loader/partitions.cpp index eee6a94..20d0001 100644 --- a/src/system/boot/loader/partitions.cpp +++ b/src/system/boot/loader/partitions.cpp @@ -24,7 +24,7 @@ using namespace boot; #define TRACE_PARTITIONS #ifdef TRACE_PARTITIONS -# define TRACE(x) dprintf x +# define TRACE(x) kprintf x #else # define TRACE(x) ; #endif @@ -329,6 +329,7 @@ Partition::Scan(bool mountFileSystems, bool isBootDevice) void *bestCookie = NULL; float bestPriority = -1; + TRACE(("scanning %d partition modules...\n", sNumPartitionModules)); for (int32 i = 0; i < sNumPartitionModules; i++) { const partition_module_info *module = sPartitionModules[i]; void *cookie = NULL; @@ -357,9 +358,14 @@ Partition::Scan(bool mountFileSystems, bool isBootDevice) bestPriority = priority; } - // find the best FS module const file_system_module_info *bestFSModule = NULL; float bestFSPriority = -1; + + // find the best FS module + if (bestModule == NULL) + goto rawFilesystem; + + TRACE(("looking for best FS module out of %d modules\n", sNumFileSystemModules)); for (int32 i = 0; i < sNumFileSystemModules; i++) { if (sFileSystemModules[i]->identify_file_system == NULL) continue; @@ -398,6 +404,7 @@ Partition::Scan(bool mountFileSystems, bool isBootDevice) NodeIterator iterator = fChildren.GetIterator(); Partition *child = NULL; + TRACE(("looking for child partitions...\n")); while ((child = (Partition *)iterator.Next()) != NULL) { TRACE(("%p Partition::Scan(): scan child %p (start = %Ld, size " "= %Ld, parent = %p)!\n", this, child, child->offset, @@ -426,13 +433,17 @@ Partition::Scan(bool mountFileSystems, bool isBootDevice) return B_OK; } +rawFilesystem: // scan for file systems + TRACE(("looking for file systems...\n")); if (mountFileSystems) { // TODO: Use the FS module we've got, if any. Requires to implement the // identify_file_system() hook in every FS. return Mount(); } + + TRACE(("no partitions/filesystems found...\n")); return B_ENTRY_NOT_FOUND; } diff --git a/src/system/boot/loader/vfs.cpp b/src/system/boot/loader/vfs.cpp index bb7d5e0..279c557 100644 --- a/src/system/boot/loader/vfs.cpp +++ b/src/system/boot/loader/vfs.cpp @@ -662,7 +662,6 @@ mount_file_systems(stage2_args *args) if (gPartitions.IsEmpty()) return B_ENTRY_NOT_FOUND; -#if 0 void *cookie; if (gRoot->Open(&cookie, O_RDONLY) == B_OK) { Directory *directory; @@ -681,7 +680,6 @@ mount_file_systems(stage2_args *args) } gRoot->Close(cookie); } -#endif return B_OK; } diff --git a/src/system/boot/platform/efi/devices.cpp b/src/system/boot/platform/efi/devices.cpp index 5c4fa90..759776b 100644 --- a/src/system/boot/platform/efi/devices.cpp +++ b/src/system/boot/platform/efi/devices.cpp @@ -14,9 +14,9 @@ #include <string.h> -//#define TRACE_DEVICES +#define TRACE_DEVICES #ifdef TRACE_DEVICES -# define TRACE(x) dprintf x +# define TRACE(x) kprintf x #else # define TRACE(x) ; #endif @@ -197,7 +197,7 @@ find_unique_check_sums(NodeList *devices) // It's very likely that one disk is an exact copy of the other, so there is nothing // we could do, anyway. - dprintf("Could not make EFI drives unique! Might boot from the wrong disk...\n"); + kprintf("Could not make EFI drives unique! Might boot from the wrong disk...\n"); } @@ -226,11 +226,15 @@ add_block_devices(NodeList *devicesList, bool identifierMissing) if (status != EFI_SUCCESS) free(handles); } - if (status != EFI_SUCCESS) + if (status != EFI_SUCCESS) { + kprintf("failed to locate any block io handles\n"); return B_ERROR; + } nIn = size / sizeof(EFI_HANDLE); + kprintf("found %d block devices\n", nIn); + for (unsigned int n = 0; n < nIn; n++) { status = kSystemTable->BootServices->HandleProtocol(handles[n], &sDevicePathGuid, (void**)&devicePath); if (status != EFI_SUCCESS) @@ -299,6 +303,8 @@ EFIDrive::EFIDrive(EFI_BLOCK_IO *blockIO) fBlockSize = fBlockIO->Media->BlockSize; fSize = (fBlockIO->Media->LastBlock + 1) * fBlockSize; + + TRACE(("blocksize: %d, size: %ld\n", fBlockSize, fSize)); } @@ -321,36 +327,17 @@ EFIDrive::ReadAt(void *cookie, off_t pos, void *buffer, size_t bufferSize) { uint32 offset = pos % fBlockSize; pos /= fBlockSize; + + ASSERT(offset == 0); - uint32 blocksLeft = (bufferSize + offset + fBlockSize - 1) / fBlockSize; - int32 totalBytesRead = 0; - - while (blocksLeft > 0) { - uint32 blocksRead = blocksLeft; - /*if (blocksRead > scratchSize) - blocksRead = scratchSize;*/ - - EFI_STATUS status = fBlockIO->ReadBlocks(fBlockIO, - fBlockIO->Media->MediaId, - pos, blocksRead * fBlockIO->Media->BlockSize, buffer); - /* ReadBlocks(EFI_BLOCK_IO*, EFI_MEDIA_ID, - START IN BLOCKS, SIZE IN BYTES?, OUTPUT BUFFER); */ + EFI_STATUS status = fBlockIO->ReadBlocks(fBlockIO, + fBlockIO->Media->MediaId, + pos, bufferSize, buffer); - uint32 bytesRead = fBlockSize * blocksRead - offset; - // copy no more than bufferSize bytes - if (bytesRead > bufferSize) - bytesRead = bufferSize; - - //memcpy(buffer, (void *)(kExtraSegmentScratch + offset), bytesRead); - pos += blocksRead; - offset = 0; - blocksLeft -= blocksRead; - bufferSize -= bytesRead; - buffer = (void *)((addr_t)buffer + bytesRead); - totalBytesRead += bytesRead; - } + if (status != EFI_SUCCESS) + return B_ERROR; - return totalBytesRead; + return bufferSize; } ############################################################################ Commit: 2fe35ee39c14897ca38a35f5f80367b28128b29e Author: Jessica Hamilton <jessica.l.hamilton@xxxxxxxxx> Date: Tue Apr 15 05:23:35 2014 UTC UEFI: more debug. fix kprintf. ---------------------------------------------------------------------------- diff --git a/src/system/boot/platform/efi/debug.cpp b/src/system/boot/platform/efi/debug.cpp index 0500229..b1191de 100644 --- a/src/system/boot/platform/efi/debug.cpp +++ b/src/system/boot/platform/efi/debug.cpp @@ -121,17 +121,21 @@ void kprintf(const char *format, ...) { va_list args; + va_list copy; va_start(args, format); + va_copy(copy, args); // print to console, if available if (stdout != NULL) vfprintf(stdout, format, args); + va_start(args, format); // always print to serial line dprintf_args(format, args); va_end(args); + va_end(copy); } diff --git a/src/system/boot/platform/efi/devices.cpp b/src/system/boot/platform/efi/devices.cpp index 759776b..284270d 100644 --- a/src/system/boot/platform/efi/devices.cpp +++ b/src/system/boot/platform/efi/devices.cpp @@ -328,14 +328,21 @@ EFIDrive::ReadAt(void *cookie, off_t pos, void *buffer, size_t bufferSize) uint32 offset = pos % fBlockSize; pos /= fBlockSize; - ASSERT(offset == 0); + if (offset > 0) { + kprintf("can't read unaligned blocks!\n"); + return B_ERROR; + } EFI_STATUS status = fBlockIO->ReadBlocks(fBlockIO, fBlockIO->Media->MediaId, pos, bufferSize, buffer); - if (status != EFI_SUCCESS) + if (status != EFI_SUCCESS) { + kprintf("ReadBlocks EFI call failed!\n"); return B_ERROR; + } + + kprintf("read %d bytes from LBA %ld (bs: %d)\n", buffer_size, pos, fBlockSize); return bufferSize; } ############################################################################ Commit: 8edf9b3a6e9c4490c7ec77bd182e46b7ec2f3428 Author: Jessica Hamilton <jessica.l.hamilton@xxxxxxxxx> Date: Tue Apr 15 05:24:28 2014 UTC Fix typo. ---------------------------------------------------------------------------- diff --git a/src/system/boot/platform/efi/devices.cpp b/src/system/boot/platform/efi/devices.cpp index 284270d..8133690 100644 --- a/src/system/boot/platform/efi/devices.cpp +++ b/src/system/boot/platform/efi/devices.cpp @@ -342,7 +342,7 @@ EFIDrive::ReadAt(void *cookie, off_t pos, void *buffer, size_t bufferSize) return B_ERROR; } - kprintf("read %d bytes from LBA %ld (bs: %d)\n", buffer_size, pos, fBlockSize); + kprintf("read %d bytes from LBA %ld (bs: %d)\n", bufferSize, pos, fBlockSize); return bufferSize; } ############################################################################ Commit: 37bdcd15eaa6dc61daa4f4b7ec792bb9ed9c7167 Author: Jessica Hamilton <jessica.l.hamilton@xxxxxxxxx> Date: Tue Apr 15 11:01:50 2014 UTC UEFI: maybe better working read function ---------------------------------------------------------------------------- diff --git a/src/system/boot/platform/efi/devices.cpp b/src/system/boot/platform/efi/devices.cpp old mode 100644 new mode 100755 index 8133690..ec2edea --- a/src/system/boot/platform/efi/devices.cpp +++ b/src/system/boot/platform/efi/devices.cpp @@ -27,10 +27,10 @@ static EFI_GUID sBlockIOGuid = BLOCK_IO_PROTOCOL; static EFI_GUID sDevicePathGuid = DEVICE_PATH_PROTOCOL; -class EFIDrive : public Node { +class EFIBlockDevice : public Node { public: - EFIDrive(EFI_BLOCK_IO *blockIO); - virtual ~EFIDrive(); + EFIBlockDevice(EFI_BLOCK_IO *blockIO); + virtual ~EFIBlockDevice(); status_t InitCheck() const; @@ -45,7 +45,7 @@ class EFIDrive : public Node { disk_identifier &Identifier() { return fIdentifier; } uint8 DriveID() const { return fDriveID; } - + protected: EFI_BLOCK_IO *fBlockIO; uint8 fDriveID; @@ -82,7 +82,7 @@ get_next_check_sum_offset(int32 index, off_t maxSize) */ static uint32 -compute_check_sum(EFIDrive *drive, off_t offset) +compute_check_sum(EFIBlockDevice *drive, off_t offset) { char buffer[512]; ssize_t bytesRead = drive->ReadAt(NULL, offset, buffer, sizeof(buffer)); @@ -118,7 +118,7 @@ find_unique_check_sums(NodeList *devices) iterator.Rewind(); while ((device = iterator.Next()) != NULL) { - EFIDrive *drive = (EFIDrive *)device; + EFIBlockDevice *drive = (EFIBlockDevice *)device; #if 0 // there is no RTTI in the boot loader... BIOSDrive *drive = dynamic_cast<BIOSDrive *>(device); @@ -138,7 +138,7 @@ find_unique_check_sums(NodeList *devices) NodeIterator compareIterator = devices->GetIterator(); while ((device = compareIterator.Next()) != NULL) { - EFIDrive *compareDrive = (EFIDrive *)device; + EFIBlockDevice *compareDrive = (EFIBlockDevice *)device; if (compareDrive == drive || compareDrive->Identifier().device_type != UNKNOWN_DEVICE) @@ -180,7 +180,7 @@ find_unique_check_sums(NodeList *devices) iterator.Rewind(); while ((device = iterator.Next()) != NULL) { - EFIDrive *drive = (EFIDrive *)device; + EFIBlockDevice *drive = (EFIBlockDevice *)device; disk_identifier& disk = drive->Identifier(); disk.device.unknown.check_sums[i].offset = offset; @@ -270,7 +270,7 @@ add_block_devices(NodeList *devicesList, bool identifierMissing) // Use handles[n] to create an EFIDisk given the current Block IO handle // kprintf: blocks = blockIO->Media->LastBlock + 1; removable = blockIO->Media->RemovableMedia - EFIDrive *drive = new(nothrow) EFIDrive(blockIO); + EFIBlockDevice *drive = new(nothrow) EFIBlockDevice(blockIO); if (drive->InitCheck() != B_OK) { delete drive; continue; @@ -290,7 +290,7 @@ add_block_devices(NodeList *devicesList, bool identifierMissing) // #pragma mark - -EFIDrive::EFIDrive(EFI_BLOCK_IO *blockIO) +EFIBlockDevice::EFIBlockDevice(EFI_BLOCK_IO *blockIO) : fBlockIO(blockIO), fDriveID(++sDriveIdentifier), @@ -308,48 +308,45 @@ EFIDrive::EFIDrive(EFI_BLOCK_IO *blockIO) } -EFIDrive::~EFIDrive() +EFIBlockDevice::~EFIBlockDevice() { } status_t -EFIDrive::InitCheck() const +EFIBlockDevice::InitCheck() const { return fSize > 0 ? B_OK : B_ERROR; } + /* * pos is in bytes, bufferSize is also in bytes */ ssize_t -EFIDrive::ReadAt(void *cookie, off_t pos, void *buffer, size_t bufferSize) +EFIBlockDevice::ReadAt(void *cookie, off_t pos, void *buffer, size_t bufferSize) { uint32 offset = pos % fBlockSize; pos /= fBlockSize; - if (offset > 0) { - kprintf("can't read unaligned blocks!\n"); - return B_ERROR; - } - - EFI_STATUS status = fBlockIO->ReadBlocks(fBlockIO, - fBlockIO->Media->MediaId, - pos, bufferSize, buffer); - - if (status != EFI_SUCCESS) { - kprintf("ReadBlocks EFI call failed!\n"); + uint32 numBlocks = (offset + bufferSize + fBlockSize) / fBlockSize; + + char readBuffer[fBlockSize * numBlocks]; + + EFI_STATUS status = fBlockIO->ReadBlocks(fBlockIO, fBlockIO->Media->MediaId, + pos, sizeof(readBuffer), readBuffer); + + if (status != EFI_SUCCESS) return B_ERROR; - } - kprintf("read %d bytes from LBA %ld (bs: %d)\n", bufferSize, pos, fBlockSize); + memcpy(buffer, readBuffer + offset, bufferSize); return bufferSize; } ssize_t -EFIDrive::WriteAt(void* cookie, off_t pos, const void* buffer, +EFIBlockDevice::WriteAt(void* cookie, off_t pos, const void* buffer, size_t bufferSize) { return B_UNSUPPORTED; @@ -357,14 +354,14 @@ EFIDrive::WriteAt(void* cookie, off_t pos, const void* buffer, off_t -EFIDrive::Size() const +EFIBlockDevice::Size() const { return fSize; } status_t -EFIDrive::FillIdentifier() +EFIBlockDevice::FillIdentifier() { fIdentifier.bus_type = UNKNOWN_BUS; fIdentifier.device_type = UNKNOWN_DEVICE; @@ -407,7 +404,7 @@ platform_add_block_devices(stage2_args *args, NodeList *devicesList) status_t platform_register_boot_device(Node *device) { - EFIDrive *drive = (EFIDrive *)device; + EFIBlockDevice *drive = (EFIBlockDevice *)device; gBootVolume.SetInt64("boot drive number", drive->DriveID()); gBootVolume.SetData(BOOT_VOLUME_DISK_IDENTIFIER, B_RAW_TYPE, ############################################################################ Commit: ad7597be6425953afdcb5adc6ce8e2b4afc8732d Author: Jessica Hamilton <jessica.l.hamilton@xxxxxxxxx> Date: Wed Apr 16 05:39:59 2014 UTC UEFI: lots of debugging, getting closer to mounting a BFS partition. ---------------------------------------------------------------------------- diff --git a/headers/private/package/hpkg/ReaderImplBase.h b/headers/private/package/hpkg/ReaderImplBase.h index 9d04175..c06850b 100644 --- a/headers/private/package/hpkg/ReaderImplBase.h +++ b/headers/private/package/hpkg/ReaderImplBase.h @@ -424,20 +424,46 @@ private: // #pragma mark - template and inline methods - +inline uint16 swap16(uint16 val) + { + return ((((val) >> 8) & 0xff) | (((val) & 0xff) << 8)); + } +inline uint32 swap32(uint32 val) + { + return ((((val) & 0xff000000) >> 24) | + (((val) & 0x00ff0000) >> 8) | + (((val) & 0x0000ff00) << 8) | + (((val) & 0x000000ff) << 24)); + } +inline uint64 swap64(uint64 val) + { + return ((((val) & 0xff00000000000000ull) >> 56) | + (((val) & 0x00ff000000000000ull) >> 40) | + (((val) & 0x0000ff0000000000ull) >> 24) | + (((val) & 0x000000ff00000000ull) >> 8 ) | + (((val) & 0x00000000ff000000ull) << 8 ) | + (((val) & 0x0000000000ff0000ull) << 24) | + (((val) & 0x000000000000ff00ull) << 40) | + (((val) & 0x00000000000000ffull) << 56)); + } template<typename Header, uint32 kMagic, uint16 kVersion, uint16 kMinorVersion> status_t ReaderImplBase::Init(int fd, bool keepFD, Header& header, uint32 flags) { + printf("_Init\n"); status_t error = _Init(fd, keepFD); - if (error != B_OK) + printf("go? "); + if (error != B_OK) { + printf("no\n"); return error; + } + printf("yes\n"); // stat the file struct stat st; - if (fstat(FD(), &st) < 0) { - ErrorOutput()->PrintError("Error: Failed to access %s file: %s\n", + if (fstat(FD(), &st) < 0) { + printf("Error: Failed to access %s file: %s\n", fFileType, strerror(errno)); return errno; } @@ -449,37 +475,39 @@ ReaderImplBase::Init(int fd, bool keepFD, Header& header, uint32 flags) // check the header // magic - if (B_BENDIAN_TO_HOST_INT32(header.magic) != kMagic) { - ErrorOutput()->PrintError("Error: Invalid %s file: Invalid " + if (swap32(header.magic) != kMagic) { + printf("Error: Invalid %s file: Invalid " "magic\n", fFileType); + printf("kMagic = %x; header.magic = %x; header.magic (bendian) = %x\n", + kMagic, header.magic, swap32(header.magic)); return B_BAD_DATA; } // version - if (B_BENDIAN_TO_HOST_INT16(header.version) != kVersion) { + if (swap16(header.version) != kVersion) { if ((flags & B_HPKG_READER_DONT_PRINT_VERSION_MISMATCH_MESSAGE) == 0) { - ErrorOutput()->PrintError("Error: Invalid/unsupported %s file " + printf("Error: Invalid/unsupported %s file " "version (%d)\n", fFileType, - B_BENDIAN_TO_HOST_INT16(header.version)); + swap16(header.version)); } return B_MISMATCHED_VALUES; } - fMinorFormatVersion = B_BENDIAN_TO_HOST_INT16(header.minor_version); + fMinorFormatVersion = swap16(header.minor_version); fCurrentMinorFormatVersion = kMinorVersion; // header size - uint64 heapOffset = B_BENDIAN_TO_HOST_INT16(header.header_size); + uint64 heapOffset = swap16(header.header_size); if (heapOffset < (off_t)sizeof(header)) { - ErrorOutput()->PrintError("Error: Invalid %s file: Invalid header " + printf("Error: Invalid %s file: Invalid header " "size (%" B_PRIu64 ")\n", fFileType, heapOffset); return B_BAD_DATA; } // total size - uint64 totalSize = B_BENDIAN_TO_HOST_INT64(header.total_size); + uint64 totalSize = swap64(header.total_size); if (totalSize != (uint64)st.st_size) { - ErrorOutput()->PrintError("Error: Invalid %s file: Total size in " + printf("Error: Invalid %s file: Total size in " "header (%" B_PRIu64 ") doesn't agree with total file size (%" B_PRIdOFF ")\n", fFileType, totalSize, st.st_size); return B_BAD_DATA; @@ -487,10 +515,10 @@ ReaderImplBase::Init(int fd, bool keepFD, Header& header, uint32 flags) // heap size uint64 compressedHeapSize - = B_BENDIAN_TO_HOST_INT64(header.heap_size_compressed); + = swap64(header.heap_size_compressed); if (compressedHeapSize > totalSize || heapOffset > totalSize - compressedHeapSize) { - ErrorOutput()->PrintError("Error: Invalid %s file: Heap size in " + printf("Error: Invalid %s file: Heap size in " "header (%" B_PRIu64 ") doesn't agree with total file size (%" B_PRIu64 ") and heap offset (%" B_PRIu64 ")\n", fFileType, compressedHeapSize, totalSize, heapOffset); @@ -498,10 +526,10 @@ ReaderImplBase::Init(int fd, bool keepFD, Header& header, uint32 flags) } error = InitHeapReader( - B_BENDIAN_TO_HOST_INT16(header.heap_compression), - B_BENDIAN_TO_HOST_INT32(header.heap_chunk_size), heapOffset, + swap16(header.heap_compression), + swap32(header.heap_chunk_size), heapOffset, compressedHeapSize, - B_BENDIAN_TO_HOST_INT64(header.heap_size_uncompressed)); + swap64(header.heap_size_uncompressed)); if (error != B_OK) return error; diff --git a/src/kits/package/hpkg/PackageReaderImpl.cpp b/src/kits/package/hpkg/PackageReaderImpl.cpp index b821d4c..47cf05c 100644 --- a/src/kits/package/hpkg/PackageReaderImpl.cpp +++ b/src/kits/package/hpkg/PackageReaderImpl.cpp @@ -335,38 +335,62 @@ status_t PackageReaderImpl::Init(int fd, bool keepFD, uint32 flags) { hpkg_header header; + printf("::Init (printf)\n"); + ErrorOutput()->PrintError("::Init (error-output)\n"); + printf(".. "); status_t error = inherited::Init<hpkg_header, B_HPKG_MAGIC, B_HPKG_VERSION, B_HPKG_MINOR_VERSION>(fd, keepFD, header, flags); - if (error != B_OK) + printf(".. "); + if (error != B_OK) { + printf("!!\n"); return error; + } + printf(".. "); fHeapSize = UncompressedHeapSize(); // init package attributes section + printf(".. "); error = InitSection(fPackageAttributesSection, fHeapSize, B_BENDIAN_TO_HOST_INT32(header.attributes_length), kMaxPackageAttributesSize, B_BENDIAN_TO_HOST_INT32(header.attributes_strings_length), B_BENDIAN_TO_HOST_INT32(header.attributes_strings_count)); - if (error != B_OK) + printf(".. "); + if (error != B_OK) { + printf("!!\n"); return error; - + } + // init TOC section + printf(".. "); error = InitSection(fTOCSection, fPackageAttributesSection.offset, B_BENDIAN_TO_HOST_INT64(header.toc_length), kMaxTOCSize, B_BENDIAN_TO_HOST_INT64(header.toc_strings_length), B_BENDIAN_TO_HOST_INT64(header.toc_strings_count)); - if (error != B_OK) + printf(".. "); + if (error != B_OK) { + printf("!!\n"); return error; - + } + // prepare the sections for use + printf(".. "); error = PrepareSection(fTOCSection); - if (error != B_OK) + printf(".. "); + if (error != B_OK) { + printf("!!\n"); return error; - + } + + printf(".. "); error = PrepareSection(fPackageAttributesSection); - if (error != B_OK) + printf(".. "); + if (error != B_OK) { + printf("!!\n"); return error; - + } + + printf(":-)\n"); return B_OK; } diff --git a/src/kits/package/hpkg/ReaderImplBase.cpp b/src/kits/package/hpkg/ReaderImplBase.cpp index e5c1564..9e34cfe 100644 --- a/src/kits/package/hpkg/ReaderImplBase.cpp +++ b/src/kits/package/hpkg/ReaderImplBase.cpp @@ -1055,9 +1055,10 @@ ReaderImplBase::_Init(int fd, bool keepFD) fOwnsFD = keepFD; // allocate a scratch buffer + printf("allocating scratch buffer of size %ld\n", kScratchBufferSize); fScratchBuffer = new(std::nothrow) uint8[kScratchBufferSize]; if (fScratchBuffer == NULL) { - fErrorOutput->PrintError("Error: Out of memory!\n"); + printf("ReaderImplBase::_Init: Out of memory!\n"); return B_NO_MEMORY; } fScratchBufferSize = kScratchBufferSize; diff --git a/src/system/boot/loader/file_systems/packagefs/packagefs.cpp b/src/system/boot/loader/file_systems/packagefs/packagefs.cpp index 5223662..83ed184 100644 --- a/src/system/boot/loader/file_systems/packagefs/packagefs.cpp +++ b/src/system/boot/loader/file_systems/packagefs/packagefs.cpp @@ -834,44 +834,62 @@ status_t packagefs_mount_file(int fd, ::Directory* systemDirectory, ::Directory*& _mountedDirectory) { + kprintf("create the error output\n"); PackageLoaderErrorOutput errorOutput; + kprintf("create the package reader\n"); PackageReaderImpl packageReader(&errorOutput); + kprintf("check init\n"); status_t error = packageReader.Init(fd, false, 0); - if (error != B_OK) + if (error != B_OK) { + kprintf("failed\n"); RETURN_ERROR(error); + } // create the volume + kprintf("create the volume\n"); PackageVolume* volume = new(std::nothrow) PackageVolume; if (volume == NULL) return B_NO_MEMORY; BReference<PackageVolume> volumeReference(volume, true); error = volume->Init(fd, packageReader.RawHeapReader()); - if (error != B_OK) + if (error != B_OK) { + kprintf("init failed\n"); RETURN_ERROR(error); + } // load settings for the package + kprintf("load settings for package\n"); PackageSettingsItem* settings = PackageSettingsItem::Load(systemDirectory, "haiku"); ObjectDeleter<PackageSettingsItem> settingsDeleter(settings); // parse content -- this constructs the entry/node tree + kprintf("parse content\n"); PackageLoaderContentHandler handler(volume, settings); error = handler.Init(); - if (error != B_OK) + if (error != B_OK) { + kprintf("init failed\n"); RETURN_ERROR(error); + } error = packageReader.ParseContent(&handler); - if (error != B_OK) + if (error != B_OK) { + kprintf("parsing failed\n"); RETURN_ERROR(error); + } // create a VFS node for the root node + kprintf("create vfs node for root\n"); ::Node* rootNode; error = create_node(volume->RootDirectory(), rootNode); - if (error != B_OK) + if (error != B_OK) { + kprintf("failed\n"); RETURN_ERROR(error); + } _mountedDirectory = static_cast< ::Directory*>(rootNode); + kprintf("success\n"); return B_OK; } diff --git a/src/system/boot/loader/heap.cpp b/src/system/boot/loader/heap.cpp index af6da19..7c7a720 100644 --- a/src/system/boot/loader/heap.cpp +++ b/src/system/boot/loader/heap.cpp @@ -21,7 +21,7 @@ //#define TRACE_HEAP #ifdef TRACE_HEAP -# define TRACE(format...) dprintf(format) +# define TRACE(format...) kprintf(format) #else # define TRACE(format...) do { } while (false) #endif @@ -262,12 +262,12 @@ malloc_large(size_t size) { LargeAllocation* allocation = new(std::nothrow) LargeAllocation; if (allocation == NULL) { - dprintf("malloc_large(): Out of memory!\n"); + kprintf("malloc_large(): Out of memory!\n"); return NULL; } if (allocation->Allocate(size) != B_OK) { - dprintf("malloc_large(): Out of memory!\n"); + kprintf("malloc_large(): Out of memory!\n"); delete allocation; return NULL; } @@ -392,7 +392,7 @@ void heap_print_statistics() { #ifdef DEBUG_MAX_HEAP_USAGE - dprintf("maximum boot loader heap usage: %zu, currently used: %zu\n", + kprintf("maximum boot loader heap usage: %zu, currently used: %zu\n", sMaxHeapUsage, sMaxHeapSize - sAvailable); #endif } @@ -464,11 +464,13 @@ malloc(size_t size) size = sizeof(FreeChunkData); size = align(size); - if (size >= kLargeAllocationThreshold) + if (size >= kLargeAllocationThreshold) { + kprintf("using large allocator\n"); return malloc_large(size); + } if (size > sAvailable) { - dprintf("malloc(): Out of memory!\n"); + kprintf("malloc(): Out of memory!\n"); return NULL; } @@ -477,7 +479,7 @@ malloc(size_t size) if (chunk == NULL) { // could not find a free chunk as large as needed - dprintf("malloc(): Out of memory!\n"); + kprintf("malloc(): Out of memory!\n"); return NULL; } diff --git a/src/system/boot/loader/loader.cpp b/src/system/boot/loader/loader.cpp index 9824ee5..cd89e0e 100644 --- a/src/system/boot/loader/loader.cpp +++ b/src/system/boot/loader/loader.cpp @@ -61,8 +61,10 @@ open_maybe_packaged(BootVolume& volume, const char* path, int openMode) if (strncmp(path, kSystemDirectoryPrefix, strlen(kSystemDirectoryPrefix)) == 0) { path += strlen(kSystemDirectoryPrefix); + kprintf("open from system directory with path %s\n", path); return open_from(volume.SystemDirectory(), path, openMode); } + kprintf("open from root directory with path %s\n", path); return open_from(volume.RootDirectory(), path, openMode); } @@ -72,6 +74,7 @@ static int find_kernel(BootVolume& volume, const char** name = NULL) { for (int32 i = 0; sKernelPaths[i][0] != NULL; i++) { + kprintf("maybe packaged at %s\n", sKernelPaths[i][0]); int fd = open_maybe_packaged(volume, sKernelPaths[i][0], O_RDONLY); if (fd >= 0) { if (name) @@ -88,14 +91,21 @@ find_kernel(BootVolume& volume, const char** name = NULL) bool is_bootable(Directory *volume) { - if (volume->IsEmpty()) + kprintf("check if empty...\n"); + if (volume->IsEmpty()) { + kprintf("is empty\n"); return false; + } + kprintf("set to boot volume...\n"); BootVolume bootVolume; - if (bootVolume.SetTo(volume) != B_OK) + if (bootVolume.SetTo(volume) != B_OK) { + kprintf("can't make it a boot volume\n"); return false; + } // check for the existance of a kernel (for our platform) + kprintf("looking for a kernel...\n"); int fd = find_kernel(bootVolume); if (fd < 0) return false; diff --git a/src/system/boot/loader/main.cpp b/src/system/boot/loader/main.cpp index 62de4a5..1a3a9a6 100644 --- a/src/system/boot/loader/main.cpp +++ b/src/system/boot/loader/main.cpp @@ -53,6 +53,10 @@ main(stage2_args *args) #endif if (vfs_init(args) < B_OK) panic("Could not initialize VFS!\n"); + + // the following fails?! + //uint8 *test = new(std::nothrow) uint8[65536]; + uint8 *test = (uint8*)malloc(sizeof(uint8) * 65536); kprintf("Welcome to the Haiku boot loader!\n"); diff --git a/src/system/boot/loader/menu.cpp b/src/system/boot/loader/menu.cpp index 4aa756c..9fd6de5 100644 --- a/src/system/boot/loader/menu.cpp +++ b/src/system/boot/loader/menu.cpp @@ -1063,6 +1063,7 @@ debug_menu_save_previous_syslog(Menu* menu, MenuItem* item) static Menu* add_boot_volume_menu(Directory* bootVolume) { + TRACE(("add boot volume menu...\n")); Menu* menu = new(std::nothrow) Menu(CHOICE_MENU, "Select Boot Volume"); MenuItem* item; void* cookie; @@ -1072,11 +1073,17 @@ add_boot_volume_menu(Directory* bootVolume) Directory* volume; while (gRoot->GetNextNode(cookie, (Node**)&volume) == B_OK) { // only list bootable volumes - if (volume != bootVolume && !is_bootable(volume)) + TRACE(("next volume... (%p)\n", volume)); + if (volume != bootVolume && !is_bootable(volume)) { + TRACE(("not boot volume and not bootable\n")); continue; + } else { + TRACE(("getting the name, and trying to add...\n")); + } char name[B_FILE_NAME_LENGTH]; if (volume->GetName(name, sizeof(name)) == B_OK) { + TRACE(("adding %s\n", name)); menu->AddItem(item = new(nothrow) MenuItem(name)); item->SetTarget(user_menu_boot_volume); item->SetData(volume); diff --git a/src/system/boot/loader/vfs.cpp b/src/system/boot/loader/vfs.cpp index 279c557..b4bbaf6 100644 --- a/src/system/boot/loader/vfs.cpp +++ b/src/system/boot/loader/vfs.cpp @@ -424,38 +424,51 @@ BootVolume::SetTo(Directory* rootDirectory) return B_BAD_VALUE; fRootDirectory = rootDirectory; + kprintf("acquire root directory\n"); fRootDirectory->Acquire(); // find the system directory + kprintf("lookup system node\n"); Node* systemNode = fRootDirectory->Lookup("system", true); if (systemNode == NULL || !S_ISDIR(systemNode->Type())) { if (systemNode != NULL) systemNode->Release(); Unset(); + kprintf("system node null or not a directory (%s)\n", systemNode == NULL ? "null" : "not dir"); return B_ENTRY_NOT_FOUND; } + kprintf("cast to Directory\n"); fSystemDirectory = static_cast<Directory*>(systemNode); // try opening the system package + kprintf("open system package\n"); int packageFD = _OpenSystemPackage(); fPackaged = packageFD >= 0; - if (!fPackaged) + if (!fPackaged) { + kprintf("not a packaged system\n"); return B_OK; + } // the system is packaged -- mount the packagefs Directory* packageRootDirectory; + kprintf("mounting packagefs\n"); status_t error = packagefs_mount_file(packageFD, fSystemDirectory, packageRootDirectory); + kprintf("releasing file descriptor\n"); close(packageFD); if (error != B_OK) { Unset(); + kprintf("mounting failed\n"); return error; } + kprintf("releasing system directory\n"); fSystemDirectory->Release(); + kprintf("system directory is now package root\n"); fSystemDirectory = packageRootDirectory; + kprintf("done!\n"); return B_OK; } diff --git a/src/system/boot/platform/efi/debug.cpp b/src/system/boot/platform/efi/debug.cpp index b1191de..8d460c1 100644 --- a/src/system/boot/platform/efi/debug.cpp +++ b/src/system/boot/platform/efi/debug.cpp @@ -89,20 +89,25 @@ void panic(const char *format, ...) { va_list list; + + //platform_switch_to_text_mode(); - platform_switch_to_text_mode(); - - puts("*** PANIC ***"); + //puts("*** PANIC ***"); va_start(list, format); - vprintf(format, list); + // print to console, if available + if (stdout != NULL) + vfprintf(stdout, format, list); + else + vprintf(format, list); va_end(list); - puts("\nPress key to reboot."); + //puts("\nPress key to reboot."); clear_key_buffer(); wait_for_key(); - platform_exit(); + //platform_exit(); + while (true) { }; } diff --git a/src/system/boot/platform/efi/heap.cpp b/src/system/boot/platform/efi/heap.cpp index 75e73df..e847f45 100644 --- a/src/system/boot/platform/efi/heap.cpp +++ b/src/system/boot/platform/efi/heap.cpp @@ -10,29 +10,63 @@ #include <boot/stage2.h> #include <boot/stdio.h> -#define STAGE_PAGES 10000 /* 64 MB */ +#define STAGE_PAGES 0x10000 /* 256 MB */ +#define PAGE_SIZE 0x1000 /* 4kB */ + EFI_PHYSICAL_ADDRESS staging; + void platform_release_heap(struct stage2_args *args, void *base) { - // TODO + ASSERT((void*)&staging == base); + kSystemTable->BootServices->FreePages(staging, STAGE_PAGES); } status_t platform_init_heap(struct stage2_args *args, void **_base, void **_top) { - kSystemTable->BootServices->AllocatePages( - AllocateAnyPages, EfiLoaderData, STAGE_PAGES, &staging); - // get_next_physical_address(args->heap_size); + size_t heap_size = args->heap_size / PAGE_SIZE; + while ((kSystemTable->BootServices->AllocatePages( + AllocateAnyPages, EfiLoaderData, STAGE_PAGES, &staging) + != EFI_SUCCESS) && (heap_size >= STAGE_PAGES)) { + heap_size /= 2; + } kprintf("heap address = %lx\n", staging); if (staging == 0l) return B_NO_MEMORY; *_base = (void *)staging; - *_top = (void *)((int8 *)staging + STAGE_PAGES); + *_top = (void *)((int8 *)staging + heap_size); kprintf("heap: base = %lx, top = %lx\n", (uint64)*_base, (uint64)*_top); return B_OK; } + + +extern "C" status_t +platform_allocate_region(void **_address, size_t size, uint8 protection, bool /* exactAddress */) +{ + EFI_STATUS status; + + status = kSystemTable->BootServices-> + AllocatePool(EfiLoaderData, size, _address); + if (status != EFI_SUCCESS) { + kprintf("platform_allocate_region: %d\n", status); + return B_NO_MEMORY; + } + + return B_OK; +} + + +extern "C" status_t +platform_free_region(void *address, size_t /* size */) +{ + /*EFI_STATUS status; + + status = kSystemTable->BootServices->FreePool(address);*/ + + return B_OK; +} ############################################################################ Commit: 53beb3af446f53a7bf5d9c3984a3c1126ec5baa6 Author: Jessica Hamilton <jessica.l.hamilton@xxxxxxxxx> Date: Wed Apr 16 11:07:59 2014 UTC UEFI: lots more debug, no real progress... ---------------------------------------------------------------------------- diff --git a/headers/private/package/hpkg/ReaderImplBase.h b/headers/private/package/hpkg/ReaderImplBase.h index c06850b..e2fc2ec 100644 --- a/headers/private/package/hpkg/ReaderImplBase.h +++ b/headers/private/package/hpkg/ReaderImplBase.h @@ -524,6 +524,13 @@ ReaderImplBase::Init(int fd, bool keepFD, Header& header, uint32 flags) compressedHeapSize, totalSize, heapOffset); return B_BAD_DATA; } + + printf("heap compression: %ld, heap chunk size: %ld, heap offset: %ld, compressed heap size: %ld, uncompressed heap size: %ld\n", + swap16(header.heap_compression), + swap32(header.heap_chunk_size), + heapOffset, + compressedHeapSize, + swap64(header.heap_size_uncompressed)); error = InitHeapReader( swap16(header.heap_compression), diff --git a/src/kits/package/hpkg/DataReader.cpp b/src/kits/package/hpkg/DataReader.cpp index 97bc29f..bd1b1b1 100644 --- a/src/kits/package/hpkg/DataReader.cpp +++ b/src/kits/package/hpkg/DataReader.cpp @@ -68,6 +68,7 @@ BBufferDataReader::ReadData(off_t offset, void* buffer, size_t size) return B_OK; } +#include <stdio.h> status_t BBufferDataReader::ReadDataToOutput(off_t offset, size_t size, @@ -76,8 +77,10 @@ BBufferDataReader::ReadDataToOutput(off_t offset, size_t size, if (size == 0) return B_OK; - if (offset < 0) + if (offset < 0) { + printf("B_BAD_VALUE: offset = %ld\n", offset); return B_BAD_VALUE; + } if (size > fSize || offset > (off_t)fSize - (off_t)size) return B_ERROR; diff --git a/src/kits/package/hpkg/PackageReaderImpl.cpp b/src/kits/package/hpkg/PackageReaderImpl.cpp index 47cf05c..e9c60e3 100644 --- a/src/kits/package/hpkg/PackageReaderImpl.cpp +++ b/src/kits/package/hpkg/PackageReaderImpl.cpp @@ -331,6 +331,43 @@ PackageReaderImpl::Init(const char* fileName, uint32 flags) } +inline uint16 __swap16(uint16 val) + { + return ((((val) >> 8) & 0xff) | (((val) & 0xff) << 8)); + } +inline uint32 __swap32(uint32 val) + { + return ((((val) & 0xff000000) >> 24) | + (((val) & 0x00ff0000) >> 8) | + (((val) & 0x0000ff00) << 8) | + (((val) & 0x000000ff) << 24)); + } +inline uint64 __swap64(uint64 val) + { + return ((((val) & 0xff00000000000000ull) >> 56) | + (((val) & 0x00ff000000000000ull) >> 40) | + (((val) & 0x0000ff0000000000ull) >> 24) | + (((val) & 0x000000ff00000000ull) >> 8 ) | + (((val) & 0x00000000ff000000ull) << 8 ) | + (((val) & 0x0000000000ff0000ull) << 24) | + (((val) & 0x000000000000ff00ull) << 40) | + (((val) & 0x00000000000000ffull) << 56)); + } + + #define B_BENDIAN_TO_HOST_INT16 __swap16 + #define B_BENDIAN_TO_HOST_INT32 __swap32 + #define B_BENDIAN_TO_HOST_INT64 __swap64 +# define RETURN_ERROR(err) \ + { \ + status_t _status = err; \ + if (_status < B_OK) { \ + printf("%s:%d: %s\n", __FILE__, __LINE__, strerror(_status)); \ + while (true) { } ; \ + } \ + return _status; \ + } + + status_t PackageReaderImpl::Init(int fd, bool keepFD, uint32 flags) { @@ -342,8 +379,8 @@ PackageReaderImpl::Init(int fd, bool keepFD, uint32 flags) B_HPKG_MINOR_VERSION>(fd, keepFD, header, flags); printf(".. "); if (error != B_OK) { - printf("!!\n"); - return error; + printf("!!\n"); + RETURN_ERROR(error); } printf(".. "); fHeapSize = UncompressedHeapSize(); @@ -357,8 +394,7 @@ PackageReaderImpl::Init(int fd, bool keepFD, uint32 flags) B_BENDIAN_TO_HOST_INT32(header.attributes_strings_count)); printf(".. "); if (error != B_OK) { - printf("!!\n"); - return error; + printf("!!\n");RETURN_ERROR(error); } // init TOC section @@ -369,8 +405,7 @@ PackageReaderImpl::Init(int fd, bool keepFD, uint32 flags) B_BENDIAN_TO_HOST_INT64(header.toc_strings_count)); printf(".. "); if (error != B_OK) { - printf("!!\n"); - return error; + printf("!!\n");RETURN_ERROR(error); } // prepare the sections for use @@ -378,8 +413,7 @@ PackageReaderImpl::Init(int fd, bool keepFD, uint32 flags) error = PrepareSection(fTOCSection); printf(".. "); if (error != B_OK) { - printf("!!\n"); - return error; + printf("!!\n");RETURN_ERROR(error); } printf(".. "); @@ -387,10 +421,12 @@ PackageReaderImpl::Init(int fd, bool keepFD, uint32 flags) printf(".. "); if (error != B_OK) { printf("!!\n"); - return error; + //return error; + RETURN_ERROR(error); } printf(":-)\n"); + while (true) { } ; return B_OK; } diff --git a/src/kits/package/hpkg/ReaderImplBase.cpp b/src/kits/package/hpkg/ReaderImplBase.cpp index 9e34cfe..f71d0f7 100644 --- a/src/kits/package/hpkg/ReaderImplBase.cpp +++ b/src/kits/package/hpkg/ReaderImplBase.cpp @@ -881,6 +881,9 @@ ReaderImplBase::InitSection(PackageFileSection& section, uint64 endOffset, section.currentOffset = 0; section.stringsLength = stringsLength; section.stringsCount = stringsCount; + + printf("real len: %ld, offset: %ld, str len: %ld, str count: %ld\n", + length, endOffset - length, stringsLength, stringsCount); return B_OK; } @@ -1360,6 +1363,7 @@ status_t ReaderImplBase::ReadSection(const PackageFileSection& section) { BBufferDataOutput output(section.data, section.uncompressedLength); + printf("ReaderImplBase::ReadSection at %ld (%ld bytes)\n", section.offset, section.uncompressedLength); return fHeapReader->ReadDataToOutput(section.offset, section.uncompressedLength, &output); } diff --git a/src/system/boot/loader/file_systems/packagefs/packagefs.cpp b/src/system/boot/loader/file_systems/packagefs/packagefs.cpp index 83ed184..e14ed84 100644 --- a/src/system/boot/loader/file_systems/packagefs/packagefs.cpp +++ b/src/system/boot/loader/file_systems/packagefs/packagefs.cpp @@ -841,7 +841,7 @@ packagefs_mount_file(int fd, ::Directory* systemDirectory, kprintf("check init\n"); status_t error = packageReader.Init(fd, false, 0); if (error != B_OK) { - kprintf("failed\n"); + kprintf("failed package reader init\n"); RETURN_ERROR(error); } diff --git a/src/system/boot/platform/efi/debug.cpp b/src/system/boot/platform/efi/debug.cpp index 8d460c1..8292e51 100644 --- a/src/system/boot/platform/efi/debug.cpp +++ b/src/system/boot/platform/efi/debug.cpp @@ -75,7 +75,7 @@ dprintf_args(const char *format, va_list args) syslog_write(buffer, length); serial_puts(buffer, length); - if (platform_boot_options() & BOOT_OPTION_DEBUG_OUTPUT) + //if (platform_boot_options() & BOOT_OPTION_DEBUG_OUTPUT) fprintf(stderr, "%s", buffer); } diff --git a/src/system/boot/platform/efi/heap.cpp b/src/system/boot/platform/efi/heap.cpp index e847f45..b7ed818 100644 --- a/src/system/boot/platform/efi/heap.cpp +++ b/src/system/boot/platform/efi/heap.cpp @@ -34,7 +34,7 @@ platform_init_heap(struct stage2_args *args, void **_base, void **_top) != EFI_SUCCESS) && (heap_size >= STAGE_PAGES)) { heap_size /= 2; } - kprintf("heap address = %lx\n", staging); + kprintf("heap address = %lx, size = %d pages\n", staging, heap_size); if (staging == 0l) return B_NO_MEMORY; @@ -64,9 +64,7 @@ platform_allocate_region(void **_address, size_t size, uint8 protection, bool /* extern "C" status_t platform_free_region(void *address, size_t /* size */) { - /*EFI_STATUS status; - - status = kSystemTable->BootServices->FreePool(address);*/ + kSystemTable->BootServices->FreePool(address); return B_OK; } ############################################################################ Commit: e39eb7f06f2b2677346d00be625ab13b8b0f2d0a Author: Jessica Hamilton <jessica.l.hamilton@xxxxxxxxx> Date: Fri Apr 18 07:44:07 2014 UTC UEFI: More debug and fun. Not sure what to do about MMU. ---------------------------------------------------------------------------- diff --git a/src/system/boot/loader/main.cpp b/src/system/boot/loader/main.cpp index 1a3a9a6..8fa4f2b 100644 --- a/src/system/boot/loader/main.cpp +++ b/src/system/boot/loader/main.cpp @@ -88,6 +88,7 @@ main(stage2_args *args) if (bootVolume.IsValid()) { // we got a volume to boot from! + kprintf("we got a volume to boot from!\n"); status_t status; while ((status = load_kernel(args, bootVolume)) < B_OK) { // loading the kernel failed, so let the user choose another @@ -113,6 +114,7 @@ main(stage2_args *args) // is already loaded at this point and we definitely // know our boot volume, too if (status == B_OK) { + kprintf("everything is looking good!\n"); if (bootVolume.IsPackaged()) { packagefs_apply_path_blacklist(bootVolume.SystemDirectory(), pathBlacklist); diff --git a/src/system/boot/platform/efi/Jamfile b/src/system/boot/platform/efi/Jamfile index e2c8dae..8f9d18a 100644 --- a/src/system/boot/platform/efi/Jamfile +++ b/src/system/boot/platform/efi/Jamfile @@ -28,7 +28,9 @@ BootMergeObject boot_platform_efi.o : menu.cpp heap.cpp # mmu.cpp + acpi.cpp serial.cpp + video.cpp $(efi_glue_src) : : boot_platform_generic.a diff --git a/src/system/boot/platform/efi/acpi.cpp b/src/system/boot/platform/efi/acpi.cpp new file mode 100644 index 0000000..d0b6e29 --- /dev/null +++ b/src/system/boot/platform/efi/acpi.cpp @@ -0,0 +1,280 @@ +/* + * Copyright 2011, Rene Gollent, rene@xxxxxxxxxxx. + * Copyright 2008, Dustin Howett, dustin.howett@xxxxxxxxx. All rights reserved. + * Copyright 2007, Michael Lotz, mmlr@xxxxxxxx + * Copyright 2004-2005, Axel Dörfler, axeld@xxxxxxxxxxxxxxxx. + * Distributed under the terms of the MIT License. + * + * Copyright 2001, Travis Geiselbrecht. All rights reserved. + * Distributed under the terms of the NewOS License. +*/ + + +#include "efi_platform.h" + +#include "acpi.h" +//#include "mmu.h" + +#include <string.h> + +#include <KernelExport.h> + + +#define TRACE_ACPI +#ifdef TRACE_ACPI +# define TRACE(x) dprintf x +#else +# define TRACE(x) ; +#endif + +static acpi_descriptor_header* sAcpiRsdt; // System Description Table +static acpi_descriptor_header* sAcpiXsdt; // Extended System Description Table +static int32 sNumEntries = -1; + +#define EFI_PAGE_SIZE 4096 + +static addr_t +mmu_map_physical_memory(addr_t physicalAddress, size_t size) +{ + #if 0 + addr_t pageOffset = physicalAddress & (EFI_PAGE_SIZE - 1); + + physicalAddress -= pageOffset; + size += pageOffset; + + EFI_STATUS status = + kSystemTable->BootServices->AllocatePages(AllocateAddress, EfiLoaderData, + size / EFI_PAGE_SIZE + 1, &physicalAddress); + if (status != EFI_SUCCESS) + panic("mmu_map_physical_memory failed: %d; phys address = %lx, size = %ld", + status, physicalAddress, size); + #endif + return physicalAddress; +} + + +static void +mmu_free(void *virtualAddress, size_t size) +{ + TRACE(("mmu_free: not implemented\n")); +} + + +static status_t +acpi_validate_rsdp(acpi_rsdp* rsdp) +{ + const char* data = (const char*)rsdp; + unsigned char checksum = 0; + for (uint32 i = 0; i < sizeof(acpi_rsdp_legacy); i++) + checksum += data[i]; + + if ((checksum & 0xff) != 0) { + TRACE(("acpi: rsdp failed basic checksum\n")); + return B_BAD_DATA; + } + + // for ACPI 2.0+ we need to also validate the extended checksum + if (rsdp->revision > 0) { + for (uint32 i = sizeof(acpi_rsdp_legacy); + i < sizeof(acpi_rsdp_extended); i++) { + checksum += data[i]; + } + + if ((checksum & 0xff) != 0) { + TRACE(("acpi: rsdp failed extended checksum\n")); + return B_BAD_DATA; + } + } + + return B_OK; +} + + +static status_t +acpi_validate_rsdt(acpi_descriptor_header* rsdt) +{ + const char* data = (const char*)rsdt; + unsigned char checksum = 0; + for (uint32 i = 0; i < rsdt->length; i++) + checksum += data[i]; + + return checksum == 0 ? B_OK : B_BAD_DATA; +} + + +static status_t +acpi_check_rsdt(acpi_rsdp* rsdp) +{ + if (acpi_validate_rsdp(rsdp) != B_OK) + return B_BAD_DATA; + + bool usingXsdt = false; + [ *** diff truncated: 264 lines dropped *** ] ############################################################################ Commit: c709aecd4e21ef61c4b85c2fd66685dc73c70e1c Author: Jessica Hamilton <jessica.l.hamilton@xxxxxxxxx> Date: Tue Apr 22 23:00:44 2014 UTC UEFI: redo creating the heap ----------------------------------------------------------------------------