diff --git a/Makefile b/Makefile index 0482834accd3b966deb274ec770bffc2c516b9ad..0ca1e7bf777d275ad240668770d019fa746d0dbc 100644 --- a/Makefile +++ b/Makefile @@ -5,22 +5,25 @@ # @version 0.1 ARCH ?= x86_64 +#ARCH ?= x86 PROFILE ?= debug #PROFILE ?= release +# binary config NASM ?= nasm LD ?= ld.lld OBJCOPY ?= llvm-objcopy CARGO ?= cargo #CARGO ?= cargo-clif +# common directories TARGET_DIR ?= target HYPER_DIR := ${TARGET_DIR}/hyperion/${ARCH} ARCH_DIR := src/arch/${ARCH} +CARGO_DIR = ${TARGET_DIR}/${RUST_T_${ARCH}}/${PROFILE} # hyperion kernel lib RUST_T_x86_64 := x86_64-unknown-none -CARGO_DIR := ${TARGET_DIR}/${RUST_T_${ARCH}}/${PROFILE} RUST_F_debug := RUST_F_release:= --release CARGO_FLAGS ?= diff --git a/src/.dir-locals.el b/src/.dir-locals.el new file mode 100644 index 0000000000000000000000000000000000000000..df82ef173787a5970a17c5df92c808e67a900a0e --- /dev/null +++ b/src/.dir-locals.el @@ -0,0 +1,3 @@ +((nil . ((lsp-rust-analyzer-cargo-target . "x86_64-unknown-none") + (lsp-rust-all-targets . nil) + (lsp-rust-analyzer-cargo-all-targets . nil)))) diff --git a/src/arch/x86_64/link.ld b/src/arch/x86_64/link.ld index eb5ae92337ff526991988521a56ef5b15407d977..ae313ee218f5225a7688de46aa7efbee9c872eb4 100644 --- a/src/arch/x86_64/link.ld +++ b/src/arch/x86_64/link.ld @@ -3,12 +3,25 @@ ENTRY(start) SECTIONS { . = 1M; - .boot_text : ALIGN(4k) { - KEEP(*(.multiboot1)) - *(.boot) + .boot : ALIGN(4k) { + KEEP(*(.multiboot1)) + *(.boot) } .text : ALIGN(4k) { - *(.text) + *(.text) + } + + .rodata : ALIGN(4k) { + *(.rodata) + } + + .data : ALIGN(4k) { + *(.data) + } + + .bss : ALIGN(4k) { + *(COMMON) + *(.bss) } } diff --git a/src/arch/x86_64/start.asm b/src/arch/x86_64/start.asm index c5ef80103f930633ba73799a8e83e938bcd5c0ef..e4b6d60ea745e9a64cbd1d6c744ff919e49075ae 100644 --- a/src/arch/x86_64/start.asm +++ b/src/arch/x86_64/start.asm @@ -1,3 +1,6 @@ + global start + extern kernel_main + ;; ---------- ;; Multiboot2 ;; ---------- @@ -27,7 +30,205 @@ header_end: global start bits 32 + ;; ---------- + ;; Boot entry + ;; ---------- + start: cli cld + + ;; init stack + mov esp, stack_top + + ;; support checks + call check_multiboot1 + call check_cpuid + call check_long_mode + + ;; setup + call setup_page_tables + call enable_paging + + ;; enter long mode + lgdt [gdt64.pointer] + jmp gdt64.code_segment: long_mode_start + jmp halt + +error: + ;; print 'ERR: <err>' + mov dword [0xb8000], 0x4f524f45 + mov dword [0xb8004], 0x4f3a4f52 + mov dword [0xb8008], 0x4f204f20 + mov byte [0xb800a], al + jmp halt + +halt: + ;; print ZZZ + mov word [0xb8f00], 0x0f5a + mov word [0xb8f02], 0x0f5a + mov word [0xb8f04], 0x0f5a hlt + jmp halt + + ;; ------ + ;; Checks + ;; ------ + + section .boot + bits 32 + +check_multiboot2: + cmp eax, 0x36D76289 + jne .no_multiboot2 + ret + +.no_multiboot2: + mov al, 'M' + jmp error + +check_multiboot1: + cmp eax, 0x2BADB002 + jne .no_multiboot1 + ret + +.no_multiboot1: + 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 + + ;; ---------- + ;; Page setup + ;; ---------- + +setup_page_tables: + mov eax, page_table_l3 + or eax, 0b11 ; present, writeable + mov [page_table_l4], eax + + mov eax, page_table_l2 + or eax, 0b11 ; present, writeable + mov [page_table_l3], eax + + mov ecx, 0 ; counter + +.loop: + mov eax, 0x200000 ; 2MiB + mul ecx, + or eax, 0b10000011 ; present, writeable, huge page + mov [page_table_l2 + ecx * 8], eax + + inc ecx ; inc counter + cmp ecx, 512 ; check if the whole table is mapped + jne .loop ; if not: continue + + ret + +enable_paging: + ; pass page table location to the 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 + + ;; --------- + ;; Long mode + ;; --------- + + 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 + + ; print 'OK' + mov dword [0xb8000], 0x2f4b2f4f + + call kernel_main +.halt: + hlt + jmp halt + + ;; ------ + ;; Memory + ;; ------ + + section .bss + +page_table_l4: + resb 4096 +page_table_l3: + resb 4096 +page_table_l2: + resb 4096 + +stack_bottom: + ;; 16 KiB + 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) +.pointer: + dw $ - gdt64 - 1 + dq gdt64 diff --git a/src/lib.rs b/src/lib.rs index 1c26aad36a307c9123bab5c7443f91041fd278d2..eda8e74d96fbc10c33fec94130e77a0d1e3a8aa6 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -8,4 +8,14 @@ fn panic_handler(_: &core::panic::PanicInfo) -> ! { #[no_mangle] #[link_section = ".boot"] -pub extern "C" fn _start() {} +pub extern "C" fn kernel_main() -> ! { + unsafe { + *(0xB8000 as *mut u32) = 0x4f524f45; + } + + loop { + unsafe { + core::arch::asm!("hlt"); + } + } +}