21
第第第 第第第第第 第第第 第第第第第 (lab3) (lab3)

第五章,抢占式调度 (lab3)

  • Upload
    demont

  • View
    164

  • Download
    0

Embed Size (px)

DESCRIPTION

第五章,抢占式调度 (lab3). 提纲. 用户环境的建立 中断、系统调用. 用户环境的建立. 用户执行环境数据结构的分配 装载并执行用户环境. 用户环境的建立(续). 用户环境 (Environments) 数据结构的分配 envs 是指向一个包含 1024 个( 1

Citation preview

Page 1: 第五章,抢占式调度 (lab3)

第五章,抢占式调度第五章,抢占式调度(lab3)(lab3)

Page 2: 第五章,抢占式调度 (lab3)

提纲提纲 用户环境的建立用户环境的建立 中断、系统调用中断、系统调用

Page 3: 第五章,抢占式调度 (lab3)

用户环境的建立用户环境的建立 用户执行环境数据结构的分配用户执行环境数据结构的分配 装载并执行用户环境装载并执行用户环境

Page 4: 第五章,抢占式调度 (lab3)

用户环境的建立(续)用户环境的建立(续) 用户环境用户环境 (Environments)(Environments)数据结构的分配数据结构的分配

envsenvs是指向一个包含是指向一个包含 10241024个(个( 1<<NENV(10)1<<NENV(10))) struct Envstruct Env结构结构的指针,与的指针,与 pagespages指针非常类似,连建立链表的一些宏定义都和在指针非常类似,连建立链表的一些宏定义都和在页面管理中的一模一样页面管理中的一模一样

可以在分配完可以在分配完 pagespages结构后,分配结构后,分配 envsenvs结构,并在结构,并在 env_init()env_init()函数函数中中

在在 i386_vm_init()i386_vm_init()函数中,将函数中,将 envsenvs结构映射到结构映射到 UENVSUENVS逻辑地址处逻辑地址处

0 4KB

Real Mode IDT

Boot Sector Code

0x7C00 0x10000

ELF header

1MB

Kernel Code

endedata

4KB

Program entrance

0x10000c

End of Physical

Mem

640KB

Bios Data, Video Ram

Setted by Bochs

About 25 pages

4KB aligned

Page Directory

pages (4KB aligned)

envs (4KB aligned)

boot_freemem (4KB aligned)

Page 5: 第五章,抢占式调度 (lab3)

用户环境的建立(续)用户环境的建立(续) 装载并执行用户环境装载并执行用户环境

相关的函数调用相关的函数调用 i386_init->ENV_CREATE(user_hello)->envi386_init->ENV_CREATE(user_hello)->env

_create->env_alloc->load_icode_create->env_alloc->load_icode i386_init->env_runi386_init->env_run 需要解决以下问题:需要解决以下问题:

用户环境页表的配置与空间分配用户环境页表的配置与空间分配装载用户执行代码装载用户执行代码切换到用户执行代码切换到用户执行代码

Page 6: 第五章,抢占式调度 (lab3)

用户环境的建立(续)用户环境的建立(续) 用户环境页表的配置与空间分配用户环境页表的配置与空间分配

页表的配置页表的配置 在在 env_create->env_alloc->env_setup_vmenv_create->env_alloc->env_setup_vm 按照按照 JOSJOS的规划,用户执行的逻辑地址空间实际上是与内核的规划,用户执行的逻辑地址空间实际上是与内核共享共享 4GB4GB ,内核代码在,内核代码在 lab2lab2 中已经映射到中已经映射到 KERNBASEKERNBASE(( 00xf0000000xf0000000 )以上的空间,而剩下的低地址空间则留给了用户)以上的空间,而剩下的低地址空间则留给了用户执行代码执行代码

构建用户环境的页表,为了保持内核部分的逻辑地址到物理内构建用户环境的页表,为了保持内核部分的逻辑地址到物理内存的映射关系,实际上可以将内核的地址映射关系拷贝到用户存的映射关系,实际上可以将内核的地址映射关系拷贝到用户环境的页表中来。环境的页表中来。

思考:通过拷贝,可以让用户环境顺利寻址到所有内核端的代思考:通过拷贝,可以让用户环境顺利寻址到所有内核端的代码,可是用户代码装载到的低地址空间,还没有实际的物理内码,可是用户代码装载到的低地址空间,还没有实际的物理内存页面与之进行映射,应该采用什么样的办法呢?是通过分配存页面与之进行映射,应该采用什么样的办法呢?是通过分配页面的办法将用户环境的空间填满,还是以后根据需要动态分页面的办法将用户环境的空间填满,还是以后根据需要动态分配页面?为什么?配页面?为什么?

Page 7: 第五章,抢占式调度 (lab3)

用户环境的建立(续)用户环境的建立(续) 装载用户程序到内存装载用户程序到内存 (load_icode)(load_icode)

函数原型函数原型 load_icode(struct Env *e, uint8_t *load_icode(struct Env *e, uint8_t *binary, size_t size)binary, size_t size)其中其中 binarybinary指向用户程序在内存中的镜像(如何指向指向用户程序在内存中的镜像(如何指向的?)的?)

SizeSize是用户程序在内存中镜像的大小是用户程序在内存中镜像的大小 ELFELF文件的装载过程文件的装载过程

ELFELF文件的格式(见第文件的格式(见第 33章)章)将将 ELFELF文件中的代码段、数据段、文件中的代码段、数据段、 bssbss段拷贝到段拷贝到 Env Env

*e*e指向的用户环境中(用哪一个指向的用户环境中(用哪一个 CR3CR3会比较方便?)会比较方便?)找到用户程序的入口地址,并将该入口地址赋值到找到用户程序的入口地址,并将该入口地址赋值到 e->e->

env_tf. tf_eipenv_tf. tf_eip中中

Page 8: 第五章,抢占式调度 (lab3)

用户环境的建立(续)用户环境的建立(续) 将用户环境投入执行将用户环境投入执行

env_run(struct Env *e)env_run(struct Env *e)函数函数 载入用户环境的页目录载入用户环境的页目录 将将 e->env_tfe->env_tf中包含的寄存器值赋值到物理的中包含的寄存器值赋值到物理的寄存器,使得用户环境中的程序开始执行寄存器,使得用户环境中的程序开始执行

Page 9: 第五章,抢占式调度 (lab3)

用户环境的建立(续)用户环境的建立(续) 完成用户环境加载完成用户环境加载 跟踪其运行过程,直到跟踪其运行过程,直到 int $0x30int $0x30 思考思考

1. 1. 如何赋值如何赋值 e->env_tfe->env_tf 才能使装载进来的用户程序投才能使装载进来的用户程序投入真正的执行?入真正的执行?

2. JOS2. JOS系统在系统在 env_pop_tfenv_pop_tf之前都对之前都对 e->env_tfe->env_tf 中的中的值做了哪些初始化的工作?值做了哪些初始化的工作?

3. 3. 用户环境的堆栈段从什么地方开始?用户环境的堆栈段从什么地方开始? JOSJOS是如何实是如何实现堆栈段的定位的?现堆栈段的定位的?

4. env_pop_tf4. env_pop_tf 是如何工作的?为什么首先执行是如何工作的?为什么首先执行 popalpopal来设置通用寄存器,而不是先来设置通用寄存器,而不是先 pop env_tfpop env_tf结构中后面结构中后面的的 tf_sstf_ss和和 tf_esptf_esp??

Page 10: 第五章,抢占式调度 (lab3)

中断、系统调用中断、系统调用 i386i386 的异常与中断的异常与中断 i386i386 的异常或中断处理过程的异常或中断处理过程 TSSTSS 的作用与发生中断后堆栈的构成的作用与发生中断后堆栈的构成 JOSJOS 中的异常处理中的异常处理 缺页错误、系统调用的实现缺页错误、系统调用的实现

Page 11: 第五章,抢占式调度 (lab3)

中断、系统调用(续)中断、系统调用(续) i386i386的异常与中断的异常与中断

Exceptions and interrupts are both "protected contExceptions and interrupts are both "protected control transfers," which cause the processor to switch rol transfers," which cause the processor to switch from user to kernel mode (CPL=0) without giving tfrom user to kernel mode (CPL=0) without giving the user-mode code any opportunity to interfere withe user-mode code any opportunity to interfere with the functioning of the kernel or other environmeh the functioning of the kernel or other environments. In Intel's terminology, an nts. In Intel's terminology, an interruptinterrupt is a protect is a protected control transfer that is caused by an ed control transfer that is caused by an asynchronasynchronousous event usually external to the processor, such as event usually external to the processor, such as notification of external device I/O activity. An notification of external device I/O activity. An exceexceptionption, in contrast, is a protected control transfer ca, in contrast, is a protected control transfer caused used synchronouslysynchronously by the currently running code, by the currently running code, for example due to a divide by zero or an invalid m for example due to a divide by zero or an invalid memory access. emory access.

ExceptionException在在 i386i386中与中与 traptrap是一个意思,但中文翻译是一个意思,但中文翻译的时候往往翻译成异常或陷阱,其实也是一个意思的时候往往翻译成异常或陷阱,其实也是一个意思

中断是一些异步事件(如中断是一些异步事件(如 I/OI/O或程序的系统调用)或程序的系统调用)

Page 12: 第五章,抢占式调度 (lab3)

中断、系统调用(续)中断、系统调用(续) i386i386的异常或中断处理过程的异常或中断处理过程

异常或中断的设计是为了实现从用户态到核态的转换,同异常或中断的设计是为了实现从用户态到核态的转换,同时实现对特权级代码的保护时实现对特权级代码的保护

i386i386采用两个机制来实现这一目标:采用两个机制来实现这一目标: IDTIDT和和 TSSTSS IDT(Interrupt Descriptor Table)IDT(Interrupt Descriptor Table) 制定了制定了 256256个中断入个中断入口,其中前口,其中前 3232个用于异常个用于异常 (traps(traps或或 exceptions)exceptions),后面,后面的的 ((中断号中断号 >31)>31)用于异步中断用于异步中断 (interrupts)(interrupts)的处理。的处理。

用户程序在运行过程中产生异常或者中断后,需要将产生用户程序在运行过程中产生异常或者中断后,需要将产生中断的地方存储起来,以便在处理完中断后返回,可是存中断的地方存储起来,以便在处理完中断后返回,可是存在什么地方呢?这里就要用到在什么地方呢?这里就要用到 TSS(Task State Segment)TSS(Task State Segment)

Page 13: 第五章,抢占式调度 (lab3)

中断、系统调用(续)中断、系统调用(续) TSSTSS的作用与发生中断后堆栈的构成的作用与发生中断后堆栈的构成

本来本来 IntelIntel 设计设计 TSSTSS的初衷是想通过这个段,来实现的初衷是想通过这个段,来实现操作系统中多任务的切换操作系统中多任务的切换

但使用这个切换任务,会占用很多但使用这个切换任务,会占用很多 CPUCPU的时间,并且的时间,并且打破打破 CPUCPU的流水。因而,的流水。因而, LinuxLinux和和WindowsWindows 都没有都没有采用采用 TSSTSS用作切换任务用作切换任务

TSSTSS记录着“记录着“ I/OI/O权限位图”。另外权限位图”。另外 TSSTSS中还记录着中还记录着0-20-2环的环的 espesp和和 ssss寄存器。当外环寄存器。当外环 ((如如 ring3)ring3)进入内进入内环环 ((如如 ring0)ring0)时,会自动加载时,会自动加载 TSSTSS中内环的中内环的 espesp和和 ssss。。那为什么那为什么 tsstss没有记录没有记录 ring3ring3 的的 espesp和和 ssss呢?这是因呢?这是因为,外环进入内环时,会将这些压入堆栈。当从内环为,外环进入内环时,会将这些压入堆栈。当从内环返回外环时,从堆栈中恢复就可以了返回外环时,从堆栈中恢复就可以了

Page 14: 第五章,抢占式调度 (lab3)

中断、系统调用(续)中断、系统调用(续) TSSTSS 的结构的结构

其中最重要的是其中最重要的是 espesp和和 ssss

当从当从 ring 3ring 3到到 ring 0ring 0的的过程中,会将断点通过过程中,会将断点通过压栈存储到压栈存储到 ssss和和 espesp指指向的堆栈空间向的堆栈空间

I/O Map Base Address

GS

FS

DS

SS

LDT Segment Selector

CS

ES

T

EDI

ESI

EBP

ESP

EBX

EDX

ECX

EAX

EFLAGS

EIP

CR3

SS2

ESP2

SS1

ESP1

SS0

ESP0

Previous Task Link

Reserved

Page 15: 第五章,抢占式调度 (lab3)

中断、系统调用(续)中断、系统调用(续) 通过通过 TSSTSS进行特权级进行特权级转换并压栈后的内核转换并压栈后的内核堆栈结构堆栈结构

注:这些压栈动作都注:这些压栈动作都由由 CPUCPU自动完成,不自动完成,不需要写代码来实现需要写代码来实现

完成这些动作后,完成这些动作后, CPCPUU会根据发生中断的会根据发生中断的中断号到中断号到 IDTIDT中寻找中寻找对应的中断处理函数,对应的中断处理函数,跳转过去执行跳转过去执行

+----------------------+ KSTACKTOP | 0x00000 old SS | " – 4 | old ESP | " – 8

| old EFLAGS | " – 12 | 0x00000 | old CS | " – 16

| old EIP | " - 20 <---- ESP +----------------------+

+--------------------+ KSTACKTOP | 0x00000 old SS | " – 4 | old ESP | " – 8

| old EFLAGS | " - 12 | 0x00000 | old CS | " – 16 | old EIP | " – 20

| error code | " - 24 <---- ESP +----------------------+

压入信息之后的内核堆栈结构

带 error code的内核堆栈结构

Page 16: 第五章,抢占式调度 (lab3)

中断、系统调用(续)中断、系统调用(续) JOSJOS系统中断过程的控制流系统中断过程的控制流

…………

CPU

&Handler1

IDT

&Handler2

&Handler3

&Handler4

……

&HandlerX

中断向量

Handler1

Trapentry.s Trap.c

HandlerX

Handler2

Trap()

Trap_dispatch()

Process

…………

Page 17: 第五章,抢占式调度 (lab3)

中断、系统调用(续)中断、系统调用(续) 中断函数的建立中断函数的建立

在在 kern/trapentry.Skern/trapentry.S中建中建立各个中断处理函数的原型立各个中断处理函数的原型

调用调用 TRAPHANDLERTRAPHANDLER和和TRAPHANDLER_NOECTRAPHANDLER_NOEC宏,并将创建的函数原型宏,并将创建的函数原型 eexternxtern 到到 trap.ctrap.c

在在 idt_initidt_init 函数中初始化函数中初始化 IIDTDT

注意注意 SETGATESETGATE宏的使用宏的使用

Vector

0

1

2

3

4

5

6

7

8

9

Description

Divide Error

Debug Exception

NMI Interrupt

Breakpoint

Overflow

Bound Check

Illegal Opcode

Device Not available

Double Fault

Reserved

Type

Fault

Fault/Trap

Interrupt

Trap

Trap

Fault

Fault

Fault

Abort

ErrorCode

No

No

No

No

No

No

No

No

Yes

10

11

12

13

14

15

16

17

18

19

Invalid TSS

Segment Not Present

Stack Exception

General Protection Fault

Page Fault

Reserved

Floating Point Error

Alignment Check

Machine Check

Simd Floating Point Error

Fault

Fault

Fault

Fault

Fault

Fault

Fault

Abort

Fault

Yes

Yes

Yes

Yes

Yes

No

Yes

No

No

Page 18: 第五章,抢占式调度 (lab3)

中断、系统调用(续)中断、系统调用(续) _alltrap_alltrap

首先注意调用首先注意调用 _alltrap_alltrap 的方式是的方式是 jjmp _alltrapsmp _alltraps 而不是而不是 call _alltracall _alltrapsps!这意味着调用!这意味着调用 _alltraps_alltraps之之前不需要将前不需要将 _alltraps_alltraps之后的指令之后的指令cs:eipcs:eip压栈压栈

在进入在进入 _alltraps_alltraps后,(系统)堆后,(系统)堆栈的组成:栈的组成:

接下来的工作,是要将堆栈组织接下来的工作,是要将堆栈组织成一个成一个 TrapframeTrapframe 结构,并将栈结构,并将栈顶指针顶指针 espesp压栈,做为参数传递压栈,做为参数传递给给 trap(struct Trapframe *tf)trap(struct Trapframe *tf) 函函数数

这里要注意这里要注意 struct Trapframestruct Trapframe 的的构成,应该压栈哪些才能组成一构成,应该压栈哪些才能组成一个个 TrapframeTrapframe 结构?结构?

KSTACKTOP0x0000 old SS -4

old ESP -8

old EFLAGS -12

0x0000 old CS -16

old EIP -20

Error code(或者0) -24

Num(由TRAPHANDLER定义的函数写入)

-28esp

Page 19: 第五章,抢占式调度 (lab3)

中断、系统调用(续)中断、系统调用(续) 思考思考

1. 1. 系统采用系统采用 i386i386提供的提供的 TSSTSS机制顺利地从机制顺利地从 riring3ng3转换到转换到 ring0ring0,但是如何在处理完中断后,但是如何在处理完中断后从从 ring0ring0回到回到 ring3ring3呢?呢?

2. 2. 系统如何保证从系统如何保证从 ring0ring0回到回到 ring3ring3后,仍然后,仍然能够继续用户环境的执行?能够继续用户环境的执行?

Page 20: 第五章,抢占式调度 (lab3)

中断、系统调用(续)中断、系统调用(续) 缺页错误和断点中断缺页错误和断点中断

改变中断处理流程,根据中断产生时的中断号改变中断处理流程,根据中断产生时的中断号进行相应的处理流程进行相应的处理流程

修改修改 trap_dispatchtrap_dispatch 系统调用系统调用

相应中断号:相应中断号: T_SYSCALLT_SYSCALL(( 0x30, 480x30, 48)) 从从 lib/syscall.c lib/syscall.c 到到 kern/syscall.ckern/syscall.c的调用路的调用路径径

注意参数的传递注意参数的传递

Page 21: 第五章,抢占式调度 (lab3)

本章结束