ucoreLAB5实验报告word文档良心出品.docx

上传人:b****8 文档编号:12853733 上传时间:2023-06-08 格式:DOCX 页数:28 大小:289.51KB
下载 相关 举报
ucoreLAB5实验报告word文档良心出品.docx_第1页
第1页 / 共28页
ucoreLAB5实验报告word文档良心出品.docx_第2页
第2页 / 共28页
ucoreLAB5实验报告word文档良心出品.docx_第3页
第3页 / 共28页
ucoreLAB5实验报告word文档良心出品.docx_第4页
第4页 / 共28页
ucoreLAB5实验报告word文档良心出品.docx_第5页
第5页 / 共28页
ucoreLAB5实验报告word文档良心出品.docx_第6页
第6页 / 共28页
ucoreLAB5实验报告word文档良心出品.docx_第7页
第7页 / 共28页
ucoreLAB5实验报告word文档良心出品.docx_第8页
第8页 / 共28页
ucoreLAB5实验报告word文档良心出品.docx_第9页
第9页 / 共28页
ucoreLAB5实验报告word文档良心出品.docx_第10页
第10页 / 共28页
ucoreLAB5实验报告word文档良心出品.docx_第11页
第11页 / 共28页
ucoreLAB5实验报告word文档良心出品.docx_第12页
第12页 / 共28页
ucoreLAB5实验报告word文档良心出品.docx_第13页
第13页 / 共28页
ucoreLAB5实验报告word文档良心出品.docx_第14页
第14页 / 共28页
ucoreLAB5实验报告word文档良心出品.docx_第15页
第15页 / 共28页
ucoreLAB5实验报告word文档良心出品.docx_第16页
第16页 / 共28页
ucoreLAB5实验报告word文档良心出品.docx_第17页
第17页 / 共28页
ucoreLAB5实验报告word文档良心出品.docx_第18页
第18页 / 共28页
ucoreLAB5实验报告word文档良心出品.docx_第19页
第19页 / 共28页
ucoreLAB5实验报告word文档良心出品.docx_第20页
第20页 / 共28页
亲,该文档总共28页,到这儿已超出免费预览范围,如果喜欢就下载吧!
下载资源
资源描述

ucoreLAB5实验报告word文档良心出品.docx

《ucoreLAB5实验报告word文档良心出品.docx》由会员分享,可在线阅读,更多相关《ucoreLAB5实验报告word文档良心出品.docx(28页珍藏版)》请在冰点文库上搜索。

ucoreLAB5实验报告word文档良心出品.docx

ucoreLAB5实验报告word文档良心出品

LAB5实验报告

实验目的:

●了解第一个用户进程创建过程

●了解系统调用框架的实现机制

●了解ucore如何实现系统调用sys_fork/sys_exec/sys_exit/sys_wait来进行进程管理

实验内容:

实验4完成了内核线程,但到目前为止,所有的运行都在内核态执行。

实验5将创建用户进程,让用户进程在用户态执行,且在需要ucore支持时,可通过系统调用来让ucore提供服务。

为此需要构造出第一个用户进程,并通过系统调用sys_fork/sys_exec/sys_exit/sys_wait来支持运行不同的应用程序,完成对用户进程的执行过程的基本管理。

1.练习

练习0:

填写已有实验

根据提示,对标注LAB5YOURCODE:

(updateLAB4steps)的部分进行一定的改动。

Kern/trap/trap.c:

/*LAB1YOURCODE:

STEP3*/

/*handlethetimerinterrupt*/

/*

(1)Afteratimerinterrupt,youshouldrecordthiseventusingaglobalvariable(increaseit),suchasticksinkern/driver/clock.c

*

(2)EveryTICK_NUMcycle,youcanprintsomeinfousingafunciton,suchasprint_ticks().

*(3)TooSimple?

Yes,Ithinkso!

*/

/*LAB5YOURCODE*/

/*youshouldupateyoulab1code(justaddONEorTWOlinesofcode):

*EveryTICK_NUMcycle,youshouldsetcurrentprocess'scurrent->need_resched=1

*/

ticks++;

if(ticks%TICK_NUM==0){

assert(current!

=NULL);

current->need_resched=1;

}

/*LAB1YOURCODE:

STEP2*/

/*

(1)WherearetheentryaddrsofeachInterruptServiceRoutine(ISR)?

*AllISR'sentryaddrsarestoredin__vectors.whereisuintptr_t__vectors[]?

*__vectors[]isinkern/trap/vector.Swhichisproducedbytools/vector.c

*(try"make"commandinlab1,thenyouwillfindvector.Sinkern/trapDIR)

*Youcanuse"externuintptr_t__vectors[];"todefinethisexternvariablewhichwillbeusedlater.

*

(2)NowyoushouldsetuptheentriesofISRinInterruptDescriptionTable(IDT).

*Canyouseeidt[256]inthisfile?

Yes,it'sIDT!

youcanuseSETGATEmacrotosetupeachitemofIDT

*(3)AftersetupthecontentsofIDT,youwillletCPUknowwhereistheIDTbyusing'lidt'instruction.

*Youdon'tknowthemeaningofthisinstruction?

justgoogleit!

andcheckthelibs/x86.htoknowmore.

*Notice:

theargumentoflidtisidt_pd.trytofindit!

*/

/*LAB5YOURCODE*/

//youshouldupdateyourlab1code(justaddONEorTWOlinesofcode),letuserapptousesyscalltogettheserviceofucore

//soyoushouldsetupthesyscallinterruptgateinhere

externuintptr_t__vectors[];

inti;

for(i=0;i

SETGATE(idt[i],0,GD_KTEXT,__vectors[i],DPL_KERNEL);

}

SETGATE(idt[T_SYSCALL],1,GD_KTEXT,__vectors[T_SYSCALL],DPL_USER);

lidt(&idt_pd);

Kern/process/proc.c:

staticstructproc_struct*

alloc_proc(void){

structproc_struct*proc=kmalloc(sizeof(structproc_struct));

if(proc!

=NULL){

//LAB4:

EXERCISE1YOURCODE

/*

*belowfieldsinproc_structneedtobeinitialized

*enumproc_statestate;//Processstate

*intpid;//ProcessID

*intruns;//therunningtimesofProces

*uintptr_tkstack;//Processkernelstack

*volatileboolneed_resched;//boolvalue:

needtoberescheduledtoreleaseCPU?

*structproc_struct*parent;//theparentprocess

*structmm_struct*mm;//Process'smemorymanagementfield

*structcontextcontext;//Switchheretorunprocess

*structtrapframe*tf;//Trapframeforcurrentinterrupt

*uintptr_tcr3;//CR3register:

thebaseaddrofPageDirectroyTable(PDT)

*uint32_tflags;//Processflag

*charname[PROC_NAME_LEN+1];//Processname

*/

proc->state=PROC_UNINIT;

proc->pid=-1;

proc->runs=0;

proc->kstack=0;

proc->need_resched=0;

proc->parent=NULL;

proc->mm=NULL;

memset(&(proc->context),0,sizeof(structcontext));

proc->tf=NULL;

proc->cr3=boot_cr3;

proc->flags=0;

memset(proc->name,0,PROC_NAME_LEN);

//LAB5YOURCODE:

(updateLAB4steps)

/*

*belowfields(addinLAB5)inproc_structneedtobeinitialized

*uint32_twait_state;//waitingstate

*structproc_struct*cptr,*yptr,*optr;//relationsbetweenprocesses

*/

proc->wait_state=0;

proc->cptr=proc->yptr=proc->optr=NULL;

}

returnproc;

}

int

do_fork(uint32_tclone_flags,uintptr_tstack,structtrapframe*tf){

intret=-E_NO_FREE_PROC;

structproc_struct*proc;

if(nr_process>=MAX_PROCESS){

gotofork_out;

}

ret=-E_NO_MEM;

//LAB4:

EXERCISE2YOURCODE

/*

*SomeUsefulMACROs,FunctionsandDEFINEs,youcanusetheminbelowimplementation.

*MACROsorFunctions:

*alloc_proc:

createaprocstructandinitfields(lab4:

exercise1)

*setup_kstack:

allocpageswithsizeKSTACKPAGEasprocesskernelstack

*copy_mm:

process"proc"duplicateORshareprocess"current"'smmaccordingclone_flags

*ifclone_flags&CLONE_VM,then"share";else"duplicate"

*copy_thread:

setupthetrapframeontheprocess'skernelstacktopand

*setupthekernelentrypointandstackofprocess

*hash_proc:

addprocintoprochash_list

*get_pid:

allocauniquepidforprocess

*wakup_proc:

setproc->state=PROC_RUNNABLE

*VARIABLES:

*proc_list:

theprocessset'slist

*nr_process:

thenumberofprocessset

*/

//1.callalloc_proctoallocateaproc_struct

//2.callsetup_kstacktoallocateakernelstackforchildprocess

//3.callcopy_mmtodupORsharemmaccordingclone_flag

//4.callcopy_threadtosetuptf&contextinproc_struct

//5.insertproc_structintohash_list&&proc_list

//6.callwakup_proctomakethenewchildprocessRUNNABLE

//7.setretvauleusingchildproc'spid

if((proc=alloc_proc())==NULL){

gotofork_out;

}

proc->parent=current;

assert(current->wait_state==0);

if(setup_kstack(proc)!

=0){

gotobad_fork_cleanup_proc;

}

if(copy_mm(clone_flags,proc)!

=0){

gotobad_fork_cleanup_kstack;

}

copy_thread(proc,stack,tf);

boolintr_flag;

local_intr_save(intr_flag);

{

proc->pid=get_pid();

hash_proc(proc);

set_links(proc);

}

local_intr_restore(intr_flag);

wakeup_proc(proc);

ret=proc->pid;

//LAB5YOURCODE:

(updateLAB4steps)

/*SomeFunctions

*set_links:

settherelationlinksofprocess.ALSOSEE:

remove_links:

leantherelationlinksofprocess

*-------------------

*updatestep1:

setchildproc'sparenttocurrentprocess,makesurecurrentprocess'swait_stateis0

*updatestep5:

insertproc_structintohash_list&&proc_list,settherelationlinksofprocess

*/

fork_out:

returnret;

bad_fork_cleanup_kstack:

put_kstack(proc);

bad_fork_cleanup_proc:

kfree(proc);

gotofork_out;

}

练习1:

加载应用程序并执行

do_execv函数调用load_icode(位于kern/process/proc.c中)来加载并解析一个处于内存中的ELF执行文件格式的应用程序,建立相应的用户内存空间来放置应用程序的代码段、数据段等,且要设置好proc_struct结构中的成员变量trapframe中的内容,确保在执行此进程后,能够从应用程序设定的起始执行地址开始执行。

需设置正确的trapframe内容。

程序代码:

staticintload_icode(unsignedchar*binary,size_tsize){

if(current->mm!

=NULL){

panic("load_icode:

current->mmmustbeempty.\n");

}

intret=-E_NO_MEM;

structmm_struct*mm;

//为当前进程申请内存

if((mm=mm_create())==NULL){

gotobad_mm;

}

//建立一个新的PDT,设置mm->pgdir为PDT的内核虚拟地址

if(setup_pgdir(mm)!

=0){

gotobad_pgdir_cleanup_mm;

}

//复制上下文和数据部分,建立二进制程序的BSS段

structPage*page;

//getthefileheaderofthebianryprogram(ELFformat)

structelfhdr*elf=(structelfhdr*)binary;

//gettheentryoftheprogramsectionheadersofthebianryprogram(ELFformat)

structproghdr*ph=(structproghdr*)(binary+elf->e_phoff);

//Thisprogramisvalid?

if(elf->e_magic!

=ELF_MAGIC){

ret=-E_INVAL_ELF;

gotobad_elf_cleanup_pgdir;

}

uint32_tvm_flags,perm;

structproghdr*ph_end=ph+elf->e_phnum;

for(;ph

//findeveryprogramsectionheaders

if(ph->p_type!

=ELF_PT_LOAD){

continue;

}

if(ph->p_filesz>ph->p_memsz){

ret=-E_INVAL_ELF;

gotobad_cleanup_mmap;

}

if(ph->p_filesz==0){

continue;

}

//callmm_mapfuntosetupthenewvma(ph->p_va,ph->p_memsz)

vm_flags=0,perm=PTE_U;

if(ph->p_flags&ELF_PF_X)vm_flags|=VM_EXEC;

if(ph->p_flags&ELF_PF_W)vm_flags|=VM_WRITE;

if(ph->p_flags&ELF_PF_R)vm_flags|=VM_READ;

if(vm_flags&VM_WRITE)perm|=PTE_W;

if((ret=mm_map(mm,ph->p_va,ph->p_memsz,vm_flags,NULL))!

=0){

gotobad_cleanup_mmap;

}

unsignedchar*from=binary+ph->p_offset;

size_toff,size;

uintptr_tstart=ph->p_va,end,la=ROUNDDOWN(start,PGSIZE);

ret=-E_NO_MEM;

//allocmemory,andcopythecontentsofeveryprogramsection(from,from+end)toprocess'smemory(la,la+end)

end=ph->p_va+ph->p_filesz;

//copyTEXT/DATAsectionofbianryprogram

while(start

if((page=pgdir_alloc_page(mm->pgdir,la,perm))==NULL){

gotobad_cleanup_mmap;

}

off=start-la,size=PGSIZE-off,la+=PGSIZE;

if(end

size-=la-end;

}

memcpy(page2kva(page)+off,from,size);

start+=size,from+=size;

}

//buildBSSsectionofbinaryprogram

end=ph->p_va+ph->p_memsz;

if(start

/*ph->p_memsz==ph->p_filesz*/

if(start==end){

continue;

}

off=start+PGSIZE-la,size=PGSIZE-off;

if(end

size-=la-end;

}

memset(page2kva(page)+off,0,size);

start+=size;

assert((end=la&&start==la));

}

while(start

if((page=pgdir_alloc_page(mm->pgdir,la,perm))==NULL){

gotobad_cleanup_mmap;

}

off=start-la,size=PGSIZE-off,la+=PGSIZE;

if(end

size-=la-end;

}

memset(page2kva(page)+off,0,size);

start+=size;

}

}

//设置用户堆栈内存

vm_flags=VM_READ|VM_WRITE|VM_STACK;

if((ret=mm_map(mm,USTACKTOP-USTACKSIZE,USTACKSIZE,vm_flags,NULL))!

=0){

gotobad_cleanup_mmap;

}

assert(pgdir_alloc_page(mm->pgdir,USTACKTOP-PGSIZE,PTE_USER)!

=NULL);

assert(pgdir_alloc_page(mm->pgdir,USTACKTOP-2*PGSIZE,PTE_USER)!

=NULL);

assert(pgdir_alloc_page(mm->pgdir,USTACKTOP-3*PGSIZE,PTE_USER)!

=

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > IT计算机 > 电脑基础知识

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2