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
This commit is contained in:
Michael Pfeiffer 2008-04-19 07:43:03 +00:00
parent 1dde19ddbc
commit 88321c8cd5
4 changed files with 100 additions and 50 deletions

View File

@ -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
};

View File

@ -10,6 +10,7 @@
#include "LegacyBootDrive.h"
#include <Drivers.h>
#include <DiskDevice.h>
#include <DiskDeviceRoster.h>
#include <DiskDeviceVisitor.h>
@ -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)
{

View File

@ -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,

View File

@ -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