diff --git a/.vscode/tasks.json b/.vscode/tasks.json index 637711b..166af0e 100755 --- a/.vscode/tasks.json +++ b/.vscode/tasks.json @@ -13,6 +13,7 @@ } }, { +<<<<<<< HEAD "taskName": "make run-debug", "type": "shell", "command": "make run-debug", @@ -22,6 +23,8 @@ } }, { +======= +>>>>>>> 54b2b70a2ee02e4ffea5b8eb418a797a006e9595 "taskName": "make clean", "type": "shell", "command": "make clean", @@ -40,6 +43,7 @@ } }, { +<<<<<<< HEAD "taskName": "x86_64-linux env", "type": "shell", "command": "sh x86_64-linux_env.sh", @@ -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 } ] } \ No newline at end of file diff --git a/arch/x86_64/boot2snow/src/boot2snow.rs b/arch/x86_64/boot2snow/src/boot2snow.rs index 4e0d541..c5969d4 100755 --- a/arch/x86_64/boot2snow/src/boot2snow.rs +++ b/arch/x86_64/boot2snow/src/boot2snow.rs @@ -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::() as u32, @@ -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::() 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 }; @@ -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::() ) } ).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/conf.rs b/arch/x86_64/boot2snow/src/conf.rs index b26ed66..fb573b2 100755 --- a/arch/x86_64/boot2snow/src/conf.rs +++ b/arch/x86_64/boot2snow/src/conf.rs @@ -32,4 +32,4 @@ impl<'bs> Configuration<'bs> Err(e) => Err(e), } } -} \ No newline at end of file +} diff --git a/arch/x86_64/boot2snow/src/lib.rs b/arch/x86_64/boot2snow/src/lib.rs index d881545..909387b 100755 --- a/arch/x86_64/boot2snow/src/lib.rs +++ b/arch/x86_64/boot2snow/src/lib.rs @@ -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 } -} \ No newline at end of file +} diff --git a/kernel/Cargo.toml b/kernel/Cargo.toml index b92c99c..c22229d 100755 --- a/kernel/Cargo.toml +++ b/kernel/Cargo.toml @@ -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" } \ No newline at end of file +uefi = { git = "https://github.com/SnowFlakeOS/rust-uefi", branch = "beta" } diff --git a/share/utf16_literal/Cargo.toml b/share/utf16_literal/Cargo.toml new file mode 100644 index 0000000..67552c7 --- /dev/null +++ b/share/utf16_literal/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "utf16_literal" +version = "0.0.0" + +[lib] +proc-macro = true diff --git a/share/utf16_literal/src/lib.rs b/share/utf16_literal/src/lib.rs new file mode 100644 index 0000000..9e4961c --- /dev/null +++ b/share/utf16_literal/src/lib.rs @@ -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 +{ + 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) +} +