part: Fix long standing issue with GPT logical block sizes and implement lsvol console command
diff --git a/common/console.c b/common/console.c
index ae3c5941..b43d259a 100644
--- a/common/console.c
+++ b/common/console.c
@@ -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) {
diff --git a/common/lib/part.c b/common/lib/part.c
new file mode 100644
index 00000000..30fcab15
--- /dev/null
+++ b/common/lib/part.c
@@ -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");
+ }
+}
diff --git a/common/lib/part.h b/common/lib/part.h
index 8b14590f..f468b7d8 100644
--- a/common/lib/part.h
+++ b/common/lib/part.h
@@ -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;
diff --git a/common/lib/part.s2.c b/common/lib/part.s2.c
index 10a71e2c..10c3e457 100644
--- a/common/lib/part.s2.c
+++ b/common/lib/part.s2.c
@@ -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;
-
- // read header, located after the first block
- volume_read(volume, &header, sector_size * 1, sizeof(header));
+ int lb_guesses[] = {
+ 512,
+ 4096
+ };
+ int lb_size = -1;
+
+ 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))
+ continue;
+
+ lb_size = lb_guesses[i];
+ break;
+ }
- // check the header
- // 'EFI PART'
- if (strncmp(header.signature, "EFI PART", 8))
+ 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;
+
+ 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));
- // read header, located after the first block
- volume_read(volume, &header, sector_size * 1, sizeof(header));
+ // check the header
+ // 'EFI PART'
+ if (strncmp(header.signature, "EFI PART", 8))
+ continue;
- // check the header
- // 'EFI PART'
- if (strncmp(header.signature, "EFI PART", 8))
+ 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;
