This commit is contained in:
nub31
2025-08-31 20:23:52 +02:00
parent cc7b16ee1e
commit b3ceaa5eaf
4 changed files with 68 additions and 55 deletions

View File

@@ -4,24 +4,15 @@
### Building the kernel ### Building the kernel
- `make`
- `i386-elf-gcc`
- `i386-elf-ld`
- `nasm`
### Creating a disk image
- `grub` - `grub`
- `mtools` - `mtools`
- `make`
- `x86_64-elf-gcc`
- `x86_64-elf-ld`
- `nasm`
## Building ## Building
### Kernel
```sh
make kernel
```
### Disk image ### Disk image
```sh ```sh
@@ -30,8 +21,15 @@ make iso
## Running ## Running
After building, run the following: After building the iso, run the following:
```sh ```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"
``` ```

View File

@@ -2,5 +2,5 @@ menuentry "nub-os" {
multiboot /boot/kernel multiboot /boot/kernel
} }
set default=0 set default="nub-os"
set timeout=0 set timeout=0

View File

@@ -1,8 +1,10 @@
CC = i386-elf-gcc CC = x86_64-elf-gcc
LD = i386-elf-ld LD = x86_64-elf-ld
AS = nasm
CFLAGS = -m32 -ffreestanding -fno-builtin -Wall -Wextra -Wshadow -std=c23 CFLAGS = -m64 -ffreestanding -fno-builtin -Wall -Wextra -Wshadow -std=c23 -g
LDFLAGS = LDFLAGS = -g
ASFLAGS = -f elf64 -g -F dwarf
SRC_C := src/kernel.c src/string.c src/vga.c SRC_C := src/kernel.c src/string.c src/vga.c
SRC_ASM := src/boot.asm 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) OBJ_ASM := $(SRC_ASM:src/%.asm=.build/%.o)
OBJS := $(OBJ_C) $(OBJ_ASM) OBJS := $(OBJ_C) $(OBJ_ASM)
kernel: .build/kernel
@echo "Kernel created at '.build/kernel'"
iso: .build/nub-os.iso iso: .build/nub-os.iso
@echo "ISO created at '.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/ grub-mkrescue -o .build/nub-os.iso .build/nub-os/
.build/kernel: $(OBJS) | linker.ld .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 .build/%.o: src/%.c | build-dir
$(CC) $(CFLAGS) -c -o $@ $< $(CC) $(CFLAGS) -c -o $@ $<
.build/%.o: src/%.asm | build-dir .build/%.o: src/%.asm | build-dir
nasm -f elf32 -o $@ $< $(AS) $(ASFLAGS) -o $@ $<

View File

@@ -1,5 +1,4 @@
global _start global _start
extern kernel_main
%define FLAGS 0b10 %define FLAGS 0b10
%define MAGIC 0x1BADB002 %define MAGIC 0x1BADB002
@@ -11,21 +10,20 @@ section .multiboot
dd FLAGS dd FLAGS
dd CHECKSUM dd CHECKSUM
section .bss
align 4096
pml4_table:
resb 4096
pdpt_table:
resb 4096
pd_table:
resb 4096
section .bss section .bss
align 16 align 16
stack_bottom:
resb 16384 resb 16384
stack_top: stack_top:
section .bss
align 4096
pml4:
resb 4096
pdpt:
resb 4096
pd:
resb 4096
section .data section .data
align 8 align 8
gdt64: gdt64:
@@ -48,7 +46,7 @@ section .text
cmp eax, 0x2BADB002 cmp eax, 0x2BADB002
jne error 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 ; in the eflags register and checking if the cpu flipped it back
pushfd pushfd
pop eax pop eax
@@ -74,33 +72,51 @@ section .text
; Check if long mode is available by calling cpuid with 0x80000001 ; Check if long mode is available by calling cpuid with 0x80000001
; this will place the extended features of the cpu in edx ; 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 mov eax, 0x80000001
cpuid cpuid
test edx, 1 << 29 test edx, 1 << 29
jz error jz error
; todo(nub31): setup paging ; Enable PAE by setting bit 5 in cr4 to 1
; todo(nub31): enter long mode 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] lgdt [gdt64.descriptor]
call kernel_main ; Enable long mode by setting bit 8 to 1 in EFER (Extended Feature Enable Register)
jmp error 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: error:
cli cli
mov byte [0xb8000], 'B' mov byte [0xb8000], 'E'
mov byte [0xb8002], 'O' mov byte [0xb8002], 'R'
mov byte [0xb8004], 'O' mov byte [0xb8004], 'R'
mov byte [0xb8006], 'T' .hang:
mov byte [0xb8008], ' '
mov byte [0xb800a], 'E'
mov byte [0xb800c], 'R'
mov byte [0xb800e], 'R'
mov byte [0xb8010], 'O'
mov byte [0xb8012], 'R'
hang:
hlt hlt
jmp hang jmp .hang
section .text
bits 64
long_mode:
cli
.hang:
hlt
jmp .hang