操作系统-5-内核级线程

  • 本系列博客为观看哈工大李治军老师的操作系统视频而做的整理总结。
  • 本文为第五篇,主要是内核级线程及编码实现
    关键词索引:
    多核、内核栈、用户态、内核态

一、内核级线程的引入

操作系统-5-内核级线程_第1张图片
多线程才能发挥多核的优势。 因为共用了一套资源。
多进程不能发挥优势。

操作系统-5-内核级线程_第2张图片

核心是实现两套栈 (用户栈+内核栈)

操作系统-5-内核级线程_第3张图片

操作系统-5-内核级线程_第4张图片
带着中断才能进入内核 int 0x80
操作系统-5-内核级线程_第5张图片
EFLAGS 中断返回标志
304 是IP 地址, 即中断后的返回地址。
cs是段基址。 此处为100。

操作系统-5-内核级线程_第6张图片

进了线程T ,执行一小段后要执行用户态的代码。
所以????应该是一段包含iret的代码,从中断返回到用户态

操作系统-5-内核级线程_第7张图片
操作系统-5-内核级线程_第8张图片

进入内核,通过TCB切换完成内核栈的切换,完成用户态的切换

操作系统-5-内核级线程_第9张图片
如果不是同一进程,还有内存地址映射表的切换
如果是同一进程,那就是线程
操作系统-5-内核级线程_第10张图片

操作系统-5-内核级线程_第11张图片

二、内核级线程的代码实现

操作系统-5-内核级线程_第12张图片
fork() 是创建资源的系统调用

操作系统-5-内核级线程_第13张图片
此处,先是用户态执行
函数A()发生调用,要在用户栈中保存恢复场景:
将A()返回后将要执行的函数入口地址压入栈中 A:ret=B
在A()中执行,遇到fork (),又发生了系统调用:
要转到系统调用,先要在内核栈中保存恢复场景:
操作系统-5-内核级线程_第14张图片
先在内核栈中将SS:SP关联用户栈 (用户栈的基址和指针偏移量,如箭头所示)
因为要调用中断,将中断标志位EFLAGS压入,以便处理完代码后完成中断返回
要执行中断处理函数,所以需将中断后的PC指针地址压入栈中
要用中断要发生system _call调用, 在这之前先将中断后的指令地址压入
即ret =?? 指针指向箭头所示。

接下来是0x80进内核:
操作系统-5-内核级线程_第15张图片
system_call 又是一系列压栈的过程
call sys_fork 过程中,看PCB控制块(记录进程信息的数据结构)中的进程状态,
看多进程图像一文中关于PCB的部分
判断是否需要发生调度。 阻塞或时间片用完均需要调度。 否则可以正常返回。
ret_from_sys_call
如果发生重新调度
首先是把返回地址入栈,然后跳转执行schedule ,完成中间的切换
操作系统-5-内核级线程_第16张图片
中间切换后相当于线程切换了。
_schedule 是C函数 ,当执行到 } ,函数返回后弹出 ret_from_sys_call ,开始中断出口部分:

操作系统-5-内核级线程_第17张图片
操作系统-5-内核级线程_第18张图片

操作系统-5-内核级线程_第19张图片
共用用户栈,但内核栈分开
操作系统-5-内核级线程_第20张图片
操作系统-5-内核级线程_第21张图片
中断返回后,父进程子进程都执行MOV res ,%eax

eax 非零时执行一段代码(父进程)
eax=0时执 行子进程的代码。 (子进程中将eax置0了,在填写栈的时候)

操作系统-5-内核级线程_第22张图片
操作系统-5-内核级线程_第23张图片

你可能感兴趣的:(#,操作系统)