Skip to content

Commit

Permalink
Boot2Snow: Now work kernel load
Browse files Browse the repository at this point in the history
  • Loading branch information
ANEP-ET committed Mar 29, 2018
2 parents d9044b0 + 54b2b70 commit 5829eea
Show file tree
Hide file tree
Showing 7 changed files with 182 additions and 3 deletions.
13 changes: 13 additions & 0 deletions .vscode/tasks.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
}
},
{
<<<<<<< HEAD
"taskName": "make run-debug",
"type": "shell",
"command": "make run-debug",
Expand All @@ -22,6 +23,8 @@
}
},
{
=======
>>>>>>> 54b2b70a2ee02e4ffea5b8eb418a797a006e9595
"taskName": "make clean",
"type": "shell",
"command": "make clean",
Expand All @@ -40,6 +43,7 @@
}
},
{
<<<<<<< HEAD
"taskName": "x86_64-linux env",
"type": "shell",
"command": "sh x86_64-linux_env.sh",
Expand All @@ -48,6 +52,15 @@
"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
}
]
}
61 changes: 61 additions & 0 deletions arch/x86_64/boot2snow/src/boot2snow.rs
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ 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 @@ -111,10 +112,35 @@ 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 Down Expand Up @@ -148,12 +174,47 @@ fn load_kernel_file(boot_services: &::uefi::boot_services::BootServices, sys_vol
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
}

2 changes: 1 addition & 1 deletion arch/x86_64/boot2snow/src/conf.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,4 +32,4 @@ impl<'bs> Configuration<'bs>
Err(e) => Err(e),
}
}
}
}
2 changes: 1 addition & 1 deletion arch/x86_64/boot2snow/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -167,4 +167,4 @@ pub extern "C" fn memcmp(dst: *mut u8, src: *const u8, count: usize) -> isize {
asm!("repnz cmpsb ; movq $$0, $0 ; ja 1f; jb 2f; jmp 3f; 1: inc $0 ; jmp 3f; 2: dec $0; 3:" : "=r" (rv) : "{rcx}" (count), "{rdi}" (dst), "{rsi}" (src) : "rcx", "rsi", "rdi" : "volatile");
rv
}
}
}
2 changes: 1 addition & 1 deletion kernel/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,4 @@ crate-type = ["staticlib"]
rlibc = "1.0"
volatile = "0.1.0"
spin = "0.4.5"
uefi = { git = "https://github.com/SnowFlakeOS/rust-uefi", branch = "beta" }
uefi = { git = "https://github.com/SnowFlakeOS/rust-uefi", branch = "beta" }
6 changes: 6 additions & 0 deletions share/utf16_literal/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
[package]
name = "utf16_literal"
version = "0.0.0"

[lib]
proc-macro = true
99 changes: 99 additions & 0 deletions share/utf16_literal/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
#![feature(proc_macro)] // allow defining non-derive proc macros

extern crate proc_macro;

use proc_macro::TokenStream;

#[proc_macro]
pub fn utf16(input: TokenStream) -> TokenStream
{
let mut it = input.into_iter();

let mut rv = Vec::new();
loop
{
match it.next()
{
Some(::proc_macro::TokenTree { kind: ::proc_macro::TokenNode::Literal(l), .. }) => {
let s = match literal_to_string(l)
{
Ok(s) => s,
Err(l) => panic!("Unexpected token '{}'", l),
};
//println!("s = {:?}", s);
for c in s.chars()
{
if c as u32 <= 0xFFFF {
rv.push(::proc_macro::TokenNode::Literal(::proc_macro::Literal::u16(c as u32 as u16)));
rv.push(::proc_macro::TokenNode::Op(',', ::proc_macro::Spacing::Alone));
}
else {
let v = c as u32 - 0x1_0000;
let hi = v >> 10;
assert!(hi <= 0x3FF);
let lo = v & 0x3FF;

rv.push(::proc_macro::TokenNode::Literal(::proc_macro::Literal::u16(0xD800 + hi as u16)));
rv.push(::proc_macro::TokenNode::Op(',', ::proc_macro::Spacing::Alone));
rv.push(::proc_macro::TokenNode::Literal(::proc_macro::Literal::u16(0xDC00 + lo as u16)));
rv.push(::proc_macro::TokenNode::Literal(::proc_macro::Literal::u16(c as u32 as u16)));
rv.push(::proc_macro::TokenNode::Op(',', ::proc_macro::Spacing::Alone));
}
}
},
Some(t) => panic!("Unexpected token '{}'", t),
None => panic!("utf16! requires a string literal argument"),
}


match it.next()
{
Some(::proc_macro::TokenTree { kind: ::proc_macro::TokenNode::Op(',', _), .. }) => {},
Some(t) => panic!("Unexpected token '{}'", t),
None => break,
}
}
//println!("{:?}", rv);

vec![
::proc_macro::TokenNode::Op('&', ::proc_macro::Spacing::Alone),
::proc_macro::TokenNode::Group(::proc_macro::Delimiter::Bracket, rv.into_iter().collect()),
].into_iter().collect()
}

fn literal_to_string(lit: ::proc_macro::Literal) -> Result<String,::proc_macro::Literal>
{
let formatted = lit.to_string();

let mut it = formatted.chars();
if it.next() != Some('"') {
return Err(lit);
}

let mut rv = String::new();
loop
{
match it.next()
{
Some('"') =>
match it.next()
{
Some(v) => panic!("malformed string, stray \" in the middle (followed by '{:?}')", v),
None => break,
},
Some('\\') =>
match it.next()
{
Some('0') => rv.push('\0'),
Some('\\') => rv.push('\\'),
Some(c) => panic!("TODO: Escape sequence \\{:?}", c),
None => panic!("malformed string, unexpected EOS (after \\)"),
},
Some(c) => rv.push(c),
None => panic!("malformed string, unexpected EOS"),
}
}

Ok(rv)
}

0 comments on commit 5829eea

Please sign in to comment.