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

下载本文档

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

文档简介

练习1、理解通过make生成执行文件的过程。[练习1.1]操作系统镜像文件ucore.img?proj1makeV=make指令执行的过程makemakeV=+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-O2-ctools/sign.c-oobj/sign/tools/sign.ogcc-g-Wall-O2obj/sign/tools/sign.o-obin/sign+ldbin/bootblockld-m elf_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=1000010000+0的读入10000+0的写出5120230字节(5.1MB)已复制,0.0227439秒,225MB/秒ddif=bin/bootblockof=bin/ucore.imgconv=notrunc1+0的读入1+0的写出512字节(512B)已复制,0.000214966秒,2.4MB/秒ucore.imgbootblock,而bootblockbootmain.obootasm.osign,这三个文件又bootmain.c、bootasm.S、sigh.c来生成。ld-m elf_i386-N-estart-Ttext0x7C00obj/boot/bootasm.oobj/boot/bootmain.o–oobj/bootblock.obootblock,elf_i386elf头,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,0xAA,做完这样的检查才能认为是符合标准的磁盘主引导扇区。Sign.c文件中有作检查:if(size!=512){fprintf(stderr,“write”%s”error,sizeis%d.\n“,argv[2],size);return-1;}练习2:使用qemu执行并调试lab1中的软件。[练习2.1]CPU加电后执行的第一条指令开头,BIOS的执行。[练习2.2]0x7c00,测试断点正常。[练习2.3]qemu-din_asm-Dq.log参数,便可以将运行的汇q.logbootasm.S和bootblock.asm进展比较,看看二者是否全都。lab1/proj1做的,练习开头时是打算用命令行一句一句执makefilegdbinit可以大大提高调试效率。于是在makefile中增加以下代码lab1-mon:lab1-mon:$(UCOREIMG)$(V)$(TERMINAL)-e“$(QEMU)-S-s-din_asm-D$(BINDIR)/q.log-monitorstdio-hda$<-serialnull“$(V)sleep2$(V)$(TERMINAL)-e“gdb-q-tui-x tools/gdbinit“-S–s是使得qemuqemu时增加-din_asm-Dq.log参数,便可以将运行的汇编指令保存q.log中。然后sleep两秒应当是给qemuGDB调试工具,fileobj/bootblock.otargetremote:1234setarchitecturei8086fileobj/bootblock.otargetremote:1234setarchitecturei8086b*0x7c00continuex/10i$pc先是加载调试文件6的实模式0,也就是bootloader10条指令。运行结果图如下boot.asm文件中的代码完全全都,说明断点q.log文件看,看到了很奇葩的结果。能够看cli,cld之类生疏的指令,但是他们的地址以及消灭的挨次都不是想象的那样从0x0x00007c00kcld)。之后听大神解释,在q.logBIOS之后的跳转地址与实际应跳转地bootasm.S和bootblock.asm不一样。可以通过makedebug之后在qemu的掌握台中输入x/10i$pc看到BIOS执行bootloader局部的代码。进过比照bootasm.Sbootblock.asm中的代码完全全都。练习3分析bootloader进入保护模式的过程。clicld#Disableinterruptsclicld#Disableinterrupts#Stringoperations#Setuptheimportantdatasegmentregisters(DS,ES,SS).xorw%ax,%ax%ax,%ds%ax,%es%ax,%ss#Segmentnumberzero#->DataSegment#->ExtraSegment1A20A20?seta20.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内存空间了。2GDT表?lgdtlgdtgdtdescmovl%cr0,%eaxorl$CR0_PE_ON,%eaxmovl%eax,%cr0把gdt表的起始位置和界限装入GDTR存放器复习一下cr0存放器,它的第0位为保护模式位PE:设置PE将让处理器工作在保护模式下。复位PE将返回到实模式工作。此外,gdtdesc指出了全局描述符表在符号gdt处,如下上面四句话实现了翻开保护模式位。3、如何使能进入保护模式?通过长跳转指令gdt:gdt:SEG_NULLASMSEG_ASM(STA_X|STA_R,0x0,0xffffffff)SEG_ASM(STA_W,0x0,0xffffffff)空段代码段〔起始地址,大小〕数据段〔起始地址,大小〕ljmp$PROT_MODE_CSEG,$protcseg进入了保护模式。进入保护模式之后还有一个步骤:把全部的数据段存放器指向上面的描述符表中的数据段〔0。练习四、分析bootloader加载ELF格式的OS的过程。在proj2中,增加主要增加了对磁盘简洁的读取函数readsect,以及对FF头构造在)。staticstaticvoidreadseg(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);}}//kernel8个扇区〔ELF4KB〕0x10000疑问:为什么要把ELF头读到0X10000?从哪读?以下为一些硬件端口上实现读取一个扇区到内存0x10000。//waitfordisktobereadywaitdisk;outb(0x1F2,1);outb(0x1F3,secno&0xFF);/*readsect/*readsect-readasinglesectorat@secnointo@dst*/staticvoidreadsect(void*dst,uint32_tsecno){//count=1outb(0x1F4,(secno>>8)&0xFF);outb(0x1F5,(secno>>16)&0xFF);outb(0x1F6,((secno>>24)&0xF)|0xE0);outb(0x1F7,0x20);//waitfordisktobereadywaitdisk;//readasectorinsl(0x1F0,dst,SECTSIZE/4);//cmd0x20-readsectors}读I/O地址0x1f7,等待磁盘预备好;写I/O地址0x1f2~0x1f5,0x1f7,发出读取第offseet个扇区处的磁盘数据的命令;读I/O地址0x1f7,等待磁盘预备好;连续读I/O地址0x1f0,把磁盘扇区数据读到指定内存。练习五、实现函数调用堆栈跟踪函数〔需要编程〕uint32_tebp=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++){x“,}cprintf(“\n“);print_debuginfo(eip-1);注:read_ebp和readeip都是通过内联汇编实现的。Eip-1是为了能找到上一条指令结果图:练习六、完善中断初始化和处理〔需要编程〕[练习6.1]中断向量表中一个表项占多少字节?其中哪几位代表中断处理代码的入口?中断向量表一个表项占用8字节,其中2-3字节是段选择子,0-1字节和6-7字节拼成位移,两者联合便是中断处理程序的入口地址。kern/trap/trap.c中对中断向量表进展初始化的函idt_init。idt_initidt_init(void){externuintptr_t 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);}trap.ctrap,在对时钟中断进展处理的局部填写trap函数中处理时钟中断的局部,使操作系统每遇100次时钟中断s子程序,向屏幕上打印一行文字0casecaseIRQ_OFFSET+IRQ_TIMER:ticks++;if(ticks%TICK_NUM==0){print_ticks;}//当有100次时钟中断输出一次break;练习7、增加syscall功能,即增加一用户态函数〔可执行一特定系统调用:获得时钟计数值,当内核初始完毕后,可从内核态返回到用户态的函数,而用户态的函数又通过系统调用得到内核态的效劳。先附上两个最重要的图,分别是内核态切换到用户态、用户态切换到内核态的过程。这局部是最花时间的,光是看代码就有很多疑问。1、 为什么需要构建一个临时的trapframe来实现切换栈,切换栈说白了不就是需要修改那几个存放器吗?2、 PPT上两个切换过程中的的两个老栈顶是一个地址吗?老栈顶是什么意思?3、 切换到用户态的过程中,trapframe的tf_esp为什么要指向原

温馨提示

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

评论

0/150

提交评论