第15天 多任务(1)
2020.4.17
1. 挑战任务切换(harib12a)
-
多任务,就是进程管理。假如有多个CPU核心,多任务也就很简单了。这是面向单核处理器的操作系统,一个CPU,照样可以实现多任务。
-
一个CPU实现多任务,其实,这些程序根本没有在同时运行,只不过给人一种同时在运行的假象而已。。如下图:
看上去是在同时运行:程序A运行一会儿,程序B再运行一会儿,程序C再运行一会儿,然后再A运行……如此往复。 -
为了让人察觉不出来,OS需要尽快地切换任务。但是切换的太快也不行,这样的话,CPU的大部分算力都要被任务切换占用。
-
在一般的OS中,切换任务的频率是每0.01s~0.03s进行一次。切换的时间越短,对用户的友好性就越好。CPU进行任务切换所消耗的时间大约是0.0001s左右,不同的CPU时间不同。
- 如果CPU每0.0002s进行一次切换,那么CPU处理能力的50%都被任务切换占用。
- 如果CPU每0.001s进行一次切换,那么CPU处理能力的10%都被任务切换占用。
- 如果CPU每0.01s进行一次切换,那么CPU处理能力的1%被任务切换占用。
- 综上,10%和50%的算力被占用是我们不能允许的。因此,OS让CPU每0.01s进行任务切换。
- 显然,此时的进程切换方式是时间片轮转,时间片大小是0.01s。
-
CPU处理多任务的过程:
- 当OS向CPU发出任务切换的指令时,CPU会先把寄存器中的值全部写入内存,这样做是为了以后切换回这个任务的时候,可以从中断的地方继续运行。然后,为了运行下一个程序,CPU会把所有寄存器中的值从内存中读出来(这个读取的地址和刚刚写入的地址一定是不一样的),这样就完成了一次任务切换。任务切换的时间就是对内存进行写入和读取所消耗的时间,大约是0.0001s。
-
寄存器中的内容写入内存:
- 任务状态段(task status segment, TSS),TSS有16位和32位版本,使用32位版本。TSS是内存段的一种,需要在GDT中定义后才能使用。
- 结构体TSS:(暂时在bootpack.c中)
struct TSS32 { int 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共26个int成员,总计104字节。
- 第一行从backlink到cr3的共8个成员,保存的不是寄存器数据,而是与任务设置相关的信息。 在任务切换的时候,这些数据不会被写入内存(backlink有时会被写入)。后面会详细解释这8个成员。现在可以先忽略。
- 第二行是32位寄存器:
- EIP,指令指针寄存器
- EFlags,标志寄存器
- EAX,(通用)数据寄存器
- ECX,(通用)数据寄存器
- EDX,(通用)数据寄存器
- EBX,(通用)数据寄存器
- ESP,指针寄存器
- EBP,指针寄存器
- ESI,变址寄存器
- EDI,变址寄存器
- 第三行是16位段寄存器:
ES: 附加段寄存器(extra segment)
CS: 代码段寄存器(code segment)
SS: 栈段寄存器(stack segment)
DS: 数据段寄存器(data segment)
FS: 没有名称(segment part 2)
GS: 没有名称(segment part 3) - 寄存器详解:
https://blog.csdn.net/yun_ge/article/details/85158670 - EIP寄存器和JMP的小故事:
EIP:一直指向以一条指令所在的内存地址。
- 在TSS中将EIP记录下来,当返回这个任务的时候,CPU就知道应该从哪里继续运行了。
- 段寄存器是16位,在TSS中被设置成为了32位。(可能以后段寄存器会变成32位吧)
- 第四行的ldtr和iomap也是有关任务设置的,在任务切换时不会被CPU写入内存。 暂时,我们需要设定ldtr=0;iomap=0x40000000。
- TSS其实就是进程控制块(process control block,PCB),是进程存在的唯一标志。
-
JMP指令
- JMP指令有两种:
- 只改写EIP的称为near模式。
- 改写EIP和CS的称为far模式。 CS:代码段寄存器。
- 使用的大部分JMP指令都是near模式。在asmhead.nas中bootpack启动的最后一句:
这条指令向EIP存入0x0000001b的同时,将CS置为2*8(=16)。JMP目标地址中带冒号(:)的就是far模式的JMP指令。JMP DWORD 2*8:0x0000001b
- 如果一条JMP指令所制定的
- JMP指令有两种: