64 bit mode
This commit is contained in:
@@ -5,8 +5,8 @@
|
||||
- `make`
|
||||
- `grub`
|
||||
- `mtools`
|
||||
- `i386-elf-gcc`
|
||||
- `i386-elf-ld`
|
||||
- `x86_64-elf-gcc`
|
||||
- `x86_64-elf-ld`
|
||||
|
||||
## Building
|
||||
|
||||
|
||||
8
makefile
8
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
|
||||
nasm -f elf64 -o .build/boot.o src/boot.asm
|
||||
130
src/boot.asm
130
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
|
||||
|
||||
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
|
||||
Reference in New Issue
Block a user