30天自制操作系统日志第15天_第1页
30天自制操作系统日志第15天_第2页
30天自制操作系统日志第15天_第3页
30天自制操作系统日志第15天_第4页
30天自制操作系统日志第15天_第5页
全文预览已结束

下载本文档

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

文档简介

1、操作系统实验日志学号姓名甘昆禄专业年级班级智能1601实验日期2018.01.02实验项目第15、16天:多任务一、实验主要内容终于等到第十五天-多进程的实现,在30天自制操作系统中介绍了多任务的实现,在此理清一下思路。1.首先一个很重要的概念:在我们平常windows系统上我们可以同时做很多事(下载,听音乐,看视频等),如果电脑是单核(一个CPU),那么这些事并不是这个CPU在同时在做,而是CPU使用了一种障眼法(其实不是CPU使用的,而是我们写的程序使用了障眼法,我们写的程序让CPU以一个极短的时间轮流执行着这些事,极短的时间让肉眼看不见)。CPU在每个时刻只能执行一件事。2.那么写多进程

2、的思路是什么?首先我们先执行两个进程(不讨论多进程),进程其实也就是一段可执行的程序,这段程序要在内存中才能执行,那么放在内存的什么地方呢?CPU又是怎么找到这段程序呢?从这开始下手:在32位的保护模式下,我们通过 段选择子+全局描述符表 进行内存的寻址(非常好的文章介绍内存寻址的文章/qq/article/details/)那么我们就要在全局描述符表中选择一段来写入我们即将执行的进程的首地址。#define ADR_GDT 0x /全局描述符表的开始位置#define AR_TSS32 0x0089struct SEGMENT_DESCRIPTOR *g

3、dt=(struct SEGMENT_DESCRIPTOR *) ADR_GDT;set_segmdesc(gdt+3,103,(int) &tss_a,AR_TSS32);/第一个进程,这个地方gdt+3其实是bootpack.c的程序的位置set_segmdesc(gdt+4,103,(int) &tss_b,AR_TSS32);/这个是第二个进程,tss_a和tss_b可以先想成程序地址 通过这个设置,就将这两个进程的位置设置好,那么CPU执行进程二的时候,先到GDT表中找到位置,如果执行指令 JMP FAR0:3*8(CS置0,EIP置为3*8,那么段基址+段内偏移=0+&tss_b)

4、,那么CPU会找到程序的位置&tss_b。CPU也是同样找到进程一的地址,那么至此程序的地址找到了。如果这样想就错了为什么错了?仔细想想如果进程一执行到一半,找到进程二的地址,切到进程二去执行了,那么再切回到进程一,凭什么CPU就知道到执行上次进程一切换的地方接着执行呢?那么这就涉及到上面写入全局描述符表里的tss_a和tss_b了,这两个并不是进程的入口地址,而是为了切换进程时保存当前进程的所有进程的状态的。 TSS 全称为task state segment,是指在操作系统进程管理的过程中,进程切换时的任务现场信息。下面是网上的资料:X86体系从硬件上支持任务间的切换。为此目的,它增设了一

5、个新段:任务状态段(TSS),它和数据段、代码段一样也是一种段,记录了任务的状态信息。 与其它段一样,TSS也有描述它的结构:TSS描述符表,它记录了一个TSS的信息,同时还有一个TR寄存器,它指向当前任务的TSS。任务切换的时候,CPU会将原寄存器的内容写出到相应的TSS,同时将新TSS的内容填到寄存器中,这样就实现了任务的切换。TSS在任务切换过程中起着重要作用,通过它实现任务的挂起和恢复。所谓任务切换是指挂起当前正在执行的任务,恢复或启动执行另一个任务。Linux任务切换是通过switch_to这个宏来实现的,它利用长跳指令,当长跳指令的操作数是TSS描述符的时候,就会引起CPU的任务的

6、切换,此时,CPU将所有寄存器的状态保存到当前任务寄存器TR所指向的TSS段中,然后利用长跳指令的操作数(TSS描述符)找到新任务的TSS段,并将其中的内容填写到各个寄存器中,最后,将新任务的TSS选择符更新到TR中。这样系统就开始运行新切换的任务了。由此可见,通过在TSS中保存任务现场各寄存器状态的完整映象,实现了任务的切换。 task_struct中的tss成员就是记录TSS段内容的。当进程被切换前,该进程用tss_struct保存处理器的所有寄存器的当前值。当进程重新执行时,CPU利用tss恢复寄存器状态。上面提到的TR寄存器是用来记住当前正在运行的任务,当任务切换时,TR的值会自动变化

7、。我们可以通过LTR汇编指令来向TR寄存器写入值。 TSS的结构:struct TSS32int backlink,esp0,ss0,esp1,ss1,esp2,ss2,cr3;int eip,eflags,eax,ecx,edx,ebx,esp,ebp,esi,edi;int es,cs,ss,ds,fs,gs;int ldtr,iomap;设置到全局描述符中的tss_a和tss_b还没有初始化。因为上述的进程一其实就是第一个开始的进程,因此tss_a在切换的时候会自动保存数据到tss_a,因此不用初始化;现在对tss_b进行初始化,tss_b_esp=(int) memman_alloc_

8、4k(memman,64*1024)+64*1024-8;tss.esp=task_b_esp;tss.eip=(int) &task_b_main;tss.cs=2*8;tss.ds=1*8;tss.ss=1*8;tss.gs=1*8;tss.fs=1*8;tss.es=1*8;重点是esp,eip和cs寄存器,因为这几个寄存器关乎到程序的执行,因为第二个进程的代码写在bootpack.c中,二bootpack.c的代码段是在GDT中的第三段,因此CS为2*8,段内偏移就是进程二的地址&task_b_main。这样就会切换到第二个进程执行了。那么前面说的CPU会以极短的时间来轮流执行这些进程

9、,这个结合定时器实现的,每个进程运行到定时器的一定时间,就自动切换到其他进程,这样每个进程执行一段时间。16天:任务自动化:要实现任务切换的自动化。最好能够有一个任务数组,每次定时器timeout就切换到下一个,这样就不用写很复杂的taskswitch()了。 首先执行task_init(),这里创建TASKCTL结构,为task数组的每一个TASK在段表中注册。最后设置当前的任务,也就是把调用task_init()函数的这个程序变成一个任务。之后便可进行任务切换了。 task_run()只是将任务加入running列表,真正的运行是在task_switch()切换到该任务时。让任务休眠如果任

10、务主要是IO操作,没有IO的时候没事干,这时可以让它休眠。当IO中断时再把它叫醒。休眠的方法是将任务从running列表中删除,需要唤醒时再次task_run()即可。 task_sleep():将指定的task移出running列表。如果要sleep的任务是当前正在执行的任务(taskctl-now),则立刻进行切换。具体的做法是: 1. 为FIFO结构添加task成员变量,表示当这个FIFO来数据时,唤醒哪一个task。 2. 在fifo32_put()中,当有数据来时,判断task是否处于休眠,是则调用task_run()。 3. 在主程序for循环中,判断fifo的状态。如果fifo中

11、没有数据则让task休眠。实现任务的优先级之前的任务切换都是以0.02秒为固定间隔。要实现优先级,则应该能够以不同的时间间隔切换。为TASK结构添加priority成员变量。可以在task_init()中设置,也可以在task_run()中改变。在task_switch()中,通过timer_settime(),根据task的priority来设置定时器的timeout值,从而改变任务切换的间隔。除了时间长短不同,不同优先级的执行顺序也应该不一样。在这里使用了多级队列。处在高级队列中的全部任务休眠或降级时,低级队列才有机会执行。新增TASKLEVEL结构,每个结构包含一个TASK指针数组。在T

12、ASKCTL结构中加入一个TASKLEVEL结构的数组,保存所有TASK结构的数组只在TASKCTL中有一个。这样形成多级任务队列。添加task_add(),task_remove()函数,方便任务在多级间的移动。添加task_switchsub()函数,用于改变level。为实现多级队列,还是改了挺多地方。总的来说,首先将处理鼠标键盘的任务A放在LEVEL0(高优先级),其他任务放在LEVEL1。如果任务A休眠了,则LEVEL0空了,task_sleep()就会调用task_switchsub(),找到一个有任务的level。如果任务A要唤醒了,则task_run()会改变lv_change值,提醒切换任务时切换到更高级level中。二、遇到

温馨提示

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

评论

0/150

提交评论