Skip to content
Snippets Groups Projects
Commit 2fd118d0 authored by Overpeek's avatar Overpeek
Browse files

initial commit

parents
Branches
No related tags found
No related merge requests found
/target
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 3
[[package]]
name = "kernel"
version = "0.1.0"
[package]
name = "kernel"
version = "0.1.0"
edition = "2021"
build = "build.rs"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
Makefile 0 → 100644
# target specific
TARGET = x86_64-unknown-none
QEMU = qemu-system-x86_64
CONFIG = x86_64
EXTRA_RUSTFLAGS =
KERNEL = kernel
KERNEL_ELF = target/$(TARGET)/release/$(KERNEL)
KERNEL_ELF_DEPS = $(filter-out %: ,$(file < $(KERNEL_ELF).d)) $(LD_SCRIPT_PATH)/$(LD_SCRIPT) Cargo.toml
OS_ISO = target/$(TARGET)/release/$(KERNEL).iso
LD_SCRIPT_PATH = $(shell pwd)/src/arch/x86_64
LD_SCRIPT = kernel.ld
RUSTFLAGS = $(EXTRA_RUSTFLAGS) \
-C link-arg=--library-path=$(LD_SCRIPT_PATH) \
-C link-arg=--script=$(LD_SCRIPT)
CARGO_RUSTC = cargo rustc --release --target=$(TARGET)
.PHONY: run
# compile kernel
$(KERNEL_ELF): $(KERNEL_ELF_DEPS) Makefile
@echo "Compiling kernel ELF"
@RUSTFLAGS="$(RUSTFLAGS)" cargo rustc --target=$(TARGET)
cp target/$(TARGET)/debug/$(KERNEL) target/$(TARGET)/release/$(KERNEL)
# generate grub iso
$(OS_ISO): $(KERNEL_ELF) Makefile
@echo "Generate os iso"
@cp $(KERNEL_ELF) iso/boot/kernel
@grub-mkrescue /usr/lib/grub/i386-pc -o $@ iso &> /dev/null
# just compile the kernel
build: $(KERNEL_ELF) Makefile
@echo "$(KERNEL_ELF)"
# compile and run silently
run: $(OS_ISO) Makefile
@echo "Running kernel in QEMU"
@$(QEMU) $(OS_ISO) &> /dev/null
# compile, run and start gdb
debug: $(KERNEL_ELF) $(OS_ISO) Makefile
@echo "Debugging kernel in QEMU"
@$(QEMU) $(OS_ISO) -s &> /dev/null
@sleep 1
@gdb $(KERNEL_ELF) --eval-command "target remote :1234"
fn main() {}
/kernel
set timeout=0
set default=0
menuentry "kernel" {
multiboot2 /boot/kernel
boot
}
use core::arch::global_asm;
global_asm!(include_str!("boot.s"));
// global_asm!(include_str!("boot/check.asm"));
// global_asm!(include_str!("boot/header.asm"));
// global_asm!(include_str!("boot/long.asm"));
// global_asm!(include_str!("boot/main.asm"));
// global_asm!(include_str!("boot/memory.asm"));
// global_asm!(include_str!("boot/setup.asm"));
// x86_64 multiboot2 kernel start
/*
Multiboot header
*/
.section .multiboot_header, "a"
.align 4
.global header_start
header_start:
// magic number (multiboot2)
.int 0xE85250D6
// arch (protected mode i386)
.int 0
// header length
.int header_end - header_start
// checksum
.int 0x100000000 - (0xe85250d6 + 0 + header_end - header_start)
// end tag
.word 0
.word 0
.int 8
header_end:
/*
protected mode start
*/
.section .inittext
.global start
.code32
start:
// setup stack
mov esp, stack_top
// checks
call check_multiboot
call check_cpuid
call check_long_mode
// setups
call setup_page_tables
call enable_paging
// TODO: GDT before long mode
// lgdt [gdt64.pointer]
// jmp gdt64.code: start64
jmp start64
jmp halt
error:
// print 'ERR: <err>'
mov dword ptr [0xb8000], 0x4f524f45
mov dword ptr [0xb8004], 0x4f3a4f52
mov dword ptr [0xb8008], 0x4f204f20
mov byte ptr [0xb800a], al
jmp halt
halt:
cli
// print 'ZZZ' as halting
mov word ptr [0xb8f00], 0x0f5a
mov word ptr [0xb8f02], 0x0f5a
mov word ptr [0xb8f04], 0x0f5a
halt_repeat:
hlt
jmp halt_repeat
/*
checks
*/
// check if booted from a multiboot
// compliant bootloader
check_multiboot:
cmp eax, 0x36d76289
jne .no_multiboot
ret
.no_multiboot:
mov al, 'M'
jmp error
// check for cpuid instruction availability
// requirement for checking long mode support
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 for long mode availability
// requires cpuid instruction availability
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
/*
setups - page tables, paging, long mode
*/
setup_page_tables:
mov eax, p3_table
or eax, 0b11 // present, writeable
mov [p4_table], eax
mov eax, p2_table
or eax, 0b11 // present, writeable
mov [p3_table], eax
mov ecx, 0 // counter
.loop:
mov eax, 0x200000 // 2MiB
mul ecx
or eax, 0b10000011 // present, writeable, huge page
mov [p2_table + 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, p4_table
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
hlt
// enable paging
mov eax, cr0
or eax, 1 << 31
mov cr0, eax
ret
.section .text
.code64
start64:
mov ax, 0
mov ss, ax
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax
// print 'OK'
mov dword ptr [0xb8000], 0x2f4b2f4f
call kernel_main
jmp halt
/*
memory
*/
.section .bss
.align 4096
// page tables
p4_table:
.skip 4096
p3_table:
.skip 4096
p2_table:
.skip 4096
// 16 KiB stack
stack_bottom:
.skip 4096 * 4
stack_top:
// TODO: global descriptor table
/*.section .rodata
gdt64:
.long 0 ; zero entry
.code_segment: equ $ - gdt64
.long (1 << 43) | (1 << 44) | (1 << 47) | (1 << 53)
.pointer:
.word $ - gdt64 - 1
.long gdt64*/
ENTRY(start)
OUTPUT_FORMAT(elf64-x86-64)
SECTIONS {
/* 2 << 20 */
. = 0x100000;
.boot : {
KEEP(*(.multiboot_header))
*(.inittext)
}
.text : {
*(.text)
}
.rodata : {
*(.rodata)
}
.data : {
*(.data)
}
.bss : {
*(.bss)
}
}
#![no_std]
#![no_main]
#[cfg(target_arch = "x86_64")]
#[path = "arch/x86_64/boot.rs"]
mod arch_boot;
use core::panic::PanicInfo;
#[panic_handler]
fn panic_handler(_: &PanicInfo) -> ! {
loop {}
}
#[no_mangle]
fn kernel_main() {}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment