part: Fix long standing issue with GPT logical block sizes and implement lsvol console command

This commit is contained in:
mintsuki 2022-07-01 17:30:53 +02:00
parent f3621c7bcc
commit 20640083d8
4 changed files with 66 additions and 16 deletions

View File

@ -9,13 +9,15 @@
#include <lib/libc.h>
#include <lib/blib.h>
#include <lib/term.h>
#include <lib/part.h>
static void console_help(void) {
print(
"Available commands:\n"
"exit -- Exit Limine console.\n"
"clear -- Clears the console.\n"
"clear -- Clear the console.\n"
"%s"
"lsvol -- List volumes.\n"
"version -- Print version.\n"
"copyright -- Print copyright.\n"
"help -- Print this help message.\n",
@ -38,6 +40,8 @@ void console(void) {
break;
} else if (strcmp(prompt, "clear") == 0) {
print("\e[2J\e[H");
} else if (strcmp(prompt, "lsvol") == 0) {
list_volumes();
} else if (editor_enabled && strcmp(prompt, "editor") == 0) {
char *new_entry = config_entry_editor("New Entry", "");
if (new_entry != NULL) {

16
common/lib/part.c Normal file
View File

@ -0,0 +1,16 @@
#include <stddef.h>
#include <lib/part.h>
void list_volumes(void) {
for (size_t i = 0; i < volume_index_i; i++) {
struct volume *v = volume_index[i];
print("index: %u\n", v->index);
print("is_optical: %u\n", v->is_optical);
print("partition: %u\n", v->partition);
print("sector_size: %u\n", v->sector_size);
print("max_partition: %d\n", v->max_partition);
print("first_sect: %X\n", v->first_sect);
print("sect_count: %X\n", v->sect_count);
print("---\n");
}
}

View File

@ -52,6 +52,8 @@ struct volume {
struct guid part_guid;
};
void list_volumes(void);
extern struct volume **volume_index;
extern size_t volume_index_i;

View File

@ -125,15 +125,29 @@ struct gpt_entry {
bool gpt_get_guid(struct guid *guid, struct volume *volume) {
struct gpt_table_header header = {0};
int sector_size = 512;
int lb_guesses[] = {
512,
4096
};
int lb_size = -1;
// read header, located after the first block
volume_read(volume, &header, sector_size * 1, sizeof(header));
for (size_t i = 0; i < SIZEOF_ARRAY(lb_guesses); i++) {
// read header, located after the first block
volume_read(volume, &header, lb_guesses[i] * 1, sizeof(header));
// check the header
// 'EFI PART'
if (strncmp(header.signature, "EFI PART", 8))
// check the header
// 'EFI PART'
if (strncmp(header.signature, "EFI PART", 8))
continue;
lb_size = lb_guesses[i];
break;
}
if (lb_size == -1) {
return false;
}
if (header.revision != 0x00010000)
return false;
@ -145,15 +159,29 @@ bool gpt_get_guid(struct guid *guid, struct volume *volume) {
static int gpt_get_part(struct volume *ret, struct volume *volume, int partition) {
struct gpt_table_header header = {0};
int sector_size = 512;
int lb_guesses[] = {
512,
4096
};
int lb_size = -1;
// read header, located after the first block
volume_read(volume, &header, sector_size * 1, sizeof(header));
for (size_t i = 0; i < SIZEOF_ARRAY(lb_guesses); i++) {
// read header, located after the first block
volume_read(volume, &header, lb_guesses[i] * 1, sizeof(header));
// check the header
// 'EFI PART'
if (strncmp(header.signature, "EFI PART", 8))
// check the header
// 'EFI PART'
if (strncmp(header.signature, "EFI PART", 8))
continue;
lb_size = lb_guesses[i];
break;
}
if (lb_size == -1) {
return INVALID_TABLE;
}
if (header.revision != 0x00010000)
return INVALID_TABLE;
@ -163,7 +191,7 @@ static int gpt_get_part(struct volume *ret, struct volume *volume, int partition
struct gpt_entry entry = {0};
volume_read(volume, &entry,
(header.partition_entry_lba * sector_size) + (partition * sizeof(entry)),
(header.partition_entry_lba * lb_size) + (partition * sizeof(entry)),
sizeof(entry));
struct guid empty_guid = {0};
@ -181,8 +209,8 @@ static int gpt_get_part(struct volume *ret, struct volume *volume, int partition
ret->is_optical = volume->is_optical;
ret->partition = partition + 1;
ret->sector_size = volume->sector_size;
ret->first_sect = entry.starting_lba;
ret->sect_count = (entry.ending_lba - entry.starting_lba) + 1;
ret->first_sect = entry.starting_lba / (lb_size / 512);
ret->sect_count = ((entry.ending_lba - entry.starting_lba) + 1) / (lb_size / 512);
ret->backing_dev = volume;
struct guid guid;