summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/fs/gpt.h40
-rw-r--r--meson.build1
-rw-r--r--src/fs/gpt.c71
-rw-r--r--src/nrvn.c47
4 files changed, 154 insertions, 5 deletions
diff --git a/include/fs/gpt.h b/include/fs/gpt.h
new file mode 100644
index 0000000..a1a8356
--- /dev/null
+++ b/include/fs/gpt.h
@@ -0,0 +1,40 @@
+#ifndef _GPT_H_
+#define _GPT_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+struct gpt_header {
+ char sig[8];
+ uint32_t revision;
+ uint32_t size;
+ uint32_t crc32;
+ uint32_t res;
+ uint64_t lba;
+ uint64_t lba_mirror;
+ uint64_t first_block;
+ uint64_t last_block;
+ uint8_t guid[16];
+ uint64_t first_lba;
+ uint32_t number_partitions;
+ uint32_t size_partitions;
+ uint32_t crc32_entry;
+};
+
+struct gpt_entry {
+ uint8_t type[16];
+ uint8_t guid[16];
+ struct {
+ uint64_t start;
+ uint64_t end;
+ } lba;
+ uint64_t attrs;
+ char name[72];
+};
+
+struct disk;
+struct gpt_header *read_gpt_disk(struct disk *disk);
+struct gpt_entry *get_gpt_entry(struct disk *disk, struct gpt_header *header, size_t num);
+char *read_gpt_entry(struct disk *disk, struct gpt_entry *entry);
+
+#endif
diff --git a/meson.build b/meson.build
index 6393037..94f7334 100644
--- a/meson.build
+++ b/meson.build
@@ -26,6 +26,7 @@ files = [
'src/ps2.c',
'src/ahci.c',
'src/vga.c',
+ 'src/fs/gpt.c',
linker_script
]
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;
+}
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 <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);
}