Auto exit in qemu

master
WangRunji 7 years ago
parent 9bf95a5443
commit 2e405a0393

@ -6,6 +6,9 @@ authors = ["Philipp Oppermann <dev@phil-opp.com>"]
[lib] [lib]
crate-type = ["staticlib"] crate-type = ["staticlib"]
[features]
qemu_auto_exit = []
[dependencies] [dependencies]
bit_field = "0.7.0" bit_field = "0.7.0"
rlibc = "1.0" rlibc = "1.0"

@ -10,6 +10,10 @@ grub_cfg := $(boot_src)/grub.cfg
assembly_source_files := $(wildcard $(boot_src)/*.asm) assembly_source_files := $(wildcard $(boot_src)/*.asm)
assembly_object_files := $(patsubst $(boot_src)/%.asm, \ assembly_object_files := $(patsubst $(boot_src)/%.asm, \
build/arch/$(arch)/boot/%.o, $(assembly_source_files)) build/arch/$(arch)/boot/%.o, $(assembly_source_files))
qemu_opts := -cdrom $(iso) \
-smp 2 \
-device isa-debug-exit # enable shutdown inside the qemu
features := qemu_auto_exit
ifeq ($(shell uname), Linux) ifeq ($(shell uname), Linux)
prefix := prefix :=
@ -27,7 +31,7 @@ clean:
@rm -r build @rm -r build
run: $(iso) run: $(iso)
@qemu-system-$(arch) -cdrom $(iso) -smp 2 @qemu-system-$(arch) $(qemu_opts)
iso: $(iso) iso: $(iso)
@ -43,7 +47,7 @@ $(kernel): kernel $(rust_os) $(assembly_object_files) $(linker_script)
$(assembly_object_files) $(rust_os) $(assembly_object_files) $(rust_os)
kernel: kernel:
@RUST_TARGET_PATH=$(shell pwd) xargo build --target $(target) @RUST_TARGET_PATH=$(shell pwd) xargo build --target $(target) --features $(features)
# compile assembly files # compile assembly files
build/arch/$(arch)/boot/%.o: $(boot_src)/%.asm build/arch/$(arch)/boot/%.o: $(boot_src)/%.asm

@ -1,4 +1,4 @@
// Enable 'No-Execute' bit in page entry /// Enable 'No-Execute' bit in page entry
pub fn enable_nxe_bit() { pub fn enable_nxe_bit() {
use x86_64::registers::msr::{IA32_EFER, rdmsr, wrmsr}; use x86_64::registers::msr::{IA32_EFER, rdmsr, wrmsr};
@ -11,7 +11,7 @@ pub fn enable_nxe_bit() {
} }
} }
// Enable write protection in kernel mode /// Enable write protection in kernel mode
pub fn enable_write_protect_bit() { pub fn enable_write_protect_bit() {
use x86_64::registers::control_regs::{cr0, cr0_write, Cr0}; use x86_64::registers::control_regs::{cr0, cr0_write, Cr0};
@ -19,3 +19,14 @@ pub fn enable_write_protect_bit() {
// But we are in kernel mode. So it's safe. // But we are in kernel mode. So it's safe.
unsafe { cr0_write(cr0() | Cr0::WRITE_PROTECT) }; unsafe { cr0_write(cr0() | Cr0::WRITE_PROTECT) };
} }
/// Exit qemu
/// See: https://wiki.osdev.org/Shutdown
/// Must run qemu with `-device isa-debug-exit`
/// The error code is `value written to 0x501` *2 +1, so it should be odd
pub unsafe fn exit_in_qemu(error_code: u8) -> ! {
use x86_64::instructions::port::outb;
assert!(error_code & 1 == 1);
outb(0x501, (error_code - 1) / 2);
unreachable!()
}

@ -1,5 +1,5 @@
pub mod driver; pub mod driver;
mod cpu; pub mod cpu;
pub fn init() { pub fn init() {
cpu::enable_nxe_bit(); cpu::enable_nxe_bit();

@ -1,6 +1,7 @@
// Rust language features implementions // Rust language features implementions
use core; use core;
use arch::cpu;
#[lang = "eh_personality"] #[lang = "eh_personality"]
extern fn eh_personality() { extern fn eh_personality() {
@ -11,5 +12,9 @@ extern fn eh_personality() {
pub extern fn panic_fmt(fmt: core::fmt::Arguments, file: &'static str, line: u32) -> ! { pub extern fn panic_fmt(fmt: core::fmt::Arguments, file: &'static str, line: u32) -> ! {
println!("\n\nPANIC in {} at line {}:", file, line); println!("\n\nPANIC in {} at line {}:", file, line);
println!(" {}", fmt); println!(" {}", fmt);
loop{} if cfg!(feature = "qemu_auto_exit") {
unsafe{ cpu::exit_in_qemu(1) }
} else {
loop { }
}
} }
Loading…
Cancel
Save