在我们的操作系统中,已经存在的3个进程是运行在ring1上的,它们已经不能任意地使用某些指令,不能访问某些权限更高的内存区域,但如果一项任务需要这些使用指令或者内存区域时,只能通过系统调用来实现,它是应用程序和操作系统之间的桥梁。

所以,一件事情就可能是应用程序做一部分,操作系统做一部分。这样,问题就又涉及特权级变换。

很明显,这已经难不倒我们了,因为进程的切换就是不停地在重复这么一个特权级变换的过程。在那里,触发变换的是外部中断,我们把这个诱因换一下就可以了,变成"int nnn",一切就都解决了。

我们来实现一个叫做int get_ticks()的函数,用这个函数来得到当前总共发生了多少次时钟中断。设置一个全局变量ticks,每发生一次时钟中断,它就加1,进程可以随时通过get_ticks()这个系统调用来得到这个值。

见syscall.asm:

_NR_get_ticks       equ 0 ; 要跟 global.c 中 sys_call_table 的定义相对应!
INT_VECTOR_SYS_CALL equ 0x90 global get_ticks ; 导出符号 bits 32
[section .text] get_ticks:
mov eax, _NR_get_ticks
int INT_VECTOR_SYS_CALL
ret

这里将系统调用对应的中断号设为0x90,它只要不和原来的中断号重复即可。

马上来定义INT_VECTOR_SYS_CALL对应的中断门,protect.c:

PUBLIC void init_prot()
{
...
init_idt_desc(INT_VECTOR_SYS_CALL, DA_386IGate,
sys_call, PRIVILEGE_USER);
...
}

这样我们就将第INT_VECTOR_SYS_CALL号中断与sys_call对应起来了。这里的call [sys_call_table+eax*4](调用的是sys_call_table[eax]),与irq_table类似,sys_call_table是一个函数指针数组,每一个成员都指向一个函数,用以处理相应的系统调用。

extern	sys_call_table

global sys_call

sys_call:
call save sti call [sys_call_table + eax * 4]
mov [esi + EAXREG - P_STACKBASE], eax cli ret

前面eax已被赋值为_NR_get_ticks(即0),而sys_call_table[0]已经初始化为sys_get_ticks,所以call [sys_call_table+eax*4]这一句调用的便是sys_get_ticks。

mov [esi+EAXREG-P_STACKBASE],eax是把函数sys_call_table[eax]的返回值放在进程表中eax的位置,以便进程P被恢复执行时eax中装的是正确的返回值。

现在可以在进程中添加调用get_ticks的代码了:

void TestA()
{
int i = 0;
while (1) {
get_ticks();
disp_str("A");
disp_int(i++);
disp_str(".");
delay(1);
}
}

别忘了在kernel.asm和syscall.asm中导入和导出相应符号。

修改

void TestA()
{
int i = 0;
while (1) {
disp_str("A");
disp_int(get_ticks());
disp_str(".");
delay(1);
}
}

运行如下,第一个是A0x0,第二个是A0x27,两次之间的“#”恰好是39个,我们的get_ticks一切正常:

源码

操作系统开发系列—13.g.操作系统的系统调用 ●的更多相关文章

  1. 操作系统开发系列—13.i.进程调度 ●

    上面的三个进程都是延迟相同的时间,让我们修改一下,尝试让它们延迟不同的时间. void TestA() { int i = 0; while (1) { disp_str("A." ...

  2. 操作系统开发系列—13.h.延时操作

    计数器的工作原理是这样的:它有一个输入频率,在PC上是1193180HZ.在每一个时钟周期(CLK cycle),计数器值会减1,当减到0时,就会触发一个输出.由于计数器是16位的,所以最大值是655 ...

  3. 操作系统开发系列—13.e.三进程

    我们再来添加一个任务,首先添加一个进程体: void TestC() { int i = 0x2000; while(1){ disp_str("C"); disp_int(i++ ...

  4. 操作系统开发系列—13.d.多进程 ●

    进程此时不仅是在运行而已,它可以随时被中断,可以在中断处理程序完成之后被恢复.进程此时已经有了两种状态:运行和睡眠.我们已经具备了处理多个进程的能力,只需要让其中一个进程处在运行态,其余进程处在睡眠态 ...

  5. 操作系统开发系列—13.c.进程之中断重入

    现在又出现了另外一个的问题,在中断处理过程中是否应该允许下一个中断发生? 让我们修改一下代码,以便让系统可以在时钟中断的处理过程中接受下一个时钟中断.这听起来不是个很好的主意,但是可以借此来做个试验. ...

  6. 操作系统开发系列—13.b.进程之丰富中断处理程序

    首先打开时钟中断: out_byte(INT_M_CTLMASK, 0xFE); // Master 8259, OCW1. out_byte(INT_S_CTLMASK, 0xFF); // Sla ...

  7. 操作系统开发系列—13.a.进程 ●

    进程的切换及调度等内容是和保护模式的相关技术紧密相连的,这些代码量可能并不多,但却至关重要. 我们需要一个数据结构记录一个进程的状态,在进程要被挂起的时候,进程信息就被写入这个数据结构,等到进程重新启 ...

  8. 操作系统开发系列—12.g.在内核中设置键盘中断

    8259A虽然已经设置完成,但是我们还没有真正开始使用它呢. 所有的中断都会触发一个函数spurious_irq(),这个函数的定义如下: PUBLIC void spurious_irq(int i ...

  9. 微信公众号开发系列-13、基于RDIFramework.NET框架整合微信开发应用效果展示

    1.前言 通过前面一系列文章的学习,我们对微信公众号开发已经有了一个比较深入和全面的了解. 微信公众号开发为企业解决那些问题呢? 我们经常看到微信公众号定制开发.微信公众平台定制开发,都不知道这些能给 ...

随机推荐

  1. Windows Azure Web Site (8) 设置Web Site时区

    <Windows Azure Platform 系列文章目录> 许多已经使用Azure Web Site的用户已经发现了,Azure Web Site默认的系统时间是UTC时区. 比如我们 ...

  2. 【模式匹配】更快的Boyer-Moore算法

    1. 引言 前一篇中介绍了字符串KMP算法,其利用失配时已匹配的字符信息,以确定下一次匹配时模式串的起始位置.本文所要介绍的Boyer-Moore算法是一种比KMP更快的字符串匹配算法,它到底是怎么快 ...

  3. GitHub一代:我们都是开源控

    我们是新的GitHub一代?GitHub塑造了新式开源文化?嗯,看看十几年开源控.Getable CTO Mikeal Rogers 是怎么说的吧: GitHub本来想做一个开源软件协作平台,结果做着 ...

  4. iOS平台快速发布HT for Web拓扑图应用

    iOS平台一直是封闭的生态圈,iOS开发者要缴纳年费加入开发者计划才可进行iOS平台的APP开发测试,所开发的APP需要上传到App Store经过苹果审核以后才可对外发布.如果要开发企业内部应用,则 ...

  5. 关于WEB Service&WCF&WebApi实现身份验证之WEB Service篇

    在这个WEB API横行的时代,讲WEB Service技术却实显得有些过时了,过时的技术并不代表无用武之地,有些地方也还是可以继续用他的,我之所以会讲解WEB Service,源于我最近面试时被问到 ...

  6. SQL Server获取下一个编码字符实现继续重构与增强

        我在SQL Server获取下一个编码字符实现的博文中,虽然实现了这个问题,但是感觉维护起来比较麻烦,例如如果调整编码字符串的固定长度,就需要变更三个函数,这样的为何成本确实比较大.面向对象编 ...

  7. Html5离线缓存详细讲解

    离线缓存是Html5新特性之一,简单理解就是第一次加载后将数据缓存,在没有清除缓存前提下,下一次没有网络也可以加载,用在静态数据的网页或游戏比较好用.当然,Html5新的特性都不是所有浏览器都能支持的 ...

  8. 解决MVC EF Code First错误:Model compatibility cannot be checked because the EdmMetadata type was not included in the model.

    Model compatibility cannot be checked because the EdmMetadata type was not included in the model. En ...

  9. LeetCode - Balanced Binary Tree

    题目: Given a binary tree, determine if it is height-balanced. For this problem, a height-balanced bin ...

  10. 【转】NoSQL初探之人人都爱Redis:(2)Redis API与常用数据类型简介

    一.Redis API For .Net 首先,不得不说Redis官方提供了众多的API开发包,但是目前Redis官方版本不支持.Net直接进行连接,需要使用一些第三方的开源类库.目前最流行的就是Se ...