void switch_to_user_mode() { alloc_page_dir(&(bar_p)); _ptcr3(bar_p.cr3); alloc_user_stack(&(bar_p)); bar_p.rsp_p = (uint64_t)&(bar_p.k_stack[63]); printf("\n Inside call %p\n",(uint64_t)video_vm); tss.rsp0 = bar_p.rsp_p; uint64_t tem = 0x28; __asm volatile("mov %0,%%rax;"::"r"(tem)); __asm volatile("ltr %ax"); __asm volatile("\ push $0x23;\ push %0;\ pushf;\ push $0x1B;\ push %1"::"g"(&bar_p.u_stack[511]),"g"(&bar):"memory"); __asm volatile("\ iretq;\ "); }
static int try_load_elf(elf_prog_t *prog, long bailout) { int err, has_interp; char i_filename[PATH_MAX]; /* so much easier */ elf_bin_t *bin=&prog->bin, *interp=&prog->interp; if ( (err = open_elf(prog->filename, bin)) < 0 ) return err; Elf32_Phdr phdr_bin_tmp[bin->hdr.e_phnum]; bin->phdr = phdr_bin_tmp; /* point to mmapped region later if any */ if (read_at(bin->fd, bin->hdr.e_phoff, bin->phdr, sizeof(*bin->phdr)*bin->hdr.e_phnum) != (long)sizeof(*bin->phdr)*bin->hdr.e_phnum) return -EIO; if ( (err = find_interp_name(bin, i_filename, PATH_MAX)) < 0 ) return err; has_interp = err; interp->phdr = NULL; interp->hdr.e_phnum = 0; if ( has_interp && (err = open_elf(i_filename, interp)) < 0) return err; Elf32_Phdr phdr_interp_tmp[interp->hdr.e_phnum]; if ( has_interp ) { interp->phdr = phdr_interp_tmp; /* point to mmapped region later */ if (read_at(interp->fd, interp->hdr.e_phoff, interp->phdr, sizeof(*interp->phdr)*interp->hdr.e_phnum) != (long)sizeof(*interp->phdr)*interp->hdr.e_phnum) return -EIO; } /* point of no return */ if (bailout) return 0; int stack_prot = get_stack_prot(bin); err = alloc_user_stack(prog, stack_prot); if ( mmap_binary(bin, 0) & PG_MASK ) raise(SIGKILL); if ( has_interp && (mmap_binary(interp, 1) & PG_MASK) ) raise(SIGKILL); /* set up stack */ bin->phdr = mapped_phdr(bin); if ( has_interp ) interp->phdr = mapped_phdr(interp); init_user_stack(prog, stack_prot); if (err & PG_MASK) raise(SIGKILL); if (has_interp) prog->entry = (void *)(interp->base + interp->hdr.e_entry); else prog->entry = (void *)(bin->base + bin->hdr.e_entry); return 0; }
//#define ENTRY 0X8048074 PCB* create_process(uint8_t *buf) { struct ELFHeader *elf = (struct ELFHeader*) buf; struct ProgramHeader *ph, *eph; uint32_t va, eva, pa, len, sublen, tmpva, offset; uint8_t *kst; int ret; PCB* pcb = create_kthread((void*)NULL); ph = (struct ProgramHeader*)((char*)elf + elf->phoff); eph = ph + elf->phnum; assert(pcb != NULL); printk("in create process pid=%d\n",pcb->pid); for(; ph < eph; ph++) { if(ph->type != PT_LOAD) continue; va = ph->vaddr; //in boot/main.c is paddr, it may be a bug len = ph->memsz; eva = va + len; printk("segment start = %x\n",va); printk("segment end = %x\n",eva); //request new page here //start= ph->vaddr, len=ph->memsz // printk("before alloc pages...va=%x\n",va); ret = alloc_pages(pcb,va,len); printk("after alloc pages\n"); assert(ret == 0); // must be successful printk("after alloc pages and assertion\n"); //attention: virtual adrress to physical address offset = ph->off; for(; va < eva;) { pa = pcb_va_to_pa(pcb,va); printk("physical address = %x\n",pa); kst = (uint8_t*)pa_to_va(pa); //virtual address printk("virtual address = %x\n",kst); tmpva = va; va = to_next_page(va) < eva ? to_next_page(va) : eva; //when va == ea this loop end sublen = va - tmpva; memcpy(kst, (char*)elf + offset,sublen); offset += sublen; } } printk("before alloc stack\n"); ret = alloc_user_stack(pcb); assert(ret==0); printk("after alloc user stack\n"); struct TrapFrame* tf = ((struct TrapFrame*)(pcb->tf)); tf->eip = elf->entry;//ENTRY; //set user stack here tf->cs = SELECTOR_USER(SEG_USER_CODE); tf->ds = SELECTOR_USER(SEG_USER_DATA); tf->irq = 1000; tf->ss = SELECTOR_USER(SEG_USER_DATA); tf->esp = USER_STACK_END; //should I set tf->ebp? return pcb; }