-
Notifications
You must be signed in to change notification settings - Fork 121
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
a7f90bb
commit 31bc853
Showing
6 changed files
with
282 additions
and
4 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,13 +1,29 @@ | ||
kernel_source_files := $(shell find src/impl/kernel -name *.c) | ||
kernel_object_files := $(patsubst src/impl/kernel/%.c, build/kernel/%.o, $(kernel_source_files)) | ||
|
||
x86_64_c_source_files := $(shell find src/impl/x86_64 -name *.c) | ||
x86_64_c_object_files := $(patsubst src/impl/x86_64/%.c, build/x86_64/%.o, $(x86_64_c_source_files)) | ||
|
||
x86_64_asm_source_files := $(shell find src/impl/x86_64 -name *.asm) | ||
x86_64_asm_object_files := $(patsubst src/impl/x86_64/%.asm, build/x86_64/%.o, $(x86_64_asm_source_files)) | ||
|
||
x86_64_object_files := $(x86_64_c_object_files) $(x86_64_asm_object_files) | ||
|
||
$(kernel_object_files): build/kernel/%.o : src/impl/kernel/%.c | ||
mkdir -p $(dir $@) && \ | ||
x86_64-elf-gcc -c -I src/intf -ffreestanding $(patsubst build/kernel/%.o, src/impl/kernel/%.c, $@) -o $@ | ||
|
||
$(x86_64_c_object_files): build/x86_64/%.o : src/impl/x86_64/%.c | ||
mkdir -p $(dir $@) && \ | ||
x86_64-elf-gcc -c -I src/intf -ffreestanding $(patsubst build/x86_64/%.o, src/impl/x86_64/%.c, $@) -o $@ | ||
|
||
$(x86_64_asm_object_files): build/x86_64/%.o : src/impl/x86_64/%.asm | ||
mkdir -p $(dir $@) && \ | ||
nasm -f elf64 $(patsubst build/x86_64/%.o, src/impl/x86_64/%.asm, $@) -o $@ | ||
|
||
.PHONY: build-x86_64 | ||
build-x86_64: $(x86_64_asm_object_files) | ||
build-x86_64: $(kernel_object_files) $(x86_64_object_files) | ||
mkdir -p dist/x86_64 && \ | ||
x86_64-elf-ld -n -o dist/x86_64/kernel.bin -T targets/x86_64/linker.ld $(x86_64_asm_object_files) && \ | ||
x86_64-elf-ld -n -o dist/x86_64/kernel.bin -T targets/x86_64/linker.ld $(kernel_object_files) $(x86_64_object_files) && \ | ||
cp dist/x86_64/kernel.bin targets/x86_64/iso/boot/kernel.bin && \ | ||
grub-mkrescue /usr/lib/grub/i386-pc -o dist/x86_64/kernel.iso targets/x86_64/iso |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
#include "print.h" | ||
|
||
void kernel_main() { | ||
print_clear(); | ||
print_set_color(PRINT_COLOR_YELLOW, PRINT_COLOR_BLACK); | ||
print_str("Welcome to our 64-bit kernel!"); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,8 +1,136 @@ | ||
global start | ||
extern long_mode_start | ||
|
||
section .text | ||
bits 32 | ||
start: | ||
; print `OK` | ||
mov dword [0xb8000], 0x2f4b2f4f | ||
mov esp, stack_top | ||
|
||
call check_multiboot | ||
call check_cpuid | ||
call check_long_mode | ||
|
||
call setup_page_tables | ||
call enable_paging | ||
|
||
lgdt [gdt64.pointer] | ||
jmp gdt64.code_segment:long_mode_start | ||
|
||
hlt | ||
|
||
check_multiboot: | ||
cmp eax, 0x36d76289 | ||
jne .no_multiboot | ||
ret | ||
.no_multiboot: | ||
mov al, "M" | ||
jmp error | ||
|
||
check_cpuid: | ||
pushfd | ||
pop eax | ||
mov ecx, eax | ||
xor eax, 1 << 21 | ||
push eax | ||
popfd | ||
pushfd | ||
pop eax | ||
push ecx | ||
popfd | ||
cmp eax, ecx | ||
je .no_cpuid | ||
ret | ||
.no_cpuid: | ||
mov al, "C" | ||
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 eax, page_table_l3 | ||
or eax, 0b11 ; present, writable | ||
mov [page_table_l4], eax | ||
mov eax, page_table_l2 | ||
or eax, 0b11 ; present, writable | ||
mov [page_table_l3], eax | ||
|
||
mov ecx, 0 ; counter | ||
.loop: | ||
|
||
mov eax, 0x200000 ; 2MiB | ||
mul ecx | ||
or eax, 0b10000011 ; present, writable, huge page | ||
mov [page_table_l2 + ecx * 8], eax | ||
|
||
inc ecx ; increment counter | ||
cmp ecx, 512 ; checks if the whole table is mapped | ||
jne .loop ; if not, continue | ||
|
||
ret | ||
|
||
enable_paging: | ||
; pass page table location to cpu | ||
mov eax, page_table_l4 | ||
mov cr3, eax | ||
|
||
; enable PAE | ||
mov eax, cr4 | ||
or eax, 1 << 5 | ||
mov cr4, eax | ||
|
||
; enable long mode | ||
mov ecx, 0xC0000080 | ||
rdmsr | ||
or eax, 1 << 8 | ||
wrmsr | ||
|
||
; enable paging | ||
mov eax, cr0 | ||
or eax, 1 << 31 | ||
mov cr0, eax | ||
|
||
ret | ||
|
||
error: | ||
; print "ERR: X" where X is the error code | ||
mov dword [0xb8000], 0x4f524f45 | ||
mov dword [0xb8004], 0x4f3a4f52 | ||
mov dword [0xb8008], 0x4f204f20 | ||
mov byte [0xb800a], al | ||
hlt | ||
|
||
section .bss | ||
align 4096 | ||
page_table_l4: | ||
resb 4096 | ||
page_table_l3: | ||
resb 4096 | ||
page_table_l2: | ||
resb 4096 | ||
stack_bottom: | ||
resb 4096 * 4 | ||
stack_top: | ||
|
||
section .rodata | ||
gdt64: | ||
dq 0 ; zero entry | ||
.code_segment: equ $ - gdt64 | ||
dq (1 << 43) | (1 << 44) | (1 << 47) | (1 << 53) ; code segment | ||
.pointer: | ||
dw $ - gdt64 - 1 ; length | ||
dq gdt64 ; address |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
global long_mode_start | ||
extern kernel_main | ||
|
||
section .text | ||
bits 64 | ||
long_mode_start: | ||
; load null into all data segment registers | ||
mov ax, 0 | ||
mov ss, ax | ||
mov ds, ax | ||
mov es, ax | ||
mov fs, ax | ||
mov gs, ax | ||
|
||
call kernel_main | ||
hlt |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
#include "print.h" | ||
|
||
const static size_t NUM_COLS = 80; | ||
const static size_t NUM_ROWS = 25; | ||
|
||
struct Char { | ||
uint8_t character; | ||
uint8_t color; | ||
}; | ||
|
||
struct Char* buffer = (struct Char*) 0xb8000; | ||
size_t col = 0; | ||
size_t row = 0; | ||
uint8_t color = PRINT_COLOR_WHITE | PRINT_COLOR_BLACK << 4; | ||
|
||
void clear_row(size_t row) { | ||
struct Char empty = (struct Char) { | ||
character: ' ', | ||
color: color, | ||
}; | ||
|
||
for (size_t col = 0; col < NUM_COLS; col++) { | ||
buffer[col + NUM_COLS * row] = empty; | ||
} | ||
} | ||
|
||
void print_clear() { | ||
for (size_t i = 0; i < NUM_ROWS; i++) { | ||
clear_row(i); | ||
} | ||
} | ||
|
||
void print_newline() { | ||
col = 0; | ||
|
||
if (row < NUM_ROWS - 1) { | ||
row++; | ||
return; | ||
} | ||
|
||
for (size_t row = 1; row < NUM_ROWS; row++) { | ||
for (size_t col = 0; col < NUM_COLS; col++) { | ||
struct Char character = buffer[col + NUM_COLS * row]; | ||
buffer[col + NUM_COLS * (row - 1)] = character; | ||
} | ||
} | ||
|
||
clear_row(NUM_COLS - 1); | ||
} | ||
|
||
void print_char(char character) { | ||
if (character == '\n') { | ||
print_newline(); | ||
return; | ||
} | ||
|
||
if (col > NUM_COLS) { | ||
print_newline(); | ||
} | ||
|
||
buffer[col + NUM_COLS * row] = (struct Char) { | ||
character: (uint8_t) character, | ||
color: color, | ||
}; | ||
|
||
col++; | ||
} | ||
|
||
void print_str(char* str) { | ||
for (size_t i = 0; 1; i++) { | ||
char character = (uint8_t) str[i]; | ||
|
||
if (character == '\0') { | ||
return; | ||
} | ||
|
||
print_char(character); | ||
} | ||
} | ||
|
||
void print_set_color(uint8_t foreground, uint8_t background) { | ||
color = foreground + (background << 4); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
#pragma once | ||
|
||
#include <stdint.h> | ||
#include <stddef.h> | ||
|
||
enum { | ||
PRINT_COLOR_BLACK = 0, | ||
PRINT_COLOR_BLUE = 1, | ||
PRINT_COLOR_GREEN = 2, | ||
PRINT_COLOR_CYAN = 3, | ||
PRINT_COLOR_RED = 4, | ||
PRINT_COLOR_MAGENTA = 5, | ||
PRINT_COLOR_BROWN = 6, | ||
PRINT_COLOR_LIGHT_GRAY = 7, | ||
PRINT_COLOR_DARK_GRAY = 8, | ||
PRINT_COLOR_LIGHT_BLUE = 9, | ||
PRINT_COLOR_LIGHT_GREEN = 10, | ||
PRINT_COLOR_LIGHT_CYAN = 11, | ||
PRINT_COLOR_LIGHT_RED = 12, | ||
PRINT_COLOR_PINK = 13, | ||
PRINT_COLOR_YELLOW = 14, | ||
PRINT_COLOR_WHITE = 15, | ||
}; | ||
|
||
void print_clear(); | ||
void print_char(char character); | ||
void print_str(char* string); | ||
void print_set_color(uint8_t foreground, uint8_t background); |