就拿 int 0x80 中断实现系统调用来说吧,Linux 内核版本 2.6.32 。中断门在 trap_init() 函数中初始化,set_system_trap_gate(SYSCALL_VECTOR, &system_call) (
https://elixir.bootlin.com/linux/v2.6.32/source/arch/x86/kernel/traps.c#L963 )。从这里可以看出,触发 0x80 号中断时会执行 system_call 函数。而 system_call 函数时定义在 /arch/x86/kernel/entry_64.S 中的汇编代码(
https://elixir.bootlin.com/linux/v2.6.32/source/arch/x86/kernel/entry_64.S#L455 )。看看这个函数就知道为了进入系统调用做了哪些操作。
再看看进程切换。进程切换发生在进程被调度的时候,由 context_switch() 函数实现。其中最关键的 switch_mm() 和 switch_to() 函数完成了主要的工作。
通过比较内核代码,你看看哪个简单,哪个麻烦。
不要觉得没人回答你的问题就是他们不懂。我开始看到你这个问题的时候就觉得你对一些基本的操作系统概念不熟悉,表述问题太多。如果不是为了复习一下以前的知识,我是不会回答你的问题的。其实请教问题的时候可以稍微虚心一点。
至于怎样学习操作系统,首先你对一些基本的概念了解的怎样?例如操作系统的目的、出现的原因,以及操作系统的基本组成部分,如进程管理和调度、内存管理、文件系统、进程间通信等等。然后每个组成部分的基本概念是否熟悉,例如对于进程管理来说,操作系统通过 PCB 来描述每个进程,等等。
基本概念了解之后,带着这些具体的疑问结合相关的书和文章去看内核源码。就拿这个问题来说,首先要了解系统调用的具体实现,先去 Google 一些文章,了解大致的实现。然后边读书边看源码去深入研究。同时用一些内核调试技术去亲手实践一下。