分析 Linux 内核创建一个新进程的过程
理解 task_struct 数据结构
询问ChatGPT task_struct 数据结构
task_struct
数据结构的定义位于 <linux/sched.h>
头文件中。下面是一个简化的 task_struct
数据结构的示例:
struct task_struct {
/* 进程状态和标志 */
volatile long state;
unsigned int flags;/* 进程 ID 和父进程 ID */
pid_t pid;
pid_t tgid;
pid_t ppid;/* 进程调度和优先级信息 */
struct sched_entity se;
int prio;
int static_prio;
int normal_prio;
int rt_priority;
struct sched_class *sched_class;/* 进程上下文信息 */
struct thread_info *thread_info;
struct exec_domain *exec_domain;/* 进程文件系统信息 */
struct fs_struct *fs;/* 其他字段... */
};
实验过程
启动MenuOS
首先进入LinuxKernel 文件夹,删除menu目录,然后git clone克隆一个新版本的menu,进入menu之后,运行make rootfs脚本自动编译生成根目录系统。、
cd LinuxKernel
rm -rf menu
git clone https://github.com/mengning/menu.git
cd menu
mv test_fork.c test.c
make rootfs
调试MenuOS
通过增加-s -S启动参数打开调试模式,并打开gdb进行调试。
qemu -kernel linux-3.18.6/arch/x86/boot/bzImage -initrd rootfs.img -s -S
gdb
file linux-3.18.6/vmlinux
target remote:1234
在sys_clone、do_fork、dup_task_struct、 copy_process、 copy_thread、ret_from_fork等处设置断点查看。
连续n命令后可以看到子进程的初始化过程:
执行finish,及continue命令,进入了子进程执行的起点ret_from_fork.
总结
sys_clone
函数的实现包括以下步骤:
- 创建一个新的进程结构体,并初始化该结构体的各个字段。
- 复制父进程的内存空间,包括页表、内核栈、用户栈等。
- 复制父进程的文件描述符表,使子进程与父进程共享打开的文件。
- 复制父进程的信号处理相关信息。
- 设置子进程的状态为可执行,并将其添加到进程调度队列中。
sys_clone
函数是进程创建的核心函数之一,它通过复制父进程的资源,创建一个新的进程,并使其开始执行。