用户空间和内核空间是隔离的
切换内核态和用户态为什么要内存复制?
问题 | 描述 |
---|---|
安全性 | 用户程序可能传入非法地址,导致内核崩溃或被利用攻击 |
稳定性 | 用户程序可能在 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 从运行普通用户代码(权限受限)切换到执行内核代码(最高权限)的过程,常常发生在系统调用、异常、硬件中断时。