diff --git a/README.md b/README.md index 8e2984e..a974b4b 100644 --- a/README.md +++ b/README.md @@ -5,8 +5,8 @@ - `make` - `grub` - `mtools` -- `i386-elf-gcc` -- `i386-elf-ld` +- `x86_64-elf-gcc` +- `x86_64-elf-ld` ## Building diff --git a/makefile b/makefile index 36dd030..af8061e 100644 --- a/makefile +++ b/makefile @@ -1,7 +1,7 @@ -CC = i386-elf-gcc -LD = i386-elf-ld +CC = x86_64-elf-gcc +LD = x86_64-elf-ld -CFLAGS = -ffreestanding -m32 +CFLAGS = -ffreestanding -m64 all: .build/nub-os.iso @@ -27,4 +27,4 @@ build-dir: $(CC) $(CFLAGS) -c -o .build/print.o src/print.c .build/boot.o: build-dir src/boot.asm - nasm -f elf32 -o .build/boot.o src/boot.asm \ No newline at end of file + nasm -f elf64 -o .build/boot.o src/boot.asm \ No newline at end of file diff --git a/src/boot.asm b/src/boot.asm index 660a9b9..437e295 100644 --- a/src/boot.asm +++ b/src/boot.asm @@ -4,7 +4,7 @@ %define CHECKSUM -(MAGIC + ARCH + LEN) header_start: -align 8 +align 4 dd MAGIC dd ARCH dd LEN @@ -14,18 +14,144 @@ align 8 header_end: section .bss +align 4096 +page_table_l4: + resb 4096 +page_table_l3: + resb 4096 +page_table_l2: + resb 4096 + align 16 -resb 16384 + resb 16384 stack_top: extern kernel_main section .text +bits 32 global _start _start: mov esp, stack_top + + call check_cpuid + call check_long_mode + + call setup_page_tables + call enable_paging + + lgdt [gdt64.pointer] + + jmp gdt64.kernel_code:long_mode_start + +check_cpuid: + pushfd + pop eax + mov ecx, eax + xor eax, 1 << 21 + push eax + popfd + pushfd + pop eax + push ecx + popfd + xor eax, ecx + jz .no_cpuid + ret +.no_cpuid: + mov al, 'I' + jmp error + +check_long_mode: + mov eax, 0x80000000 + cpuid + cmp eax, 0x80000001 + jb .no_long_mode + + mov eax, 0x80000001 + cpuid + test edx, 1 << 29 + jz .no_long_mode + ret +.no_long_mode: + mov al, 'L' + jmp error + +setup_page_tables: + mov edi, page_table_l4 + mov ecx, 4096 * 3 / 4 + xor eax, eax + rep stosd + + mov eax, page_table_l3 + or eax, 0b11 + mov [page_table_l4], eax + + mov eax, page_table_l2 + or eax, 0b11 + mov [page_table_l3], eax + + mov ecx, 0 +.map_p2_table: + mov eax, 0x200000 + mul ecx + or eax, 0b10000011 + mov [page_table_l2 + ecx * 8], eax + inc ecx + cmp ecx, 512 + jne .map_p2_table + ret + +enable_paging: + mov eax, page_table_l4 + mov cr3, eax + + mov eax, cr4 + or eax, 1 << 5 + mov cr4, eax + + mov ecx, 0xC0000080 + rdmsr + or eax, 1 << 8 + wrmsr + + mov eax, cr0 + or eax, 1 << 31 + mov cr0, eax + ret + +bits 64 +long_mode_start: + mov ax, gdt64.kernel_data + mov ss, ax + mov ds, ax + mov es, ax + mov fs, ax + mov gs, ax + + mov rsp, stack_top + call kernel_main + cli hang: hlt - jmp hang \ No newline at end of file + jmp hang + +error: + mov dword [0xb8000], 0x4f524f45 + mov dword [0xb8004], 0x4f3a4f52 + mov dword [0xb8008], 0x4f204f20 + mov byte [0xb800a], al + hlt + +section .rodata +gdt64: + dq 0 +.kernel_code: equ $ - gdt64 + dq (1<<44) | (1<<47) | (1<<41) | (1<<43) | (1<<53) +.kernel_data: equ $ - gdt64 + dq (1<<44) | (1<<47) | (1<<41) +.pointer: + dw $ - gdt64 - 1 + dq gdt64 \ No newline at end of file