The kernel boot code now supports the unknown bus/device method to identify the
boot volume. The other (better) methods are now disabled in the boot loader. This fixes bug #241. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@16895 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
855697b122
commit
fabe8c62ff
@ -14,7 +14,7 @@
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#define TRACE_DEVICES
|
||||
//#define TRACE_DEVICES
|
||||
#ifdef TRACE_DEVICES
|
||||
# define TRACE(x) dprintf x
|
||||
#else
|
||||
@ -367,6 +367,7 @@ get_next_check_sum_offset(int32 index, off_t maxSize)
|
||||
/** 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
|
||||
@ -699,11 +700,21 @@ BIOSDrive::FillIdentifier()
|
||||
if (HasParameters()) {
|
||||
// try all drive_parameters versions, beginning from the most informative
|
||||
|
||||
#if 0
|
||||
if (fill_disk_identifier_v3(fIdentifier, fParameters) == B_OK)
|
||||
return B_OK;
|
||||
|
||||
if (fill_disk_identifier_v2(fIdentifier, fParameters) == B_OK)
|
||||
return B_OK;
|
||||
#else
|
||||
// TODO: the above version is the correct one - it's currently
|
||||
// disabled, as the kernel boot code only supports the
|
||||
// UNKNOWN_BUS/UNKNOWN_DEVICE way to find the correct boot
|
||||
// device.
|
||||
if (fill_disk_identifier_v3(fIdentifier, fParameters) != B_OK)
|
||||
fill_disk_identifier_v2(fIdentifier, fParameters);
|
||||
|
||||
#endif
|
||||
|
||||
// no interesting information, we have to fall back to the default
|
||||
// unknown interface/device type identifier
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2005, Axel Dörfler, axeld@pinc-software.de.
|
||||
* Copyright 2002-2006, Axel Dörfler, axeld@pinc-software.de.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Copyright 2001-2002, Travis Geiselbrecht. All rights reserved.
|
||||
@ -27,11 +27,9 @@
|
||||
|
||||
//#define TRACE_VFS
|
||||
#ifdef TRACE_VFS
|
||||
# define PRINT(x) dprintf x
|
||||
# define FUNCTION(x) dprintf x
|
||||
# define TRACE(x) dprintf x
|
||||
#else
|
||||
# define PRINT(x) ;
|
||||
# define FUNCTION(x) ;
|
||||
# define TRACE(x) ;
|
||||
#endif
|
||||
|
||||
|
||||
@ -109,10 +107,100 @@ compare_cd_boot(const void *_a, const void *_b)
|
||||
}
|
||||
|
||||
|
||||
/** 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
|
||||
* boot/platform/bios_ia32/devices.cpp (or similar solutions).
|
||||
*/
|
||||
|
||||
static uint32
|
||||
compute_check_sum(KDiskDevice *device, off_t offset)
|
||||
{
|
||||
char buffer[512];
|
||||
ssize_t bytesRead = read_pos(device->FD(), 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;
|
||||
}
|
||||
|
||||
|
||||
/** Checks if the device matches the boot device as specified by the
|
||||
* boot loader.
|
||||
*/
|
||||
|
||||
static bool
|
||||
is_boot_device(kernel_args *args, KDiskDevice *device)
|
||||
{
|
||||
disk_identifier &disk = args->boot_disk.identifier;
|
||||
|
||||
TRACE(("boot device: bus %ld, device %ld\n", disk.bus_type,
|
||||
disk.device_type));
|
||||
|
||||
switch (disk.bus_type) {
|
||||
case PCI_BUS:
|
||||
case LEGACY_BUS:
|
||||
// TODO: implement this! (and then enable this feature in the boot loader)
|
||||
// (we need a way to get the device_node of a device, then)
|
||||
break;
|
||||
|
||||
case UNKNOWN_BUS:
|
||||
// nothing to do here
|
||||
break;
|
||||
}
|
||||
|
||||
switch (disk.device_type) {
|
||||
case UNKNOWN_DEVICE:
|
||||
// test if the size of the device matches
|
||||
if (device->Size() != disk.device.unknown.size)
|
||||
return false;
|
||||
|
||||
// check if the check sums match, too
|
||||
for (int32 i = 0; i < NUM_DISK_CHECK_SUMS; i++) {
|
||||
if (disk.device.unknown.check_sums[i].offset == -1)
|
||||
continue;
|
||||
|
||||
if (compute_check_sum(device, disk.device.unknown.check_sums[i].offset)
|
||||
!= disk.device.unknown.check_sums[i].sum)
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
|
||||
case ATA_DEVICE:
|
||||
case ATAPI_DEVICE:
|
||||
case SCSI_DEVICE:
|
||||
case USB_DEVICE:
|
||||
case FIREWIRE_DEVICE:
|
||||
case FIBRE_DEVICE:
|
||||
// TODO: implement me!
|
||||
break;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/** Make the boot partition (and probably others) available.
|
||||
* The partitions that are a boot candidate a put into the /a partitions
|
||||
* stack. If the user selected a boot device, there is will only be one
|
||||
* entry in this stack; if not, the most likely is put up first.
|
||||
* The boot code should then just try them one by one.
|
||||
*/
|
||||
|
||||
static status_t
|
||||
get_boot_partitions(kernel_args *args, PartitionStack &partitions)
|
||||
{
|
||||
// make the boot partition (and probably others) available
|
||||
KDiskDeviceManager::CreateDefault();
|
||||
KDiskDeviceManager *manager = KDiskDeviceManager::Default();
|
||||
|
||||
@ -129,9 +217,6 @@ get_boot_partitions(kernel_args *args, PartitionStack &partitions)
|
||||
return status;
|
||||
}
|
||||
|
||||
// ToDo: do this for real! It will currently only use the partition offset;
|
||||
// it does not yet use the disk_identifier information.
|
||||
|
||||
struct BootPartitionVisitor : KPartitionVisitor {
|
||||
BootPartitionVisitor(kernel_args &args, PartitionStack &stack)
|
||||
: fArgs(args), fPartitions(stack) {}
|
||||
@ -168,6 +253,9 @@ get_boot_partitions(kernel_args *args, PartitionStack &partitions)
|
||||
KDiskDevice *device;
|
||||
int32 cookie = 0;
|
||||
while ((device = manager->NextDevice(&cookie)) != NULL) {
|
||||
if (!is_boot_device(args, device))
|
||||
continue;
|
||||
|
||||
if (device->VisitEachDescendant(&visitor) != NULL)
|
||||
break;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user