Skip to content

Commit

Permalink
Boot2Snow & Kernel: Fix build error and get set_virtual_address_map()
Browse files Browse the repository at this point in the history
  • Loading branch information
ANEP-ET committed Apr 5, 2018
1 parent b132915 commit 1cc4fff
Show file tree
Hide file tree
Showing 12 changed files with 51 additions and 94 deletions.
13 changes: 0 additions & 13 deletions .vscode/tasks.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
}
},
{
<<<<<<< HEAD
"taskName": "make run-debug",
"type": "shell",
"command": "make run-debug",
Expand All @@ -23,8 +22,6 @@
}
},
{
=======
>>>>>>> 54b2b70a2ee02e4ffea5b8eb418a797a006e9595
"taskName": "make clean",
"type": "shell",
"command": "make clean",
Expand All @@ -43,7 +40,6 @@
}
},
{
<<<<<<< HEAD
"taskName": "x86_64-linux env",
"type": "shell",
"command": "sh x86_64-linux_env.sh",
Expand All @@ -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
}
]
}
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
71 changes: 5 additions & 66 deletions arch/x86_64/boot2snow/src/boot2snow.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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 {
Expand All @@ -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::<MemoryDescriptor>() as u32,
Expand All @@ -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::<MemoryDescriptor>() 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<EntryPoint, ()> {
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::<elf::ElfHeader>() ) } ).expect("ElfHeader read");
hdr
};
Expand All @@ -165,56 +140,20 @@ fn load_kernel_file(simple_vol: &File, filename: &[u16]) -> Result<EntryPoint, (
unsafe { (boot_services.allocate_pages)(
AllocateType::Address,
MemoryType::LoaderData,
(ent.p_memsz + 0xFFF) as usize / 0x1000,

ent.p_memsz as usize / 0x4096,
&mut addr
).expect("Allocating pages for program segment") };

// SAFE: This memory has just been allocated by the above
let data_slice = unsafe { ::core::slice::from_raw_parts_mut(ent.p_paddr as usize as *mut u8, ent.p_memsz as usize) };
kernel_file.set_position(ent.p_offset as u64).expect("seek segment");
kernel_file.read( &mut data_slice[.. ent.p_filesz as usize] ).expect("read segment");
=======
let _ = kernel_file.read( unsafe { ::core::slice::from_raw_parts_mut( &mut hdr as *mut _ as *mut u8, size_of::<elf::ElfHeader>() ) } ).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::<elf::PhEnt>()) 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::<elf::PhEnt>() ) } ).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
}

4 changes: 2 additions & 2 deletions arch/x86_64/boot2snow/src/panic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {}
}

Expand Down
1 change: 0 additions & 1 deletion arch/x86_64/linker.ld
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ SECTIONS
Next we'll put the .text section. */
.text BLOCK(4K) : ALIGN(4K)
{
*(.multiboot)
*(.text)
}

Expand Down
4 changes: 3 additions & 1 deletion kernel/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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"}
6 changes: 3 additions & 3 deletions kernel/src/console.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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(())
}
}
Expand All @@ -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;
}
}
Expand Down
2 changes: 1 addition & 1 deletion kernel/src/display.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
32 changes: 29 additions & 3 deletions kernel/src/kmain.rs
Original file line number Diff line number Diff line change
@@ -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};

Expand All @@ -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) };
}
3 changes: 3 additions & 0 deletions kernel/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
4 changes: 2 additions & 2 deletions kernel/src/macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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]
Expand Down
3 changes: 2 additions & 1 deletion kernel/src/panic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {}
}

Expand Down

0 comments on commit 1cc4fff

Please sign in to comment.