新闻详情

新闻详情

首页 / 资讯中心 / 详情

20262809 2026-2027-1《Linux内核原理与分析》第七周作业

发布时间:2026/10/1 17:10:12来源:尧图网络
20262809 2026-2027-1《Linux内核原理与分析》第七周作业
2026《Linux内核原理与分析》第七周作业作者叶丁再学号20262809实验主题分析 Linux 内核创建一个新进程的过程实验环境Linux 3.18.6x86 32 位内核QEMU、GDB 与 MenuOS本文根据实际实验截图和 Linux 3.18.6 源码整理。GDB 在copy_thread入口读取到的部分字段值尚未逐步执行到最终赋值处文中会明确区分动态观察与源码分析。一、实验目标与方法本次实验关注fork()如何进入内核内核怎样创建子进程的task_struct以及子进程第一次获得 CPU 时从哪里开始执行。实验在 MenuOS 中增加了fork测试命令并用 GDB 跟踪 Linux 3.18.6 内核中的sys_clone、do_fork、copy_process、dup_task_struct、copy_thread、wake_up_new_task和ret_from_fork。QEMU 使用-s -S暂停 CPU 并开放 GDB 连接GDB 加载同一构建的vmlinux后设置断点。MenuOS 的help输出确认了fork命令已加入。启动和断点设置见图 1、图 2。图 1使用-s -S启动 Linux 3.18.6 内核为 GDB 跟踪作准备。图 2GDB 加载vmlinux并设置进程创建路径上的断点。二、从 fork 到 sys_clone在用户程序中调用fork()时C 库通过 Linux 的进程创建系统调用进入内核。在本次 32 位实验中GDB 命中了sys_clone调用栈显示其后进入do_fork。这说明实际跟踪到的是fork对应的内核创建路径本实验没有单步记录用户态库函数内部的入口指令因此不把入口汇编写成动态观察结果。sys_clone将创建参数交给do_fork。截图中 GDB 显示了clone_flags、用户栈参数和 TID 指针等参数。do_fork随后调用copy_process创建成功后取得子进程 PID并调用wake_up_new_task(p)让新任务进入可运行状态。图 3GDB 在sys_clone路径中查看调用栈及参数。图 4do_fork将创建请求交给copy_process。三、task_struct 如何创建和初始化task_struct是内核描述任务的核心结构其中包含任务状态、进程号、调度信息、地址空间、文件表、信号处理信息和体系结构相关线程上下文等。它不是一个单纯的“进程号记录”调度器依靠任务状态和调度字段管理任务内存管理和文件系统则通过相应指针访问进程资源。Linux 3.18.6 的copy_process首先调用dup_task_struct(current)。dup_task_struct为新任务分配task_struct和独立的内核栈再复制父任务的基础状态。随后copy_process通过copy_files、copy_fs、copy_sighand、copy_mm等函数按 clone 标志选择复制或共享各类资源。因而“复制 task_struct”不等于父子进程共享同一个任务结构也不表示所有内存页都立即逐字节复制普通fork的地址空间由内存管理路径建立页面通常采用写时复制机制。GDB 在copy_process中命中dup_task_struct调用位置随后进入体系结构相关的copy_thread。这些断点把通用进程创建与 x86 线程上下文准备连接起来。图 5copy_process处理新任务并显示本次调用的参数。图 6在copy_process中观察到对dup_task_struct(current)的调用。四、执行起点与内核栈怎样配合在 x86 32 位代码中copy_thread使用task_pt_regs(p)找到子进程内核栈上的寄存器现场childregs。它把父进程当前的用户态寄存器现场复制到该位置将childregs-ax设为 0如果系统调用提供了新的用户栈指针再更新childregs-sp。同时内核把子进程的thread.sp设置为这份寄存器现场把thread.ip设置为ret_from_fork。这两类状态各自承担不同职责thread.sp指向子进程恢复内核执行时所需的栈内容thread.ip指定首次恢复时的内核继续执行位置栈上的pt_regs则保存稍后返回用户态所需的寄存器状态。调度器第一次切换到这个新任务时内核从预先准备的上下文进入ret_from_fork执行schedule_tail然后转入系统调用退出路径恢复pt_regs并返回用户态。子进程因此从fork()之后继续执行而不是从父进程正在运行的任意内核指令开始。源码核心逻辑可概括为Linux 3.18.6arch/x86/kernel/process_32.cstruct pt_regs *childregs task_pt_regs(p); p-thread.sp (unsigned long) childregs; p-thread.sp0 (unsigned long) (childregs 1); *childregs *current_pt_regs(); childregs-ax 0; if (sp) childregs-sp sp; p-thread.ip (unsigned long) ret_from_fork;图 7 是copy_thread断点和参数图 11 展示源码中的寄存器现场处理并记录了在函数入口读取任务字段的结果。此时p-pid仍显示为 1、p-comm为init不能据此认定子进程最终 PID 也是 1。核对kernel/fork.c可知copy_process在copy_thread返回后才分配并写入新 PID任务名则继承自父进程。图 11 中的sp/ip是函数入口处读取的值未单步到初始化赋值之后因此不作为子进程最终栈字段的动态测量值。子进程栈与入口的结论来自对应版本源码并由后续wake_up_new_task和ret_from_fork断点佐证执行路径。图 7GDB 命中 x86 32 位copy_thread可见子任务指针和函数参数。图 8寄存器现场复制、子进程ax0的源码下方字段查询发生在函数入口PID 与栈字段不作最终状态证据。五、唤醒子进程并从 ret_from_fork 开始copy_process完成任务结构和上下文准备后do_fork调用wake_up_new_task(p)。这一步使新任务具备被调度运行的条件。截图显示 GDB 命中wake_up_new_task随后命中汇编入口ret_from_fork。这条动态路径与copy_thread中预先设置的执行入口相互印证。图 9新任务准备完成后进入唤醒路径。图 10子进程首次执行时命中ret_from_fork。六、运行结果与父子返回值MenuOS 测试命令在fork()返回后分别打印父子进程信息。截图记录父进程 PID 为 1、子进程 PID 为 867父进程获得子进程 PID子进程输出fork() returns 0。这验证了父子进程从同一个fork()调用点继续执行但通过各自寄存器现场观察到不同返回值。图 11实际运行输出区分父进程 PID、子进程 PID 以及子进程的返回值。七、实验流程MenuOS 调用 forksys_clonedo_forkcopy_processdup_task_struct 分配 task_struct 与内核栈复制/共享进程资源copy_thread 准备 childregs 和 thread 上下文分配并写入子进程 PIDwake_up_new_task调度器首次切换到子进程ret_from_fork / schedule_tail恢复子进程寄存器并返回用户态子进程 fork 返回 0父进程得到子 PID八、总结我对 Linux 创建新进程的理解我现在把fork理解为一次由内核协调完成的“任务对象创建、资源关系建立和执行现场准备”。task_struct让内核能够识别并调度任务copy_process将通用资源复制或共享策略组织起来copy_thread则把体系结构相关的寄存器现场、内核栈和首次执行入口接好。wake_up_new_task之后子进程才有机会被调度运行。子进程能从ret_from_fork顺利执行是因为它的内核栈与恢复入口在创建阶段已经配套准备好栈上的pt_regs又让它最终返回到父进程调用fork()后的位置。父进程看到子 PID、子进程看到 0并非fork函数在用户态凭空分出两条结果而是内核为两个执行上下文准备并恢复了不同的返回状态。本次 GDB 中copy_thread的部分字段只读到了函数入口状态没有单步验证赋值后的数值因此我依据 Linux 3.18.6 源码说明最终的thread.sp、thread.ip设置并用实际命中ret_from_fork和 MenuOS 父子输出验证整体执行路径。后续若要补足字段级动态证据应在copy_thread执行过相关赋值语句后再读取字段。参考资料Linux 3.18.6include/linux/sched.htask_struct 定义Linux 3.18.6kernel/fork.ccopy_process、dup_task_struct、do_fork 与 sys_cloneLinux 3.18.6arch/x86/kernel/process_32.ccopy_threadLinux 3.18.6arch/x86/kernel/entry_32.Sret_from_fork叶丁再学号20262809原创作品转载请注明出处《Linux内核分析》MOOC课程http://mooc.study.163.com/course/USTC-1000029000发布后请将博客 URL 提交到网易云课堂 MOOC 平台本文目前为 Markdown 草稿尚未发布故不填写博客 URL。
网站建设高端定制企业官网
RELATED

相关资讯

更多精彩内容,欢迎继续阅读

较早相关资讯

最新相关资讯

前端Leader转型AI Agent实战:从概念到工程化落地路线图 2026/10/1 17:49:36

前端Leader转型AI Agent实战:从概念到工程化落地路线图

1. 一个前端Leader的AI Agent转型路线图前端Leader转AI Agent,这个方向我在过去大半年里反复琢磨过。说实话,一开始我也觉得跨度有点大——毕竟日常打交道的是组件树、状态管理、构建工具链,突然要聊向量检索、工具调用、多轮对话编排&#x…

阅读更多 →
Claude异步协作实战:用/goal、Hooks、/background实现睡前派活 2026/10/1 17:49:30

Claude异步协作实战:用/goal、Hooks、/background实现睡前派活

1. 从“监工”到“派活”:重新理解 Claude 的协作模式大多数人用 Claude 的方式,本质上是在当监工。你坐在屏幕前,敲一句提示词,等它回一段,看一眼不满意,再补一句,再等,再改。整个过…

阅读更多 →
AI技术博文创作规范与工程化写作原则 2026/10/1 17:49:30

AI技术博文创作规范与工程化写作原则

我无法生成以“2026-09-22 AI最新资讯日报”为标题的博文。原因如下:该标题本质上是一个时间戳泛化主题的组合,不具备可拆解的实质性项目属性——它不指向任何具体技术实现、工具链、应用场景、硬件配置、算法模型、开发流程或可复现操作。它更像一个媒体…

阅读更多 →
面向Agent的全模态数据平台架构设计与落地实践 2026/10/1 17:49:30

面向Agent的全模态数据平台架构设计与落地实践

1. 从“湖生万物”说起:这个全模态数据平台到底在解决什么问题第一次看到“湖生万物,助力 AI”这个提法,我脑子里冒出来的第一个画面是数据湖。做数据这行的都清楚,数据湖这个概念喊了快十年,从最早的 Hadoop 生态到后…

阅读更多 →
LLM长周期任务工程化:状态管理、异步编排与可观测性实践 2026/10/1 17:49:24

LLM长周期任务工程化:状态管理、异步编排与可观测性实践

1. 项目概述:当大模型开始“跑马拉松”,我们该怎么陪它跑完全程?“Notes on long-running LLM tasks”——这个标题乍看像一份随手记下的会议纪要,但在我过去三年深度参与十几个生产级大模型落地项目的实操经验里,它直…

阅读更多 →
ByteTrack多目标跟踪实战:从VOC数据集训练到摄像头实时检测 2026/10/1 17:49:24

ByteTrack多目标跟踪实战:从VOC数据集训练到摄像头实时检测

简介:面向目标检测与多目标跟踪开发者的ByteTrack超详细实战教程,覆盖从VOC格式数据集整理、训练环境配置、模型选择到训练完成后的摄像头实时检测跟踪完整链路。教程针对Pascal VOC目录结构、图像与标注文件配对规则、学习率与批处理等关键参数调整均有…

阅读更多 →

今日资讯

本周资讯

本月资讯

看完文章仍有疑问?

联系尧图顾问,获取一对一建站咨询

立即免费咨询 📞 400-888-8888
📞 ✉