进入内核后,当然不能无所事事。先创建三个进程,分别打印 A,B,C。虽然只是简单的打印,但却是一切扩展的基础,不可等闲视之。

进程切换,涉及一系列的寄存器需要保护,于是,就有了 ProcessStack 结构,代码如下:

typedef struct {
u32 gs;
u32 fs;
u32 es;
u32 ds;
u32 edi;
u32 esi;
u32 ebp;
u32 KernelEsp;
u32 ebx;
u32 edx;
u32 ecx;
u32 eax;
u32 RetAddr;
u32 eip;
u32 cs;
u32 eflags;
u32 esp;
u32 ss;
} ProcessStack;

稍加注意,会发现有个 KernelEsp。它的作用,是防止进程切换时,栈指针乱指。

进程切换,当然离不开中断。有意思的是,涉及中断调用的任务状态栈 TSS 同 ProcessStack 竟有异曲同工之妙。

进程切换,还有一个关键,就是不能再用简单的 ret 来返回了。kernel.s 中的 save 代码如下:

save:
pushad
push ds
push es
push fs
push gs mov dx, ss
mov ds, dx
mov es, dx mov esi, esp
inc dword [g_IntReenter]
cmp dword [g_IntReenter],
jne .
mov esp, StackTop
push Restart
jmp [esi + P_RetAddr - P_StackBase]
.:
push reenter
jmp [esi + P_RetAddr - P_StackBase] Restart:
mov esp, [g_pProcReady]
lldt [esp + P_LdtSel]
lea esi, [esp + P_StackTop]
mov dword [g_Tss + TSS_ESP0], esi
reenter:
dec dword [g_IntReenter] pop gs
pop fs
pop es
pop ds
popad
add esp,
iretd

其中的 jmp  [esi + P_RetAddr - P_StackBase] ,就是跳到事先保存的返回地址。而这一返回地址,由 main.c 中的 KernelMain 设置。即 for 循环里的 pProc->Regs.esp = (u32)pTaskStack; 这种多兵种作战,需细心体会,方能领会之。

此关键点如能领会,进程切换就不是难事。所谓进程,不过在 ProcessStack 的基础上,添加一些进程 Id,name,优先级而已。

进入工程目录,make 后,再 bochs,即可看到如下界面:

其中,优先级的设置为 15:5:3, 同显示的基本一致。完整代码,可到 x01.Lab.Download 中下载。虚拟机及开发工具,可参看 x01.os.7

有个问题需说明一下。就是修改后重新 make 时,会出现 /mnt/temp 忙,可运行命令 sudo umount /mnt/temp 卸载之。

x01.os.9: 进程切换的更多相关文章

  1. x01.os.13: 文件系统

    停了两天电,忽然得空闲.找来破吉他,已然不成弦.           丁丁当当敲,敲到电来到.为把时间捡,熬夜三四点. 从我的置顶随笔 x01.Lab.Download 中下载 x01.os.12.t ...

  2. Python::OS 模块 -- 进程管理

    os模块的简介参看 Python::OS 模块 -- 简介 os模块的文件相关操作参看 Python::OS 模块 -- 文件和目录操作 os模块的进程参数 Python::OS 模块 -- 进程参数 ...

  3. 【原创】(三)Linux进程调度器-进程切换

    背景 Read the fucking source code! --By 鲁迅 A picture is worth a thousand words. --By 高尔基 说明: Kernel版本: ...

  4. linux0.11改进之四 基于内核栈的进程切换

    这是学习哈工大李治军在mooc课操作系统时做的实验记录.原实验报告在实验楼上.现转移到这里.备以后整理之用. 完整的实验代码见:实验楼代码 一.tss方式的进程切换 Linux0.11中默认使用的是硬 ...

  5. Linux内核分析——理解进程调度时机跟踪分析进程调度与进程切换的过程

    20135125陈智威 +原创作品转载请注明出处 +<Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 实验 ...

  6. Linux内核分析之理解进程调度时机跟踪分析进程调度与进程切换的过程

    一.原理分析 1.调度时机 背景不同类型的进程有不同的调度需求第一种分类I/O-bond:频繁的进行I/O:通常会花费很多时间等待I/O操作的完成CPU-bound:计算密集型:需要大量的CPU时间进 ...

  7. x01.os.14: 时间都去哪儿了

    时间都去哪儿了 老帕的“花儿为什么这样红”,三分钟引起六次欢呼,却败给了张碧晨.试想一下,如果是人气更高的陈冰,即使唱得和张碧晨一模一样,可能仍然不敌老帕,为什么张碧晨就能取胜呢?有这么个笑话:一人弹 ...

  8. x01.os.8: 加载内核

    在 x01.os.7 中,借助 freedos,学习了保护模式.但操作系统必须完成引导:boot, 加载内核:loader,kernel,进而管理process,memory,file等. 引导比较简 ...

  9. x01.os.7: 傻子一样的等

    傻子一样的等 昨日出差,办完事后,下午 2:30,准备进长途汽车站买票回家,被一人拦住,说可以带我进去,车马上就要开了,买票来不及.我以为是汽车司机,就跟了进去.进去后,他打了个电话,说 3:30 车 ...

随机推荐

  1. 2016年湖南省第十二届大学生计算机程序设计竞赛Problem A 2016 找规律归类

    Problem A: 2016 Time Limit: 5 Sec  Memory Limit: 128 MB Description  给出正整数 n 和 m,统计满足以下条件的正整数对 (a,b) ...

  2. 初识 PHPunit stub 模拟返回数据

    这是这段时间以来结合 PHPunit 文档和大牛们的讲解,想记录下自己学习到的知识,未来参考补充,完善学到的东西 我们一般使用单测对公司业务里的代码进行测试,他会帮忙找到你的一个个小小的思考不够全面的 ...

  3. Thinkphp各种方法知识图谱

    A方法:用于实例化控制器 ThinkPHP函数详解:A方法 B方法:执行某个行为 I方法(其命名来自于英文Input):获取输入参数 支持过滤和默认值 ThinkPHP函数详解:I方法 D方法:D函数 ...

  4. linux常用命令之压缩打包

    DF df – report file system disk space usage 查看文件系统的使用清空 用法 df [-hi] [path] 选项 -h human readable ,以人类 ...

  5. Framework7 – 赞!功能齐全的 iOS7 App 前端框架

    Framework7 是一个功能很全的 HTML 框架,用来构建 iOS7 应用程序. Framework7 允许您灵活搭建列表视图(表视图) .你可以让他们作为导航菜单,你可以在列表里面使用图标,输 ...

  6. babel 无法解析jsx (webpack react )

    webpack.config.js的配置如下图: 报错: 修改webpack.config.js文件,如下即可:

  7. js实现标准无缝滚动

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  8. 盒图(boxplot)

    最近在摆弄数据离散度的时候遇到一种图形,叫做盒图(boxplot).它对于显示数据的离散的分布情况效果不错. 盒图是在1977年由美国的统计学家约翰·图基(John Tukey)发明的.它由五个数值点 ...

  9. 在SSRS 里实现 SUMIF

    最近在做报表时,要实现Excel中的SUMIF的功能, 示例:SUMIF($B$2:$B$465,"East",$G$2:$G$465),即汇总B列值等于East的G列值. 在SS ...

  10. SharePoint 2013 JavaScript API 记录

    1.获取创建者字段(Author),oListItem为SPListItem对象 oListItem.get_item('Author')只能获取到对象,获取用户名要用oListItem.get_it ...