进程是什么
单核系统上同一时间内,只有一个进程(进程A)在跑,该进程占用了
1.cpu的所有寄存器资源
2.cp15协处理器的所有寄存器资源
其他的进程都在内存中,也就是说 进程 B /进程 C 等 其实就是内存中的一组数据
那么这组数据是什么
这组数据 应该是 TCB
TCB 从上到下包括什么
1.pt_regs (18*4 B)
2.栈 8KB - 18*4 - (sizeof(thread_info)) - (sizeof(task_struct))
3.thread_info (sizeof(thread_info))=528B
4.task_struct (sizeof(task_struct))=1200B
TCB 有多大
8KB/即8192B
每个进程的 TCB 都不一样,差别就在这里
根据 idle 进程来解析
idle 进程只运行在内核空间,应该不包括 pt_regs
根据之前https://blog.csdn.net/u011011827/article/details/116056620 的分析
init_task 的 地址 是 c0800000
__end_init_task 的 地址 是 c0802000
两个地址 中间 的数据 从上到下 分别是
c0801ffc : 第 1 个地址
...
c0801fc8 : 第 14 个地址
c0801fc4 : 第 15 个地址 : 存储了 start_kernel 的 第一个局部变量 command_line
...
...
...
: thread_info
c0800000 : task_struct
进程分类
内核进程
没有这个概念
内核线程
对应一个唯一的task_struct
mm成员 为null
其他资源成员 不为null, 且不与其他进程共享
只能运行在 内核态
用户进程
对应一个唯一的task_struct
mm成员 不为null, 且不与其他进程共享
其他资源成员 不为null, 且不与其他进程共享
可以运行在 内核态与用户态
用户线程
对应一个唯一的task_struct
mm成员 不为null, 且与其他线程共享
其他资源成员 不为null, 且与其他线程共享
可以运行在 内核态与用户态
其他
kernel_clone 的调用者 有
1.SYSCALL_DEFINE0(fork)
2.kernel_thread
3.SYSCALL_DEFINE0(vfork)
4.SYSCALL_DEFINE[5/6](clone
5.SYSCALL_DEFINE2(clone3
线程模型 线程实现
1:1
LinuxThreads库+kernel
NPTL库+kernel
N:1
Portable Thread (用户空间实现)
N:M
NGPT
用户态 内核态
运行模式 usermode svcmode
寄存器 r13 r14 无spsr r13 r14 spsr
权限 有些指令不能跑 所有指令都能跑
----
用户态 切入 内核态 , 需要保存 用户态的 寄存器 到 pt_regs , 说明 用户态的 寄存器 是唯一的,需要保存
内核态 切入 用户态 , 不需要保存 内核态的 寄存器 , 说明 内核态的 寄存器 是固定值
---
用户态 与 内核态 都是 占用了 cpu , 对应的 task_struct 是同一个 , 只不过 用户态 访问不到 task_struct
用户态 的 pc 和 内核态的 pc 是同一个 pc ,但是 pc 的地址不同
一般来说,我们关注用户态进程,最大的关注点在代码,看到 pc 指向的值 就是 我写的 代码中的地址,然后就说看起来很对
一般来说,我们关注进程内核态,最大的关注点也在代码,但是 pc 指向的 是 内核代码,但是内核代码 和 我的进程代码 完全是 两个概念
于是,就说 内核(A)代理了 进程 在 内核态 执行,那么这里说的 内核(A) 是什么
内核 是 线程的集合,那么 内核(A) 是指的其他内核线程吗?
用户进程B 切换到内核 还是 内核进程B , 因为 其对应的 task_struct 没变,不存在 被其他的线程代理 的说法
可不可以这么理解
从用户态切到内核态后,进程还是那个进程
对于代码路径的说法, 可以认为是 pc 变了,而决定pc(内核代码路径)的是 切换时的 系统调用号
内核是服务,可以认为干活的虽然不是用户代码了,但是决定权仍然在用户代码
---
如果 进程中的用户代码路径 被看做 是 人 的话
这是的内核路径代码可以被看做是
零散的电子设备
用户代码 不能深入内核,所以通过 系统调用号 将 零散的电子设备 整合成 一个 机器人 (该机器人和人有一样的 身份(task_struct))
机器人 干活的时候, 是一个用户进程的内核态
机器人 干完活之后, 回归 零散的电子设备,然后 人来接管 干活的收获(系统调用得到的数据)
---
而 内核线程是一个人,不被会 拆解
用户进程(线程)的用户态 也是一个人,不会被 拆解
---
用户进程(线程)的用户态 运行的时候, 其实 用户进程的核心数据 (TCB) 还是在 内核,这时候
这些数据是 一些 零散的电子设备, 没法被用户态访问
用户态要访问这些 零散的电子设备 的话,只能通过 一种方法(系统调用) 来 生成机器人