逐帧分析系统调用
系统调用的基本概念
Linux内核提供了一组用来实现各种系统功能的API函数,这就称为系统调用。系统调用除了将底层接口(例如驱动)的实现包装了起来,还能做到权限控制以及保护。试想一下,假设现在任意程序都能绕开系统调用直接操纵底层接口,例如能绕开页表向任意的物理内存地址写入或者读取数据,那么进程之间的数据隔离也就无法做到了,严重一点地说整个系统内核都能被任意进程破坏,也就没有秩序可言。
为了解决这个问题,现代操作系统一般都在硬件级(也就是CPU)支持指令集权限控制,例如Intel的x86指令集处理器就提供了4个等级的状态:ring0-ring3,CPU在某一时刻可能处于这4个状态的其中一个,在ring0状态下,CPU能够调用所有指令,而在ring3状态下,CPU仅能调用基本的运算指令。
而为什么操作系统能占据Ring0状态,而进程无法进入Ring0状态呢,这就要从系统启动过程说起了。
系统启动过程分析
计算机从上电开始是如何一步步从硬盘加载操作系统的,这篇文章讲得已经很清楚了。在Bootloader执行之后,位于/boot目录下的Linux内核会被加载到内存并执行,这个过程又分为两步:第一步是在实模式下执行boot/setup.bin,这一步主要也是执行一些初始化的操作和硬件的检查工作;第二步是在保护模式下执行boot/vmlinux.bin,在这个过程中会初始化页表、开启分页机制,最终会跳转到start_kernel()函数,到此为止内核便加载成功了。之后会执行/sbin/init,这便是Linux系统中的第一个进程。
上面提到了实模式和保护模式,下面就来解释一下。实模式指的就是实地址模式,顾名思义,实模式是将整个物理内存看成分段的区域,程序代码和数据位于不同区域,系统程序和用户程序没有区别对待,而且每一个指针都是指向"实在"的物理地址。而保护模式保护的就是物理内存的访问,通过段式内存管理或者页式内存管理将请求的内存地址映射到实际的物理地址,而段表或页表只有系统内核才有权限修改,从而通过这种方式实现了内存访问的控制。
计算机的外设都会通过各种方式挂载在系统总线上的,具体来说,挂载的设备在CPU上能对应上一些物理内存地址,而通过读写这些内存地址就能达到控制外设(网卡、声卡)或者读写外设(磁盘)的目的。在实现了对物理内存访问控制之后,便能够限制普通进程操纵这些设备。
在进入保护模式之后,进程所能够寻址的地址就全都由内核通过页表来控制了。
进程启动过程分析
上面一节解释了为什么用户的进程无法访问实际的物理地址,接下来就要介绍一下为什么进程无法运行ring0权限下的指令。
在Linux中能通过fork()或者exec()函数创建一个进程。以exec函数族为例,其中一个声明是这样的:int execv(const char *path, char *const argv[]);,它会把第一个参数路径对应的可执行文件(例如ELF)加载到内存,紧接着执行分配资源(例如页表)、拷贝环境变量和命令行参数、将此进程加入进程调度队列开始调度和执行,至此大致的进程启动过程便结束了。
那么有一个问题,Linux内核将时间片分配给这个进程并将CPU交给此进程来使用,那么在此进程的时间片耗尽或者需要重新调度的时候,Linux内核是如何重新获得CPU的使用权的呢。
在内核加载的过程中,所有的中断向量表对应的地址都会被写入Linux内核的相应的处理函数的基址。简单一点来说,只需要定义一个硬件定时器(这个由CPU的硬件实现),并将这个定时器的中断向量注册为Linux的相应处理函数,那么时间一到,CPU会自动打断当前正在运行的代码,并将PC指向定时器的中断向量,此时Linux内核便重新获取到了CPU的使用权。
到了这一步就能解释为什么操作系统能占据ring0状态,而普通进程无法进入ring0状态了。原因很简单,Linux在将CPU使用权交给进程之前,主动从ring0退到ring3,这个过程是不可逆的,因而普通进程执行的全过程都是在ring3下的。而在定时器中断或者其他硬件中断被捕获到的时候,CPU会恢复到ring0,而此时CPU的控制权又已经在Linux内核手中了,所以在一般情况下普通进程是无法得到ring0权限的。
系统调用过程
虽然普通进程无法在ring0权限下操纵底层设备或者执行命令,但是很多情况下往往也是需要和设备进行交互的(例如读写磁盘),因而系统调用应运而生。
下面来分析一个简单的系统调用过程,考虑一段最简单的系统调用代码:
#include <unistd.h>
int main()
{
char* message = "Hello, World!";
write(1, message, 13);
return 0;
}
write的第一个参数代表stdout,这个程序会在屏幕上打印出字符串message。如前面所说,普通进程是无法操纵底层设备的,那么毫无疑问,write中执行了系统调用,Linux内核帮我们完成了将字符串输出到屏幕的这个过程。来看一下write函数在32bit下的汇编实现:
#include <sys/linux-syscalls.h>
.text
.type write, @function
.globl write
.align 4
write:
pushl %ebx
pushl %ecx
pushl %edx
mov 16(%esp), %ebx
mov 20(%esp), %ecx
mov 24(%esp), %edx
movl $__NR_write, %eax
int $0x80
cmpl $-129, %eax
jb 1f
negl %eax
pushl %eax
call __set_errno
addl $4, %esp
orl $-1, %eax
1:
popl %edx
popl %ecx
popl %ebx
ret
可以很清楚的看到,在将参数保存到寄存器后,write函数调用了int指令产生了一个软件触发的硬件中断。此时如上面所说,CPU的控制权将在此交接给Linux内核,并执行Linux相应的中断处理函数。中断处理函数只需读取eax寄存器,就能够知道是要执行哪个系统调用(此处为__NR_write),内核根据这个交给不同的系统调用去处理。处理完毕后内核将执行调度,并降低运行权限,再将CPU运行权交给下一个就绪的进程。
(注:在64bit模式下,系统调用不再使用int指令,转而使用syscall指令)
标签: 无标签
已有 22 条评论
2024年12月01日
《青春海滩2》喜剧片高清在线免费观看:https://www.jgz518.com/xingkong/95414.html
回复
2024年12月06日
《我的野蛮女友》韩国剧高清在线免费观看:https://www.jgz518.com/xingkong/140830.html
回复
2024年12月16日
《青春海滩2》喜剧片高清在线免费观看:https://www.jgz518.com/xingkong/95414.html
回复
2024年12月26日
《乐高忍者:旋风术大师第三季》欧美动漫高清在线免费观看:https://www.jgz518.com/xingkong/164425.html
回复
1月6日
哈哈哈,写的太好了https://www.lawjida.com/
回复
2月28日
部分语句稍显冗长,可精简以增强节奏感。
回复
2月28日
情感真挚自然,字里行间传递出强烈的感染力。
回复
3月1日
文章紧扣主题,观点鲜明,展现出深刻的思考维度。
回复
3月1日
建议多用口语化表达,拉近与读者距离。
回复
3月2日
韵律感强烈,朗读时如音乐流淌。
回复
3月2日
学术术语使用精准,专业性突出。
回复
3月2日
?金句式评语?
回复
3月2日
建议引入反面案例,增强辩证性。
回复
3月2日
立意高远,以小见大,引发读者对社会/人性的深层共鸣。
回复
3月2日
每一个段落都紧密相连,逻辑清晰,展现了作者高超的写作技巧。
回复
3月2日
文章结构紧凑,层次分明,逻辑严密,让人一读即懂。
回复
3月4日
立意高远,以小见大,引发读者对社会/人性的深层共鸣。
回复
3月4日
文章中的实用建议和操作指南,让读者受益匪浅,值得珍藏。
回复
3月4日
文字流畅如丝,语言优美动人,读来令人心旷神怡。
回复
10月6日
新车即将上线 真正的项目,期待你的参与coinsrore.com
回复
10月7日
2025年10月新盘 做第一批吃螃蟹的人coinsrore.com
新车新盘 嘎嘎稳 嘎嘎靠谱coinsrore.com
新车首发,新的一年,只带想赚米的人coinsrore.com
新盘 上车集合 留下 我要发发 立马进裙coinsrore.com
做了几十年的项目 我总结了最好的一个盘(纯干货)coinsrore.com
新车上路,只带前10个人coinsrore.com
新盘首开 新盘首开 征召客户!!!coinsrore.com
新项目准备上线,寻找志同道合 的合作伙伴coinsrore.com
新车即将上线 真正的项目,期待你的参与coinsrore.com
新盘新项目,不再等待,现在就是最佳上车机会!coinsrore.com
新盘新盘 这个月刚上新盘 新车第一个吃螃蟹!coinsrore.com
回复
10月7日
2025年10月新盘 做第一批吃螃蟹的人coinsrore.com
新车新盘 嘎嘎稳 嘎嘎靠谱coinsrore.com
新车首发,新的一年,只带想赚米的人coinsrore.com
新盘 上车集合 留下 我要发发 立马进裙coinsrore.com
做了几十年的项目 我总结了最好的一个盘(纯干货)coinsrore.com
新车上路,只带前10个人coinsrore.com
新盘首开 新盘首开 征召客户!!!coinsrore.com
新项目准备上线,寻找志同道合 的合作伙伴coinsrore.com
新车即将上线 真正的项目,期待你的参与coinsrore.com
新盘新项目,不再等待,现在就是最佳上车机会!coinsrore.com
新盘新盘 这个月刚上新盘 新车第一个吃螃蟹!coinsrore.com
回复