From 88321c8cd55f5fd9e1720a799769ec8e0b1bd4a2 Mon Sep 17 00:00:00 2001 From: Michael Pfeiffer Date: Sat, 19 Apr 2008 07:43:03 +0000 Subject: [PATCH] Prepared bootman to boot from other than the first drive. The ioctl B_GET_BIOS_DRIVE_ID still needs to be implemented. Only partitions from the first drive can be added to the boot menu, until B_GET_BIOS_DRIVE_ID is implemented. Fixed bug calculating the offset of the first partition. off_t is a signed type, the fact? that Be FS is a 64-bit filesystem, lead me to the wrong assumption that this is an unsigned type :-( git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@25044 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- src/apps/bootman/BootLoader.h | 56 ++++++++++------------- src/apps/bootman/LegacyBootDrive.cpp | 68 ++++++++++++++++++++++------ src/apps/bootman/LegacyBootDrive.h | 1 + src/apps/bootman/bootman.S | 25 ++++++++-- 4 files changed, 100 insertions(+), 50 deletions(-) diff --git a/src/apps/bootman/BootLoader.h b/src/apps/bootman/BootLoader.h index 87f03d84e4..3b6c9907c7 100644 --- a/src/apps/bootman/BootLoader.h +++ b/src/apps/bootman/BootLoader.h @@ -34,36 +34,30 @@ static const uint8 kBootLoader[] = { 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x55, 0xaa, - 0xa1, 0x99, 0x03, 0xa3, 0x46, 0x03, 0xb8, 0x13, 0x00, 0xf7, 0x26, 0x9b, 0x03, 0x89, 0xd3, 0x50, - 0xb4, 0x00, 0xcd, 0x1a, 0x58, 0x01, 0xd0, 0x11, 0xcb, 0xa3, 0x4a, 0x03, 0x89, 0x1e, 0x4c, 0x03, - 0xa0, 0x97, 0x03, 0xd0, 0xe8, 0xb3, 0x0c, 0x28, 0xc3, 0x88, 0x1e, 0x48, 0x03, 0xe8, 0x65, 0x00, - 0x81, 0x3e, 0x9b, 0x03, 0xff, 0xff, 0x74, 0x27, 0xb4, 0x01, 0xcd, 0x16, 0x75, 0x21, 0xe8, 0x05, - 0x00, 0x73, 0xf5, 0xe9, 0x9b, 0x00, 0xb4, 0x00, 0xcd, 0x1a, 0x3b, 0x0e, 0x4c, 0x03, 0x72, 0x08, - 0x77, 0x08, 0x3b, 0x16, 0x4a, 0x03, 0x77, 0x02, 0xf8, 0xc3, 0xf9, 0xc3, 0xe8, 0x36, 0x00, 0xb4, + 0xa1, 0x9a, 0x03, 0xa3, 0x47, 0x03, 0xb8, 0x13, 0x00, 0xf7, 0x26, 0x9c, 0x03, 0x89, 0xd3, 0x50, + 0xb4, 0x00, 0xcd, 0x1a, 0x58, 0x01, 0xd0, 0x11, 0xcb, 0xa3, 0x4b, 0x03, 0x89, 0x1e, 0x4d, 0x03, + 0xa0, 0x98, 0x03, 0xd0, 0xe8, 0xb3, 0x0c, 0x28, 0xc3, 0x88, 0x1e, 0x49, 0x03, 0xe8, 0x65, 0x00, + 0x81, 0x3e, 0x9c, 0x03, 0xff, 0xff, 0x74, 0x27, 0xb4, 0x01, 0xcd, 0x16, 0x75, 0x21, 0xe8, 0x05, + 0x00, 0x73, 0xf5, 0xe9, 0x9b, 0x00, 0xb4, 0x00, 0xcd, 0x1a, 0x3b, 0x0e, 0x4d, 0x03, 0x72, 0x08, + 0x77, 0x08, 0x3b, 0x16, 0x4b, 0x03, 0x77, 0x02, 0xf8, 0xc3, 0xf9, 0xc3, 0xe8, 0x36, 0x00, 0xb4, 0x00, 0xcd, 0x16, 0x80, 0xfc, 0x50, 0x74, 0x0c, 0x80, 0xfc, 0x48, 0x74, 0x18, 0x80, 0xfc, 0x1c, - 0x74, 0x6f, 0xeb, 0xeb, 0xa1, 0x46, 0x03, 0x40, 0x3b, 0x06, 0x97, 0x03, 0x75, 0x02, 0x31, 0xc0, - 0xa3, 0x46, 0x03, 0xeb, 0xd7, 0xa1, 0x46, 0x03, 0x09, 0xc0, 0x75, 0x03, 0xa1, 0x97, 0x03, 0x48, - 0xa3, 0x46, 0x03, 0xeb, 0xc7, 0xa0, 0x48, 0x03, 0xa2, 0x49, 0x03, 0xbe, 0x9d, 0x03, 0x31, 0xc9, - 0xac, 0xfe, 0xc8, 0xd0, 0xe8, 0xb2, 0x28, 0x28, 0xc2, 0x8a, 0x36, 0x49, 0x03, 0xb4, 0x02, 0xcd, - 0x10, 0x89, 0xcf, 0x81, 0xe7, 0x03, 0x00, 0x8a, 0x9d, 0x5e, 0x03, 0x3b, 0x0e, 0x46, 0x03, 0x75, - 0x03, 0x80, 0xf3, 0x08, 0xe8, 0x56, 0x00, 0x81, 0xc6, 0x08, 0x00, 0xfe, 0x06, 0x49, 0x03, 0x41, - 0x3b, 0x0e, 0x97, 0x03, 0x75, 0xca, 0xb4, 0x02, 0xba, 0x1a, 0x15, 0xba, 0x1c, 0x18, 0xcd, 0x10, - 0xc3, 0xbe, 0x9d, 0x03, 0x8b, 0x0e, 0x46, 0x03, 0x41, 0x30, 0xe4, 0xe9, 0x04, 0x00, 0x81, 0xc6, - 0x08, 0x00, 0xac, 0x01, 0xc6, 0xe2, 0xf7, 0xbf, 0x56, 0x03, 0xb9, 0x04, 0x00, 0xad, 0xab, 0xe2, - 0xfc, 0xb4, 0x42, 0xb2, 0x80, 0xbe, 0x4e, 0x03, 0xcd, 0x13, 0xbe, 0x62, 0x03, 0x72, 0x2a, 0xa1, - 0xfe, 0x01, 0x3d, 0x55, 0xaa, 0xbe, 0x78, 0x03, 0x75, 0x1f, 0xe9, 0xe3, 0xfc, 0x51, 0xe9, 0x11, - 0x00, 0xb9, 0x01, 0x00, 0xb4, 0x09, 0xcd, 0x10, 0xb4, 0x03, 0xcd, 0x10, 0xfe, 0xc2, 0xb4, 0x02, - 0xcd, 0x10, 0xac, 0x3c, 0x00, 0x75, 0xea, 0x59, 0xc3, 0xbb, 0x0f, 0x00, 0xe8, 0xde, 0xff, 0xb4, - 0x00, 0xcd, 0x16, 0xf4, 0xeb, 0xf9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, - 0x01, 0x00, 0x00, 0x00, 0xc0, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x04, - 0x03, 0x02, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x20, 0x6c, 0x6f, 0x61, 0x64, 0x69, 0x6e, 0x67, 0x20, - 0x73, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x73, 0x00, 0x4e, 0x6f, 0x74, 0x20, 0x61, 0x20, 0x62, 0x6f, - 0x6f, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x20, 0x70, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, - 0x00, 0x42, 0x6f, 0x6f, 0x74, 0x21, 0x00, 0x06, 0x00, 0x02, 0x00, 0x05, 0x00, 0x06, 0x48, 0x41, - 0x49, 0x4b, 0x55, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x46, 0x72, 0x65, - 0x65, 0x42, 0x53, 0x44, 0x00, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x44, 0x4f, - 0x53, 0x00, 0x3e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x4c, 0x49, 0x4e, 0x55, 0x58, - 0x00, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x42, 0x65, 0x4f, 0x53, 0x20, 0x52, - 0x35, 0x00, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x4f, 0x70, 0x65, 0x6e, 0x42, - 0x53, 0x44, 0x00, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + 0x74, 0x6f, 0xeb, 0xeb, 0xa1, 0x47, 0x03, 0x40, 0x3b, 0x06, 0x98, 0x03, 0x75, 0x02, 0x31, 0xc0, + 0xa3, 0x47, 0x03, 0xeb, 0xd7, 0xa1, 0x47, 0x03, 0x09, 0xc0, 0x75, 0x03, 0xa1, 0x98, 0x03, 0x48, + 0xa3, 0x47, 0x03, 0xeb, 0xc7, 0xa0, 0x49, 0x03, 0xa2, 0x4a, 0x03, 0xbe, 0x9e, 0x03, 0x31, 0xc9, + 0xac, 0xfe, 0xc8, 0xd0, 0xe8, 0xb2, 0x28, 0x28, 0xc2, 0x8a, 0x36, 0x4a, 0x03, 0xb4, 0x02, 0xcd, + 0x10, 0x89, 0xcf, 0x81, 0xe7, 0x03, 0x00, 0x8a, 0x9d, 0x5f, 0x03, 0x3b, 0x0e, 0x47, 0x03, 0x75, + 0x03, 0x80, 0xf3, 0x08, 0xe8, 0x57, 0x00, 0x81, 0xc6, 0x09, 0x00, 0xfe, 0x06, 0x4a, 0x03, 0x41, + 0x3b, 0x0e, 0x98, 0x03, 0x75, 0xca, 0xb4, 0x02, 0xba, 0x1a, 0x15, 0xba, 0x1c, 0x18, 0xcd, 0x10, + 0xc3, 0xbe, 0x9e, 0x03, 0x8b, 0x0e, 0x47, 0x03, 0x41, 0x30, 0xe4, 0xe9, 0x04, 0x00, 0x81, 0xc6, + 0x09, 0x00, 0xac, 0x01, 0xc6, 0xe2, 0xf7, 0xac, 0x88, 0xc2, 0xbf, 0x57, 0x03, 0xb9, 0x04, 0x00, + 0xad, 0xab, 0xe2, 0xfc, 0xb4, 0x42, 0xbe, 0x4f, 0x03, 0xcd, 0x13, 0xbe, 0x63, 0x03, 0x72, 0x2a, + 0xa1, 0xfe, 0x01, 0x3d, 0x55, 0xaa, 0xbe, 0x79, 0x03, 0x75, 0x1f, 0xe9, 0xe2, 0xfc, 0x51, 0xe9, + 0x11, 0x00, 0xb9, 0x01, 0x00, 0xb4, 0x09, 0xcd, 0x10, 0xb4, 0x03, 0xcd, 0x10, 0xfe, 0xc2, 0xb4, + 0x02, 0xcd, 0x10, 0xac, 0x3c, 0x00, 0x75, 0xea, 0x59, 0xc3, 0xbb, 0x0f, 0x00, 0xe8, 0xde, 0xff, + 0xb4, 0x00, 0xcd, 0x16, 0xf4, 0xeb, 0xf9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, + 0x00, 0x01, 0x00, 0x00, 0x00, 0xc0, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + 0x04, 0x03, 0x02, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x20, 0x6c, 0x6f, 0x61, 0x64, 0x69, 0x6e, 0x67, + 0x20, 0x73, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x73, 0x00, 0x4e, 0x6f, 0x74, 0x20, 0x61, 0x20, 0x62, + 0x6f, 0x6f, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x20, 0x70, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, + 0x6e, 0x00, 0x42, 0x6f, 0x6f, 0x74, 0x21, 0x00 }; diff --git a/src/apps/bootman/LegacyBootDrive.cpp b/src/apps/bootman/LegacyBootDrive.cpp index 1b4a08e986..36e4e6876d 100644 --- a/src/apps/bootman/LegacyBootDrive.cpp +++ b/src/apps/bootman/LegacyBootDrive.cpp @@ -10,6 +10,7 @@ #include "LegacyBootDrive.h" +#include #include #include #include @@ -33,6 +34,7 @@ #define USE_SECOND_DISK 0 +#define GET_FIRST_BIOS_DRIVE 1 class Buffer : public BMallocIO @@ -109,7 +111,7 @@ Buffer::Fill(int16 size, int8 fillByte) class PartitionRecorder : public BDiskDeviceVisitor { public: - PartitionRecorder(BMessage* settings); + PartitionRecorder(BMessage* settings, int8 drive); virtual bool Visit(BDiskDevice* device); virtual bool Visit(BPartition* partition, int32 level); @@ -121,15 +123,17 @@ private: bool _Record(BPartition* partition); BMessage* fSettings; + int8 fDrive; int32 fIndex; off_t fFirstOffset; }; -PartitionRecorder::PartitionRecorder(BMessage* settings) +PartitionRecorder::PartitionRecorder(BMessage* settings, int8 drive) : fSettings(settings) + , fDrive(drive) , fIndex(0) - , fFirstOffset((off_t)-1) + , fFirstOffset(LONGLONG_MAX) { } @@ -151,7 +155,7 @@ PartitionRecorder::Visit(BPartition* partition, int32 level) bool PartitionRecorder::HasPartitions() const { - return fFirstOffset != (off_t)-1; + return fFirstOffset != LONGLONG_MAX; } @@ -186,14 +190,16 @@ PartitionRecorder::_Record(BPartition* partition) message.AddString("name", name); message.AddString("type", type); message.AddString("path", partitionPath.Path()); + message.AddInt8("drive", fDrive); message.AddInt64("size", partition->ContentSize()); // Specific data - message.AddInt64("offset", partition->Offset()); + off_t offset = partition->Offset(); + message.AddInt64("offset", offset); fSettings->AddMessage("partition", &message); - if (partition->Offset() < fFirstOffset) - fFirstOffset = partition->Offset(); + if (offset < fFirstOffset) + fFirstOffset = offset; return false; } @@ -224,24 +230,35 @@ LegacyBootDrive::ReadPartitions(BMessage *settings) BDiskDevice device; bool diskFound = false; while (diskDeviceRoster.GetNextDevice(&device) == B_OK) { - BPath path; - if (device.GetPath(&path) != B_OK) - return B_ERROR; - PartitionRecorder recorder(settings); + BPath path; + status_t status = device.GetPath(&path); + if (status != B_OK) + return status; + + // skip not from BIOS bootable drives + int8 drive; + if (!_GetBiosDrive(path.Path(), &drive)) + continue; + + PartitionRecorder recorder(settings, drive); device.VisitEachDescendant(&recorder); if (!diskFound) { settings->AddString("disk", path.Path()); diskFound = true; - + #if !USE_SECOND_DISK - // ignored in test build + // Enough space to write boot menu to drive? + // (ignored in test build) off_t size = sizeof(kBootLoader); if (!recorder.HasPartitions() || recorder.FirstOffset() < size) return kErrorBootSectorTooSmall; #endif } + + // TODO remove when booting from all drives works + break; } #if USE_SECOND_DISK @@ -260,7 +277,8 @@ status_t LegacyBootDrive::WriteBootMenu(BMessage *settings) { printf("WriteBootMenu:\n"); - settings->PrintToStream(); + // TODO fix crash since AddInt8("drive", ...) + // settings->PrintToStream(); BString path; if (settings->FindString("disk", &path) != B_OK) @@ -320,15 +338,18 @@ LegacyBootDrive::WriteBootMenu(BMessage *settings) BString name; BString path; int64 offset; + int8 drive; partition.FindBool("show", &show); partition.FindString("name", &name); partition.FindString("path", &path); - // LegacyBootDrive provides offset in message as well + // LegacyBootDrive specific data partition.FindInt64("offset", &offset); + partition.FindInt8("drive", &drive); if (!show) continue; newBootLoader.WriteString(name.String()); + newBootLoader.WriteInt8(drive); newBootLoader.WriteInt64(offset / kBlockSize); } @@ -438,6 +459,23 @@ LegacyBootDrive::RestoreMasterBootRecord(BMessage* settings, BFile* file) } +bool +LegacyBootDrive::_GetBiosDrive(const char* device, int8* drive) +{ + #if !GET_FIRST_BIOS_DRIVE + int fd = open(device, O_RDONLY); + if (fd < 0) + return false; + bool isBootableDrive = ioctl(fd, B_GET_BIOS_DRIVE_ID, drive, 1) == B_OK; + close(fd); + return isBootableDrive; + #else + *drive = 0x80; + return true; + #endif +} + + status_t LegacyBootDrive::_ReadBlocks(int fd, uint8* buffer, size_t size) { diff --git a/src/apps/bootman/LegacyBootDrive.h b/src/apps/bootman/LegacyBootDrive.h index 80c0b60110..b051b757c6 100644 --- a/src/apps/bootman/LegacyBootDrive.h +++ b/src/apps/bootman/LegacyBootDrive.h @@ -40,6 +40,7 @@ public: virtual status_t RestoreMasterBootRecord(BMessage* settings, BFile* file); private: + bool _GetBiosDrive(const char* device, int8* drive); status_t _ReadBlocks(int fd, uint8* buffer, size_t size); status_t _WriteBlocks(int fd, const uint8* buffer, size_t size); void _CopyPartitionTable(MasterBootRecord* destination, diff --git a/src/apps/bootman/bootman.S b/src/apps/bootman/bootman.S index 3af0acd18a..2a2ad8066b 100644 --- a/src/apps/bootman/bootman.S +++ b/src/apps/bootman/bootman.S @@ -126,6 +126,9 @@ %assign BRIGHT_COLOR_MASK 8 +; Characters +%assign TRIANGLE_TO_RIGHT 16 +%assign TRIANGLE_TO_LEFT 17 ; Key codes %assign KEY_DOWN 0x50 @@ -205,6 +208,11 @@ struc AddressPacket .offset nstruc quadword endstruc +struc BootLoaderAddress + .device resb 1 ; hard drive number + .offset nstruc quadword ; LBA of start start sector +endstruc + ; use code available in stage 1 %define printstr printStringStage1 @@ -414,7 +422,7 @@ printMenu: .print: call printstr - add si, sizeof(quadword) ; Skip start sector quad word + add si, sizeof(BootLoaderAddress) inc byte [currentLine] inc cx @@ -443,13 +451,16 @@ bootSelectedPartition: jmp .search_loop_entry .search_loop: - add si, sizeof(quadword) ; Skip to begin of next menu item + add si, sizeof(BootLoaderAddress) .search_loop_entry: lodsb ; Length of menu item name - add si, ax ; Skip name to address of start sector + add si, ax ; Skip name to BootLoaderAddess loop .search_loop + lodsb ; Set boot drive + mov dl, al + mov di, bootSectorDAP+AddressPacket.offset ; Copy start sector mov cx, 4 ; It is stored in a quad word .copy_start_sector @@ -458,7 +469,6 @@ bootSelectedPartition: loop .copy_start_sector mov ah, EXTENDED_READ ; Now read start sector from HD - mov dl, 0x80 ; overwriting our first stage mov si, bootSectorDAP int BIOS_DISK_SERVICES mov si, kReadError @@ -525,6 +535,7 @@ list equ timeout + 2 ; entry: ; db size of partition name 0-terminated string ; db 0-terminated string with partition name +; db hard drive number ; quadword start sector %if USE_TEST_MENU @@ -536,26 +547,32 @@ list equ timeout + 2 db 0x06 db 'HAIKU', 0 + db 0x80 dw 1, 0, 0, 0 db 0x08 db 'FreeBSD', 0 + db 0x80 dw 0x003F, 0, 0, 0 db 0x04 db 'DOS', 0 + db 0x80 dw 0x003E, 0, 0, 0 db 0x06 db 'LINUX', 0 + db 0x80 dw 0x003F, 0, 0, 0 db 0x08 db 'BeOS R5', 0 + db 0x80 dw 0x003F, 0, 0, 0 db 0x07 db 'OpenBSD', 0 + db 0x80 dw 0xAAAA, 0, 0, 0 %endif