lab3 介绍

整理文档很辛苦,赏杯茶钱您下走!

免费阅读已结束,点击下载阅读编辑剩下 ...

阅读已结束,您可以下载文档离线阅读编辑

资源描述

Lab3introduction2010-5Lab3任务清单用户环境的建立实现中断处理实现系统调用概要引言PartAPartB引言新的debug命令内联汇编简介重要文件说明重要数据结构Structtask_structv.s.structEnv引言新的debug命令内联汇编简介重要文件说明重要数据结构Structtask_structv.s.structEnvBochsdebug命令infoidt查看idt的内容在lab3中,用于检查idt的设置是否正确vb在逻辑地址上设断点注意参数——selector:offset内核地址vb8:offset用户地址vb0x1b:offset(why0x1b?)Bochsdebug命令——举例(1)在obj/kernel.asm中找到lidt的位置0xf0103a4e(各人可能不同)在lidt的上一条指令地址设置0xf0103a4b处设置断点vb8:0xf0103a4b运行到断点处,在lidt前查看idt内容infoidt在执行完lidt之后查看idt的内容Bochsdebug命令——举例(2)引言新的debug命令内联汇编简介重要文件说明重要数据结构Structtask_structv.s.structEnvGCC内联汇编回顾GCC支持在C/C++代码中嵌入汇编代码,这些汇编代码被称作GCC内联汇编(GCCInlineAssembly)功能:可以使用内联汇编表达一些C/C++语言中无法表达的指令允许我们直接在C/C++代码中使用汇编语言编写简洁高效的代码GCC内联汇编-基本格式asm(“statements”);说明:__asm或asm用来声明一个内联汇编表达式,所以任何一个内联汇编表达式都是以它开头的,是必不可少的statements是指令序列,每条指令都必须被双引号括起来示例:asm(pushl%eax\n\t“movl$0,%eax\n\t“popl%eax);注意:如果修改了寄存器,可能会造成灾难性后果GCC内联汇编-扩展格式asm(statements:output_registers:input_registers:clobbered_registers);output_registers:用来指定当前内联汇编语句的输出input_registers:用来指定当前内联汇编语句的输入clobbered_registers:声明当前内联汇编在statements中对某些寄存器或内存进行修改示例-1asm(cld\n\trep\n\tstosl:/*nooutputregisters*/:c(count),a(fill_value),D(dest):%ecx,%edi);示例-2asm(leal(%%ebx,%%ebx,4),%%ebx:=b(x):b(x));指令中寄存器前必须使用两个百分号(%%),而不是像基本汇编格式一样在寄存器前只使用一个百分号(%)引言新的debug命令内联汇编简介重要文件说明重要数据结构Structtask_structv.s.structEnv重要文件说明env.c:env的初始化、创建、释放等trap.c:中断处理相关,包含dispatchtrapentry.S:中断入口的生成及中断相关的栈操作syscall.c:系统调用相关*.h:……引言新的debug命令内联汇编简介重要文件说明重要数据结构Structtask_structv.s.structEnv重要数据结构(1/2)NENV:宏定义的可被创建的最大的环境数量structEnv*envs:全部环境的数组structEnv*curenv:当前运行环境staticstructEnv_listenv_free_list:环境的空闲链表structEnv:环境结构重要数据结构(2/2)structEnv{structTrapframeenv_tf;//切换时,在此保存寄存器LIST_ENTRY(Env)env_link;//空闲链表指针envid_tenv_id;//环境id,唯一辨识envid_tenv_parent_id;//父亲的idunsignedenv_status;//环境的状态uint32_tenv_runs;//环境已运行次数//Addressspacepde_t*env_pgdir;//页目录的虚拟地址physaddr_tenv_cr3;//页目录的物理地址};引言新的debug命令内联汇编简介重要文件说明重要数据结构Structtask_structv.s.structEnvLinux中的进程描述符Linux内核2.6.11版本用structtask_struct来描述进程StructTask_struct比structEnv复杂得多。StructEnv里的各个结构成员在structTask_struct中都可以找到对应的部分Structtask_structv.s.structEnv完整的task_structPartA新的PC启动初始化过程load_icode-ELF文件的加载interruptVSexception中断处理流程PartA新的PC启动初始化过程load_icode-ELF文件的加载interruptVSexception中断处理流程初始化流程PartA新的PC启动初始化过程load_icode-ELF文件的加载interruptVSexception中断处理流程ELF文件格式(回顾)描述整个文件的组织节区部分包含链接视图的大量信息:指令、数据、符号表、重定位信息等等告诉系统如何创建进程映像。用来构造进程映像的目标文件必须具有程序头部表SectionVSSectorVSSegment与ELF文件相关的数据结构ELF头程序头部表节区structELF长度为ELF-e_phoff和节(section)一一对应structproghdr{p_type;//段的类型p_va;//段的第一个字节将被放到内存中的虚拟地址。p_offset;//从文件头到该段第一个字节的偏移p_filesz;//段在文件映像中所占的字节数p_memsz;//段在内存映像中占用的字节数}加载ELF文件的流程1.略过ELF头;2.找到第一个section对应的structproghdr;3.while(还有section没有加载),do4.分配p_memsz大小的内存5.根据p_offset找到section;6.把section开始的p_filesz导入内存;7.将剩余部分的内存设置为0;8.endwhile**ELF_PROG_LOADPartA新的PC启动初始化过程load_icode-ELF文件的加载interruptVSexception中断处理流程中断与异常ExceptionsandInterrupts区别在于:中断处理异步事件(相对处理器是外部的),而异常是指处理器自己检测到的情况中断的分类:可屏蔽、不可屏蔽异常的分类:处理器检测、程序触发(bp,int0x30)中断号对应表PartA新的PC启动初始化过程load_icode-ELF文件的加载interruptVSexception中断处理流程中断处理过程概览寄存器idtr保存了中断描述符表的基址和长度每个中断描述符保存了一个中断处理程序入口的cs和eip发生中断时,硬件用获得的中断号作为中断描述符表的下标,找到相应的中断处理程序入口,执行中断处理程序IDTR和idt(interruptdescriptortable)中断描述符Interruptgate定义中断处理程序的入口Trapgate定义异常处理程序的入口Idt的初始化在kern/trap.c中定义了全局数组structGatedescidt[256]={{0}};作为中断描述符表在idt_init中使用宏SETGATE设置中断描述符中断处理程序入口在kern/trapentry.S中定义。所以要想引用中断处理程序入口的eip,需要使用C中的extern关键字中断处理程序在kern/trapentry.S中,使用宏TRAPHANDLER和TRAPHANDLER_NOEC定义中断处理程序的入口中断处理程序先在栈中设置好structTrapframe,然后调用kern/trap.c里面的trap函数进行中断处理图示PartB系统调用原理与简单流程系统调用系统调用通过软件中断实现int0x30设置idt需要在idt中进行相应的设置参数传递:传递系统调用号:EAX;5个参数:EDX,ECX,EBX,EDI,ESI返回值:EAX思考:为什么用寄存器传参?系统调用—流程实例1在lib/syscall.c--syscall()中使用int0x30指令陷入到内核态user/hello.cumain()……cprintf()……lib/printf.cprintf()……vcprintf()…………………………lib/syscall.csys_cputs()……syscall()……syscall()asmvolatile(int%1\n:=a(ret):i(T_SYSCALL),a(num),d(a1),c(a2),b(a3),D(a4),S(a5):cc,memory);要求:阅读参考资料中的InlineAssemblywithDJGPP.mht系统调用—流程实例2内核中通过trapdispatch根据trapno进行分发kern/syscall.c/syscall()是实现系统调用指定功能的函数注意与lib目录中syscall()函数的区别kern/trapentry.S_alltraps……calltrap……kern/trap.ctrap……trapdispatch()……kern/trap.ctrapdispatch()……syscall()……kern/syscall.csyscall()……sys_cputs()……Q&A

1 / 46
下载文档,编辑使用

©2015-2020 m.777doc.com 三七文档.

备案号:鲁ICP备2024069028号-1 客服联系 QQ:2149211541

×
保存成功