0%

用户态和内核态

用户空间和内核空间是隔离的

切换内核态和用户态为什么要内存复制?

问题 描述
安全性 用户程序可能传入非法地址,导致内核崩溃或被利用攻击
稳定性 用户程序可能在 poll() 返回前修改数组,导致内核读取不一致
内存管理 用户空间内存可能被 swap 出或者释放,内核无法保证访问有效

内核态

我们在说“切换到内核态”时,其实指的是 CPU 特权级别从用户态(ring3)切换到内核态(ring0) 的过程。

用户态 vs 内核态

用户态(user mode)

应用程序(比如你写的 C++ 程序)运行的环境。

权限受限,不能直接操作硬件(如磁盘、网卡),也不能随便访问内核内存。

只能通过 系统调用 (syscall) 向内核请求服务。

内核态(kernel mode)

操作系统内核运行的环境。

拥有最高权限(ring0),可以操作 CPU 指令集、内存管理、驱动、硬件寄存器。

系统调用的实现代码就在内核态里。

“切换到内核态”的过程

当你调用一个系统调用,比如:

read(fd, buf, size);

你的程序在 用户态,调用 read()。

实际上 read() 会触发一条特殊指令(例如 Linux x86-64 用 syscall 指令)。

CPU 捕捉到这个指令,自动:

从用户态切换到内核态。

切换到内核栈。

保存用户态寄存器上下文。

跳到系统调用处理函数(比如 sys_read)。

内核态代码执行 sys_read,比如访问文件系统、检查 socket buffer。

处理完后返回,CPU 再切回用户态,恢复上下文,继续执行应用代码。

🔹 为什么要区分用户态/内核态?

安全:用户程序不能直接操作硬件。

稳定性:即使用户程序崩溃,内核和其他进程不会受影响。

性能隔离:内核提供抽象(系统调用接口),避免应用直接干扰底层资源。

✅ 所以,总结一句:
“切换到内核态”就是 CPU 从运行普通用户代码(权限受限)切换到执行内核代码(最高权限)的过程,常常发生在系统调用、异常、硬件中断时。