64 bit support
This commit is contained in:
@@ -5,8 +5,8 @@
|
|||||||
- `make`
|
- `make`
|
||||||
- `grub`
|
- `grub`
|
||||||
- `mtools`
|
- `mtools`
|
||||||
- `i386-elf-gcc`
|
- `x86_64-elf-gcc`
|
||||||
- `i386-elf-ld`
|
- `x86_64-elf-ld`
|
||||||
|
|
||||||
## Building
|
## Building
|
||||||
|
|
||||||
|
|||||||
4
grub.cfg
4
grub.cfg
@@ -1,7 +1,3 @@
|
|||||||
menuentry "nub-os" {
|
menuentry "nub-os" {
|
||||||
multiboot2 /boot/kernel
|
multiboot2 /boot/kernel
|
||||||
boot
|
|
||||||
}
|
}
|
||||||
|
|
||||||
set default="nub-os"
|
|
||||||
set timeout=0
|
|
||||||
|
|||||||
10
makefile
10
makefile
@@ -1,8 +1,8 @@
|
|||||||
CC = i386-elf-gcc
|
CC = x86_64-elf-gcc
|
||||||
LD = i386-elf-ld
|
LD = x86_64-elf-ld
|
||||||
|
|
||||||
CFLAGS = -m32 -ffreestanding -fno-builtin -Wall -Wextra -Werror -Wshadow -std=c23
|
CFLAGS = -m64 -ffreestanding -fno-builtin -Wall -Wextra -Werror -Wshadow -std=c23
|
||||||
LDFLAGS = -m elf_i386
|
LDFLAGS =
|
||||||
|
|
||||||
all: .build/nub-os.iso
|
all: .build/nub-os.iso
|
||||||
|
|
||||||
@@ -28,4 +28,4 @@ build-dir:
|
|||||||
$(CC) $(CFLAGS) -c -o .build/vga.o src/vga.c
|
$(CC) $(CFLAGS) -c -o .build/vga.o src/vga.c
|
||||||
|
|
||||||
.build/boot.o: build-dir src/boot.asm
|
.build/boot.o: build-dir src/boot.asm
|
||||||
nasm -f elf32 -o .build/boot.o src/boot.asm
|
nasm -f elf64 -o .build/boot.o src/boot.asm
|
||||||
179
src/boot.asm
179
src/boot.asm
@@ -19,14 +19,185 @@ align 16
|
|||||||
resb 16384
|
resb 16384
|
||||||
stack_top:
|
stack_top:
|
||||||
|
|
||||||
extern kernel_main
|
align 4096
|
||||||
|
pml4_table:
|
||||||
|
resb 4096
|
||||||
|
pdp_table:
|
||||||
|
resb 4096
|
||||||
|
pd_table:
|
||||||
|
resb 4096
|
||||||
|
|
||||||
section .text
|
section .text
|
||||||
|
bits 32
|
||||||
global _start
|
global _start
|
||||||
_start:
|
_start:
|
||||||
mov esp, stack_top
|
mov esp, stack_top
|
||||||
call kernel_main
|
|
||||||
|
; Check if CPU supports 64-bit mode
|
||||||
|
call check_multiboot
|
||||||
|
call check_cpuid
|
||||||
|
call check_long_mode
|
||||||
|
|
||||||
|
; Set up paging for 64-bit mode
|
||||||
|
call set_up_page_tables
|
||||||
|
call enable_paging
|
||||||
|
|
||||||
|
; Load GDT and jump to 64-bit mode
|
||||||
|
lgdt [gdt64.pointer]
|
||||||
|
jmp gdt64.code:long_mode_start
|
||||||
|
|
||||||
|
check_multiboot:
|
||||||
|
cmp eax, 0x36d76289
|
||||||
|
jne .no_multiboot
|
||||||
|
ret
|
||||||
|
|
||||||
|
.no_multiboot:
|
||||||
|
mov al, 'M'
|
||||||
|
jmp error
|
||||||
|
|
||||||
|
check_cpuid:
|
||||||
|
; Copy flags to eax through the stack
|
||||||
|
pushfd
|
||||||
|
pop eax
|
||||||
|
|
||||||
|
; Copy flags to ecx for a later comparison
|
||||||
|
mov ecx, eax
|
||||||
|
|
||||||
|
; Flit the cpuid bit
|
||||||
|
xor eax, 1 << 21
|
||||||
|
|
||||||
|
; Copy eax (with the flipped cpuid bit) back to flags
|
||||||
|
push eax
|
||||||
|
popfd
|
||||||
|
|
||||||
|
; Copy flags back to eax. The cpiuid bit will be flipped if cpuid is supported
|
||||||
|
pushfd
|
||||||
|
pop eax
|
||||||
|
|
||||||
|
; Restore flags from the original flags stored in ecx
|
||||||
|
push ecx
|
||||||
|
popfd
|
||||||
|
|
||||||
|
; Compare eax and ecx. If thry are equal, cpuid is not supported
|
||||||
|
cmp eax, ecx
|
||||||
|
je .no_cpuid
|
||||||
|
ret
|
||||||
|
|
||||||
|
.no_cpuid:
|
||||||
|
mov al, 'I'
|
||||||
|
jmp error
|
||||||
|
|
||||||
|
check_long_mode:
|
||||||
|
; Test if extended processor info is available
|
||||||
|
mov eax, 0x80000000
|
||||||
|
cpuid
|
||||||
|
cmp eax, 0x80000001
|
||||||
|
jb .no_long_mode
|
||||||
|
|
||||||
|
; Test if long mode is available
|
||||||
|
mov eax, 0x80000001
|
||||||
|
cpuid
|
||||||
|
test edx, 1 << 29
|
||||||
|
jz .no_long_mode
|
||||||
|
ret
|
||||||
|
|
||||||
|
.no_long_mode:
|
||||||
|
mov al, 'L'
|
||||||
|
jmp error
|
||||||
|
|
||||||
|
; todo(nub): This is copy pasted. I will research hat it does later
|
||||||
|
set_up_page_tables:
|
||||||
|
; Map first PML4 entry to PDP table
|
||||||
|
mov eax, pdp_table
|
||||||
|
or eax, 0b11 ; present + writable
|
||||||
|
mov [pml4_table], eax
|
||||||
|
|
||||||
|
; Map first PDP entry to PD table
|
||||||
|
mov eax, pd_table
|
||||||
|
or eax, 0b11 ; present + writable
|
||||||
|
mov [pdp_table], eax
|
||||||
|
|
||||||
|
; Map each PD entry to a huge 2MiB page
|
||||||
|
mov ecx, 0 ; counter variable
|
||||||
|
.map_pd_table:
|
||||||
|
; Map ecx-th PD entry to a huge page that starts at address (2MiB * ecx)
|
||||||
|
mov eax, 0x200000 ; 2MiB
|
||||||
|
mul ecx ; Start address of ecx-th page
|
||||||
|
or eax, 0b10000011 ; present + writable + huge
|
||||||
|
mov [pd_table + ecx * 8], eax ; Map ecx-th entry
|
||||||
|
|
||||||
|
inc ecx ; Increase counter
|
||||||
|
cmp ecx, 512 ; If counter == 512, the whole PD table is mapped
|
||||||
|
jne .map_pd_table ; Else map the next entry
|
||||||
|
|
||||||
|
ret
|
||||||
|
|
||||||
|
; todo(nub): This is copy pasted. I will research hat it does later
|
||||||
|
enable_paging:
|
||||||
|
; Load PML4 to cr3 register (cpu uses this to access the PML4 table)
|
||||||
|
mov eax, pml4_table
|
||||||
|
mov cr3, eax
|
||||||
|
|
||||||
|
; Enable PAE-flag in cr4 (Physical Address Extension)
|
||||||
|
mov eax, cr4
|
||||||
|
or eax, 1 << 5
|
||||||
|
mov cr4, eax
|
||||||
|
|
||||||
|
; Set the long mode bit in the EFER MSR (model specific register)
|
||||||
|
mov ecx, 0xC0000080
|
||||||
|
rdmsr
|
||||||
|
or eax, 1 << 8
|
||||||
|
wrmsr
|
||||||
|
|
||||||
|
; Enable paging in the cr0 register
|
||||||
|
mov eax, cr0
|
||||||
|
or eax, 1 << 31
|
||||||
|
mov cr0, eax
|
||||||
|
|
||||||
|
ret
|
||||||
|
|
||||||
|
error:
|
||||||
|
mov byte [0xb8000], '['
|
||||||
|
mov byte [0xb8002], ' '
|
||||||
|
mov byte [0xb8004], 'E'
|
||||||
|
mov byte [0xb8005], 4
|
||||||
|
mov byte [0xb8006], 'R'
|
||||||
|
mov byte [0xb8007], 4
|
||||||
|
mov byte [0xb8008], 'R'
|
||||||
|
mov byte [0xb8009], 4
|
||||||
|
mov byte [0xb800a], ' '
|
||||||
|
mov byte [0xb800c], ']'
|
||||||
|
mov byte [0xb800e], ':'
|
||||||
|
mov byte [0xb8010], ' '
|
||||||
|
mov byte [0xb8012], al
|
||||||
cli
|
cli
|
||||||
hang:
|
.hang:
|
||||||
hlt
|
hlt
|
||||||
jmp hang
|
jmp .hang
|
||||||
|
|
||||||
|
section .rodata
|
||||||
|
gdt64:
|
||||||
|
dq 0
|
||||||
|
.code: equ $ - gdt64
|
||||||
|
dq (1<<43) | (1<<44) | (1<<47) | (1<<53)
|
||||||
|
.pointer:
|
||||||
|
dw $ - gdt64 - 1
|
||||||
|
dq gdt64
|
||||||
|
|
||||||
|
section .text
|
||||||
|
bits 64
|
||||||
|
long_mode_start:
|
||||||
|
mov ax, 0
|
||||||
|
mov ss, ax
|
||||||
|
mov ds, ax
|
||||||
|
mov es, ax
|
||||||
|
mov fs, ax
|
||||||
|
mov gs, ax
|
||||||
|
|
||||||
|
extern kernel_main
|
||||||
|
call kernel_main
|
||||||
|
|
||||||
|
cli
|
||||||
|
.hang:
|
||||||
|
hlt
|
||||||
|
jmp .hang
|
||||||
Reference in New Issue
Block a user