diff --git a/Makefile b/Makefile index 96da4a5..32170c0 100644 --- a/Makefile +++ b/Makefile @@ -4,11 +4,12 @@ iso := build/os-$(arch).iso target ?= $(arch)-blog_os rust_os := target/$(target)/debug/libblog_os.a -linker_script := src/arch/$(arch)/linker.ld -grub_cfg := src/arch/$(arch)/grub.cfg -assembly_source_files := $(wildcard src/arch/$(arch)/*.asm) -assembly_object_files := $(patsubst src/arch/$(arch)/%.asm, \ - build/arch/$(arch)/%.o, $(assembly_source_files)) +boot_src := src/arch/$(arch)/boot +linker_script := $(boot_src)/linker.ld +grub_cfg := $(boot_src)/grub.cfg +assembly_source_files := $(wildcard $(boot_src)/*.asm) +assembly_object_files := $(patsubst $(boot_src)/%.asm, \ + build/arch/$(arch)/boot/%.o, $(assembly_source_files)) ifeq ($(shell uname), Linux) prefix := @@ -45,7 +46,7 @@ kernel: @RUST_TARGET_PATH=$(shell pwd) xargo build --target $(target) # compile assembly files -build/arch/$(arch)/%.o: src/arch/$(arch)/%.asm +build/arch/$(arch)/boot/%.o: $(boot_src)/%.asm @mkdir -p $(shell dirname $@) @nasm -felf64 $< -o $@ @@ -66,7 +67,7 @@ docker_iso: @docker run --rm $(docker_args) $(docker_image):$(tag) make iso docker_run: docker_iso - @qemu-system-x86_64 -cdrom $(iso) -s + @qemu-system-$(arch) -cdrom $(iso) -s docker_interactive: @docker run -it --rm $(docker_args) $(docker_image):$(tag) diff --git a/src/arch/x86_64/boot.asm b/src/arch/x86_64/boot/boot.asm similarity index 100% rename from src/arch/x86_64/boot.asm rename to src/arch/x86_64/boot/boot.asm diff --git a/src/arch/x86_64/grub.cfg b/src/arch/x86_64/boot/grub.cfg similarity index 100% rename from src/arch/x86_64/grub.cfg rename to src/arch/x86_64/boot/grub.cfg diff --git a/src/arch/x86_64/linker.ld b/src/arch/x86_64/boot/linker.ld similarity index 100% rename from src/arch/x86_64/linker.ld rename to src/arch/x86_64/boot/linker.ld diff --git a/src/arch/x86_64/long_mode_init.asm b/src/arch/x86_64/boot/long_mode_init.asm similarity index 100% rename from src/arch/x86_64/long_mode_init.asm rename to src/arch/x86_64/boot/long_mode_init.asm diff --git a/src/arch/x86_64/multiboot_header.asm b/src/arch/x86_64/boot/multiboot_header.asm similarity index 100% rename from src/arch/x86_64/multiboot_header.asm rename to src/arch/x86_64/boot/multiboot_header.asm diff --git a/src/arch/x86_64/mod.rs b/src/arch/x86_64/mod.rs new file mode 100644 index 0000000..cdb5aec --- /dev/null +++ b/src/arch/x86_64/mod.rs @@ -0,0 +1,26 @@ +// Enable 'No-Execute' bit in page entry +fn enable_nxe_bit() { + use x86_64::registers::msr::{IA32_EFER, rdmsr, wrmsr}; + + let nxe_bit = 1 << 11; + // The EFER register is only allowed in kernel mode + // But we are in kernel mode. So it's safe. + unsafe { + let efer = rdmsr(IA32_EFER); + wrmsr(IA32_EFER, efer | nxe_bit); + } +} + +// Enable write protection in kernel mode +fn enable_write_protect_bit() { + use x86_64::registers::control_regs::{cr0, cr0_write, Cr0}; + + // The CR0 register is only allowed in kernel mode + // But we are in kernel mode. So it's safe. + unsafe { cr0_write(cr0() | Cr0::WRITE_PROTECT) }; +} + +pub fn init() { + enable_nxe_bit(); + enable_write_protect_bit(); +} \ No newline at end of file diff --git a/src/lang.rs b/src/lang.rs new file mode 100644 index 0000000..9dfff44 --- /dev/null +++ b/src/lang.rs @@ -0,0 +1,15 @@ +// Rust language features implementions + +use core; + +#[lang = "eh_personality"] +extern fn eh_personality() { +} + +#[lang = "panic_fmt"] +#[no_mangle] +pub extern fn panic_fmt(fmt: core::fmt::Arguments, file: &'static str, line: u32) -> ! { + println!("\n\nPANIC in {} at line {}:", file, line); + println!(" {}", fmt); + loop{} +} \ No newline at end of file diff --git a/src/lib.rs b/src/lib.rs index 71611f7..4b93db9 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -26,22 +26,27 @@ extern crate linked_list_allocator; #[macro_use] extern crate lazy_static; extern crate bit_field; -#[macro_use] + +#[macro_use] // println! mod vga_buffer; mod memory; mod interrupts; +mod lang; +#[allow(dead_code)] +#[cfg(target_arch = "x86_64")] +#[path = "arch/x86_64/mod.rs"] +mod arch; + +// The entry point of Rust kernel #[no_mangle] pub extern "C" fn rust_main(multiboot_information_address: usize) { // ATTENTION: we have a very small stack and no guard page vga_buffer::clear_screen(); println!("Hello World{}", "!"); - let boot_info = unsafe { - multiboot2::load(multiboot_information_address) - }; - enable_nxe_bit(); - enable_write_protect_bit(); + let boot_info = unsafe { multiboot2::load(multiboot_information_address) }; + arch::init(); // set up guard page and map the heap pages let mut memory_controller = memory::init(boot_info); @@ -72,32 +77,6 @@ pub extern "C" fn rust_main(multiboot_information_address: usize) { loop {} } -fn enable_nxe_bit() { - use x86_64::registers::msr::{IA32_EFER, rdmsr, wrmsr}; - - let nxe_bit = 1 << 11; - unsafe { - let efer = rdmsr(IA32_EFER); - wrmsr(IA32_EFER, efer | nxe_bit); - } -} - -fn enable_write_protect_bit() { - use x86_64::registers::control_regs::{cr0, cr0_write, Cr0}; - - unsafe { cr0_write(cr0() | Cr0::WRITE_PROTECT) }; -} - -#[lang = "eh_personality"] extern fn eh_personality() {} - -#[lang = "panic_fmt"] -#[no_mangle] -pub extern fn panic_fmt(fmt: core::fmt::Arguments, file: &'static str, line: u32) -> ! { - println!("\n\nPANIC in {} at line {}:", file, line); - println!(" {}", fmt); - loop{} -} - use linked_list_allocator::LockedHeap; pub const HEAP_START: usize = 0o_000_001_000_000_0000;