diff --git a/Makefile b/Makefile index 6fbfb42..f0a84c4 100644 --- a/Makefile +++ b/Makefile @@ -9,7 +9,7 @@ # way. There are better way to do the hthings I do below, but who gives a # shit. -default: emulate +default: emulate-nohdd SHELL:=/bin/bash ENV:=/usr/xdev/bin @@ -20,6 +20,7 @@ AS:=nasm LD:=$(ENV)/$(TARGET)-ld CFLAGS:=-Wall -Wextra -Werror -nostdlib -nostartfiles -nodefaultlibs -std=c99 +CFLAGS+=-I ./include LFLAGS:=-nostdlib -nostartfiles -nodefaultlibs .PHONY: all clean kernel.bin emulate hdd.img @@ -29,7 +30,7 @@ obj/src/%.nao : src/%.asm @$(AS) -f elf -o obj/src/$*.nao src/$*.asm obj/src/%.o : src/%.c - @echo "[i] Compining $*.c ..." + @echo "[i] Compiling $*.c ..." @mkdir -p obj/src/$*.o @rmdir obj/src/$*.o @$(CC) $(CFLAGS) -c src/$*.c -o obj/src/$*.o @@ -51,14 +52,18 @@ kernel.bin: Tier0 hdd.img: kernel.bin @echo "[i] Creating HDD image..." @if [ -e hdd_temp.img ] ; then rm hdd_temp.img ; fi - @dd if=/dev/zero of=hdd_temp.img bs=4k count=4096 2> /dev/null - @mkfs.vfat hdd_temp.img > /dev/null + @dd if=/dev/zero of=hdd_temp.img bs=512 count=10240 2> /dev/null + @mkfs.vfat hdd_temp.img @syslinux hdd_temp.img @mcopy -i hdd_temp.img /usr/lib/syslinux/mboot.c32 ::mboot.c32 @mcopy -i hdd_temp.img kernel.bin ::kernel.bin @mcopy -i hdd_temp.img dst/syslinux.cfg ::syslinux.cfg @mv hdd_temp.img hdd.img +emulate-nohdd: kernel.bin + @echo "[i] Starting QEmu..." + @qemu -kernel kernel.bin + emulate: hdd.img @echo "[i] Starting QEmu..." @qemu -hda hdd.img diff --git a/include/Tier0/gdt.h b/include/Tier0/gdt.h new file mode 100644 index 0000000..26a106b --- /dev/null +++ b/include/Tier0/gdt.h @@ -0,0 +1,46 @@ +#ifndef __GDT_H__ +#define __GDT_H__ + +#include "types.h" + +typedef enum E_GDT_RING { + GDT_RING0 = 0, + GDT_RING1, + GDT_RING2, + GDT_RING3 +} T_GDT_RING; + +typedef enum E_GDT_EXECUTABLE { + GDT_NOT_EXECUTABLE = 0, + GDT_EXECUTABLE +} T_GDT_EXECUTABLE; + +typedef enum E_GDT_RW { + GDT_NOT_RW = 0, + GDT_RW +} T_GDT_RW; + +struct S_GDT_ENTRY { + u16 LimitLow; + u16 BaseLow; + u8 BaseMiddle; + u8 Access; + u8 Granularity; + u8 BaseHigh; +} __attribute__((packed)); +typedef struct S_GDT_ENTRY T_GDT_ENTRY; + +struct S_GDT_PTR { + u16 Size; + u32 Address; +} __attribute__((packed)); +typedef struct S_GDT_PTR T_GDT_PTR; + +void gdt_entry_create(u8 Index, u32 Base, u32 Limit, T_GDT_RING Ring, \ + T_GDT_EXECUTABLE Executable, T_GDT_RW ReadWrite); +void gdt_create_flat(void); + +//From gdt.asm +void gdt_flush(void); + +#endif diff --git a/src/Tier0/kstdio.h b/include/Tier0/kstdio.h similarity index 94% rename from src/Tier0/kstdio.h rename to include/Tier0/kstdio.h index 6a013e7..721c45c 100644 --- a/src/Tier0/kstdio.h +++ b/include/Tier0/kstdio.h @@ -1,7 +1,7 @@ #ifndef __KSTDIO_H__ #define __KSTDIO_H__ -#include "Types.h" +#include "types.h" void koutb(u16 Port, u8 Data); u32 kstrlen(s8 *szString); diff --git a/src/Tier0/kstdlib.h b/include/Tier0/kstdlib.h similarity index 92% rename from src/Tier0/kstdlib.h rename to include/Tier0/kstdlib.h index 5655caf..da4fb13 100644 --- a/src/Tier0/kstdlib.h +++ b/include/Tier0/kstdlib.h @@ -1,7 +1,7 @@ #ifndef __KSTDLIB_H__ #define __KSTDLIB_H__ -#include "Types.h" +#include "types.h" void *kmemcpy(void* Destination, const void *Source, u32 Count); void *kmemset(void *Destination, u8 Value, u32 Count); diff --git a/include/Tier0/paging.h b/include/Tier0/paging.h new file mode 100644 index 0000000..3e27c4a --- /dev/null +++ b/include/Tier0/paging.h @@ -0,0 +1,6 @@ +#ifndef __PAGING_H__ +#define __PAGING_H__ + +void init_simple_paging(void); + +#endif diff --git a/src/Tier0/Types.h b/include/types.h similarity index 100% rename from src/Tier0/Types.h rename to include/types.h diff --git a/src/Tier0/.gdt.h.swp b/src/Tier0/.gdt.h.swp deleted file mode 100644 index 7b79204..0000000 Binary files a/src/Tier0/.gdt.h.swp and /dev/null differ diff --git a/src/Tier0/_start.asm b/src/Tier0/_start.asm index feee3c5..6cee47a 100644 --- a/src/Tier0/_start.asm +++ b/src/Tier0/_start.asm @@ -11,9 +11,9 @@ CHECKSUM equ -(MAGIC + FLAGS) ; Other constants STACKSIZE equ 0x4000 -; ############################################################################## -; ############################# text segment ################################### -; ############################################################################## +; ############################################################################# +; ############################## text segment ################################# +; ############################################################################# section .text align 4 @@ -26,7 +26,19 @@ MultiBootHeader: ; Actual entry point _start: + lgdt [falsegdt] + mov ax, 0x10 + mov ds, ax + mov es, ax + mov fs, ax + mov gs, ax + mov ss, ax + + jmp 0x08:higherhalf + +higherhalf: mov esp, kstack + STACKSIZE + push eax push ebx @@ -39,10 +51,25 @@ ohshit: hlt jmp ohshit +; ############################################################################# +; ############################## setup segment ################################ +; ############################################################################# -; ############################################################################## -; ################################ bss segment ################################# -; ############################################################################## +section .setup + +falsegdt: + dw gdt_end - gdt - 1 + dd gdt + +gdt: + dd 0, 0 + db 0xFF, 0xFF, 0, 0, 0, 10011010b, 11001111b, 0x40 + db 0xFF, 0xFF, 0, 0, 0, 10010010b, 11001111b, 0x40 +gdt_end: + +; ############################################################################# +; ############################### bss segment ################################# +; ############################################################################# section .bss align 4 diff --git a/src/Tier0/gdt.c b/src/Tier0/gdt.c new file mode 100644 index 0000000..7ff4e69 --- /dev/null +++ b/src/Tier0/gdt.c @@ -0,0 +1,45 @@ +#include "Tier0/gdt.h" +#include "Tier0/kstdlib.h" +#include "types.h" + +// Our GDT will be stored here. +T_GDT_PTR g_gdt_ptr; +T_GDT_ENTRY g_gdt_entries[3]; + + +void gdt_entry_create(u8 Index, u32 Base, u32 Limit, T_GDT_RING Ring, \ + T_GDT_EXECUTABLE Executable, T_GDT_RW ReadWrite) +{ + g_gdt_entries[Index].BaseLow = (Base & 0xFFFF); + g_gdt_entries[Index].BaseMiddle = ((Base >> 16) & 0xFF); + g_gdt_entries[Index].BaseHigh = ((Base >> 24) & 0xFF); + + g_gdt_entries[Index].LimitLow = (Limit & 0xFFFF); + g_gdt_entries[Index].Granularity = ((Limit >> 16) & 0x0F); + + // Let's set the granularity and size nibble to 0xC0 + g_gdt_entries[Index].Granularity |= 0xC0; + + g_gdt_entries[Index].Access = 0b10010000; + g_gdt_entries[Index].Access |= ((((u8)ReadWrite) << 1) & 0b00000010); + g_gdt_entries[Index].Access |= ((((u8)Executable) << 3) & 0b00001000); + g_gdt_entries[Index].Access |= ((((u8)Ring) << 5) & 0b01100000); +} + +void gdt_entry_create_null(u8 Index) +{ + kmemsetw(&g_gdt_entries[Index], 0, 4); +} + +void gdt_create_flat(void) +{ + g_gdt_ptr.Size = sizeof(T_GDT_ENTRY) * 6 - 1; + g_gdt_ptr.Address = (u32)&g_gdt_entries; + + gdt_entry_create_null(0); + gdt_entry_create(1, 0, 0xFFFFFFFF, GDT_RING0, GDT_EXECUTABLE, GDT_RW); + gdt_entry_create(2, 0, 0xFFFFFFFF, GDT_RING0, GDT_NOT_EXECUTABLE, GDT_RW); + + gdt_flush(); +} + diff --git a/src/Tier0/kmain.c b/src/Tier0/kmain.c index 4514707..9773adb 100644 --- a/src/Tier0/kmain.c +++ b/src/Tier0/kmain.c @@ -1,9 +1,14 @@ -#include "Types.h" -#include "kstdio.h" +#include "types.h" +#include "Tier0/kstdio.h" +#include "Tier0/gdt.h" +#include "Tier0/paging.h" // Real kernel entry point, called from _start.asm void kmain(void *mbd, u32 magic) { + init_simple_paging(); + gdt_create_flat(); + if (magic != 0x2BADB002) { kprintf("[e] Fatal! Boot via incompatible bootloader.\n"); @@ -14,4 +19,6 @@ void kmain(void *mbd, u32 magic) kclear(); kprintf("[i] Booting via %s.\n", szBootLoaderName); + } + diff --git a/src/Tier0/kstdio.c b/src/Tier0/kstdio.c index 5c065fe..77a58eb 100644 --- a/src/Tier0/kstdio.c +++ b/src/Tier0/kstdio.c @@ -1,6 +1,6 @@ -#include "Types.h" -#include "kstdio.h" -#include "kstdlib.h" +#include "types.h" +#include "Tier0/kstdio.h" +#include "Tier0/kstdlib.h" #include #define va_start(v,l) __builtin_va_start(v,l) diff --git a/src/Tier0/kstdlib.c b/src/Tier0/kstdlib.c index 7747eb3..0d33772 100644 --- a/src/Tier0/kstdlib.c +++ b/src/Tier0/kstdlib.c @@ -1,5 +1,5 @@ -#include "Types.h" -#include "kstdlib.h" +#include "types.h" +#include "Tier0/kstdlib.h" void *kmemcpy(void* Destination, const void *Source, u32 Count) { diff --git a/src/Tier0/paging.asm b/src/Tier0/paging.asm new file mode 100644 index 0000000..d3e9a71 --- /dev/null +++ b/src/Tier0/paging.asm @@ -0,0 +1,19 @@ +BITS 32 +section .text + +global gdt_flush +extern g_gdt_ptr + +gdt_flush: + lgdt [g_gdt_ptr] + mov ax, 0x10 + mov ds, ax + mov es, ax + mov fs, ax + mov gs, ax + mov ss, ax + + jmp 0x08:finish + +finish: + ret diff --git a/src/Tier0/paging.c b/src/Tier0/paging.c new file mode 100644 index 0000000..41808f9 --- /dev/null +++ b/src/Tier0/paging.c @@ -0,0 +1,26 @@ +#include "Tier0/paging.h" +#include "types.h" + +u32 g_kernel_page_directory[1024] __attribute__ ((aligned (4096))); +u32 g_low_page_table[1024] __attribute__ ((aligned (4096))); + +void init_simple_paging(void) +{ + void *RealKernelPageDir = (u8 *)g_kernel_page_directory + 0x40000000; + void *RealLowPageTable = (u8 *)g_low_page_table + 0x40000000; + + for (u16 i = 0; i < 1024; i++) + { + g_kernel_page_directory[i] = (i * 4096) | 0x03; + g_low_page_table[i] = 0; + } + + g_kernel_page_directory[0] = (u32)RealLowPageTable | 0x03; + g_kernel_page_directory[768] = (u32)RealLowPageTable | 0x03; + + __asm__ volatile ( "mov %0, %%eax\n" + "mov %%eax, %%cr3\n" + "mov %%cr0, %%eax\n" + "orl $0x80000000, %%eax\n" + "mov %%eax, %%cr0\n" :: "m" (RealKernelPageDir)); +} diff --git a/src/kernel.ld b/src/kernel.ld index 362e620..e65d75a 100644 --- a/src/kernel.ld +++ b/src/kernel.ld @@ -1,24 +1,31 @@ -ENTRY (_start) +OUTPUT_FORMAT("elf32-i386") +ENTRY(_start) -SECTIONS { - . = 0x00100000; +SECTIONS +{ + . = 0x100000; + .setup : + { + *(.setup) + } - .text : { + . += 0xC0000000; + + .text : AT(ADDR(.text) - 0xC0000000) + { *(.text) } - - .rodata ALIGN (0x1000) : { - *(.rodata) - } - - .data ALIGN (0x1000) : { + + .data ALIGN (4096) : AT(ADDR(.data) - 0xC0000000) + { *(.data) + *(.rodata*) } - - .bss : { - sbss = .; - *(COMMON) - *(.bss) - ebss = .; + + .bss ALIGN (4096) : AT(ADDR(.bss) - 0xC0000000) + { + *(COMMON*) + *(.bss*) } } +