(2023-2024-1)20232830《Linux内核原理分析与设计》第七周作业

(2023-2024-1)20232830《Linux内核原理分析与设计》第七周作业

1. 阅读理解 task_struct 数据结构

task_struct 是 Linux 内核中表示进程的重要数据结构。它包含了有关进程状态、调度信息、文件系统信息等的详细信息。以下是对 task_struct 数据结构的一些主要字段:

  • state(进程状态):表示进程的当前状态,可能是运行、睡眠、停止等。状态的改变反映了进程的活动。示例:long state;
  • pid(进程标识符):进程的唯一标识符。通过这个字段,内核可以追踪和管理进程。示例:pid_t pid;
  • parent(父进程指针):parent 字段指向父进程的 task_struct 结构。这是用于构建进程树的关键字段。示例:struct task_struct __rcu *parent;
  • children(子进程链表):children 是一个链表,包含指向当前进程的所有子进程的指针。这有助于实现进程之间的父子关系。示例:struct list_head children;
  • sibling(兄弟进程链表):sibling 是一个链表,包含指向与当前进程具有相同父进程的其他进程的指针。这是同一进程组的进程之间的链接。示例:struct list_head sibling;
  • comm(进程名):comm 字段包含了进程的名称。它是一个简短的字符串,用于标识进程。示例:char comm[TASK_COMM_LEN];
  • mm(内存管理):mm 字段指向描述进程内存布局和管理的结构。这包括进程的地址空间布局、页表等信息。示例:struct mm_struct *mm;
  • active_mm(当前地址空间):active_mm 字段指向当前进程正在使用的地址空间。在进程切换时,这个字段可能会改变。示例:struct mm_struct *active_mm;
  • group_leader(线程组领导):group_leader 字段指向线程组的领导进程。在多线程环境中,这有助于管理线程组。示例:struct task_struct __rcu *group_leader;
  • fs(文件系统信息):fs 字段包含有关进程打开的文件的信息。它指向 fs_struct 结构,其中包含有关文件系统的信息。示例:struct fs_struct *fs;
  • files(文件表):files 字段指向文件描述符表,它包含了进程打开的文件和其他 I/O 相关信息。示例:struct files_struct *files;
  • signal(信号处理):signal 字段包含有关进程信号处理的信息。信号是用于与进程通信和控制其行为的机制。示例:struct signal_struct *signal;
  • cred(安全凭证):cred 字段包含有关进程权限和身份的信息。这是与安全相关的关键信息。示例:struct cred __rcu *cred;
  • thread_info(线程信息):thread_info 字段包含了有关线程的低级信息,如堆栈指针和处理器状态。这对于线程管理是必要的。示例:struct thread_info thread_info;

2. 分析Linux内核创建一个新进程的过程

2.1 启动MenuOS

cd LinuxKernel

rm -rf menu

git clone https://github.com/mengning/menu.git

cd menu

mv test_fork.c test.c

make rootfs

启动
测试fork功能;
fork

2.2 调试MenuOS

通过增加-s -S启动参数打开调试模式;
qemu -kernel linux-3.18.6/arch/x86/boot/bzImage -initrd rootfs.img -s -S

打开调试模式

打开gdb进行远程调试;

gdb

file linux-3.18.6/vmlinux

target remote:1234

调试
设置断点;

b sys_clone

b do_fork

b dup_task_struct

b copy_process

b copy_thread

b ret_from_fork

设置断点
执行fork命令,停在了断点SyS_clone处,单步执行,定在了断点do_fork处;之后就是依次设置的断点。

fork

3. 总结

创建一个新进程在内核中的执行过程大致如下:

  1. 使用系统调用Sys_clone(或fork,vfork)系统调用创建一个新进程。这些系统调用会通过调用do_fork函数来实现进程的创建。

  2. Linux通过复制父进程的进程控制块(PCB)中的task_struct结构来创建一个新进程,并为新进程分配一个新的内核堆栈。

  3. 需要修改复制过来的进程数据,例如进程ID(pid)、进程链表等。这一步通过执行copy_process和copy_thread函数来完成。

  4. 设置新进程的内核栈顶,即p->thread.sp = (unsigned long) childregs。这个值表示当调度到子进程时,使用的内核栈的顶部位置。

  5. 设置子进程的第一条指令地址,即p->thread.ip = (unsigned long) ret_from_fork。这个地址表示当调度到子进程时,执行的第一条指令。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值