diff --git a/Makefile b/Makefile index c8cef4b..c6f1a27 100644 --- a/Makefile +++ b/Makefile @@ -34,7 +34,8 @@ $(BUILDDIR)/%.o: */%.c kernel: $(BUILDDIR)/$(KIMG) $(BUILDDIR)/$(ISO): kernel - rm -f $(BUILDDIR)/$(ISO) + rm -f $(BUILDDIR)/$(ISO) boot/initrd + nasm -fbin user/userinit.asm -o boot/initrd cp $(BUILDDIR)/$(KIMG) boot/$(KIMG) grub-mkrescue -o $(BUILDDIR)/$(ISO) . iso: $(BUILDDIR)/$(ISO) @@ -42,4 +43,4 @@ iso: $(BUILDDIR)/$(ISO) qemu: iso qemu-system-i386 $(QEMUFLAGS) clean: - rm -f build/* boot/*.bin + rm -f build/* boot/*.bin boot/initrd diff --git a/boot/grub/grub.cfg b/boot/grub/grub.cfg index 0942425..f3acf6e 100644 --- a/boot/grub/grub.cfg +++ b/boot/grub/grub.cfg @@ -2,4 +2,5 @@ default=0 timeout=0 menuentry "Hazel" { multiboot /boot/kernel.bin + module /boot/initrd } diff --git a/boot/initrd b/boot/initrd new file mode 100644 index 0000000..60f94fd --- /dev/null +++ b/boot/initrd @@ -0,0 +1 @@ +¸ï¾­Þëþ \ No newline at end of file diff --git a/include/kernel/multiboot.h b/include/kernel/multiboot.h index c2e781d..ebbf15e 100644 --- a/include/kernel/multiboot.h +++ b/include/kernel/multiboot.h @@ -28,19 +28,31 @@ typedef struct { struct multiboot_mmap_entry { - uint32_t size; - uint32_t addr_low; - uint32_t addr_high; - uint32_t len_low; - uint32_t len_high; + uint32_t size; + uint64_t addr; + uint64_t len; #define MULTIBOOT_MEMORY_AVAILABLE 1 #define MULTIBOOT_MEMORY_RESERVED 2 #define MULTIBOOT_MEMORY_ACPI_RECLAIMABLE 3 #define MULTIBOOT_MEMORY_NVS 4 #define MULTIBOOT_MEMORY_BADRAM 5 - uint32_t type; + uint32_t type; } __attribute__((packed)); typedef struct multiboot_mmap_entry multi_mmap_t; +struct multiboot_mod_list +{ + /* the memory used goes from bytes ’mod_start’ to ’mod_end-1’ inclusive */ + uint32_t mod_start; + uint32_t mod_end; + + /* Module command line */ + uint32_t cmdline; + + /* padding to take it to 16 bytes (must be zero) */ + uint32_t pad; +}; +typedef struct multiboot_mod_list multi_mod_t; + #endif diff --git a/kernel/init.asm b/kernel/init.asm index 5835e32..e06490a 100644 --- a/kernel/init.asm +++ b/kernel/init.asm @@ -71,8 +71,7 @@ jmp_user_mode: push eax pushf push (3*8) | 3 - extern test_entry - push test_entry + push edx iret diff --git a/kernel/kernel.c b/kernel/kernel.c index d66a444..8d09321 100644 --- a/kernel/kernel.c +++ b/kernel/kernel.c @@ -32,6 +32,7 @@ void sleep(int delay) { } void kernel(multiboot_info_t *info) { + if (!CHECK_FLAG(info->flags, 3)) goto halt; // Modules if (!CHECK_FLAG(info->flags, 6)) goto halt; // Memory map if (!CHECK_FLAG(info->flags, 12)) goto halt; // VBE data ctx.multi_mmap = (multi_mmap_t *)info->memmapaddress; @@ -58,7 +59,10 @@ void kernel(multiboot_info_t *info) { ctx.ticks = 0; //pit_init(); - jmp_user_mode(0x5000, (uint32_t)test_entry); + uint32_t stack = (uint32_t)mmap_find_first_free_block(); + multi_mod_t *init = (multi_mod_t *)info->moduleaddress; + LOG("Switching to ring 3... EIP: 0x%08X ESP: 0x%08X", init->mod_start, stack+0x1000); + jmp_user_mode(stack+0x1000, init->mod_start); halt: for (;;) {} diff --git a/kernel/mem.c b/kernel/mem.c index 43a10b3..9d8cb5d 100644 --- a/kernel/mem.c +++ b/kernel/mem.c @@ -9,10 +9,10 @@ void *mmap_block_to_physical(int block) { for (uint32_t i = 0; i < ctx.multi_mmap_size; i++) { struct multiboot_mmap_entry entry = ctx.multi_mmap[i]; - if (entry.type != MULTIBOOT_MEMORY_AVAILABLE) continue; + if (entry.type != MULTIBOOT_MEMORY_AVAILABLE || entry.len > UINT32_MAX || entry.addr > UINT32_MAX) continue; - uint32_t len = (uint32_t)(entry.len_low | entry.len_high); - uint32_t addr = (uint32_t)(entry.addr_low | entry.addr_high); + uint32_t len = (uint32_t)(entry.len); + uint32_t addr = (uint32_t)(entry.addr); if (len > offset) return (void *)(addr + offset); } @@ -39,11 +39,12 @@ uint8_t mmap_init(void) { // Calculate the number of bytes available to us uint64_t available_bytes = 0; for (uint32_t i = 0; i < ctx.multi_mmap_size; i++) { - struct multiboot_mmap_entry entry = ctx.multi_mmap[i]; - if (entry.type != MULTIBOOT_MEMORY_AVAILABLE) continue; + struct multiboot_mmap_entry entry = ctx.multi_mmap[i]; + if (entry.type != MULTIBOOT_MEMORY_AVAILABLE || entry.len > UINT32_MAX || entry.addr > UINT32_MAX) continue; - uint32_t len = (uint32_t)(entry.len_low | entry.len_high); - available_bytes += len; + //uint32_t len = (uint32_t)(entry.len_low | entry.len_high); + available_bytes += entry.len; + LOG("Entry: Addr: %016llX -- Len: %016llX\n", (long long)entry.addr, (long long)entry.len); } ctx.mmap_size = available_bytes / BLOCK_SIZE / 8; @@ -52,10 +53,10 @@ uint8_t mmap_init(void) { int index = -1; for (uint32_t i = 0; i < ctx.multi_mmap_size; i++) { struct multiboot_mmap_entry entry = ctx.multi_mmap[i]; - if (entry.type != MULTIBOOT_MEMORY_AVAILABLE) continue; + if (entry.type != MULTIBOOT_MEMORY_AVAILABLE || entry.len > UINT32_MAX || entry.addr > UINT32_MAX) continue; - uint32_t len = (uint32_t)(entry.len_low | entry.len_high); - if (len > ctx.mmap_size) { + //uint32_t len = (uint32_t)(entry.len_low | entry.len_high); + if (entry.len > ctx.mmap_size) { index = i; break; } @@ -65,8 +66,8 @@ uint8_t mmap_init(void) { // Create map struct multiboot_mmap_entry entry = ctx.multi_mmap[index]; - uint32_t addr = (uint32_t)(entry.addr_low | entry.addr_high); - ctx.mmap = (uint32_t *)addr; + //uint32_t addr = (uint32_t)(entry.addr_low | entry.addr_high); + ctx.mmap = (uint32_t *)(uint32_t)(entry.addr & 0xffffffff); // Zero the map memset(ctx.mmap, 0, ctx.mmap_size); // Reserve the blocks that hold the memory map + 1 diff --git a/user/userinit.asm b/user/userinit.asm new file mode 100644 index 0000000..58290f9 --- /dev/null +++ b/user/userinit.asm @@ -0,0 +1,5 @@ +[bits 32] +global _start +_start: + mov eax, 0xDEADBEEF + jmp $