[No000036]操作系统Operating Systems系统调用的实现System_Call
实现一个whoami 系统调用
系统调用的直观实现 问题+直观想法…
用户程序调用whoami, 一个字符串"systemcall "放在操作系统中(系统引导时载入) ,取出来打印,有什么问题?
- 不能随意的调用数据,不能随意的jmp 。
- 可以看到root 密码,可以修改它…
- 可以通过显存看到别人word 里的内容…
地址: |
main() { whoami();} |
用户程序 |
。。。 |
whoami() { printf(100, 8); } |
内核,都在内存中,这内存不都是我买的吗… |
100: |
"systemcall" |
内核( 用户) 态,内核( 用户)
将内核程序和用户程序 隔离!!!
区分 内核态和用户态 :一种处理器"硬件设计"
- 内核态可以访问任何数据,用户态不能访问内核数据
- 对于指令跳转也一样实现了隔离…
硬件提供了"主动进入内核的方法"
对于Intel x86 ,那就是中断指令int
- int 指令将使CS 中的CPL 改成0 ,"进入内核"(此时,CPL=3 而DPL=0)
- 这是用户程序发起的调用内核代码的唯一方式
- 系统调用的核心:
(1) 用户程序 中包含一段包含int 指令 的代码
(2) 操作系统 写 中断处理 ,获取想调程序的编号
(3) 操作系统 根据编号执行相应代码
系统调用的实现
最终展开成包含int 指令的代码…
#include <unistd.h> _syscall3(int, write, int, fd, const char *buf, off_t, count) |
在linux/lib/write.c 中 |
#define _syscall3(type, name, ...) type name(...) \ { __asm__ ("int 0x80" :"=a"(__res)...} |
在linux/include/unistd.h 中 |
Linux 系统调用的实现细节!
将关于write 的故事完整的讲完…
在linux/include/unistd.h中 _syscall3 表示有3 个参数
#define _syscall3(type,name,atype,a,btype,b,ctype,c)\
type name(atype a, btype b, ctype c) \
{ long __res;\
__asm__ volatile("int 0x80":"=a"(__res):""(__NR_##name),
"b"((long)(a)),"c"((long)(b)),"d"((long)(c)))); if(__res>=0) return
(type)__res; errno=-__res; return -1;}
显然,__NR_write 是系统调用号,放在eax 中
在linux/include/unistd.h 中
#define __NR_write 4 // 一堆连续正整数( 数组下标,函数表索引)
同时eax 也存放返回值,ebx ,ecx ,edx 存放3 个参数
int 0x80 中断的处理
void sched_init(void)
{ set_system_gate(0x80,&system_call); }
显然,set_system_gate 用来设置0x80
在linux/include/asm/system.h 中
#define set_system_gate(n, addr) \
_set_gate(&idt[n],15,3,addr); //idt 是中断向量表基址
#define _set_gate(gate_addr, type, dpl, addr)\
__asm__("movw %%dx,%%ax\n\t" "movw %0,%%dx\n\t"\
"movl %%eax,%1\n\t" "movl %%edx,%2":\
:"i"((short)(0x8000+(dpl<<13)+type<<8))),"o"(*(( \
char*)(gate_addr))),"o"(*(4+(char*)(gate_addr))),\
"d"((char*)(addr),"a"(0x00080000))
中断处理程序: system_call
在linux/kernel/system_call.s
nr_system_calls=72
.globl _system_call
_system_call: cmpl $nr_system_calls-1,%eax //eax 中存放的是系统调用号
ja bad_sys_call
push %ds push %es push %fs
pushl %edx pushl %ecx pushl %ebx // 调用的参数
movl $0x10,%edx mov %dx,%ds mov %dx,%es // 内核数据
movl $0x17,%edx mov %dx,%fs //fs 可以找到用户数据
call _sys_call_table(,%eax,4) //a(,%eax,4)=a+4*eax
pushl %eax // 返回值压栈,留着ret_from_sys_call 时用
... // 其他代码
ret_from_sys_call: popl %eax, 其他pop, iret
_sys_call_table+4*%eax 就是相应系统调用处理函数入口
_sys_call_table
call _sys_call_table(,%eax,4) 就是call sys_write // eax=4 ,函数入口地址长度也为4
[No000036]操作系统Operating Systems系统调用的实现System_Call的更多相关文章
- [No00003D]操作系统Operating Systems信号量的代码实现Coding Semaphore &死锁处理Deadlock
操作系统Operating Systems信号量的代码实现Coding Semaphore &死锁处理Deadlock 可以操刀了—从纸上到实际 从Linux 0.11 那里学点东西… 读磁盘 ...
- [No00003A]操作系统Operating Systems 内核级线程Kernel Threads内核级线程实现Create KernelThreads
开始核心级线程 内核级线程对多核的支持怎么样? 和用户级相比,核心级线程有什么不同? ThreadCreate 是系统调用,内核管理TCB ,内核负责切换线程 如何让切换成型? − − 内核栈,TCB ...
- [No00003C]操作系统Operating Systems进程同步与信号量Processes Synchronization and Semaphore
操作系统Operating Systems进程同步与信号量Processes Synchronization and Semaphore 进程合作:多进程共同完成一个任务 从纸上到实际:生产者− − ...
- [No000037]操作系统Operating Systems操作系统历史与硬件概况History of OS & Summaries!
培根:读史使人明智 操作系统的简史 (1955-1965) 计算机非常昂贵,上古神机IBM7094 ,造价在250万美元以上 计算机使用原则:只专注于计算 批处理操作系统(Batch system) ...
- [No000039]操作系统Operating Systems用户级线程User Threads
多进程是操作系统的基本图像 是否可以资源不动而切换指令序列? 进程 = 资源 + 指令执行序列 线程: 保留了并发的优点,避免了进程切换代价 实质就是映射表不变而PC 指针变 多个执行序列+ 一个地址 ...
- [No000038]操作系统Operating Systems -CPU
管理CPU ,先要使用CPU… CPU 的工作原理 CPU上电以后发生了什么? 自动的取指 — 执行 CPU 怎么工作? CPU怎么管理? 管理CPU 的最直观方法 设好PC 初值就完事! 看看这样做 ...
- [No000031]操作系统 Operating Systems 之Open the OS!
从打开电源开始… 这神秘的黑色背后发生着什么?… 打开电源,计算机执行的第一句指令什么? 计算模型(图灵机) ⇒ 我们要 关注 指针IP 及其 指向的内容 看看x86 PC (1) 刚开机时CPU 处 ...
- Modern Operating Systems(Ⅰ)——2014.12.15
进程 进程模型 进程就是一个正在执行的程序的实例 值得注意的是,若一个程序运行了两遍,则算作两个进程 创建进程 在通用系统中,有四种主要事件导致进程的创建 ①系统的初始化 ②执行了 正在 ...
- Operating Systems (COMP2006)
Operating Systems (COMP2006) 1st Semester 2019Page 1, CRICOS Number: 00301JOperating Systems (COMP20 ...
随机推荐
- arcgis破解的时候,不能启动license manager的问题
1.防火墙没关:(非常重要) 2.win+R,调出控制台,输入services.msc.然后手动开启ArcGIS license manager服务,关闭其余类似erdas,matlab影响该服务的开 ...
- VMware虚拟机无法访问外网
1.环境条件 2.VMware检查 3.虚拟机检查 1) vi /etc/sysconfig/network ----------------------------- NETWORKING=yes ...
- Convert.ChangeType不能处理Nullable类型的解决办法
在做一个ORMapping功能的时候发现,Convert.ChangeType不能处理nullable类型,比如int?. 解决办法也很简单,贴出完整的代码(大部分代码来自网络),注意下面代码没经过完 ...
- spring理解
Struts与Hibernate可以做什么事? Struts,Mvc中控制层解决方案,可以进行请求数据自动封装.类型转换.文件上传.效验… Hibernate,持久层的解决方案:可以做到,把对象保存到 ...
- Android项目实战(二十三):仿QQ设置App全局字体大小
一.项目需求: 因为产品对象用于中老年人,所以产品设计添加了APP全局字体调整大小功能. 这里仿做QQ设置字体大小的功能. QQ实现的效果是,滚动下面的seekbar,当只有seekbar到达某一个刻 ...
- Android NDK之JNI陷阱
背景: 最近一个月一直在做移植库的工作,将c代码到share library移植到Android平台.这就涉及到Android NDK(native develop kit)内容.这里只想记录下JNI ...
- Android 内容提供者的实现
接着上文<Android 内容提供者简介>进一步实现内容提供者. 每个Content Provider类都使用URI(Universal Resource Identifier,通用资源标 ...
- android环境搭建
Android开发环境的两种安装方式:JDK+Eclipse+ADT直接下载集成的开发工具,解压即可用.下载地址:http://pan.baidu.com/s/1dD3s3bN ,不管采用哪种安装方式 ...
- 转:查看sql语句执行时间/测试sql语句性能
原文出处:http://www.cnblogs.com/qanholas/archive/2011/05/06/2038543.html 写程序的人,往往需要分析所写的SQL语句是否已经优化过了,服务 ...
- 让shell脚本在后台飞
1. 使用&符号在后台执行命令 你可以在Linux命令或者脚本后面增加&符号,从而使命令或脚本在后台执行,例如:. $ ./my-shell-script.sh & 2. 使用 ...