/// Make a new user thread
/// The program elf data is placed at [begin, end)
Make a new user thread
The program elf data is placed at [begin, end)
Make a new user thread The program elf data is placed at [ begin end )
pub fn new_user(begin: usize, end: usize, act: &mut ActivePageTable) -> Self {
        //deug!("new user\nbegin={:#x} end={:#x}",begin,end);
        // Parse elf
        let slice = unsafe{ slice::from_raw_parts(begin as *const u8, end - begin) };
        let elf = ElfFile::new(slice).expect("failed to read elf");
        // Make page table
        use consts::{USER_STACK_OFFSET, USER_STACK_SIZE};
        let mut memory_set = MemorySet::from(&elf);
        memory_set.push(MemoryArea::new(USER_STACK_OFFSET, USER_STACK_OFFSET + USER_STACK_SIZE,
                                        EntryFlags::WRITABLE | EntryFlags::NO_EXECUTE | EntryFlags::USER_ACCESSIBLE, "user_stack"));
        let page_table = memory::make_page_table(&memory_set,act);
        //deug!("{:#x?}", memory_set);
        //deug!("{:?}", page_table);
        // Temporary switch to it, in order to copy data
        let backup = act.switch(page_table);
        //deug!("switch page_table over");
        for ph in elf.program_iter() {
            let ph = match ph {
                ProgramHeader::Ph64(ph) => ph,
                _ => unimplemented!(),
            };
            unsafe { memcpy(ph.virtual_addr as *mut u8, (begin + ph.offset as usize) as *mut u8, ph.file_size as usize) };
        }
        let page_table=act.switch(backup);
        //deug!("switch backup over");
        let entry_addr = match elf.header.pt2 {
            HeaderPt2::Header64(header) => header.entry_point,
            _ => {
                //deug!("elf header fail");
                unimplemented!();
            },
        } as usize;
        //deug!("entry_addr:{:#x}",entry_addr);
        // Allocate kernel stack and push trap frame
        let kstack = memory::alloc_stacks(7).unwrap();
        let tf = TrapFrame::new_user_thread(entry_addr, USER_STACK_OFFSET + USER_STACK_SIZE);
        //deug!("begin:{:#x}, end: {:#x}",begin,end);
        //deug!("entry_addr:{:#x}, rsp: {:#x}, rip: {:#x}",entry_addr, tf.rsp, tf.rip);
        let rsp = kstack.push_at_top(tf);
        Process {
            pid: 0,
            name: "user",
            kstack,
            memory_set: Some(memory_set),
            page_table: Some(page_table),
            status: Status::Ready,
            rsp,
            is_user: true,
        }
    }
pub fn new_user ( begin : usize , end : usize , act : & mut ActivePageTable ) -> Self { //deug!("new user\nbegin={:#x} end={:#x}",begin,end); // Parse elf let slice = unsafe { slice :: from_raw_parts ( begin as * const u8 , end - begin ) } ; let elf = ElfFile :: new ( slice ) . expect ( " " ) ; // Make page table use consts :: { USER_STACK_OFFSET , USER_STACK_SIZE } ; let mut memory_set = MemorySet :: from ( & elf ) ; memory_set . push ( MemoryArea :: new ( USER_STACK_OFFSET , USER_STACK_OFFSET + USER_STACK_SIZE , EntryFlags :: WRITABLE | EntryFlags :: NO_EXECUTE | EntryFlags :: USER_ACCESSIBLE , " " ) ) ; let page_table = memory :: make_page_table ( & memory_set , act ) ; //deug!("{:#x?}", memory_set); //deug!("{:?}", page_table); // Temporary switch to it, in order to copy data let backup = act . switch ( page_table ) ; //deug!("switch page_table over"); for ph in elf . program_iter ( ) { let ph = match ph { ProgramHeader :: Ph64 ( ph ) => ph , _ => unimplemented ! ( ) , } ; unsafe { memcpy ( ph . virtual_addr as * mut u8 , ( begin + ph . offset as usize ) as * mut u8 , ph . file_size as usize ) } ; } let page_table = act . switch ( backup ) ; //deug!("switch backup over"); let entry_addr = match elf . header . pt2 { HeaderPt2 :: Header64 ( header ) => header . entry_point , _ => { //deug!("elf header fail"); unimplemented ! ( ) ; } , } as usize ; //deug!("entry_addr:{:#x}",entry_addr); // Allocate kernel stack and push trap frame let kstack = memory :: alloc_stacks ( 7 ) . unwrap ( ) ; let tf = TrapFrame :: new_user_thread ( entry_addr , USER_STACK_OFFSET + USER_STACK_SIZE ) ; //deug!("begin:{:#x}, end: {:#x}",begin,end); //deug!("entry_addr:{:#x}, rsp: {:#x}, rip: {:#x}",entry_addr, tf.rsp, tf.rip); let rsp = kstack . push_at_top ( tf ) ; Process { pid : 0 , name : " " , kstack , memory_set : Some ( memory_set ) , page_table : Some ( page_table ) , status : Status :: Ready , rsp , is_user : true , } }
Make a new user thread
The program elf data is placed at [begin, end)
Make a new user thread The program elf data is placed at [ begin end )
begin
usize
end
usize
act
&mut ActivePageTable