From ddb15c409290ac5473ee36d5dc621a92f161cdfb Mon Sep 17 00:00:00 2001 From: "Anna (navi) Figueiredo Gomes" Date: Thu, 6 Jun 2024 15:05:45 +0200 Subject: basic gpt support Signed-off-by: Anna (navi) Figueiredo Gomes --- src/fs/gpt.c | 71 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/nrvn.c | 47 +++++++++++++++++++++++++++++++++++----- 2 files changed, 113 insertions(+), 5 deletions(-) create mode 100644 src/fs/gpt.c (limited to 'src') diff --git a/src/fs/gpt.c b/src/fs/gpt.c new file mode 100644 index 0000000..f9ff055 --- /dev/null +++ b/src/fs/gpt.c @@ -0,0 +1,71 @@ +#include +#include +#include +#include +#include + +struct gpt_header *read_gpt_disk(struct disk *disk) { + uint16_t *gpt = kmalloc(512); + if (!read(disk->port, 1, 1, gpt)) + return NULL; + struct gpt_header *part = (void*) gpt; + if (memcmp(part->sig, "EFI PART", 8) != 0) { + vga_puts("not gpt"); + return NULL; + } + vga_puts("found gpt table on disk 0\n"); + + vga_puts("number of partitions: "); + vga_putn(part->number_partitions); + vga_putc('\n'); + + vga_puts("starting lba: "); + vga_putn(part->first_lba); + vga_putc('\n'); + + vga_puts("size per entry: "); + vga_putn(part->size_partitions); + vga_putc('\n'); + + return part; +} + +struct gpt_entry *get_gpt_entry(struct disk *disk, struct gpt_header *header, size_t num) { + if (num >= header->number_partitions) + return NULL; + uint16_t *data = kmalloc(512); + if (!read(disk->port, header->first_lba + num, 1, data)) + return NULL; + struct gpt_entry *entry = (void *) data; + + /* + vga_puts("unique guid for first partition: "); + vga_putx(entry->guid); + vga_putc('\n'); + */ + + vga_puts("starting partition lba: "); + vga_putn(entry->lba.start); + vga_putc('\n'); + + vga_puts("ending partition lba: "); + vga_putn(entry->lba.end); + vga_putc('\n'); + + return entry; +} + +char *read_gpt_entry(struct disk *disk, struct gpt_entry *entry) { + uint16_t *data = kmalloc(512 * (entry->lba.end - entry->lba.start)); + uint16_t *ptr = data; + for (size_t lba = entry->lba.start; lba < entry->lba.end; lba += 1024) { + if (!read(disk->port, lba, entry->lba.end - lba < 1024 ? entry->lba.end - lba : 1024, ptr)) { + vga_puts("failed to read disk"); + kfree(data); + return NULL; + } + ptr += 1024 * 256; + } + + return (char *)data; +} diff --git a/src/nrvn.c b/src/nrvn.c index 66a59df..3fcbc41 100644 --- a/src/nrvn.c +++ b/src/nrvn.c @@ -8,20 +8,33 @@ #include #include #include +#include #include #include #include +#include + +#include /* Check if the compiler thinks you are targeting the wrong operating system. */ #if defined(__linux__) # error "You are not using a cross-compiler, you will most certainly run into trouble" #endif -/* This tutorial will only work for the 32-bit ix86 targets. */ #if !defined(__x86_64__) -# error "This tutorial needs to be compiled with a ix86-elf compiler" +# error "nrvn needs to be compiled with a x86_64 compiler" #endif +int oct2bin(char *str, int size) { + int n = 0; + while (size--) { + n *= 8; + n += *str - '0'; + str++; + } + return n; +} + void kernel_main(void) { vga_init(); vga_puts("hello world\n"); @@ -31,7 +44,6 @@ void kernel_main(void) { idt_init(); vga_puts("interrupt tables initialized\n"); - vga_puts("initializing the pic..."); pic_init(); vga_puts("pic initialized\n"); @@ -41,8 +53,6 @@ void kernel_main(void) { vga_puts("memory pages allocated\n"); } else { vga_puts("failed to allocate memory pages\n"); - asm volatile ("cli"); - asm volatile ("hlt"); } vga_puts("initializing ps/2...\n"); @@ -56,5 +66,32 @@ void kernel_main(void) { vga_puts("pci initialized.\n"); else vga_puts("pci initialization failed.\n"); + + struct disk *disk = get_disk(0); + + struct gpt_header *gpt = read_gpt_disk(disk); + if (!gpt) + while (1); + + struct gpt_entry *entry = get_gpt_entry(disk, gpt, 0); + if (!entry) + while (1); + + char *archive = read_gpt_entry(disk, entry); + while (!memcmp(archive + 257, "ustar", 5)) { + int size = oct2bin(archive + 0x7c, 11); + vga_puts(archive[156] == '0' ? "filename: " : "directory: "); + vga_puts(archive); + vga_puts(", size: "); + vga_putn(size); + vga_putc('\n'); + if (size > 0) { + vga_puts("contents: "); + vga_puts(archive + 512); + vga_putc('\n'); + } + archive += 512 + (size > 0 ? 512 : 0); + } + while (1); } -- cgit v1.2.3