用户态和内核态是操作系统的两种运行状态。
内核态:处于内核态的 CPU 可以访问任意的数据,包括外围设备,比如网卡、硬盘等,处于内核态的 CPU 可以从一个程序切换到另外一个程序,并且占用 CPU 不会发生抢占情况,一般处于特权级 0 的状态我们称之为内核态。
用户态:处于用户态的 CPU 只能受限的访问内存,并且不允许访问外围设备,用户态下的 CPU 不允许独占,也就是说 CPU 能够被其他程序获取。
那么为什么要有用户态和内核态呢?
这个主要是访问能力的限制的考量,计算机中有一些比较危险的操作,比如设置时钟、内存清理,这些都需要在内核态下完成,如果随意进行危险操作,极容易导致系统崩坏。
Linux的init进程(内核态到用户态的变化)
init进程,也就是内核启动3个进程中的进程1;
init进程完成了从内核态向用户态的转变;
(1)init进程是比较特殊,一个进程两个状态,init刚开始运行时是内核态,他属于内核线程,然后他自己运行了一个用户态下面的程序后,他自己强行转成了用户态,因为init进程自身完成了从内核态到用户态的过渡,因此后续的其他进程都可以工作在用户态下面的。
(2)init在内核态做了什么? 重点就是做了一件事情,就是挂载跟文件系统并试图找到用户态下的那个init程序。要运行这个应用程序就必须找到这个程序,要找到他就必须得挂载根文件系统,因为所有的应用程序都在文件系统中。
(3)init用户态做了什么?init大部分有意义的工作是在用户态下进行的,init进程对我们操作系统的意义在于其他所有的用户进程都直接或者间接派生来自init进程。说白了,init进程生了后面的所有进程。
(4)init进程如何从内核态跳转到用户态?还能回来不?
init进程在内核态下面时,通过一个函数kernel_execve来执行一个用户空间编译连接的应用程序,就跳跃到用户态了。需要注意的是:这个跳跃后进程号是不改变的,一直是进程1.
这个跳跃过程是单向的,一旦执行了init程序转到用户态下就回不来了。用户态下想进入内核态只有走API这一条路了。