diff --git a/OVMFbin/OVMF_VARS-pure-efi.fd b/OVMFbin/OVMF_VARS-pure-efi.fd index dccf4a9..829b1b4 100644 Binary files a/OVMFbin/OVMF_VARS-pure-efi.fd and b/OVMFbin/OVMF_VARS-pure-efi.fd differ diff --git a/kernel/Makefile b/kernel/Makefile index 63d9893..ae40d4f 100644 --- a/kernel/Makefile +++ b/kernel/Makefile @@ -1,23 +1,14 @@ - OSNAME = CustomOS GNUEFI = ../gnu-efi OVMFDIR = ../OVMFbin LDS = kernel.ld CC = gcc +ASMC = nasm LD = ld CFLAGS = -ffreestanding -fshort-wchar -LDFLAGS = -T $(LDS) -static -Bsymbolic -nostdlib -OSNAME = CustomOS - -GNUEFI = ../gnu-efi -OVMFDIR = ../OVMFbin -LDS = kernel.ld -CC = gcc -LD = ld - -CFLAGS = -ffreestanding -fshort-wchar +ASMFLAGS = LDFLAGS = -T $(LDS) -static -Bsymbolic -nostdlib SRCDIR := src @@ -27,8 +18,10 @@ BOOTEFI := $(GNUEFI)/x86_64/bootloader/main.efi rwildcard=$(foreach d,$(wildcard $(1:=/*)),$(call rwildcard,$d,$2) $(filter $(subst *,%,$2),$d)) -SRC = $(call rwildcard,$(SRCDIR),*.cpp) +SRC = $(call rwildcard,$(SRCDIR),*.cpp) +ASMSRC = $(call rwildcard,$(SRCDIR),*.asm) OBJS = $(patsubst $(SRCDIR)/%.cpp, $(OBJDIR)/%.o, $(SRC)) +OBJS += $(patsubst $(SRCDIR)/%.asm, $(OBJDIR)/%_asm.o, $(ASMSRC)) DIRS = $(wildcard $(SRCDIR)/*) kernel: $(OBJS) link @@ -38,9 +31,13 @@ $(OBJDIR)/%.o: $(SRCDIR)/%.cpp @ mkdir -p $(@D) $(CC) $(CFLAGS) -c $^ -o $@ +$(OBJDIR)/%_asm.o: $(SRCDIR)/%.asm + @ echo !==== ASSEMBLING $^ + @ mkdir -p $(@D) + $(ASMC) $(ASMFLAGS) $^ -f elf64 -o $@ + link: @ echo !==== LINKING - @echo $(OBJS) $(LD) $(LDFLAGS) -o $(BUILDDIR)/kernel.elf $(OBJS) setup: diff --git a/kernel/bin/CustomOS.img b/kernel/bin/CustomOS.img index e900d93..ef6e386 100644 Binary files a/kernel/bin/CustomOS.img and b/kernel/bin/CustomOS.img differ diff --git a/kernel/bin/kernel.elf b/kernel/bin/kernel.elf index d07eeb2..949fb6a 100755 Binary files a/kernel/bin/kernel.elf and b/kernel/bin/kernel.elf differ diff --git a/kernel/lib/gdt/gdt.o b/kernel/lib/gdt/gdt.o new file mode 100644 index 0000000..8dae905 Binary files /dev/null and b/kernel/lib/gdt/gdt.o differ diff --git a/kernel/lib/gdt/gdt_asm.o b/kernel/lib/gdt/gdt_asm.o new file mode 100644 index 0000000..390475f Binary files /dev/null and b/kernel/lib/gdt/gdt_asm.o differ diff --git a/kernel/lib/kernelUtil.o b/kernel/lib/kernelUtil.o index 71589d4..9750988 100644 Binary files a/kernel/lib/kernelUtil.o and b/kernel/lib/kernelUtil.o differ diff --git a/kernel/src/gdt/gdt.asm b/kernel/src/gdt/gdt.asm new file mode 100644 index 0000000..5a4dc0e --- /dev/null +++ b/kernel/src/gdt/gdt.asm @@ -0,0 +1,23 @@ +[bits 64] +LoadGDT: + ; rdi is the first argument passed to the LoadGDT function by C + lgdt [rdi] + + ; update the data segment registers + mov ax, 0x10 + mov ds, ax + mov es, ax + mov fs, ax + mov gs, ax + mov ss, ax + + ; update the code segment + pop rdi ; store return address in rdi + mov rax, 0x08 ; code segment offset + push rax ; we push 0x08 because it will be used by the far return instruction + push rdi ; push return address because it will be used by far return + + ; far return + retfq + +GLOBAL LoadGDT \ No newline at end of file diff --git a/kernel/src/gdt/gdt.cpp b/kernel/src/gdt/gdt.cpp new file mode 100644 index 0000000..2c28277 --- /dev/null +++ b/kernel/src/gdt/gdt.cpp @@ -0,0 +1,11 @@ +#include "gdt.h" + +__attribute__((aligned(0x1000))) +GDT DefaultGDT = { + {0, 0, 0, 0x00, 0x00, 0}, // null + {0, 0, 0, 0x9A, 0xA0, 0}, // kernel code + {0, 0, 0, 0x92, 0xA0, 0}, // kernel data + {0, 0, 0, 0x00, 0x00, 0}, // user null + {0, 0, 0, 0x9A, 0xA0, 0}, // user code + {0, 0, 0, 0x92, 0xA0, 0}, // user data +}; \ No newline at end of file diff --git a/kernel/src/gdt/gdt.h b/kernel/src/gdt/gdt.h new file mode 100644 index 0000000..be7e24e --- /dev/null +++ b/kernel/src/gdt/gdt.h @@ -0,0 +1,29 @@ +#pragma once +#include + +struct GDTDescriptor { + uint16_t Size; + uint64_t Offset; +}__attribute__((packed)); + +struct GDTEntry { + uint16_t Limit0; + uint16_t Base0; + uint8_t Base1; + uint8_t AccessByte; + uint8_t Limit1_Flags; + uint8_t Base2; +}__attribute__((packed)); + +struct GDT { + GDTEntry Null; // 0x00 + GDTEntry KernelCode; // 0x08 + GDTEntry KernelData; // 0x10 + GDTEntry UserNull; // 0x18 + GDTEntry UserCode; // 0x20 + GDTEntry UserData; // 0x28 +}__attribute__((packed)) __attribute__((aligned(0x1000))); + +extern GDT DefaultGDT; + +extern "C" void LoadGDT(GDTDescriptor* gdtDescriptor); \ No newline at end of file diff --git a/kernel/src/kernelUtil.cpp b/kernel/src/kernelUtil.cpp index 10347aa..76727f7 100644 --- a/kernel/src/kernelUtil.cpp +++ b/kernel/src/kernelUtil.cpp @@ -5,6 +5,7 @@ extern "C" void __stack_chk_fail(void) { } #include "kernelUtil.h" +#include "gdt/gdt.h" KernelInfo kernelInfo; PageTableManager pageTableManager = NULL; @@ -43,6 +44,11 @@ void PrepareMemory(BootInfo* bootInfo){ KernelInfo InitializeKernel(BootInfo* bootInfo){ + GDTDescriptor gdtDescriptor; + gdtDescriptor.Size = sizeof(GDT) - 1; + gdtDescriptor.Offset = (uint64_t)&DefaultGDT; + LoadGDT(&gdtDescriptor); + PrepareMemory(bootInfo); memset(bootInfo->framebuffer->BaseAddress, 0, bootInfo->framebuffer->BufferSize);