=======================================code========================================
static void load_icode(struct Env *e, uint8_t *binary, size_t size){
struct Elf *elf = (struct Elf *)binary;
struct Proghdr *ph, *eph;
uintptr_t i;
struct Page *p;
int r;
pte_t* pte;
uint32_t old_cr3 = rcr3();
if(elf->e_magic != ELF_MAGIC)
panic("elf->e_magic erro\n");
//program header
ph = (struct Proghdr *)(binary + elf->e_phoff);
// one after last program header
eph = ph + elf->e_phnum;
// load the cr3 to be able to use memmove
lcr3(PADDR(e->env_pgdir));
// For each program header, load it into memory, zeroing as necessary
for(; ph < eph; ph++){
if(ph->p_type == ELF_PROG_LOAD){
// Allocate the memory requested
segment_alloc(e, (void *)ph->p_va, ph->p_memsz);
// Copy data
memmove((void *)ph->p_va, (void *)binary + ph->p_offset, ph->p_filesz);
if(ph->p_memsz > ph->p_filesz)
memset((void *)ph->p_va + ph->p_filesz, 0, ph->p_memsz -ph->p_filesz);
}
}
// Set up the environment's trapframe to point to the right location
// Other values for the trap frame as assigned in env_alloc
e->env_tf.tf_eip = elf->e_entry;
// Now map one page for the program's initial stack
// at virtual address USTACKTOP - PGSIZE.
// LAB 3: Your code here.
r = page_alloc(&p);
if(r < 0)
panic("Alloc page erro at load_icode\n");
page_insert(e->env_pgdir, p, (void *)USTACKTOP - PGSIZE, PTE_P|PTE_U|PTE_W);
// Restore the old cr3
lcr3(old_cr3);
}
=======================================end========================================
5、env_create()函数:利用env_alloc()函数分配一个环境并掉用load_icode装载一个ELF
=======================================code========================================
void env_create(uint8_t *binary, size_t size){
struct Env *env = NULL;
int r;
// Since we setup the envs linked list so that the first one is
// envs[0], all we have to do is allocate an environment
r = env_alloc(&env, 0);
if(r < 0)
panic("env_alloc: %e",r);
load_icode(env, binary, size);
}
=======================================end========================================
6、env_run()函数:以用户态运行一个给定的环境
=======================================code========================================
void env_run(struct Env *e){
// Step 1
curenv = e;
curenv->env_runs++;
lcr3(curenv->env_cr3);
//Step 2
env_pop_tf(&curenv->env_tf);
}
=======================================end========================================
二、kern/trapentry.S
=======================================code========================================
_alltraps:
# Build trap frame.
pushl %ds
pushl %es
pushal
# Set up data segments.
movl $GD_KD, %eax
movw %ax,%ds
movw %ax,%es
# Call trap(tf), where tf=%esp
pushl %esp
call trap
popl %esp
# Cleanup pushes and ret
popal
popl %es
popl %ds
iret
=======================================end========================================