操作系统开发系列—13.g.操作系统的系统调用 ●
在我们的操作系统中,已经存在的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.操作系统的系统调用 ●的更多相关文章
- 操作系统开发系列—13.i.进程调度 ●
上面的三个进程都是延迟相同的时间,让我们修改一下,尝试让它们延迟不同的时间. void TestA() { int i = 0; while (1) { disp_str("A." ...
- 操作系统开发系列—13.h.延时操作
计数器的工作原理是这样的:它有一个输入频率,在PC上是1193180HZ.在每一个时钟周期(CLK cycle),计数器值会减1,当减到0时,就会触发一个输出.由于计数器是16位的,所以最大值是655 ...
- 操作系统开发系列—13.e.三进程
我们再来添加一个任务,首先添加一个进程体: void TestC() { int i = 0x2000; while(1){ disp_str("C"); disp_int(i++ ...
- 操作系统开发系列—13.d.多进程 ●
进程此时不仅是在运行而已,它可以随时被中断,可以在中断处理程序完成之后被恢复.进程此时已经有了两种状态:运行和睡眠.我们已经具备了处理多个进程的能力,只需要让其中一个进程处在运行态,其余进程处在睡眠态 ...
- 操作系统开发系列—13.c.进程之中断重入
现在又出现了另外一个的问题,在中断处理过程中是否应该允许下一个中断发生? 让我们修改一下代码,以便让系统可以在时钟中断的处理过程中接受下一个时钟中断.这听起来不是个很好的主意,但是可以借此来做个试验. ...
- 操作系统开发系列—13.b.进程之丰富中断处理程序
首先打开时钟中断: out_byte(INT_M_CTLMASK, 0xFE); // Master 8259, OCW1. out_byte(INT_S_CTLMASK, 0xFF); // Sla ...
- 操作系统开发系列—13.a.进程 ●
进程的切换及调度等内容是和保护模式的相关技术紧密相连的,这些代码量可能并不多,但却至关重要. 我们需要一个数据结构记录一个进程的状态,在进程要被挂起的时候,进程信息就被写入这个数据结构,等到进程重新启 ...
- 操作系统开发系列—12.g.在内核中设置键盘中断
8259A虽然已经设置完成,但是我们还没有真正开始使用它呢. 所有的中断都会触发一个函数spurious_irq(),这个函数的定义如下: PUBLIC void spurious_irq(int i ...
- 微信公众号开发系列-13、基于RDIFramework.NET框架整合微信开发应用效果展示
1.前言 通过前面一系列文章的学习,我们对微信公众号开发已经有了一个比较深入和全面的了解. 微信公众号开发为企业解决那些问题呢? 我们经常看到微信公众号定制开发.微信公众平台定制开发,都不知道这些能给 ...
随机推荐
- Redis持久化方法对比分析
1.前言 最近在项目中使用到Redis做缓存,方便多个业务进程之间共享数据.由于Redis的数据都存放在内存中,如果没有配置持久化,redis重启后数据就全丢失了,于是需要开启redis的持久化功能, ...
- c语言读取字符在记事本中出现次数
程序使用说明: 此程序可以统计出名称为1.txt的文件中/出现的次数 但是仅支持单个英文字母和标点符号查询,不支持汉字. 在本程序生成的exe根目录下放一个1.txt, 即可查询出该字符在1.txt记 ...
- chrome dev debug network 的timeline说明
在使用chrome的时候F12的开发者工具中有个network,其中对每个请求有个timeline的说明,当鼠标放上去会有下面的显示: 这里面的几个指标在说明在chrome使用文档有说明: 下面我用人 ...
- .NET的EF框架中:在应用程序配置文件中找不到名为“”的连接字符串问题
今天在使用EF Code First框架时,当把模型都定义好了,想通过程序包管理控制台利用enable-migrations –force来生成数据库表的时候报错了,如下: 找不到连接字符串,但是我仔 ...
- JavaScript基础—dom,事件
Js基础-DOM 1:dom:文档对象模型 Dom就是html页面的模型,将每个标签都作为一个对象,js通过调用dom中的属性,方法就可以对网页中的文本框,层等元素进行编程控制.Dom就是一些让jav ...
- Dispose() C# 优化内存
public void Dispose() { ((IDisposable)_designer).Dispose(); } #region IDisposable Support private bo ...
- WPF DataGrid绑定及列居中
基本的数据绑定 把集合的字段(属性)绑定在DataGrid的Binding属性就能将数据绑定列表 public class CashItem { public int Value { get; set ...
- MongoDB在实际项目中的使用
MongoDB简介 MongoDB是近些年来流行起来的NoSql的代表,和传统数据库最大的区别是支持文档型数据库. 当然,现在的一些数据库通过自定义复合类型,可变长数组等手段也可以模拟文档型数据库. ...
- 使用MongoDB作为后台数据库的尝试
MongoDB作为一个阶层型数据库,在很短的时间里面是不可能被大面积推广使用的, 本文作为一个实验性的课题,探讨一下MongoDB作为网站数据库的可能性. 1.MongoDB作为代替关系型数据库的可能 ...
- Ado.net[增删改查,GET传值]
1. <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Home.aspx.c ...