《清华大学操作系统lab1-实验报告.docx》由会员分享,可在线阅读,更多相关《清华大学操作系统lab1-实验报告.docx(5页珍藏版)》请在第壹文秘上搜索。
1、实验1:系统软件启动过程练习1:(1)操作系统镜像文件ucore.img是如何一步-一步生成的?在命令行中输入makeV=1、首先把C的源代码进行编译成为.o文件,也就是目标文件(红色方框内)2、Id命令将这些目标文件转变成可执行文件,比方此处的bootblock.out(绿色方框内)3、dd命令把bootloder放到ucore.imgcount的虚拟硬盘之中4、还生成了两个软件,一个是Bootloader,另一个是kernelo(2)一个被系统认为是符合标准的硬盘主引导扇区的特征:labltoolssign.c中我们可以了解到标准的硬盘引导扇区的大小为512字节,硬盘结束标志位55AA练习
2、2:(1) 从CPU加电后执行的第一条指令开始,单步跟踪BIOS的执行改写Makefile文件labl-mon:$(UCOREIMG)$(V)$(TERMINAL)-eS(QEMU)-S-s-din_asm-D$(BINDIR)/q.log-monitorstdio-hda$ DS: Data Segment# - ES: Extra Segment#- FS#- GS# - SS: Stack Segment#栈顶为0x7Coospin:jmpspin练习4:分析bootloader加载ELF格式的OS的过程读一个扇区的流程可参看bootmain.c中的readsect函数实现。大致如下:1
3、 .读I/O地址0xlf7,等待磁盘准备好;2 .写I/O地址OXlf20xlf5,0xlf7,发出读取第OffSeet个扇区处的磁盘数据的命令;3 .读I/O地址0xlf7,等待磁盘准备好;4 .连续读I/O地址OXlfo,把磁盘扇区数据读到指定内存。staticvoidreadsect(void*dstzuint32_tsecno)/waitfordisktobereadywaitdisk();outb(0lF2z1);/count=1outb(0xlF3zsecno&OxFF);outb(0lF4,(secno8)&OxFF);outb(0xlF5z(secno16)&OxFF);out
4、b(0lF6z(secno24)&OxF)OxEO);outb(0lF7z0x20);/cmd0x20-readsectors/waitfordisktobereadywaitdisk();/readasectorinsl(0xlF0zdst,SECTSIZE/4);该函数封装在readseg函数中,该函数完成读取任意的长度。Notice:uint32_tsecno=(offset/SECTSIZE)+1;#0号扇区已被引导占用。最后在bootmain函数中完成加载ELF格式os的操作:1:读取ELF的头部2:判断ELF文件是否是合法3:将描述表的头地址存在ph4:按照描述表将ELF文件中数据
5、载入内存5:根据ELF头部储存的入口信息,找到内核的入口(不再返回)Notice:可能会出现内存长度文件长度的现象多读入局部包含bss节,需要清0练习5:实现函数调用堆栈跟踪函数PrinJStaCkframe(VOid)Uint32_tebp=read_ebp(),eip=read_eip();inti,j;for(i=0;ebp!=0&iS1ACKFRAME_DEPTH;i+)cprintf(ebp:0x%08xeip:0x%08xargs:,ebp,eip);uint32_t*args=(uint32_t*)ebp+2;/(uint32_t)caIlingarguments0.4=thec
6、ontentsinaddress(unit32_t)ebp+20.4for(j=0;j4;j+)cprintf(0x%08x”,argsj);cprintf(n);print-debuginfo(eip-1);*callprint_debuginfo(eip-l)toprinttheCcallingfunctionnameandlinenumber,etc.*/eip=(uint32-t*)ebp)l;ebp=(uint32-t*)ebp)0;/popupacallingstackframeNotice:ss:ebp指向的堆栈位置储存着caller的ebp,以此为线索可以得到所有使用堆栈的函数
7、ebp。ss:ebp+4指向CalIer调用时的eip,ss:ebp+8等是(可能的)参数。练习6:(1)中断向量表中一个表项占多少字节?其中哪几位代表中断处理代码的入口?中断向量表一个表项占用8字节,其中2-3字节是段选择子,0-1字节和6-7字节拼成位移,入口地址=段选择子+段内偏移量。完善kern/trap/trap.c中对中断向量表进行初始化的函数idtjnit可以在lablkernmmmmu.h中可以找到SETGATE函数,查找其具体操作。idtjnit(void)externuintptr_t_vectors;inti;for(i=0;itf_cs!=USER_CS)switchk
8、2u=*tf;switchk2u.tf-cs=USER_CS;switchk2u.tf-ds=switchk2u.tf-es=switchk2u.tf_ss=USER_DS;switchk2u.tf_esp=(uint32-t)tf+Sizeof(Structtrapframe)-8;在执行intl20前系统在核心态,int不会引起栈的切换switchk2u.tf-eflags=FL_IOPL_MASK;*(uint32_t*)tf-1)=(uint32_t)&switchk2u;break;vectorsalltrapscsp-8CPUZl 入tCcagt(cp t(cfU 步 tfa tf Clp tf_crr tf tnno tftf_cs!=KERNEL_CS)tf-tf-cs=KERNEL_CS;tf-tf-ds=tf-tf_es=KERNEL_DS;tf-tf-eflags&=FL_IOPL_MASK;定位临时栈的栈顶switchu2k=(Structtrapframe*)(tf-tf-esp-(Sizeof(Structtrapframe)-8);复制me