x01.os.11: IPC 路线图

学习的最好方法就是看代码,所以我们不妨跟着 IPC 的调用路线图,来学习学习 IPC。

x01.Lab.Download 下载代码后,首先进入 main.c 文件,在 TestA 中,有这么一句:Print("<Ticks:%x>", GetTicksIPC()); 其中,GetTicksIPC 就是通过 IPC 获取时间 tick 数。进入 GetTicksIPC,会看到如下代码:

1     m.type = M_GetTicks;
2     _SendReceive(M_Both, T_IPC, &m);
3     return m.M_RetValue;    

_SendReceive 是对 syscall.s 文件中的 SendReceive 封装。调用 SendReceive 会产生一个中断而进入 SysSendReceive(在 proc.c 文件中)。顾名思义,SysSendReceive 根据消息类型,进行相应处理。现在有个问题,就是消息不止一种,每种又不止一个,处理这么多消息,需要有个生生不息的发动机。这个发动机,就是 IPC 任务,进入 ipc.c 文件,可看到如下代码:

 1 #include "kstd.h"
 2
 3 void TaskIPC() {
 4     Message    msg;
 5     while (1) {
 6         _SendReceive(M_Receive, T_Any, &msg);
 7         int src = msg.source;
 8         switch (msg.type) {
 9         case M_GetTicks:
10             msg.M_RetValue = g_Ticks;
11             _SendReceive(M_Send, src, &msg);
12             break;
13         default:
14             Panic("Unknown message type!");
15             break;
16         }
17     }
18 }

这一下就明白了,原来,在 TaskIPC 中,先接收所有的消息,再根据消息的类型进行处理,处理后的结果由 _SendReceive 发送出去。这同微软的消息处理机制如出一辙。

TaskIPC 在任务表中,由 Schedule 进行调用。而 Schedule 则由时钟中断周而复始的调用之。生生不息的机制原来在此!

由终端进入工程目录,makebochs,可看到效果图如下:

看来,我们的 IPC 机制,已然发挥作用了。

不过,说实话,这套消息机制,看起来优雅,但多了几次调用,效率是大打折扣的。从设计看优雅,从实际看却不理想。二者不可兼得,还是要从实际出发。也难怪 Linux 要舍弃这套近乎完美的消息处理机制,而采用宏内核了。

时间: 2024-10-13 22:38:51

x01.os.11: IPC 路线图的相关文章

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

时间都去哪儿了 老帕的“花儿为什么这样红”,三分钟引起六次欢呼,却败给了张碧晨.试想一下,如果是人气更高的陈冰,即使唱得和张碧晨一模一样,可能仍然不敌老帕,为什么张碧晨就能取胜呢?有这么个笑话:一人弹琴无人听,但一老妇人听得却潸然泪下.原来她的亡夫是弹棉花的!这虽是个笑话,却一语道破玄机.歌声动人,除了唱功,还有感情因素在里面.假如老帕的”花儿为什么这样红“是 1 分, 那么,张碧晨的父女情为 1 分, ”时间都去哪儿了“为 1 分.2 : 1, 张碧晨胜出也就理所当然了. shell 的实现

x01.os.1: BIOS 中断

这只是一点准备工作.为了显示字符串,需要调用中断:int  0x10 (AH=0x13).具体参数设置,参考我的归纳整理如下: INT 10 (AH = 0) -----------------功能:设置显示方式调用参数:    AL = 00:40 * 25 黑白方式         01:40 * 25 彩色方式         02:80 * 25 黑白方式         03:80 * 25 彩色方式         04:320 * 200 彩色图形方式         05:320

x01.os.13: 文件系统

停了两天电,忽然得空闲.找来破吉他,已然不成弦.           丁丁当当敲,敲到电来到.为把时间捡,熬夜三四点. 从我的置顶随笔 x01.Lab.Download 中下载 x01.os.12.tar.gz, 解压后由终端进入 os 目录,输入 bochs  命令即可见到如下界面: 注意下面的四行,分别是 open,write, read, unlink 文件.调用代码如下: 1 void TestA() { 2 int fd, n; 3 char path[] = "/test"

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

傻子一样的等 昨日出差,办完事后,下午 2:30,准备进长途汽车站买票回家,被一人拦住,说可以带我进去,车马上就要开了,买票来不及.我以为是汽车司机,就跟了进去.进去后,他打了个电话,说 3:30 车才到,让我先把票买了.我把钱给他,他拿了个代客车票的单子,写了几个字给我,说上车时再换票,然后就走了.人已走,车没来,我拿着写了字的纸,感觉像傻子一样的等.3:30,车来了,我凭那张纸,顺利的上了车.是为记. 保护模式 实模式采取 segemnt:offset 的方式,表示 20 位的内存地址.保护

x01.os.8: 加载内核

在 x01.os.7 中,借助 freedos,学习了保护模式.但操作系统必须完成引导:boot, 加载内核:loader,kernel,进而管理process,memory,file等. 引导比较简单,开机启动时,CPU 采取硬的方式,直接把 BIOS 载入内存某处运行.这就是电脑启动时按 DEL 键可以看到的画面.此时,无硬盘可以,无内存则不可以.BIOS 是一个只读芯片,但我认为它仍有可写的部分,否则,启动盘设置的保存,就说不通.BIOS 退出时,它会检测启动盘 0 扇区的最后两个字节,是

x01.os.9: 进程切换

进入内核后,当然不能无所事事.先创建三个进程,分别打印 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;

x01.os.19: compile linux-0.11 on the ubuntu

为什么学习 linux 正如不能依靠美国的 GPS 为我们的导弹指示目标一样,很难想像用运行 windows 的电脑去同美国进行信息战.而朝鲜的网络崩溃,再次警示国人,信息战.网络战离我们并不遥远.linux 的开源,可以按自己的要求进行深度定制,无疑是极佳选择. 为什么是 linux-0.11 现在的 linux-3.18,近千万行代码,即使是 linus,也没有全部看完,更不用说拿来学习了.而 linux-0.11,只有万余行代码,拿来学习,从量上是正好. 进入 linux-3.18/arc

x01.os.18: MBR

硬盘不同于软盘,它是要分区的.这时,mbr(master boot record)便不可少了.安装 os 硬盘的第一扇区,开始有一小段不多于 446 字节的程序,然后是分区表 512-446-2 字节,然后是引导标志 0xAA55 两字节.这一小段程序,便是 mbr 的主体.mbr 首先将其自身复制到 0x0600 处,代码如下: ; 0x7C00 => 0x0600 mov si, sp push si mov di, 0x0600 mov cx, 0x200 cld rep movsw 这是

x01.os.19: linux 0.0

linux 0.0 是一个丢失的版本,但赵炯老师又在 linux 0.11 的基础上,使它起死回生.www.oldlinux.org 有大量资源可供下载,值得一看. 1.要编译运行,首先需安装:sudo apt-get install bin86,取其 as86,ld86 也. 2.makefile 有两点要注意,一是 ld  的入口为 0,二是使用 objcopy 对 head 进行转换拷贝. 3.代码可到我的置顶随笔 x01.lab.download 中下载 x01.los.0.tar.gz