From 1cc4ffffdf7e746b0ec0b56295b892810a9c5097 Mon Sep 17 00:00:00 2001 From: xuserwhat Date: Thu, 5 Apr 2018 22:54:42 +0900 Subject: [PATCH] Boot2Snow & Kernel: Fix build error and get set_virtual_address_map() --- .vscode/tasks.json | 13 ----- Makefile | 2 +- arch/x86_64/boot2snow/src/boot2snow.rs | 71 ++------------------------ arch/x86_64/boot2snow/src/panic.rs | 4 +- arch/x86_64/linker.ld | 1 - kernel/Cargo.toml | 4 +- kernel/src/console.rs | 6 +-- kernel/src/display.rs | 2 +- kernel/src/kmain.rs | 32 ++++++++++-- kernel/src/lib.rs | 3 ++ kernel/src/macros.rs | 4 +- kernel/src/panic.rs | 3 +- 12 files changed, 51 insertions(+), 94 deletions(-) diff --git a/.vscode/tasks.json b/.vscode/tasks.json index 166af0e..637711b 100755 --- a/.vscode/tasks.json +++ b/.vscode/tasks.json @@ -13,7 +13,6 @@ } }, { -<<<<<<< HEAD "taskName": "make run-debug", "type": "shell", "command": "make run-debug", @@ -23,8 +22,6 @@ } }, { -======= ->>>>>>> 54b2b70a2ee02e4ffea5b8eb418a797a006e9595 "taskName": "make clean", "type": "shell", "command": "make clean", @@ -43,7 +40,6 @@ } }, { -<<<<<<< HEAD "taskName": "x86_64-linux env", "type": "shell", "command": "sh x86_64-linux_env.sh", @@ -52,15 +48,6 @@ "taskName": "gdb", "type": "shell", "command": "rust-gdb build/kernel/kernel.bin.sym -ex 'target remote :1234'", -======= - "taskName": "sh x86_64-linux_env.sh", - "type": "shell", - "command": "sh x86_64-linux_env.sh", - "group": { - "kind": "build", - "isDefault": true - } ->>>>>>> 54b2b70a2ee02e4ffea5b8eb418a797a006e9595 } ] } \ No newline at end of file diff --git a/Makefile b/Makefile index d5ef23c..fb96402 100755 --- a/Makefile +++ b/Makefile @@ -19,7 +19,7 @@ clean: @rm -r build #target run: $(img) - @qemu-system-x86_64 -bios ovmf.fd $(img) + @qemu-system-x86_64 -bios ovmf.fd -m 2048 $(img) run-debug: $(img) @qemu-system-x86_64 -s -S -bios ovmf.fd $(img) diff --git a/arch/x86_64/boot2snow/src/boot2snow.rs b/arch/x86_64/boot2snow/src/boot2snow.rs index c5969d4..39f38cc 100755 --- a/arch/x86_64/boot2snow/src/boot2snow.rs +++ b/arch/x86_64/boot2snow/src/boot2snow.rs @@ -46,7 +46,7 @@ pub extern fn init() -> Result<(), ()> { let entrypoint = load_kernel_file(boot_services, &system_volume_root, &config.kernel).expect("Unable to load kernel"); // Save memory map - let (map_key, map) = { + let (map_size, map_key, ent_size, ent_ver, map) = { let mut map_size = 0; let mut map_key = 0; let mut ent_size = 0; @@ -74,11 +74,12 @@ pub extern fn init() -> Result<(), ()> { map.set_len( map_size / ent_size ); } - (map_key, map) + (map_size, map_key, ent_size, ent_ver, map) }; unsafe { - (boot_services.exit_boot_services)(image_handle, map_key).expect("exit_boot_services"); + (boot_services.exit_boot_services)(image_handle, map_key).expect("Sorry, exit_boot_services() failed"); + (runtime_services.set_virtual_address_map)(map_size, ent_size, ent_ver, map.as_ptr()).expect("Sorry, set_virtual_address_map() failed :("); } let boot_info = kernel_proto::Info { @@ -88,7 +89,6 @@ pub extern fn init() -> Result<(), ()> { cmdline_ptr: 1 as *const u8, cmdline_len: 0, -<<<<<<< HEAD map_addr: map.as_ptr() as usize as u64, map_entnum: map.len() as u32, map_entsz: size_of::() as u32, @@ -112,35 +112,10 @@ fn load_kernel_file(boot_services: &::uefi::boot_services::BootServices, sys_vol Err(e) => panic!("Failed to open kernel '{}' - {:?}", filename, e), }; -======= - map_addr: /* memory_map */ 0 as usize as u64, - map_entnum: (memory_map_size / descriptor_size) as u32, - map_entsz: size_of::() as u32, - - vid_addr: bitmap as usize as u64, - width: resolutin_w, - height: resolutin_h, - }; - - kernel_file(0x71FF0EF1, &boot_info); - Ok(()) -} - -type EntryPoint = extern "cdecl" fn(usize, *const kernel_proto::Info) -> !; -fn load_kernel_file(simple_vol: &File, filename: &[u16]) -> Result { - let bs = get_system_table().boot_services(); - - let mut kernel_file = match simple_vol.open_read(filename) { - Ok(k) => k, - Err(e) => panic!("Failed to open kernel '{:?}' - {:?}", filename, e), - }; - ->>>>>>> 54b2b70a2ee02e4ffea5b8eb418a797a006e9595 // Load kernel from this file (ELF). let elf_hdr = { let mut hdr = elf::ElfHeader::default(); // SAFE: Converts to POD for read -<<<<<<< HEAD kernel_file.read( unsafe { ::core::slice::from_raw_parts_mut( &mut hdr as *mut _ as *mut u8, size_of::() ) } ).expect("ElfHeader read"); hdr }; @@ -165,8 +140,7 @@ fn load_kernel_file(simple_vol: &File, filename: &[u16]) -> Result Result() ) } ).expect("Fail to read ElfHeader :("); - hdr - }; - - elf_hdr.check_header(); - for i in 0 .. elf_hdr.e_phnum { - let mut ent = elf::PhEnt::default(); - let _ = kernel_file.set_position(elf_hdr.e_phoff as u64 + (i as usize * size_of::()) as u64 ).unwrap(); - // SAFE: Converts to POD for read - let _ = kernel_file.read( unsafe { ::core::slice::from_raw_parts_mut( &mut ent as *mut _ as *mut u8, size_of::() ) } ).expect("Fail to read Kernel :("); - - if ent.p_type == 1 { - println!("- {:#x}+{:#x} loads +{:#x}+{:#x}", - ent.p_vaddr, ent.p_memsz, - ent.p_offset, ent.p_filesz - ); - - let mut addr = ent.p_vaddr as u64; - // SAFE: Correct call to FFI - let _ = bs.allocate_pages( - AllocateType::Address, - MemoryType::LoaderData, - (ent.p_memsz + 0xFFF) as usize / 0x1000, - &mut addr); - - // SAFE: This memory has just been allocated by the above - let data_slice = unsafe { ::core::slice::from_raw_parts_mut(ent.p_vaddr as usize as *mut u8, ent.p_memsz as usize) }; - let _ = kernel_file.set_position(ent.p_offset as u64); - let _ = kernel_file.read( &mut data_slice[.. ent.p_filesz as usize] ); ->>>>>>> 54b2b70a2ee02e4ffea5b8eb418a797a006e9595 for b in &mut data_slice[ent.p_filesz as usize .. ent.p_memsz as usize] { *b = 0; } } } // SAFE: Assuming that the executable is sane, and that it follows the correct calling convention -<<<<<<< HEAD Ok(unsafe { ::core::mem::transmute(elf_hdr.e_entry as usize) }) -======= - Ok(unsafe { ::core::mem::transmute(elf_hdr.e_entry as u64) }) ->>>>>>> 54b2b70a2ee02e4ffea5b8eb418a797a006e9595 } diff --git a/arch/x86_64/boot2snow/src/panic.rs b/arch/x86_64/boot2snow/src/panic.rs index 68bec00..2bb1472 100755 --- a/arch/x86_64/boot2snow/src/panic.rs +++ b/arch/x86_64/boot2snow/src/panic.rs @@ -19,8 +19,8 @@ pub extern fn rust_eh_unwind_resume() { #[lang = "panic_fmt"] #[no_mangle] -pub extern fn rust_begin_panic(msg: fmt::Arguments, file: &'static str, line: u32) -> ! { - print!("{}:{}: {}", file, line, msg); +pub extern fn rust_begin_panic(fmt: fmt::Arguments, file: &'static str, line: u32) -> ! { + print!("\nPANIC in {} at line {}: {}", file, line, fmt); loop {} } diff --git a/arch/x86_64/linker.ld b/arch/x86_64/linker.ld index f2c39bd..53e2518 100755 --- a/arch/x86_64/linker.ld +++ b/arch/x86_64/linker.ld @@ -15,7 +15,6 @@ SECTIONS Next we'll put the .text section. */ .text BLOCK(4K) : ALIGN(4K) { - *(.multiboot) *(.text) } diff --git a/kernel/Cargo.toml b/kernel/Cargo.toml index c22229d..7f129a1 100755 --- a/kernel/Cargo.toml +++ b/kernel/Cargo.toml @@ -10,4 +10,6 @@ crate-type = ["staticlib"] rlibc = "1.0" volatile = "0.1.0" spin = "0.4.5" -uefi = { git = "https://github.com/SnowFlakeOS/rust-uefi", branch = "beta" } +x86_64 = "0.1.2" +bitflags = "1.0.1" +uefi = {path = "../share/libuefi"} \ No newline at end of file diff --git a/kernel/src/console.rs b/kernel/src/console.rs index 0258225..11476af 100644 --- a/kernel/src/console.rs +++ b/kernel/src/console.rs @@ -25,7 +25,7 @@ pub struct Stdout; impl Write for Stdout { fn write_str(&mut self, string: &str) -> Result<(), fmt::Error> { let console = get_console(); - unsafe { (*console).write(string) }; + unsafe { (*console).write(string, Color::rgb(255, 255, 255)) }; Ok(()) } } @@ -49,13 +49,13 @@ impl Console { } } - pub fn write(&mut self, s: &str) { + pub fn write(&mut self, s: &str, color: Color) { let display = unsafe{ DISPLAY }; let prompt = s.clone(); for c in prompt.chars() { if self.x == self.w as i32 || c == '\n' { self.newline(); } else { - unsafe { (*display).char(self.x, self.y, c, Color::rgb(255, 255, 255)) }; + unsafe { (*display).char(self.x, self.y, c, color) }; self.x += 8; } } diff --git a/kernel/src/display.rs b/kernel/src/display.rs index e94c3d8..3be1f9a 100644 --- a/kernel/src/display.rs +++ b/kernel/src/display.rs @@ -100,7 +100,7 @@ impl Display { fn inner_pixel(&mut self, x: i32, y: i32, color: Color) { let w = self.w; - unsafe { *self.output.offset((w as i32 * y + x) as isize) = color }; + unsafe { *self.output.offset((w as isize * y as isize) + x as isize) = color }; } fn inner_rect(&mut self, x: i32, y: i32, w: u32, h: u32, color: Color) { diff --git a/kernel/src/kmain.rs b/kernel/src/kmain.rs index 6660c32..8e373b2 100755 --- a/kernel/src/kmain.rs +++ b/kernel/src/kmain.rs @@ -1,6 +1,7 @@ use core::ops::Try; +use uefi::runtime_services::RuntimeServices; use color::*; -use kernel_proto::Info; +use kernel_proto::{Info, MemoryDescriptor}; use display::Display; use console::{Console, set_console}; @@ -18,11 +19,36 @@ pub extern fn start_uefi() { let resolutin_h = unsafe { (*info).height }; let AREA = resolutin_w * resolutin_h; - let mut vid_addr = unsafe { (*info).vid_addr }; + let vid_addr = unsafe { (*info).vid_addr }; let mut display = Display::new(vid_addr, resolutin_w, resolutin_h); let mut console = Console::new(&mut display); + let map = unsafe { (*info).map_addr } as *const MemoryDescriptor; set_console(&mut console); + + enable_nxe_bit(); + enable_write_protect_bit(); display.rect(0, 0, resolutin_w, resolutin_h, Color::rgb(0, 0, 0)); - println!("[INFO] SnowKernel {}", env!("CARGO_PKG_VERSION")); + + println!("SnowKernel {}", env!("CARGO_PKG_VERSION")); + + panic!("Test panic"); } + +// https://github.com/phil-opp/blog_os/blob/post_10/src/lib.rs + +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) }; +} \ No newline at end of file diff --git a/kernel/src/lib.rs b/kernel/src/lib.rs index 4b7ff5f..6bc026c 100755 --- a/kernel/src/lib.rs +++ b/kernel/src/lib.rs @@ -6,6 +6,9 @@ #![feature(const_fn)] #![feature(global_asm)] +#[macro_use] +extern crate bitflags; +extern crate x86_64; extern crate uefi; use core::ptr; diff --git a/kernel/src/macros.rs b/kernel/src/macros.rs index 68fecd1..024c731 100755 --- a/kernel/src/macros.rs +++ b/kernel/src/macros.rs @@ -6,8 +6,8 @@ macro_rules! print { #[macro_export] macro_rules! println { () => (print!("\n")); - ($fmt:expr) => (print!(concat!($fmt, "\n"))); - ($fmt:expr, $($arg:tt)*) => (print!(concat!($fmt, "\n"), $($arg)*)); + ($fmt:expr) => (print!(concat!("[Info] ", $fmt, "\n"))); + ($fmt:expr, $($arg:tt)*) => (print!(concat!("[Info] ", $fmt, "\n"), $($arg)*)); } #[macro_export] diff --git a/kernel/src/panic.rs b/kernel/src/panic.rs index 90ae045..2bb1472 100755 --- a/kernel/src/panic.rs +++ b/kernel/src/panic.rs @@ -19,7 +19,8 @@ pub extern fn rust_eh_unwind_resume() { #[lang = "panic_fmt"] #[no_mangle] -pub extern fn rust_begin_panic(msg: fmt::Arguments, file: &'static str, line: u32) -> ! { +pub extern fn rust_begin_panic(fmt: fmt::Arguments, file: &'static str, line: u32) -> ! { + print!("\nPANIC in {} at line {}: {}", file, line, fmt); loop {} }