diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/fs/gpt.c | 71 | ||||
-rw-r--r-- | src/nrvn.c | 47 |
2 files changed, 113 insertions, 5 deletions
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 <fs/gpt.h> +#include <ahci.h> +#include <mem.h> +#include <memory.h> +#include <vga.h> + +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; +} @@ -8,20 +8,33 @@ #include <pic.h> #include <acpi.h> #include <ps2.h> +#include <pci.h> #include <multiboot.h> #include <mem.h> #include <memory.h> +#include <ahci.h> + +#include <fs/gpt.h> /* 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); } |