清华大学操作系统实验lab1实验报告_第1页
清华大学操作系统实验lab1实验报告_第2页
清华大学操作系统实验lab1实验报告_第3页
清华大学操作系统实验lab1实验报告_第4页
清华大学操作系统实验lab1实验报告_第5页
已阅读5页,还剩10页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

练习1、理解通过make生成执行文件的过程。[练习1.1]操作系统镜像文件ucore.img是如何一步一步生成的?在projl执行命令make2=可以得到make指令执行的过程makeV=+ccboot/bootasm.Sgcc-Iboot/-fno-builtin-Wall-ggdb-m32-nostdinc-fno-stack-protector-Ilibs/-Os-nostdinc-cboot/bootasm.S-oobj/boot/bootasm.o+ccboot/bootmain.cgcc-Iboot/-fno-builtin-Wall-ggdb-m32-nostdinc-fno-stack-protector-Ilibs/-Os-nostdinc-cboot/bootmain.c-oobj/boot/bootmain.o+cctools/sign.cgcc-Itools/-g-Wall-02-ctools/sign.c-oobj/sign/tools/sign.ogcc-g-Wall-O2obj/sign/tools/sign.o-obin/sign+ldbin/bootblockld-melf_i386-N-estart-Ttext0x7C00obj/boot/bootasm.oobj/boot/bootmain.o-oobj/bootblock.o'obj/bootblock.out'size:440bytesbuild512bytesbootsector:'bin/bootblock'success!ddif=/dev/zeroof=bin/ucore.imgcount=10000记录了10000+0的读入记录了10000+0的写出5120000字节(5.1MB)已复制,0.0227439秒,225MB/秒ddif=bin/bootblockof=bin/ucore.imgconv=notrunc记录了1+0的读入记录了1+0的写出512字节(512B)已复制,0.000214966秒,2.4MB/秒从这几条指令中可以看出需要生成ucore.img首先需要生成bootblock,而生成bootblock需要先生成bootmain.o和bootasm.o还有sign,这三个文件又分别由bootmain.c、bootasm.S、sigh.c来生成。ld-m elf_i386-N-estart-Ttext0x7C00obj/boot/bootasm.oobj/boot/bootmain.o-oobj/bootblock.o这句话用于生成bootblock,elf_i386表示生成elf头,0x7C00为程序的入口。'obj/bootblock.out'size:440bytes这句话表示生成的bootblock的文件大小,因为大小不到512字节,所以需要给blootblock填充,填充的功能在sign.c中有所体现,最后两字节设置为了0x55,0xAAbuf[510]=0x55;buf[511]=0xAA;FILE*ofp=fopen(argv[2],"wb+");size=fwrite(buf,1,512,ofp);[练习1.2]一个被系统认为是符合规范的硬盘主引导扇区的特征是什?么前面已经提到过:引导扇区的大小为512字节,最后两个字节为标志性结束字节0x55,OxAA,做完这样的检查才能认为是符合规范的磁盘主引导扇区。Sign.c文件中有作检查:if(size!=512){fprintf(stderr,"write'%s'error,sizeis%d.\n",argv[2],size);return-1;}练习2:使用qemu执行并调试labl中的软件。[练习2.1]从CPU加电后执行的第一条指令开始,单步跟踪BIOS的执行。[练习2・2]在初始化位置刃刖设置实地址断点测试断点正常。[练习2・3]在调用qemu时增加in_asm-Dq.log参数,便可以将运行的汇编指令保存在Jog中。将执行的汇编代码与ootasm・S和bootblock.asm进行比较,看看二者是否一致。实验是基于老lab1/proj1做的,练习开始时是打算用命令行一句一句执行得到结果的,后来发现直接修改nake刑e和gdbinit可以大大提高调试效率。于是在makefile中增加以下代码Iab1-mon:$(UCOREIMG)$(V)$(TERMINAL)-e"$(QEMU)-S-s-din_asm-D$(BINDIR)/q.Iog-monitorstdio-hda$<-serialnull"$(V)sleep2$(V)$(TERMINAL)-e"gdb-q-tui-xtools/gdbinit"-S-s是使得qemu在执行第一条指令之前停下来,在调用emu时增加■din_asm-Dq.log参数,便可以将运行的汇编指令保存在Jog中。然后sleep两秒应该是给qemu充分的时间准备等待连接。接下来使用DB调试工具,-tui提供了代码与命令行分屏查看的界面tools/gdbinit中存放的是gdb调试指令如下。fileobj/bootblock.otargetremote:1234setarchitecturei8086b*0x7c00continuex/10i$pc先是加载调试文件然后连接qemu,设置8086的实模式,设置断点Ox7c00,也就是bootloader的第一条指令,然后运行到断点。再显示接下来的3条指令。运行结果图如下

B+>Terminalstart:.crotlEi辰115cid1713尊B+>Terminalstart:.crotlEi辰115cid1713尊sexupthe19X(>™塔ax#KaxZDnovw%ds21mo'/w常ax#?ies22HOW%ax,%552324#EnableA2G:25JfForbackwaBootingfremHardDisk…、snpEtlbllAtywiththe P匸»phygtrenoteThread1in:startItne:15PC:OX7CO0renoteThread1in:startThetargetarchitectureisassumedtobe1S08CBreakpoint1atGx7c00:fiteboot/bootasm.S,lineIS,ell

eldBreakpoint1pEtmrt()atboot/bootasn.SrlS"0x7c00cstart>:ell

eldoxzcai<start+l>:---Type*;return>tocontinuetorq<;return》toquit--0x7c04^start+4>;novWax^dsax7c06<start+6>:novStes0k7c08<stsrt+8?:nov0X7CO3-£seta20.1^:tn$0x&4^al0k7c0c<seta26.l+2>:test$0xZ,94olax7coe<seta2B.l+4>:jneax7toatseta20.1>3k7c10r•」l、 <seta20.l+6>:nov$3xdl,%al很明显,断点位置的代码和ootem文件中的代码完全一致,说明断点设置成功。打开Jog文件看,看到了很奇葩的结果。能够看到Cd之类熟悉的指令,但是他们的地址以及出现的顺序都不是想象的那样(从0x0x00007c00k开始,第一条指令为阳丿。 IN;OxfffffffO:Ljnp $OxeeSb|4IM;Gk^&Of«BE6-kgtOx!&&0f«C68iIM!0X&&Ofee5b:cnpl $6x9,SC5:0x65a4:jne 6xfd;2.b9ie111213J.4之后听大神解释,在q.log中进入BIOS之后的跳转地址与实际应跳转地址不相符,汇编代码也与bootasm.S和bootblock.asm不相同。

可以通过makedebug之后在qemu的控制台中输入x/10i$pc看到BIOS执行bootloader部分的代码。— j■~~1 MkjBfBy-H j]T・■■■■■■■■»4U* ■rCl00QEMU[Stopp&d]?ompat_rfionitorOconsole{EMU2.0.0ncm辻ctr[qemu)x/10i$pc)x0000?c00:cli)x0000?c01:cld-type'help"fopworeinformation)x00007cG2;xorzax,zax)x00007c04;mouzax,zds)x00007c06:mouzax,zes)x0O0O7cO6:mouzax,ZEE)x0O0O7cOa:in$0x64,zal)x0O0O7cOc:test,zal)x00007c0e:jneGx7c0aJxOOOOTclO:■nou$0xdl, 1进过对比,这些代码与bootasm.S与bootblock.asm中的代码完全一致。练习3分析bootloader进入保护模式的过程。在开启120之前,BIOS^做了很多事关中断、清除方向标志,给各个数据段清零。cli #Disableinterruptscld #Stringoperationsincrement#Setuptheimportantdatasegmentregisters(DS,ES,SS).xorw%ax,%ax#Segmentnumberzeromovw%ax,%ds#->DataSegmentmovw%ax,%es#->ExtraSegmentmovw%ax,%ss

1、为何^^A20,以及如何开启A20?seta20.1:inb$0x64,%altestb$0x2,%aljnzseta20.1#等待8042键盘控制器不忙movb$0xd1,%aloutb%al,$0x64#发送写8042输出端口的指令seta20.2:inb$0x64,%altestb$0x2,%aljnzseta20.2#等待8042键盘控制器不忙movb$0xdf,%aloutb%al,$0x60#打开A20当A20地址线控制禁止时,则程序就像在8086中运行,1MB以上的地是不可访问的。在保护模式下A20地址线控制是要打开的。为了使能所有地址位的寻址能力,必须向键盘控制器8042发送一个命令。键盘控制器8042将会将它的的某个输出引脚的输出置高电平,作为A20地址线控制的输入。一旦设置成功之后,内存将不会再被绕回(memorywrapping),这样我们就可以寻址intel80286CPU支持的16M内存空间,或者是寻址intel80386以上级别CPU支持的所有4G内存空间了。2、如何初始化D7表?lgdtgdtdesc把gdt表的起始位置和界限装入GDTR寄存器movl%cr0,%eaxorl$CR0_PE_ON,%eaxmovl%eax,%cr0#把保护模式位开启复习一下crO寄存器,它的第0位为保护模式位PE:设置PE将让处理器工作在保护模式下。复位PE将返回到实模式工作。此外,gdtdesc指出了全局描述符表在符号gdt处,如下上面四句话实现了打开保护模式位。3、如何使能进入保护模式?通过长跳转指令gdt:SEG_NULLASMSEG_ASM(STA_X|STA_R,0x0,Oxffffffff)SEG_ASM(STA_W,0x0,Oxffffffff)#空段#代码段(起始地址,大小)#数据段(起始地址,大小)ljmp$PROT_MODE_CSEG,$protcseg进入了保护模式。进入保护模式之后还有一个步骤:把所有的数据段寄存器指向上面的GDT描述符表中的数据段(0x10)。练习四、分析bootloader加载ELF格式的OS的过程。在proj2中,增加主要增加了对磁盘简单的读取函数readsect()readseg()),以及对ELF头的解析(ELF头结构在ELF.h文件中)。staticvoidreadseg(uintptr_tva,uint32_tcount,uint32_toffset){uintptr_tend_va=va+count;//指针移到边界va-=offset%SECTSIZE;//计算开始读的第一个扇区号uint32_tsecno=(offset/SECTSIZE)+1;//逐个读取扇区for(;va<end_va;va+=SECTSIZE,secno++){readsect((void*)va,secno);}}//实现了从kernel复制8个扇区(包含ELF头,共4KB)到0x10000疑问:为什么要把ELF头读到0X10000?从哪读?以下为一些硬件端口上实现读取一个扇区到内存0x10000。/*readsect-readasinglesectorat@secnointo@dst*/staticvoidreadsect(void*dst,uint32_tsecno){//waitfordisktobereadywaitdisk();outb(0x1F2,1); //count=1outb(0x1F3,secno&0xFF);outb(0x1F4,(secno>>8)&0xFF);outb(0x1F5,(secno>>16)&0xFF);outb(0x1F6,((secno>>24)&0xF)|0xE0);outb(0x1F7,0x20); //cmd0x20-readsectors//waitfordisktobereadywaitdisk();//readasectorinsl(0x1F0,dst,SECTSIZE/4);}Readsect()函数的工作大致是:1.读I/O地址0x1f7,等待磁盘准备好;2.写I/O地址0x1f2~0x1f5,0x1f7,发出读取第offseet个扇区处的磁盘数据的命令;读I/O地址0x1f7,等待磁盘准备好;连续读I/O地址0x1f0,把磁盘扇区数据读到指定内存。练习五、实现函数调用堆栈跟踪函数(需要编程)+|檢底方向 |高位地址TOC\o"1-5"\h\zI II I| #^13 ||券数2 |I奩数1 II返回地址 II上一层[出p] |U [ebp]|局部逻量 |低隹炖址可以获知栈底是在高地址,栈顶在低地址,压栈的次序为:参数(编程的时候默认有四个参数)、返回地址、上一层EBP、局部变量。uint32_tebp=read_ebp(),eip=read_eip();inti,j;for(i=0;ebp!=0&&i<STACKFRAME_DEPTH;i++){cprintf"ebp:0x%08xeip:0x%08xargs:",ebp,eip);uint32_t*args=(uint32_t*)ebp+2;for(j=0;j<4;j++){cprintf"0x%08x",args[j]);}cprintf"\n");print_debuginfo(eip-1);eip=(uint32_t*)ebp)[1];ebp=(uint32_t*)ebp)[0];注:read_ebp()和readeip()都是通过内联汇编实现的。Eip-1是为了能找到上一条指令

结果图:ITH7E0xO9007t>6eOx901O9a58exaoeeoaoe9X000001003QxMlOllldkern/debug/nonttDr.c:711runcndM370xO9l0lf14ebp:9)cae937bc8etp:okobiobqbcargs:□xeaaoooaa0X030000030xfa7502a8ITH7E0xO9007t>6eOx901O9a58exaoeeoaoe9X000001003QxMlOllldkern/debug/nonttDr.c:711runcndM370xO9l0lf14ebp:9)cae937bc8etp:okobiobqbcargs:□xeaaoooaa0X030000030xfa7502a8ebp:&K0flOO7b98eip:OxB0iaOac5args:0x00000000kern/debug/monitor-c;3B:nonitor+681oxooooeooo0x0000065cexaesaeaoeGx54e4dOBeexseeesaee□xa00iaa943backtraceebp:9K0O3O7ae8eip:OxOGlOOSCbargs:0x03990000QxOOOQGOOlkern/d!ebug/kdebug*c;307:print_stackfrane+21ebp:0K000O7afsetp:axoei90b49argsi0x00000000exaao07bickern/debug/nonitor*c:121:Tion_backtrace+19ebp:a?t&0OO7b68eip:0^00100^58args;0x00108569'0xOO007b98kern/init/tnit.c:25:kerninit-i-91ebp:DxOOOD7bf8eip:0KOG007d68args:0xc031fcfa0xcD8ed88e enMo":-- 0工Elm眦了ch?-- 练习六、完善中断初始化和处理(需要编程)[练习6.1]中断向量表中一个表项占多少字节?其中哪几位代表中断处理代码的入口?80386INTERRUPTGATE中断向量表一个表项占用8字节,其中2-3字节是段选择子,0-1字节和6-7字节拼成位移,两者联合便是中断处理程序的入口地址。2.请编程完善kern/trap/trap.c中对中断向量表进行初始化的函^Ht_initoidt_init(void){externuintptr」__vectors[];inti;for(i=0;i<sizeof(idt)/sizeof(structgatedesc);i++){SETGATE(idt[i],0,GD_KTEXT,__vectors[i],DPL_KERNEL);}//初始化每一条IDT项//设置内核态到用户态的转换SETGATE(idt[T_SWITCH_TOK],0,GD_KTEXT,__vectors[T_SWITCH_TOK],DPL_USER);//载入IDTlidt(&idt_pd);}3.请编程完善trap.中的中断处理函数rap在对时钟中断进行处理的部分填写trapS数中处理时钟中断的部分,使操作系统每遇到0次时钟中断后,调用print_tickS程序,向屏幕上打印一行文字”00tic”caseIRQ_OFFSET+IRQ_TIMER:ticks++;if(ticks%TICK_NUM==0){print_ticks();}//当有100次时钟中断输出一次break;练习7、增加sysca功能,即增加一用户态函数(可执行

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论