mirror of
https://github.com/limine-bootloader/limine
synced 2025-02-08 05:04:14 +03:00
disk: Misc bug fixes and improvements
This commit is contained in:
parent
662b5b7624
commit
eb83d013ca
@ -8,7 +8,6 @@
|
||||
# include <efi.h>
|
||||
#endif
|
||||
#include <lib/blib.h>
|
||||
#include <lib/print.h>
|
||||
#include <mm/pmm.h>
|
||||
|
||||
#if defined(bios)
|
||||
@ -78,14 +77,7 @@ bool disk_read_sectors(struct volume *volume, void *buf, uint64_t block, size_t
|
||||
void disk_create_index(void) {
|
||||
size_t volume_count = 0;
|
||||
|
||||
printv("Detected volumes:\n");
|
||||
|
||||
for (uint8_t drive = 0x80; ; drive++) {
|
||||
if (drive == 0x90)
|
||||
drive = 0xe0;
|
||||
else if (drive == 0xf0)
|
||||
break;
|
||||
|
||||
for (uint8_t drive = 0x80; drive < 0xf0; drive++) {
|
||||
struct rm_regs r = {0};
|
||||
struct bios_drive_params drive_params;
|
||||
|
||||
@ -111,10 +103,12 @@ void disk_create_index(void) {
|
||||
block.first_sect = 0;
|
||||
block.sect_count = drive_params.lba_count;
|
||||
|
||||
// The medium could not be present (e.g.: CD-ROMs)
|
||||
// Do a test run to see if we can actually read it
|
||||
if (!disk_read_sectors(&block, NULL, 0, 1)) {
|
||||
continue;
|
||||
if (drive_params.info_flags & (1 << 2)) {
|
||||
// The medium could not be present (e.g.: CD-ROMs)
|
||||
// Do a test run to see if we can actually read it
|
||||
if (!disk_read_sectors(&block, NULL, 0, 1)) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
volume_count++;
|
||||
@ -134,12 +128,9 @@ void disk_create_index(void) {
|
||||
|
||||
volume_index = ext_mem_alloc(sizeof(struct volume) * volume_count);
|
||||
|
||||
for (uint8_t drive = 0x80; ; drive++) {
|
||||
if (drive == 0x90)
|
||||
drive = 0xe0;
|
||||
else if (drive == 0xf0)
|
||||
break;
|
||||
int optical_indices = 1, hdd_indices = 1;
|
||||
|
||||
for (uint8_t drive = 0x80; drive < 0xf0; drive++) {
|
||||
struct rm_regs r = {0};
|
||||
struct bios_drive_params drive_params;
|
||||
|
||||
@ -161,24 +152,28 @@ void disk_create_index(void) {
|
||||
struct volume *block = ext_mem_alloc(sizeof(struct volume));
|
||||
|
||||
block->drive = drive;
|
||||
block->partition = -1;
|
||||
block->partition = 0;
|
||||
block->sector_size = drive_params.bytes_per_sect;
|
||||
block->first_sect = 0;
|
||||
block->sect_count = drive_params.lba_count;
|
||||
block->max_partition = -1;
|
||||
|
||||
// The medium could not be present (e.g.: CD-ROMs)
|
||||
// Do a test run to see if we can actually read it
|
||||
if (!disk_read_sectors(block, NULL, 0, 1)) {
|
||||
continue;
|
||||
if (drive_params.info_flags & (1 << 2)) {
|
||||
// The medium could not be present (e.g.: CD-ROMs)
|
||||
// Do a test run to see if we can actually read it
|
||||
if (!disk_read_sectors(block, NULL, 0, 1)) {
|
||||
continue;
|
||||
}
|
||||
block->index = optical_indices++;
|
||||
block->is_optical = true;
|
||||
} else {
|
||||
block->index = hdd_indices++;
|
||||
}
|
||||
|
||||
if (gpt_get_guid(&block->guid, block)) {
|
||||
block->guid_valid = true;
|
||||
}
|
||||
|
||||
printv(" %x\n", block->drive);
|
||||
|
||||
volume_index[volume_index_i++] = block;
|
||||
|
||||
for (int part = 0; ; part++) {
|
||||
@ -190,8 +185,6 @@ void disk_create_index(void) {
|
||||
if (ret == NO_PARTITION)
|
||||
continue;
|
||||
|
||||
printv(" %x:%u\n", block->drive, part);
|
||||
|
||||
volume_index[volume_index_i++] = p;
|
||||
|
||||
block->max_partition++;
|
||||
@ -234,7 +227,7 @@ struct volume *disk_volume_from_efi_handle(EFI_HANDLE *efi_handle) {
|
||||
if (status) {
|
||||
// Really hacky support for CDs because they are read-only
|
||||
for (size_t i = 0; i < volume_index_i; i++) {
|
||||
if (volume_index[i]->drive == 0xe0)
|
||||
if (volume_index[i]->is_optical)
|
||||
return volume_index[i];
|
||||
}
|
||||
|
||||
@ -343,9 +336,7 @@ void disk_create_index(void) {
|
||||
|
||||
volume_index = ext_mem_alloc(sizeof(struct volume) * volume_count);
|
||||
|
||||
printv("Detected volumes:\n");
|
||||
|
||||
size_t drives_counter = 0x80, optical_counter = 0xe0;
|
||||
int optical_indices = 1, hdd_indices = 1;
|
||||
|
||||
for (size_t i = 0; i < handles_size / sizeof(EFI_HANDLE); i++) {
|
||||
EFI_GUID disk_io_guid = DISK_IO_PROTOCOL;
|
||||
@ -373,12 +364,15 @@ void disk_create_index(void) {
|
||||
|
||||
struct volume *block = ext_mem_alloc(sizeof(struct volume));
|
||||
|
||||
if (status)
|
||||
block->drive = optical_counter++;
|
||||
else
|
||||
block->drive = drives_counter++;
|
||||
if (status) {
|
||||
block->index = optical_indices++;
|
||||
block->is_optical = true;
|
||||
} else {
|
||||
block->index = hdd_indices++;
|
||||
}
|
||||
|
||||
block->efi_handle = handles[i];
|
||||
block->partition = -1;
|
||||
block->partition = 0;
|
||||
block->sector_size = drive->Media->BlockSize;
|
||||
block->first_sect = 0;
|
||||
block->sect_count = drive->Media->LastBlock + 1;
|
||||
@ -388,8 +382,6 @@ void disk_create_index(void) {
|
||||
block->guid_valid = true;
|
||||
}
|
||||
|
||||
printv(" %x\n", block->drive);
|
||||
|
||||
volume_index[volume_index_i++] = block;
|
||||
|
||||
for (int part = 0; ; part++) {
|
||||
@ -401,8 +393,6 @@ void disk_create_index(void) {
|
||||
if (ret == NO_PARTITION)
|
||||
continue;
|
||||
|
||||
printv(" %x:%u\n", block->drive, part);
|
||||
|
||||
volume_index[volume_index_i++] = p;
|
||||
|
||||
block->max_partition++;
|
||||
|
@ -85,7 +85,7 @@ void entry(uint8_t boot_drive, int boot_from) {
|
||||
disk_create_index();
|
||||
|
||||
if (boot_from == BOOTED_FROM_HDD || boot_from == BOOTED_FROM_CD) {
|
||||
boot_volume = volume_get_by_coord(boot_drive, -1);
|
||||
boot_volume = volume_get_by_bios_drive(boot_drive);
|
||||
} else if (boot_from == BOOTED_FROM_PXE) {
|
||||
pxe_init();
|
||||
boot_volume = pxe_bind_volume();
|
||||
|
@ -96,7 +96,7 @@ void stage3_common(void) {
|
||||
verbose = verbose_str != NULL && strcmp(verbose_str, "yes") == 0;
|
||||
|
||||
if (verbose) {
|
||||
print("Boot drive: %x\n", boot_volume->drive);
|
||||
print("Boot drive: %x\n", boot_volume->index);
|
||||
print("Boot partition: %d\n", boot_volume->partition);
|
||||
}
|
||||
|
||||
|
@ -16,11 +16,15 @@
|
||||
struct volume {
|
||||
#if defined (uefi)
|
||||
EFI_HANDLE efi_handle;
|
||||
#elif defined (bios)
|
||||
int drive;
|
||||
#endif
|
||||
|
||||
int index;
|
||||
|
||||
bool is_optical;
|
||||
bool pxe;
|
||||
|
||||
int drive;
|
||||
int partition;
|
||||
int sector_size;
|
||||
struct volume *backing_dev;
|
||||
@ -48,7 +52,10 @@ bool gpt_get_guid(struct guid *guid, struct volume *volume);
|
||||
int part_get(struct volume *part, struct volume *volume, int partition);
|
||||
|
||||
struct volume *volume_get_by_guid(struct guid *guid);
|
||||
struct volume *volume_get_by_coord(int drive, int partition);
|
||||
struct volume *volume_get_by_coord(bool optical, int drive, int partition);
|
||||
#if defined (bios)
|
||||
struct volume *volume_get_by_bios_drive(int drive);
|
||||
#endif
|
||||
|
||||
bool volume_read(struct volume *part, void *buffer, uint64_t loc, uint64_t count);
|
||||
|
||||
@ -65,11 +72,12 @@ bool volume_read(struct volume *part, void *buffer, uint64_t loc, uint64_t count
|
||||
} \
|
||||
\
|
||||
int _PART_CNT = -1; \
|
||||
for (size_t _PARTNO = -1; ; _PARTNO++) { \
|
||||
for (size_t _PARTNO = 0; ; _PARTNO++) { \
|
||||
if (_PART_CNT > _VOLUME->max_partition) \
|
||||
break; \
|
||||
\
|
||||
struct volume *_PART = volume_get_by_coord(_VOLUME->drive, _PARTNO); \
|
||||
struct volume *_PART = volume_get_by_coord(_VOLUME->is_optical, \
|
||||
_VOLUME->index, _PARTNO); \
|
||||
if (_PART == NULL) \
|
||||
continue; \
|
||||
\
|
||||
|
@ -152,9 +152,12 @@ static int gpt_get_part(struct volume *ret, struct volume *volume, int partition
|
||||
|
||||
#if defined (uefi)
|
||||
ret->efi_handle = volume->efi_handle;
|
||||
#endif
|
||||
#elif defined (bios)
|
||||
ret->drive = volume->drive;
|
||||
ret->partition = partition;
|
||||
#endif
|
||||
ret->index = volume->index;
|
||||
ret->is_optical = volume->is_optical;
|
||||
ret->partition = partition + 1;
|
||||
ret->sector_size = sector_size;
|
||||
ret->first_sect = entry.starting_lba;
|
||||
ret->sect_count = (entry.ending_lba - entry.starting_lba) + 1;
|
||||
@ -209,9 +212,12 @@ static int mbr_get_logical_part(struct volume *ret, struct volume *extended_part
|
||||
|
||||
#if defined (uefi)
|
||||
ret->efi_handle = extended_part->efi_handle;
|
||||
#endif
|
||||
#elif defined (bios)
|
||||
ret->drive = extended_part->drive;
|
||||
ret->partition = partition + 4;
|
||||
#endif
|
||||
ret->index = extended_part->index;
|
||||
ret->is_optical = extended_part->is_optical;
|
||||
ret->partition = partition + 4 + 1;
|
||||
ret->sector_size = extended_part->sector_size;
|
||||
ret->first_sect = extended_part->first_sect + ebr_sector + entry.first_sect;
|
||||
ret->sect_count = entry.sect_count;
|
||||
@ -284,9 +290,12 @@ static int mbr_get_part(struct volume *ret, struct volume *volume, int partition
|
||||
|
||||
#if defined (uefi)
|
||||
extended_part.efi_handle = volume->efi_handle;
|
||||
#endif
|
||||
#elif defined (bios)
|
||||
extended_part.drive = volume->drive;
|
||||
extended_part.partition = i;
|
||||
#endif
|
||||
extended_part.index = volume->index;
|
||||
extended_part.is_optical = volume->is_optical;
|
||||
extended_part.partition = i + 1;
|
||||
extended_part.sector_size = volume->sector_size;
|
||||
extended_part.first_sect = entry.first_sect;
|
||||
extended_part.sect_count = entry.sect_count;
|
||||
@ -307,9 +316,12 @@ static int mbr_get_part(struct volume *ret, struct volume *volume, int partition
|
||||
|
||||
#if defined (uefi)
|
||||
ret->efi_handle = volume->efi_handle;
|
||||
#endif
|
||||
#elif defined (bios)
|
||||
ret->drive = volume->drive;
|
||||
ret->partition = partition;
|
||||
#endif
|
||||
ret->index = volume->index;
|
||||
ret->is_optical = volume->is_optical;
|
||||
ret->partition = partition + 1;
|
||||
ret->sector_size = volume->sector_size;
|
||||
ret->first_sect = entry.first_sect;
|
||||
ret->sect_count = entry.sect_count;
|
||||
@ -360,9 +372,10 @@ struct volume *volume_get_by_guid(struct guid *guid) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct volume *volume_get_by_coord(int drive, int partition) {
|
||||
struct volume *volume_get_by_coord(bool optical, int drive, int partition) {
|
||||
for (size_t i = 0; i < volume_index_i; i++) {
|
||||
if (volume_index[i]->drive == drive
|
||||
if (volume_index[i]->index == drive
|
||||
&& volume_index[i]->is_optical == optical
|
||||
&& volume_index[i]->partition == partition) {
|
||||
return volume_index[i];
|
||||
}
|
||||
@ -370,3 +383,15 @@ struct volume *volume_get_by_coord(int drive, int partition) {
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#if defined (bios)
|
||||
struct volume *volume_get_by_bios_drive(int drive) {
|
||||
for (size_t i = 0; i < volume_index_i; i++) {
|
||||
if (volume_index[i]->drive == drive) {
|
||||
return volume_index[i];
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
@ -55,7 +55,7 @@ bool uri_resolve(char *uri, char **resource, char **root, char **path) {
|
||||
}
|
||||
|
||||
static bool parse_bios_partition(char *loc, int *drive, int *partition) {
|
||||
int64_t val;
|
||||
uint64_t val;
|
||||
|
||||
for (size_t i = 0; ; i++) {
|
||||
if (loc[i] == 0)
|
||||
@ -67,8 +67,8 @@ static bool parse_bios_partition(char *loc, int *drive, int *partition) {
|
||||
panic("Drive number cannot be omitted for hdd:// and odd://");
|
||||
} else {
|
||||
val = strtoui(loc, NULL, 10);
|
||||
if (val < 1 || val > 16) {
|
||||
panic("Drive number outside range 1-16");
|
||||
if (val < 1 || val > 256) {
|
||||
panic("Drive number outside range 1-256");
|
||||
}
|
||||
*drive = val;
|
||||
}
|
||||
@ -77,16 +77,11 @@ static bool parse_bios_partition(char *loc, int *drive, int *partition) {
|
||||
}
|
||||
}
|
||||
|
||||
if (*loc == 0) {
|
||||
*partition = -1;
|
||||
return true;
|
||||
}
|
||||
|
||||
val = strtoui(loc, NULL, 10);
|
||||
if (val < 1 || val > 256) {
|
||||
panic("Partition number outside range 1-256");
|
||||
if (val > 256) {
|
||||
panic("Partition number outside range 0-256");
|
||||
}
|
||||
*partition = val - 1;
|
||||
*partition = val;
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -97,9 +92,7 @@ static bool uri_hdd_dispatch(struct file_handle *fd, char *loc, char *path) {
|
||||
if (!parse_bios_partition(loc, &drive, &partition))
|
||||
return false;
|
||||
|
||||
drive = (drive - 1) + 0x80;
|
||||
|
||||
struct volume *volume = volume_get_by_coord(drive, partition);
|
||||
struct volume *volume = volume_get_by_coord(false, drive, partition);
|
||||
|
||||
if (volume == NULL)
|
||||
return false;
|
||||
@ -116,9 +109,7 @@ static bool uri_odd_dispatch(struct file_handle *fd, char *loc, char *path) {
|
||||
if (!parse_bios_partition(loc, &drive, &partition))
|
||||
return false;
|
||||
|
||||
drive = (drive - 1) + 0xe0;
|
||||
|
||||
struct volume *volume = volume_get_by_coord(drive, partition);
|
||||
struct volume *volume = volume_get_by_coord(true, drive, partition);
|
||||
|
||||
if (volume == NULL)
|
||||
return false;
|
||||
@ -184,15 +175,16 @@ static bool uri_boot_dispatch(struct file_handle *fd, char *s_part, char *path)
|
||||
|
||||
if (s_part[0] != '\0') {
|
||||
uint64_t val = strtoui(s_part, NULL, 10);
|
||||
if (val < 1 || val > 256) {
|
||||
panic("Partition number outside range 1-256");
|
||||
if (val > 256) {
|
||||
panic("Partition number outside range 0-256");
|
||||
}
|
||||
partition = val - 1;
|
||||
partition = val;
|
||||
} else {
|
||||
partition = boot_volume->partition;
|
||||
}
|
||||
|
||||
struct volume *volume = volume_get_by_coord(boot_volume->drive, partition);
|
||||
struct volume *volume = volume_get_by_coord(boot_volume->is_optical,
|
||||
boot_volume->index, partition);
|
||||
if (volume == NULL)
|
||||
return false;
|
||||
|
||||
|
@ -75,13 +75,13 @@ void chainload(char *config) {
|
||||
int part; {
|
||||
char *part_config = config_get_value(config, 0, "PARTITION");
|
||||
if (part_config == NULL) {
|
||||
part = -1;
|
||||
part = 0;
|
||||
} else {
|
||||
val = strtoui(part_config, NULL, 10);
|
||||
if (val < 1 || val > 256) {
|
||||
panic("BIOS partition number outside range 1-256");
|
||||
if (val > 256) {
|
||||
panic("BIOS partition number outside range 0-256");
|
||||
}
|
||||
part = val - 1;
|
||||
part = val;
|
||||
}
|
||||
}
|
||||
int drive; {
|
||||
@ -90,16 +90,16 @@ void chainload(char *config) {
|
||||
panic("DRIVE not specified");
|
||||
}
|
||||
val = strtoui(drive_config, NULL, 10);
|
||||
if (val < 1 || val > 16) {
|
||||
panic("BIOS drive number outside range 1-16");
|
||||
if (val < 1 || val > 256) {
|
||||
panic("BIOS drive number outside range 1-256");
|
||||
}
|
||||
drive = (val - 1) + 0x80;
|
||||
drive = val;
|
||||
}
|
||||
|
||||
int rows, cols;
|
||||
init_vga_textmode(&rows, &cols, false);
|
||||
|
||||
struct volume *p = volume_get_by_coord(drive, part);
|
||||
struct volume *p = volume_get_by_coord(false, drive, part);
|
||||
|
||||
volume_read(p, (void *)0x7c00, 0, 512);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user