mirror of
https://git.stationery.faith/corn/corn.git
synced 2024-11-22 10:22:16 +00:00
Added basic long mode setup
This commit is contained in:
parent
05cf015382
commit
df2c0ee981
4 changed files with 138 additions and 64 deletions
8
Makefile
8
Makefile
|
@ -5,10 +5,10 @@ BUILD_DIR=build
|
||||||
K_BIN_NAME=kernel.bin
|
K_BIN_NAME=kernel.bin
|
||||||
ISO_NAME=os_image.iso
|
ISO_NAME=os_image.iso
|
||||||
|
|
||||||
CC=cc
|
CC=gcc
|
||||||
LD=ld
|
LD=ld
|
||||||
|
|
||||||
CFLAGS=-ffreestanding -g -Wall -Wextra -pedantic -lgcc -isystem $(INCLUDE_DIR)
|
CFLAGS= -std=c2x -ffreestanding -g -Wall -Wextra -pedantic -lgcc -isystem $(INCLUDE_DIR)
|
||||||
|
|
||||||
|
|
||||||
C_SRC=$(shell find $(SRC_DIR) -type f -name "*.c")
|
C_SRC=$(shell find $(SRC_DIR) -type f -name "*.c")
|
||||||
|
@ -31,6 +31,10 @@ $(A_OBJ): $(BUILD_DIR)/%.S.o : %.S
|
||||||
@mkdir -p $(@D)
|
@mkdir -p $(@D)
|
||||||
nasm $< -f elf64 -o $@
|
nasm $< -f elf64 -o $@
|
||||||
|
|
||||||
|
$(BUILD_DIR)/$(SRC_DIR)/arch/amd64/shim.o: $(SRC_DIR)/arch/amd64/shim.c
|
||||||
|
@mkdir -p $(@D)
|
||||||
|
$(CC) -c $(CFLAGS) -o $@ $< -m32
|
||||||
|
|
||||||
$(C_OBJ): $(BUILD_DIR)/%.o : %.c
|
$(C_OBJ): $(BUILD_DIR)/%.o : %.c
|
||||||
@mkdir -p $(@D)
|
@mkdir -p $(@D)
|
||||||
$(CC) -c $(CFLAGS) -o $@ $<
|
$(CC) -c $(CFLAGS) -o $@ $<
|
||||||
|
|
|
@ -3,18 +3,6 @@ extern kmain
|
||||||
extern amd64_shim
|
extern amd64_shim
|
||||||
bits 32
|
bits 32
|
||||||
|
|
||||||
; base, limit, access, flags
|
|
||||||
%macro gdt_entry 4
|
|
||||||
db %2 & 0xff
|
|
||||||
db (%2 >> 8) & 0xff
|
|
||||||
db %1 & 0xff
|
|
||||||
db (%1 >> 8) & 0xff
|
|
||||||
db (%1 >> 16) & 0xff
|
|
||||||
db %3
|
|
||||||
db ((%2 >> 16) & 0x0f) | (%4 << 4)
|
|
||||||
db (%1 >> 24) & 0xff
|
|
||||||
%endmacro
|
|
||||||
|
|
||||||
section .multiboot
|
section .multiboot
|
||||||
align 8
|
align 8
|
||||||
mb_start:
|
mb_start:
|
||||||
|
@ -38,33 +26,97 @@ stack_end:
|
||||||
|
|
||||||
section .rodata
|
section .rodata
|
||||||
align 16
|
align 16
|
||||||
gdt_start:
|
; Access bits
|
||||||
gdt_entry 0, 0, 0, 0
|
PRESENT equ 1 << 7
|
||||||
gdt_entry 0, 0xFFFFF, 0x9A, 0xC
|
NOT_SYS equ 1 << 4
|
||||||
gdt_entry 0, 0xFFFFF, 0x92, 0xC
|
EXEC equ 1 << 3
|
||||||
gdt_end:
|
DC equ 1 << 2
|
||||||
gdt_descriptor:
|
RW equ 1 << 1
|
||||||
dw gdt_end - gdt_start - 1
|
ACCESSED equ 1 << 0
|
||||||
dd gdt_start
|
|
||||||
|
|
||||||
|
; Flags bits
|
||||||
|
GRAN_4K equ 1 << 7
|
||||||
|
SZ_32 equ 1 << 6
|
||||||
|
LONG_MODE equ 1 << 5
|
||||||
|
|
||||||
|
GDT:
|
||||||
|
.Null: equ $ - GDT
|
||||||
|
dq 0
|
||||||
|
.Code: equ $ - GDT
|
||||||
|
dd 0xFFFF ; Limit & Base (low, bits 0-15)
|
||||||
|
db 0 ; Base (mid, bits 16-23)
|
||||||
|
db PRESENT | NOT_SYS | EXEC | RW ; Access
|
||||||
|
db GRAN_4K | LONG_MODE | 0xF ; Flags & Limit (high, bits 16-19)
|
||||||
|
db 0 ; Base (high, bits 24-31)
|
||||||
|
.Data: equ $ - GDT
|
||||||
|
dd 0xFFFF ; Limit & Base (low, bits 0-15)
|
||||||
|
db 0 ; Base (mid, bits 16-23)
|
||||||
|
db PRESENT | NOT_SYS | RW ; Access
|
||||||
|
db GRAN_4K | SZ_32 | 0xF ; Flags & Limit (high, bits 16-19)
|
||||||
|
db 0 ; Base (high, bits 24-31)
|
||||||
|
.TSS: equ $ - GDT
|
||||||
|
dd 0x00000068
|
||||||
|
dd 0x00CF8900
|
||||||
|
.Pointer:
|
||||||
|
dw $ - GDT - 1
|
||||||
|
dq GDT
|
||||||
|
|
||||||
section .text
|
section .text
|
||||||
align 8
|
align 8
|
||||||
start:
|
start:
|
||||||
cli
|
cli
|
||||||
lgdt [gdt_descriptor]
|
|
||||||
jmp 0x08:after_lgdt
|
|
||||||
after_lgdt:
|
|
||||||
mov ax, 0x10
|
|
||||||
mov ds, ax
|
|
||||||
mov ss, ax
|
|
||||||
mov es, ax
|
|
||||||
mov fs, ax
|
|
||||||
mov gs, ax
|
|
||||||
mov esp, stack_end
|
mov esp, stack_end
|
||||||
mov ebp, stack_end
|
mov ebp, stack_end
|
||||||
|
|
||||||
push ebx
|
push ebx
|
||||||
|
|
||||||
|
mov edi, 0x1000
|
||||||
|
mov cr3, edi
|
||||||
|
xor eax, eax
|
||||||
|
mov ecx, 4096
|
||||||
|
rep stosd
|
||||||
|
mov edi, cr3
|
||||||
|
|
||||||
|
mov DWORD [edi], 0x2003 ; Set the uint32_t at the destination index to 0x2003.
|
||||||
|
add edi, 0x1000 ; Add 0x1000 to the destination index.
|
||||||
|
mov DWORD [edi], 0x3003 ; Set the uint32_t at the destination index to 0x3003.
|
||||||
|
add edi, 0x1000 ; Add 0x1000 to the destination index.
|
||||||
|
mov DWORD [edi], 0x4003 ; Set the uint32_t at the destination index to 0x4003.
|
||||||
|
add edi, 0x1000 ; Add 0x1000 to the destination index.
|
||||||
|
|
||||||
|
mov ebx, 0x00000003 ; Set the B-register to 0x00000003.
|
||||||
|
mov ecx, 512 ; Set the C-register to 512.
|
||||||
|
|
||||||
|
.SetEntry:
|
||||||
|
mov DWORD [edi], ebx ; Set the uint32_t at the destination index to the B-register.
|
||||||
|
add ebx, 0x1000 ; Add 0x1000 to the B-register.
|
||||||
|
add edi, 8 ; Add eight to the destination index.
|
||||||
|
loop .SetEntry ; Set the next entry.
|
||||||
|
|
||||||
|
;push ebx ; Call our function to set up basic paging
|
||||||
|
;call amd64_shim
|
||||||
|
|
||||||
|
|
||||||
|
mov eax, cr4 ; Enable the PAE bit
|
||||||
|
or eax, 1 << 5
|
||||||
|
mov cr4, eax
|
||||||
|
|
||||||
|
mov ecx, 0xC0000080 ; Enable long mode
|
||||||
|
rdmsr
|
||||||
|
or eax, 1 << 8
|
||||||
|
wrmsr
|
||||||
|
|
||||||
|
mov eax, cr0 ; Enable paging
|
||||||
|
or eax, 1 << 31
|
||||||
|
mov cr0, eax
|
||||||
|
|
||||||
|
lgdt [GDT.Pointer]
|
||||||
|
jmp GDT.Code:code64
|
||||||
|
|
||||||
|
bits 64
|
||||||
|
code64:
|
||||||
call amd64_shim
|
call amd64_shim
|
||||||
|
push rax
|
||||||
call kmain
|
call kmain
|
||||||
cli
|
cli
|
||||||
halt:
|
halt:
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
#include <cpuid.h>
|
||||||
|
|
||||||
#define PG_PRESENT 0x0000'0000'0000'0001
|
#define PG_PRESENT 0x0000'0000'0000'0001
|
||||||
#define PG_READ_WRITE 0x0000'0000'0000'0002
|
#define PG_READ_WRITE 0x0000'0000'0000'0002
|
||||||
|
@ -8,14 +9,19 @@
|
||||||
#define PG_ACCESSED 0x0000'0000'0000'0020
|
#define PG_ACCESSED 0x0000'0000'0000'0020
|
||||||
#define PG_EXECUTE_DISABLE 0x8000'0000'0000'0000
|
#define PG_EXECUTE_DISABLE 0x8000'0000'0000'0000
|
||||||
|
|
||||||
|
#define F_PRESENT 0b1
|
||||||
|
#define F_WRITEABLE 0b10
|
||||||
|
#define F_UNPRIVILEGED 0b100
|
||||||
|
#define F_WRITETHROUGH 0b1000
|
||||||
|
#define F_CACHEDISABLE 0b10000
|
||||||
|
#define F_ACCESSED 0b100000
|
||||||
|
#define F_DIRTY 0b1000000
|
||||||
|
#define F_MEGABYTE 0b10000000
|
||||||
|
#define F_GLOBAL 0b100000000
|
||||||
|
|
||||||
// PAGE MAP LEVEL 4 ENTRY
|
// PAGE MAP LEVEL 4 ENTRY
|
||||||
struct pml4 {
|
struct pml4e {
|
||||||
uint64_t present : 1;
|
uint64_t flags : 6;
|
||||||
uint64_t rw : 1;
|
|
||||||
uint64_t user_supervisor : 1;
|
|
||||||
uint64_t write_through : 1;
|
|
||||||
uint64_t cache_disable : 1;
|
|
||||||
uint64_t accessed : 1;
|
|
||||||
uint64_t _reserved : 6;
|
uint64_t _reserved : 6;
|
||||||
uint64_t address : 40;
|
uint64_t address : 40;
|
||||||
uint64_t _reserved_2 : 11;
|
uint64_t _reserved_2 : 11;
|
||||||
|
@ -24,12 +30,7 @@ struct pml4 {
|
||||||
|
|
||||||
// PAGE DIRECTORY POINTER TABLE ENTRY
|
// PAGE DIRECTORY POINTER TABLE ENTRY
|
||||||
struct pdpte {
|
struct pdpte {
|
||||||
uint64_t present : 1;
|
uint64_t flags : 6;
|
||||||
uint64_t rw : 1;
|
|
||||||
uint64_t user_supervisor : 1;
|
|
||||||
uint64_t write_through : 1;
|
|
||||||
uint64_t cache_disable : 1;
|
|
||||||
uint64_t accessed : 1;
|
|
||||||
uint64_t _reserved : 1;
|
uint64_t _reserved : 1;
|
||||||
uint64_t page_size : 1;
|
uint64_t page_size : 1;
|
||||||
uint64_t _reserved_2 : 2;
|
uint64_t _reserved_2 : 2;
|
||||||
|
@ -40,12 +41,7 @@ struct pdpte {
|
||||||
|
|
||||||
// PAGE DIRECTORY ENTRY
|
// PAGE DIRECTORY ENTRY
|
||||||
struct pde {
|
struct pde {
|
||||||
uint64_t present : 1;
|
uint64_t flags : 6;
|
||||||
uint64_t rw : 1;
|
|
||||||
uint64_t user_supervisor : 1;
|
|
||||||
uint64_t write_through : 1;
|
|
||||||
uint64_t cache_disable : 1;
|
|
||||||
uint64_t accessed : 1;
|
|
||||||
uint64_t _reserved : 1;
|
uint64_t _reserved : 1;
|
||||||
uint64_t page_size : 1;
|
uint64_t page_size : 1;
|
||||||
uint64_t _reserved_2 : 2;
|
uint64_t _reserved_2 : 2;
|
||||||
|
@ -56,15 +52,7 @@ struct pde {
|
||||||
|
|
||||||
// PAGE TABLE ENTRY
|
// PAGE TABLE ENTRY
|
||||||
struct pte {
|
struct pte {
|
||||||
uint64_t present : 1;
|
uint64_t flags : 9;
|
||||||
uint64_t rw : 1;
|
|
||||||
uint64_t user_supervisor : 1;
|
|
||||||
uint64_t write_through : 1;
|
|
||||||
uint64_t cache_disable : 1;
|
|
||||||
uint64_t accessed : 1;
|
|
||||||
uint64_t dirty : 1;
|
|
||||||
uint64_t mem_type : 1;
|
|
||||||
uint64_t global : 1;
|
|
||||||
uint64_t _reserved : 3;
|
uint64_t _reserved : 3;
|
||||||
uint64_t address : 40;
|
uint64_t address : 40;
|
||||||
uint64_t _reserved_2 : 7;
|
uint64_t _reserved_2 : 7;
|
||||||
|
@ -72,7 +60,36 @@ struct pte {
|
||||||
uint64_t execute_disable : 1;
|
uint64_t execute_disable : 1;
|
||||||
};
|
};
|
||||||
|
|
||||||
// entry point for amd64
|
struct pml4e pml4[512];
|
||||||
void amd64_shim(void *boot_info) {
|
struct pdpte pdpt[512];
|
||||||
|
struct pde pd[512];
|
||||||
|
struct pte pt[512];
|
||||||
|
|
||||||
|
static int get_maxphysaddr() {
|
||||||
|
uint32_t eax, ebx, ecx, edx;
|
||||||
|
__cpuid(0x80000008, eax, ebx, ecx, edx);
|
||||||
|
return eax & 0xFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
// entry point for amd64
|
||||||
|
void* amd64_shim(void *boot_info) {
|
||||||
|
for (int i = 0; i < 512; i++) {
|
||||||
|
pml4[i].flags = 0;
|
||||||
|
}
|
||||||
|
for (int i = 0; i < 512; i++) {
|
||||||
|
pdpt[i].flags = 0;
|
||||||
|
}
|
||||||
|
for (int i = 0; i < 512; i++) {
|
||||||
|
pd[i].flags = 0;
|
||||||
|
}
|
||||||
|
pml4[0].flags = F_PRESENT | F_WRITEABLE;
|
||||||
|
pml4[0].address = (uint64_t)&pdpt;
|
||||||
|
pdpt[0].flags = F_PRESENT | F_WRITEABLE;
|
||||||
|
pdpt[0].address = (uint64_t)&pd;
|
||||||
|
pd[0].flags = F_PRESENT | F_WRITEABLE;
|
||||||
|
pd[0].address = (uint64_t)&pt;
|
||||||
|
for (int i = 0; i < 512; i++) {
|
||||||
|
pt[i].flags = F_PRESENT | F_WRITEABLE;
|
||||||
|
pt[i].address = i * 4096;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
void kmain() {
|
void kmain() {
|
||||||
|
*(char*)0xB8000 = 'c';
|
||||||
while(1) {
|
while(1) {
|
||||||
asm("cli; hlt");
|
__asm("cli; hlt");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue