实验五:分析system_call中断处理过程
2016-03-23 16:56
639 查看
将上一个系统调用函数和asm版本的实现整合进入menu的内核中:
int GetPid()
{
int pid = getpid();
printf("The Current Progress pid is : %
d\n",pid);
return 0;
}
int GetPidAsm()
{
int pid;
asm volatile(
"mov $0,%%
ebx\n\t"
"mov $0x14,%%
eax\n\t"
"int $0x80\n\t"
"mov %%
eax,% 0\n\t"
: "=m" (pid)
);
printf("The Current Progress pid asm is : %
d\n",pid);
return 0;
}
int main()
{
PrintMenuOS();
SetPrompt("MenuOS>>");
MenuConfig("version","MenuOS V1.0(Based on Linux 3.18.6)",NULL);
MenuConfig("quit","Quit from MenuOS",Quit);
MenuConfig("time","Show System Time",Time);
MenuConfig("time-asm","Show System Time(asm)",TimeAsm);
MenuConfig("getpid","Show Current Progress id",GetPid);
MenuConfig("getpid-asm","Show Current Progress asm id",GetPidAsm);
ExecuteMenu();
}
上面的一段代码,MenuConfig这个函数是菜单(也就是制作出来的内核)的初始化配置函数,第一个参数是命令,第二个参数是该命令的描述,第三个参数是这个命令相对应的handler,也就是回调函数,是通过一个函数指针进行实现的。ExecuteMenu这个函数是为了启动这个menu引擎,其实是一个循环等待用户输入命令的过程。
将上周写的两个函数分别命名为int getuidc() int getuid_asm,将这两个函数写入test.c文件中:
![](https://oscdn.geek-share.com/Uploads/Images/Content/202010/16/634a6c80d7e7d90eb0a2ee55e8d9003e)
然后,修改main()函数中的配置命令,加入两个命令usrid和userid_asm,分别有函数getuidc和函数getuid_asm实现:
![](https://oscdn.geek-share.com/Uploads/Images/Content/202010/16/e33513c585c544fb1f3c1602e0e4c350)
通过make
rootfs脚本命令运行一下,可以看出通过userid命令和userid_asm命令都可以获取程序的用户id:
![](https://oscdn.geek-share.com/Uploads/Images/Content/202010/16/681fde6580fc05a0c7a42af1f8e11817)
下面,详细分析一下menu操作系统通过user命令和user_asm命令对系统内核服务的调用。在操作系统启动过程中,首先对系统调用进行初始化,系统调用实质上是一种中断,是通过\int\main.c
\start_kernel文件中的trap_int()函数声明的,trap_int()函数指向\arch\x86\kernel\traps.c文件中的set_system_trap_gate(SYSCALL_VECTOR,&system_call)函数,在这一过程中,通过参数SYS_CALL传递系统调用中断向量,&system_call是汇编代码入口。在本例的menu操作系统中,中断向量int 0x80指向系统调用system_call:
![](https://oscdn.geek-share.com/Uploads/Images/Content/202010/16/2ff5511ed401858ff85841fd04aa9933)
在如上流程中,system_exit:是系统调用结束前的进程切换模块,其代码如下:
syscall_exit_work:
系统调用完成后,通过汇编命令iret返回主程序,至此,系统调用实现任务并返回。
总之,系统调用作为一种中断处理过程,能够反映出一般的中断处理机制,对于一般的中断处理,同样是由四个主要步骤完成的,首先进入中断,保护好现场,第二步调用中断的服务程序,第三步,完成中断退出前的进程切换工作,第四步,返回主程序并恢复现场
int GetPid()
{
int pid = getpid();
printf("The Current Progress pid is : %
d\n",pid);
return 0;
}
int GetPidAsm()
{
int pid;
asm volatile(
"mov $0,%%
ebx\n\t"
"mov $0x14,%%
eax\n\t"
"int $0x80\n\t"
"mov %%
eax,% 0\n\t"
: "=m" (pid)
);
printf("The Current Progress pid asm is : %
d\n",pid);
return 0;
}
int main()
{
PrintMenuOS();
SetPrompt("MenuOS>>");
MenuConfig("version","MenuOS V1.0(Based on Linux 3.18.6)",NULL);
MenuConfig("quit","Quit from MenuOS",Quit);
MenuConfig("time","Show System Time",Time);
MenuConfig("time-asm","Show System Time(asm)",TimeAsm);
MenuConfig("getpid","Show Current Progress id",GetPid);
MenuConfig("getpid-asm","Show Current Progress asm id",GetPidAsm);
ExecuteMenu();
}
上面的一段代码,MenuConfig这个函数是菜单(也就是制作出来的内核)的初始化配置函数,第一个参数是命令,第二个参数是该命令的描述,第三个参数是这个命令相对应的handler,也就是回调函数,是通过一个函数指针进行实现的。ExecuteMenu这个函数是为了启动这个menu引擎,其实是一个循环等待用户输入命令的过程。
将上周写的两个函数分别命名为int getuidc() int getuid_asm,将这两个函数写入test.c文件中:
然后,修改main()函数中的配置命令,加入两个命令usrid和userid_asm,分别有函数getuidc和函数getuid_asm实现:
通过make
rootfs脚本命令运行一下,可以看出通过userid命令和userid_asm命令都可以获取程序的用户id:
下面,详细分析一下menu操作系统通过user命令和user_asm命令对系统内核服务的调用。在操作系统启动过程中,首先对系统调用进行初始化,系统调用实质上是一种中断,是通过\int\main.c
\start_kernel文件中的trap_int()函数声明的,trap_int()函数指向\arch\x86\kernel\traps.c文件中的set_system_trap_gate(SYSCALL_VECTOR,&system_call)函数,在这一过程中,通过参数SYS_CALL传递系统调用中断向量,&system_call是汇编代码入口。在本例的menu操作系统中,中断向量int 0x80指向系统调用system_call:
在如上流程中,system_exit:是系统调用结束前的进程切换模块,其代码如下:
syscall_exit_work:
testl $_TIF_WORK_SYSCALL_EXIT, %ecx jz work_pending TRACE_IRQS_ON ENABLE_INTERRUPTS(CLBR_ANY) # could let syscall_trace_leave() call # schedule() instead movl %esp, %eax call syscall_trace_leave jmp resume_userspace END(syscall_exit_work)
系统调用完成后,通过汇编命令iret返回主程序,至此,系统调用实现任务并返回。
总之,系统调用作为一种中断处理过程,能够反映出一般的中断处理机制,对于一般的中断处理,同样是由四个主要步骤完成的,首先进入中断,保护好现场,第二步调用中断的服务程序,第三步,完成中断退出前的进程切换工作,第四步,返回主程序并恢复现场
相关文章推荐
- spring mvc + mybaties+ mysql搭建--2016版
- NGUI之UILabel
- android——混淆打包
- python之 rabbitmq
- Linux内核分析——分析system_call中断处理过程
- 抽象类和接口
- 3月23日学习记录(showAsAction,android:orderInCategory="100")
- Java常见面试内容
- [AI](加入随机因素)局部搜索解决N皇后问题(含源码)
- 不完美的英雄也是英雄
- 利用Angular.js从PHP读取后台数据
- Cg入门18:Fragment shader - 边缘泛光和透明
- SQL join
- 【转】潜说js对象和数组
- AngularJs路由:ngRoute
- 【API设计风格—RESTful】:服务端如何编写RESTful风格的API(二)
- 【Android】【事件】onInterceptTouchEvent(),onTouchEvent()
- Java中的二进制基础
- NSDate使用,NSDateFormatter转换,及DatePicker
- kml和kmz简介