操作系统的边界在哪里

操作系统的边界在哪里

引言

哪里是操作系统?

Linux Kernel 的维护者说,提供Syscall的是操作系统。

汇编爱好者说,提供系统调用库函数的下面的是操作系统。

ArchLinux佳豪说,上面这些加上一些Terminal,一些Network Manager,和一个Pacman,就是操作系统。

Ubuntu用户说,这个桌面和内置的小软件以下是操作系统。

余承东说鸿蒙是操作系统。

正在许愿Vibe coding的文科生说,deepseek帮我复刻一些windowsxp。

操作系统的上面。

在内存中心呼唤系统的自陷

要找到操作系统的上边界,让我们深入所谓用户软件和操作系统在书上所定义的,发生切换的一瞬间。

目态与管态

要理解为什么会有“切换的瞬间”,就要知道为什么需要这么做,他们在切换什么。

另外的一组名字叫做用户态内核态,原因很简单,互联网上的软件千千万万,良莠不齐,需要给内核操作和用户操作彻底隔离开(不只是在两种状态,后面会提到)。包括系统指令的地址空间都是用户不可达的,需要让用户软件不触及操作系统的正常允许。

你也不想qq崩溃直接给系统拉闸了吧。

但是那些系统方法总得用吧,不能用户程序啥也不做,所以需要用一种特殊的方式来切换系统模式

系统调用

对于一般的程序员,能够碰到最下面的地方就是库函数,这里我们以c语言举例。

比如write()方法,write(fd, buf, count)

  1. 传递参数

首先这几个参数(标识符,写入内容地址头,长度)会被重写为汇编能识别的参数,然后调用write函数

mov     edx, 5
lea     rsi, [rip + hello]
mov     edi, 1
call    write

注意这下面的call是正常汇编的调用函数,此时PC的值改为call+指令长+偏移指向write函数开头。

返回地址(RSP)压入用户栈。此时我们的参数们还在刚才塞进去的寄存器里面。

  1. 执行系统调用

此时执行系统调用(ABI)前,必须填写以下的规范化系统调用参数,这个过程具体有点太具体了,远远超过了408会考察的范围,总之会把刚才的参数传递进去。

RAX = 系统调用号

RDI = 参数1
RSI = 参数2
RDX = 参数3
R10 = 参数4
R8  = 参数5
R9  = 参数6

在这一堆参数传递完毕后,终于到了那传说中操作系统的边界

syscall
  1. 硬件隐指令

首先硬件会自动关中断,保存现场(原始PSW),给原函数syscall的地址入栈(RCX=syscall地址+指令长)。

值得注意的是这个地方新旧系统并不一样,64位系统通常用MSR寄存器直接表明syscall的各种内核入口内存地址,但是32位老系统(也就是408)参考书上的农逼系统一般是通过中断向量寻址,查询IDT(中断描述符表)和中断向量号来寻找syscall的入口地址。考试建议假装是后者。

这个过程纯自动,然后开中断。

然后切换CPU模式,把CPL从3(用户)改为0(内核)。

  1. 取得参数

因为刚才已经往寄存器传递了参数,所以内核可以从寄存器取得这些参数的值。

  1. 内核函数真正执行

这个时候内核函数才开始真正执行write函数实际的内容,这里就不细讲了,和主题没啥关系。

  1. 恢复现场,返回用户态

此时把栈顶的保护现场的PC值出栈,PSW写回原来的样子,需要传回的参数也写入寄存器传回。

然后执行

sysretq

此时回到原始程序syscall的下一条位置。

之后从write函数的ret地址跳回write下一个指令位置,这个过程结束。

408辩经

值得注意的,考过的,这些系统调用的库函数并不是操作系统的边界,是他们的最后一行执行的syscall(农逼老电脑可能是INT)会切换到内核态执行系统调用。

操作系统的下面

硬件和OS的冒险 Episode00

相比上一个问题,这个问题就变得没有答案了,因为OS的底层和硬件深度耦合,不太可能清楚地分开。

我们用上面那个write的瞬间举例子

回到syscall发生的那一瞬间。

硬件隐指令

在syscall之后,硬件而非os开始接管。

切换内核态,关中断,保存寄存器,保存现场,压栈地址,跳到内核syscall开始的地方,这些步骤就是硬件自己执行的,在这之后才是OS执行的地方。

配置与自动

OS与硬件更多的是一种配置和自动执行的关系。

页表

比如所谓的内存管理。首先是操作系统来建立了你所见到的树上的页表,告诉了硬件虚实地址的映射关系,这就是配置

之后每次访存OS直接传递的就是虚拟地址而非物理地址,此时查表,地址转换都是硬件自动执行,但是,但是,如果缺页错误,将会调回操作系统执行缺页处理程序。

进程调度

又比如所谓调度过程,本质上并不是CPU自己知道什么时候该调度什么进程,相反的。

是OS通过定时器中断给CPU打入内核态,然后执行调度器,这个时候才决定要不要切换上下文,切换进程。

硬件中断

当外部控制器(I/O中断)发出中断的一瞬间,CPU停止当前程序,保存现场,找到中断向量表的入口,进入内核态,之后OS接入,执行USB驱动程序(或者别的什么驱动程序),驱动程序再来处理这个外部中断具体内容。

总结

不难发现OS对于上层的边界是非常非常清晰的,但是和硬件是揉在一起的。

但是这是假象,操作系统这个词语的边界在2026年绝对不是所谓syscall的一瞬间。