diff --git a/README.md b/README.md index 6be777d..ab66815 100644 --- a/README.md +++ b/README.md @@ -4,24 +4,15 @@ ### Building the kernel -- `make` -- `i386-elf-gcc` -- `i386-elf-ld` -- `nasm` - -### Creating a disk image - - `grub` - `mtools` +- `make` +- `x86_64-elf-gcc` +- `x86_64-elf-ld` +- `nasm` ## Building -### Kernel - -```sh -make kernel -``` - ### Disk image ```sh @@ -30,8 +21,15 @@ make iso ## Running -After building, run the following: +After building the iso, run the following: ```sh -qemu-system-i386 -kernel .build/kernel +qemu-system-x86_64 -cdrom .build/nub-os.iso +``` + +## Debugging + +```sh +qemu-system-x86_64 -s -S -cdrom .build/nub-os.iso +gdb -tui .build/kernel -ex "target remote localhost:1234" ``` diff --git a/grub.cfg b/grub.cfg index 462bb74..65531ea 100644 --- a/grub.cfg +++ b/grub.cfg @@ -2,5 +2,5 @@ menuentry "nub-os" { multiboot /boot/kernel } -set default=0 +set default="nub-os" set timeout=0 diff --git a/makefile b/makefile index b2e0c4b..bc44d83 100644 --- a/makefile +++ b/makefile @@ -1,8 +1,10 @@ -CC = i386-elf-gcc -LD = i386-elf-ld +CC = x86_64-elf-gcc +LD = x86_64-elf-ld +AS = nasm -CFLAGS = -m32 -ffreestanding -fno-builtin -Wall -Wextra -Wshadow -std=c23 -LDFLAGS = +CFLAGS = -m64 -ffreestanding -fno-builtin -Wall -Wextra -Wshadow -std=c23 -g +LDFLAGS = -g +ASFLAGS = -f elf64 -g -F dwarf SRC_C := src/kernel.c src/string.c src/vga.c SRC_ASM := src/boot.asm @@ -11,9 +13,6 @@ OBJ_C := $(SRC_C:src/%.c=.build/%.o) OBJ_ASM := $(SRC_ASM:src/%.asm=.build/%.o) OBJS := $(OBJ_C) $(OBJ_ASM) -kernel: .build/kernel - @echo "Kernel created at '.build/kernel'" - iso: .build/nub-os.iso @echo "ISO created at '.build/nub-os.iso'" @@ -30,10 +29,10 @@ build-dir: grub-mkrescue -o .build/nub-os.iso .build/nub-os/ .build/kernel: $(OBJS) | linker.ld - $(LD) $(LDFLAGS) -m elf_i386 -T linker.ld -o $@ $^ + $(LD) $(LDFLAGS) -T linker.ld -o $@ $^ .build/%.o: src/%.c | build-dir $(CC) $(CFLAGS) -c -o $@ $< .build/%.o: src/%.asm | build-dir - nasm -f elf32 -o $@ $< \ No newline at end of file + $(AS) $(ASFLAGS) -o $@ $< \ No newline at end of file diff --git a/src/boot.asm b/src/boot.asm index 17f9984..d4fc095 100644 --- a/src/boot.asm +++ b/src/boot.asm @@ -1,5 +1,4 @@ global _start -extern kernel_main %define FLAGS 0b10 %define MAGIC 0x1BADB002 @@ -11,21 +10,20 @@ section .multiboot dd FLAGS dd CHECKSUM -section .bss - align 4096 - pml4_table: - resb 4096 - pdpt_table: - resb 4096 - pd_table: - resb 4096 - section .bss align 16 - stack_bottom: resb 16384 stack_top: +section .bss + align 4096 + pml4: + resb 4096 + pdpt: + resb 4096 + pd: + resb 4096 + section .data align 8 gdt64: @@ -48,7 +46,7 @@ section .text cmp eax, 0x2BADB002 jne error - ; Check if cpuid is available by flipping the 22-nth youngest bit + ; Check if cpuid is available by flipping bit 21 ; in the eflags register and checking if the cpu flipped it back pushfd pop eax @@ -74,33 +72,51 @@ section .text ; Check if long mode is available by calling cpuid with 0x80000001 ; this will place the extended features of the cpu in edx - ; The 30-nth youngest bit tells us if long mode is supported or not + ; Bit 29 tells us if long mode is supported or not mov eax, 0x80000001 cpuid test edx, 1 << 29 jz error - ; todo(nub31): setup paging - ; todo(nub31): enter long mode + ; Enable PAE by setting bit 5 in cr4 to 1 + mov eax, cr4 + or eax, 1 << 5 + mov cr4, eax + + ; todo(nub31): Set up page tables + + ; Load cr3 with the address of pml4 + mov eax, pml4 + mov cr3, eax - ; Load global descriptor table which is set up for 64 bit lgdt [gdt64.descriptor] - call kernel_main - jmp error + ; Enable long mode by setting bit 8 to 1 in EFER (Extended Feature Enable Register) + mov ecx, 0xc0000080 + rdmsr + or eax, 1 << 8 + wrmsr + + ; Enable paging bt setting bit 31 in cr0 to 1 + mov eax, cr0 + or eax, 1 << 31 + mov cr0, eax + + jmp 0x8:long_mode error: cli - mov byte [0xb8000], 'B' - mov byte [0xb8002], 'O' - mov byte [0xb8004], 'O' - mov byte [0xb8006], 'T' - mov byte [0xb8008], ' ' - mov byte [0xb800a], 'E' - mov byte [0xb800c], 'R' - mov byte [0xb800e], 'R' - mov byte [0xb8010], 'O' - mov byte [0xb8012], 'R' - hang: + mov byte [0xb8000], 'E' + mov byte [0xb8002], 'R' + mov byte [0xb8004], 'R' + .hang: hlt - jmp hang + jmp .hang + +section .text + bits 64 + long_mode: + cli + .hang: + hlt + jmp .hang \ No newline at end of file