diff --git a/Cargo.toml b/Cargo.toml index ace384d..57c18cd 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,6 +10,7 @@ crate-type = ["staticlib"] use_apic = [] test = [] qemu_auto_exit = [] +link_user_program = [] [dependencies] bit_field = "0.7.0" @@ -22,6 +23,7 @@ x86_64 = "0.1.2" once = "0.3.3" linked_list_allocator = "0.5.0" redox_syscall = "0.1.37" +xmas-elf = "0.6" [build-dependencies] cc = "1.0" diff --git a/Makefile b/Makefile index 142db7c..f3c31ae 100644 --- a/Makefile +++ b/Makefile @@ -10,9 +10,17 @@ grub_cfg := $(boot_src)/grub.cfg assembly_source_files := $(wildcard $(boot_src)/*.asm) assembly_object_files := $(patsubst $(boot_src)/%.asm, \ build/arch/$(arch)/boot/%.o, $(assembly_source_files)) +user_object_files := $(wildcard user/*.o) qemu_opts := -cdrom $(iso) -smp 4 -serial mon:stdio features := use_apic +link_user = 1 + +ifdef link_user +features := $(features) link_user_program +assembly_object_files := $(assembly_object_files) $(user_object_files) +endif + ifdef travis test := 1 features := $(features) qemu_auto_exit diff --git a/src/arch/x86_64/boot/linker.ld b/src/arch/x86_64/boot/linker.ld index f2f23f9..f43f4ec 100644 --- a/src/arch/x86_64/boot/linker.ld +++ b/src/arch/x86_64/boot/linker.ld @@ -6,6 +6,8 @@ KERNEL_OFFSET = 0xffffff0000000000; SECTIONS { + /* bootloader for first processor */ + . = BOOT_OFFSET; .rodata.32 : @@ -39,8 +41,16 @@ SECTIONS { entryother_end = . - OTHER_OFFSET + entryother_start; . = entryother_end; /* recover va */ + /* kernel */ + . += KERNEL_OFFSET; + .user ALIGN(4K): AT(ADDR(.user) - KERNEL_OFFSET) + { + KEEP(user/*.o (.data)) + . = ALIGN(4K); + } + .rodata : AT(ADDR(.rodata) - KERNEL_OFFSET) { *(.rodata .rodata.*) diff --git a/src/lib.rs b/src/lib.rs index 9e4cd4c..d7a881a 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -32,6 +32,7 @@ extern crate linked_list_allocator; extern crate lazy_static; extern crate bit_field; extern crate syscall; +extern crate xmas_elf; #[macro_use] // print! mod io; diff --git a/src/process/mod.rs b/src/process/mod.rs index 76beeef..80e5f70 100644 --- a/src/process/mod.rs +++ b/src/process/mod.rs @@ -14,11 +14,36 @@ mod processor; /// * Debug: 用于Debug输出 use arch::interrupt::TrapFrame; +// TODO: 使用宏来更优雅地导入符号,现在会有编译错误 +// +// #![feature(concat_idents)] +// +// macro_rules! binary_symbol { +// ($name: ident) => { +// extern { +// fn concat_idents!(_binary_user_, $name, _start)(); +// fn concat_idents!(_binary_user_, $name, _end)(); +// } +// }; +// } +// +// binary_symbol!(forktest); + +#[cfg(feature = "link_user_program")] +extern { + fn _binary_user_forktest_start(); + fn _binary_user_forktest_end(); +} + + pub fn init(mc: &mut MemoryController) { PROCESSOR.call_once(|| {Mutex::new({ let mut processor = Processor::new(mc); let initproc = Process::new_init(mc); let idleproc = Process::new("idle", idle_thread, mc); + #[cfg(feature = "link_user_program")] + let forktest = Process::new_user(_binary_user_forktest_start as usize, + _binary_user_forktest_end as usize); processor.add(initproc); processor.add(idleproc); processor diff --git a/src/process/process.rs b/src/process/process.rs index 5e95e66..ae5539d 100644 --- a/src/process/process.rs +++ b/src/process/process.rs @@ -1,5 +1,7 @@ use super::*; use memory::Stack; +use xmas_elf::ElfFile; +use core::slice; #[derive(Debug)] pub struct Process { @@ -47,4 +49,16 @@ impl Process { rsp: 0, // will be set at first schedule } } + + pub fn new_user(begin: usize, end: usize) -> Self { + let slice = unsafe{ slice::from_raw_parts(begin as *const u8, end - begin) }; + let elf = ElfFile::new(slice).expect("failed to read elf"); + for program_header in elf.program_iter() { + println!("{:?}", program_header); + } +// for section in elf.section_iter() { +// println!("{:?}", section); +// } + unimplemented!(); + } } \ No newline at end of file diff --git a/user/forktest.o b/user/forktest.o new file mode 100755 index 0000000..13d05d5 Binary files /dev/null and b/user/forktest.o differ