linux源代码分析实验报告格式
基于Linux内核编程的实验报告(Linux内核分析实验报告)

基于Linux内核编程的实验报告(Linux内核分析实验报告)以下是为大家整理的基于Linux内核编程的实验报告(Linux内核分析实验报告)的相关范文,本文关键词为基于,Linux,内核,编程,实验,报告,分析,,您可以从右上方搜索框检索更多相关文章,如果您觉得有用,请继续关注我们并推荐给您的好友,您可以在教育文库中查看更多范文。
Linux内核分析实验报告实验题目:文件系统实验实验目的:linux文件系统使用虚拟文件系统VFs作为内核文件子系统。
可以安装多种不同形式的文件系统在其中共存并协同工作。
VFs对用户提供了统一的文件访问接口。
本实验的要求是(1)编写一个get_FAT_boot函数,通过系统调用或动态模块调用它可以提取和显示出FAT文件系统盘的引导扇区信息。
这些信息的格式定义在内核文件的fat_boot_sector结构体中。
函数可通过系统调用或动态模块调用。
(2)编写一个get_FAT_dir函数,通过系统调用或动态模块调用它可以返回FAT文件系统的当前目录表,从中找出和统计空闲的目录项(文件名以0x00打头的为从未使用过目录项,以0xe5打头的为已删除的目录项),将这些空闲的目录项集中调整到目录表的前部。
这些信息的格式定义在内核文件的msdos_dir_entry结构体中。
硬件环境:内存1g以上软件环境:Linux(ubuntu)2-6实验步骤:一:实验原理:以实验4为蓝本,在优盘中编译并加载模块,启动测试程序,查/proc/mydir/myfile的文件内容。
从优盘得到fat文件系统的内容存在msdos_sb_info结构中,然后得到msdos_sb_info结构相应的属性值,得到实验一的数据。
实验二中,得到fat文件系统第一个扇区的十六个文件信息。
然后按照文件名头文字的比较方法,应用归并排序的方法,将头文件是0x00和0xe5的文件调到前面,其他的文件调到后面二:主要数据结构说明:(1)超级块对象:数据结构说明:一个已经安装的文件系统的安装点由超级块对象代表。
linux编程实验报告

linux编程实验报告Linux编程实验报告一、引言在计算机科学领域中,Linux操作系统一直以其开源、稳定和灵活的特性而受到广泛关注和使用。
作为一名计算机科学专业的学生,我有幸参与了一项关于Linux编程的实验,并在此报告中分享我的实验结果和心得体会。
二、实验目的本次实验的目的是通过编写Linux程序,熟悉Linux操作系统的基本命令和编程环境。
具体而言,我们需要使用C语言编写一个简单的程序,实现文件的读取、写入和修改等功能,并在Linux环境下进行测试和验证。
三、实验过程1. 环境准备在开始实验之前,我们首先需要确保已经安装了Linux操作系统,并具备基本的命令行操作能力。
此外,我们还需要安装C语言编译器,以便能够编译和运行我们的程序。
2. 编写程序根据实验要求,我们需要编写一个程序,实现文件的读写功能。
在编写程序之前,我们先进行了详细的需求分析和设计,确定了程序的基本架构和功能模块。
3. 调试和测试在编写完程序之后,我们进行了一系列的调试和测试工作,以确保程序的正确性和稳定性。
我们使用了一些常见的测试用例,包括读取已存在的文件、写入新文件以及修改已有文件等情况,并对程序的输出结果进行了验证。
四、实验结果经过多次的调试和测试,我们最终得到了一个功能完善、稳定可靠的程序。
该程序能够准确地读取、写入和修改文件,并能够处理各种异常情况,如文件不存在、权限不足等。
五、实验心得通过参与这次实验,我收获颇多。
首先,我对Linux操作系统的理解更加深入了。
在实验过程中,我学会了使用Linux的命令行工具,熟悉了Linux的文件系统和权限管理机制。
其次,我对C语言的编程能力也得到了提升。
在编写程序的过程中,我学会了使用C语言的文件操作函数和错误处理机制,提高了自己的编程技巧。
此外,我还意识到编程实践的重要性。
通过亲自动手编写程序,我不仅仅是理论上了解了Linux的一些特性,更重要的是深入了解了其背后的设计原理和实现细节。
实验报告格式-中国科学技术大学

中国科学技术大学实验报告课程名称:操作系统原理与实现实验类型:综合型/设计型实验项目名称:学生姓名:专业:学号:电子邮件地址(必须):手机:实验日期:年月日一、实验目的//如:学习重新编译Linux内核,理解、掌握Linux内核和发行版本的区别。
二、实验内容//如:重新编译内核是一件比你想像的还要简单的事情,它甚至不需要你对内核有任何的了解,只要你具备一些基本的Linux操作系统的知识就可以进行。
本次实验,要求你在RedHat Fedora Core 5的Linux系统里,下载并重新编译其内核源代码;然后,配置GNU的启动引导工具grub,成功运行你刚刚编译成功的Linux内核。
三、主要仪器设备(必填)//填写您的计算机配置,操作系统环境,LINUX版本和原KERNEL版本四、操作方法和实验步骤//如:1.查找并且下载一份内核源代码在Linux的官方网站: ,下载内核版本。
……\\图2.部署内核源代码将压缩包移到主目录下:# mv linux-2.6.17.tgz ~进入主目录:# cd ~解开rpm包# tar zxvf linux-2.6.17.tgz解压出来的是一个linux-2.6.17目录,目录里面就是2.6.17的内核源代码目录树。
…….\\图3.配置内核在编译内核前,一般来说都需要对内核进行相应的配置。
配置是精确控制新内核功能的机会。
配置过程也控制哪些需编译到内核的二进制映像中(在启动时被载入),哪些是需要时才装入的内核模块(module)。
……\\图4.编译内核和模块用make工具编译内核:#make……\\图5.应用grub配置启动文件编辑/boot/grub/grub.conf文件,修改系统引导配置。
使用vi编辑工具:# vi /boot/grub/grub.conf……\\图五、实验结果和分析//如:grub.conf文件内容如下:# grub.conf generated by anaconda## Note that you do not have to rerun grub after making changes to this file# NOTICE: You do not have a /boot partition. This means that# all kernel and initrd paths are relative to /, eg.# root (hd0,5)# kernel /boot/vmlinuz-version ro root=/dev/hda6# initrd /boot/initrd-version.img#boot=/dev/hdadefault=2timeout=10splashimage=(hd0,5)/boot/grub/splash.xpm.gzhiddenmenutitle Fedora Core (2.6.17)root (hd0,5)kernel /boot/vmlinuz-2.6.17 ro root=LABEL=/ rhgb quietinitrd /boot/initrd-2.6.17.imgtitle Fedora Core (2.6.15-1.2054_FC5)root (hd0,5)kernel /boot/vmlinuz-2.6.15-1.2054_FC5 ro root=LABEL=/ rhgb quietinitrd /boot/initrd-2.6.15-1.2054_FC5.imgtitle win_xprootnoverify (hd0,0)chainloader +1若在命令hiddenmenu前加#,则使此命令无效,在开机系统引导时直接进入选择界面。
linux实验报告

linux实验报告Linux 实验报告一、实验目的本次 Linux 实验的主要目的是熟悉 Linux 操作系统的基本命令和操作,了解其文件系统、进程管理、用户权限等核心概念,并通过实际操作加深对这些知识的理解和应用能力。
二、实验环境本次实验使用的是虚拟机软件 VirtualBox 安装的 Ubuntu 2004 LTS 操作系统。
三、实验内容及步骤(一)用户和权限管理1、使用`sudo adduser` 命令创建新用户`user1` 和`user2`。
2、使用`sudo passwd user1` 和`sudo passwd user2` 为新用户设置密码。
3、使用`sudo usermod aG sudo user1` 将`user1` 添加到`sudo` 组,使其具有管理员权限。
4、以`user1` 身份登录系统,创建一个文件`file1txt`,尝试修改其权限为 777,观察权限变化。
(二)文件和目录操作1、使用`mkdir` 命令创建目录`directory1` 和`directory2`。
2、使用`touch` 命令在当前目录下创建文件`file2txt` 和`file3txt`。
3、使用`cp` 命令将`file2txt` 复制到`directory1` 目录下。
4、使用`mv` 命令将`file3txt` 移动到`directory2` 目录下。
5、使用`rm` 命令删除`file2txt` 和`directory2` 目录及其下的所有文件。
(三)进程管理1、使用`ps` 命令查看当前系统中的进程信息。
2、使用`top` 命令实时监控系统的进程状态。
3、使用`kill` 命令结束指定进程(例如,通过进程 ID 结束一个占用大量资源的进程)。
(四)文件系统管理1、使用`df` 命令查看磁盘空间使用情况。
2、使用`du` 命令查看目录或文件的磁盘使用量。
3、使用`mount` 命令挂载一个新的磁盘分区(假设已经在虚拟机中添加了新的磁盘分区)。
linux实验报告总结-共10篇

∣inux实验报告总结(共10篇)(Linux实验报告汇总)(一)Shell 编程一、实验目的:1)掌握在Linux下的C编程基本方法。
2)掌握shell编程方法。
3)掌握dialog图形化编程方法。
二、实验内容1、编写能输出“Hello world!”问候语的C程序,并在终端中编译、执行。
要求记录所使用的命令及结果。
#include stdio.hmain()(printf(Hello world!\n);)2、编写一个C程序并设置其在后台执行,其功能是在一段时间后(可自行设置),在屏幕上显示信息:Time for play!,写出相应的程序、命令及结果。
#include stdio.hmain()(int time=0;printf(请输入等待时间(单位:s):);scanf(%d/&time);sleep(time);printf(Time for play!\n);)3、编写C程序,求1到100之间整数的阶乘和,并对程序进行优化。
写出程序、命令和结果。
#include stdio.hmain()int i;double s = l,sum = 0;for( i= l;i= 100;i++)sum+=s*=i;printf( 1到100之间整数的阶乘和:%f\n,sum);printf( 1到100之间整数的阶乘和:%e\n,sum);}4、编写C程序,根据键盘输入的半径求圆面积,要求在命令行周率(P∣=3∙14,PI=3∙14159,PI=3.14159626 等)进行编使用不同的译,写出程序、命令和结果。
#include stdio.hint main()double r = 0.0 , Area = 0.0;printf(请输入半径:);scanf(%lf, &r);Area = PI * r * r;printf(圆面积:%f∖n, Area);)5、编写shell程序sh.l,完成向用户输出“你好!”的问候语。
Linux C实验报告书模板

学生学号0120810680336实验课成绩武汉理工大学学 生 实 验 报 告 书实验课程名称 开 课 学 院 指导老师姓名 学 生 姓 名 学生专业班级《Linux 应用开发技术》 应用开发技术》 计算机科学与技术学院 祁明龙 徐泽前 软件 08032011 — 2012 学年 第 一 学期实验课程名称:实验项目名称 实验者 同组者Linux应用开发技术实验成绩 组别 实验日期 年 月 日Linux make utility and makefile scripting.徐泽前 专业班级 软件 0803第一部分:实验分析与设计(可加页)一、实验内容描述(问题域描述)在 Linux(unix)环境下使用 GNU 的 make 工具能够比较容易的构建一个属于你 自己的工程,整个工程的编译只需要一个命令就可以完成编译、连接以至于最后的 执行。
不过这需要我们投入一些时间去完成一个或者多个称之为 Makefile 文件的 编写。
此文件正是 make 正常工作的基础。
所要完成的 Makefile 文件描述了整个 工程的编译、 连接等规则。
其中包括: 工程中的哪些源文件需要编译以及如何编译、 需要创建那些库文件以及如何创建这些库文件、 如何最后产生我们想要得可执行文 件。
尽管看起来可能是很复杂的事情,但是为工程编写 Makefile 的好处是能够使 用一行命令来完成“自动化编译”, 一旦提供一个 (通常对于一个工程来说会是多个) 正确的 Makefile。
编译整个工程你所要做的唯一的一件事就是在 shell 提示符下输 入 make 命令。
整个工程完全自动编译,极大提高了效率。
此次实验的目的:了解 linux make 工具的使用,以及学会编写简单的 makefile 脚本二、实验基本原理与设计(包括实验方案设计,实验手段的确定,试验步骤等,用硬件逻辑或 者算法描述)1.了解 make 的相关规则 2.编写项目源代码,这里采用 Stu_sys 系统来进行 makefile 脚本的编写 3.运行程序 4.分析结果三、主要仪器设备及耗材设备:计算机一台 OS: Linux ubuntu Editor: VIM第二部分:实验调试与结果分析(可加页)一、调试过程(包括调试方法描述、实验数据记录,实验现象记录,实验过程发现的问题等)1. 设计实现 stu_sys 系统 2. 根据 stu_sys 系统编写 makfile 脚本 脚本文件名为 makefile.mk # # copyright(C)2011 QingxinLee Whut Email:Lee_Ware@ # vpath %.h include vpath %.c src cc=gcc -c stu_sys:main.o stu_sys.o gcc $? -o $@ main.o:main.c stu.h struct.h $(cc) $< -I include stu_sys.o:stu_sys.c stu.h struct.h $(cc) $< -I include .PHONY:clean clean: rm -f *.o stu_sys 3. 执行脚本 通过如下命令来执行脚本:make –f makefile.mk 4. 以下是执行脚本输出的结果: 以下是执行脚本输出的结果:edit : main.o kbd.o command.o display.o \ insert.o search.o files.o utils.o cc -o edit main.o kbd.o command.o display.o \ insert.o search.o files.o utils.omain.o : main.c defs.h cc -c main.c kbd.o : kbd.c defs.h command.h cc -c kbd.c command.o : command.c defs.h command.h cc -c command.c display.o : display.c defs.h buffer.h cc -c display.c insert.o : insert.c defs.h buffer.h cc -c insert.c search.o : search.c defs.h buffer.h cc -c search.c files.o : files.c defs.h buffer.h command.h cc -c files.c utils.o : utils.c defs.h cc -c utils.c clean :rm edit main.o kbd.o command.o display.o \ insert.o search.o files.o utils.o二、实验结果及分析(包括结果描述、实验现象分析、影响因素讨论、综合分析和结论等) make 命令执行时,需要一个 Makefile 文件,以告诉 make 命令需要怎么样的去编译和链接程 序。
linux编程 实验报告

linux编程实验报告Linux编程实验报告一、引言Linux操作系统是一种自由开源的操作系统,具有稳定性、安全性和灵活性等优点,被广泛应用于服务器、嵌入式系统和个人电脑等领域。
本实验旨在通过编程实践,探索Linux编程的基本概念和技术,并通过实验结果验证相关理论。
二、实验目的本实验的主要目的是通过编写C语言程序,理解Linux系统调用的原理和使用方法。
具体目标包括:1. 熟悉Linux系统调用的概念和基本原理;2. 掌握Linux系统调用的常用函数及其使用方法;3. 理解文件操作、进程管理和网络编程等方面的基本知识。
三、实验环境本实验使用的实验环境为Ubuntu 20.04 LTS操作系统。
在该系统上,我们可以使用gcc编译器编译C语言程序,并通过终端执行程序。
四、实验内容1. 文件操作文件操作是Linux编程中的重要内容之一。
通过使用系统调用函数,我们可以实现对文件的读写、创建和删除等操作。
在本实验中,我们编写了一个简单的文件复制程序,实现将一个文件的内容复制到另一个文件中。
2. 进程管理进程是Linux系统中的基本执行单元。
通过创建和管理进程,我们可以实现并发执行和多任务处理等功能。
在本实验中,我们编写了一个简单的多进程程序,实现同时执行多个任务的效果。
3. 网络编程网络编程是Linux编程中的一个重要领域,它涉及到网络通信、套接字编程和网络协议等内容。
在本实验中,我们编写了一个简单的客户端-服务器程序,实现了基于TCP协议的网络通信。
五、实验结果与分析通过实验,我们成功编写了文件复制程序、多进程程序和客户端-服务器程序,并在实验环境中运行和测试了这些程序。
实验结果表明,我们对Linux编程的基本概念和技术有了初步的理解和掌握。
在文件复制程序中,我们使用了open、read和write等系统调用函数,实现了将源文件的内容复制到目标文件中。
通过实验测试,我们发现该程序能够正确地复制文件,保持了源文件的内容和结构。
LINUX实验报告参考模板

$ ll
注意单引号的使用,这使得BASH将该项目传递给别名,而不是自己
估计它。别名还可用作较长的路径名的缩写:
$ alias jdev9i=/jdev9i/jdev/bin/jdev
cat、more和less
命令让能够从命令行查看一个文本文件的内容,而无需调用编辑器。Cat是'concatenate'的缩写,它将默认地在标准输出(显示屏)上显示文件内容。和cat一起提供的最有趣的选项之一是-n选项,它用编号的输出行来显示文件内容。
$ cat -n test.out
1 This is a test.
因为cat一次性输出文件中的所有行,所以可能更喜欢用more和less,因为它们都一次输出一屏的文件内容。Less是more的一个增强的版本,它允许用来自vi文本编辑器的关键命令来增强文件查看。例如,d向前翻滚、b向后翻滚N行(如果N是在d或b之前指定的)。为N输入的值成为随后的d命令的默认值。man页面实用工具使用less来显示使用说明的内容。
二、实验环境(实验设备)
WindowsXP+ VMWare +RedHatLinux8
实 验 报 告
三、实验过程描述与结果分析
1.目录/proc下与系统相关的文件和目录
(1) /proc/$pid/fd:这是一个目录,该进程($PID号码进程)每个打开的文件在该目录下有一个对应的文件。
例如:#ls /proc/851/fd
0 1 2 255
这表示,851号进程目前正在使用(已经打开的)文件有4个,它们的描述符分别是0、1、2、255。其中,0、1、2依次分别是进程的标准输入、标准输出和标准错误输出设备。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
linux源代码分析实验报告格式Linux的fork、exec、wait代码的分析指导老师:景建笃组员:王步月张少恒完成日期:2005-12-16一、 设计目的1.通过对Linux 的fork 、exec 、wait 代码的分析,了解一个操作系统进程的创建、执行、等待、退出的过程,锻炼学生分析大型软件代码的能力;2.通过与同组同学的合作,锻炼学生的合作能力。
二、准备知识由于我们选的是题目二,所以为了明确分工,我们必须明白进程的定义。
经过查阅资料,我们得知进程必须具备以下四个要素:1、有一段程序供其执行。
这段程序不一定是进程专有,可以与其他进程共用。
2、有起码的“私有财产”,这就是进程专用的系统堆栈空间3、有“户口”,这就是在内核中有一个task_struct 结构,操作系统称为“进程控制块”。
有了这个结构,进程才能成为内核调度的一个基本单位。
同时,这个结构又是进程的“财产登记卡”,记录着进程所占用的各项资源。
4、有独立的存储空间,意味着拥有专有的用户空间:进一步,还意味着除前述的系统空间堆栈外,还有其专用的用户空间堆栈。
系统为每个进程分配了一个task_struct 结构,实际分配了两个连续的物理页面(共8192字节),其图如下: Struct task_struct (大约1K)系统空间堆栈 (大约7KB )两个连续的物理页面对这些基本的知识有了初步了解之后,我们按老师的建议,商量分工。
如下:四、 小组成员以及任务分配1、王步月:分析进程的创建函数fork.c ,其中包含了get_pid 和do_fork get_pid,写出代码分析结果,并画出流程图来表示相关函数之间的相互调用关系。
所占工作比例35%。
2、张少恒:分析进程的执行函数exec.c,其中包含了do_execve 。
写出代码分析结果,并画出流程图来表示相关函数之间的相互调用关系。
所占工作比例35% 。
3、余波:分析进程的退出函数exit.c,其中包含了do_exit 、sys_wait4。
写出代码分析结果,并画出流程图来表示相关函数之间的相互调用关系。
所占工作比例30% 。
五、各模块分析:1、fork.c一)、概述进程大多数是由FORK 系统调用创建的.fork 能满足非常高效的生灭机制.除了0进程等少数一,两个进程外,几乎所有的进程都是被另一个进程执行fork 系统调用创建的.调用fork 的进程是父进程,由fork 创建的程是子进程.每个进程都有一个父进程.而一个进程可以有多个子进程.父进程创建一个子进程完成一定的工作时,往往希望子进程结束后,还要把控制权交给父进程,因此子进程不应把父进程覆盖掉.fork系统调用创建子进程的做法,是把自己复制给子进程,也就是说,新创建的子进程是父进程的一个副本.继而子进程通过exec系统调用,用一个新的程序来覆盖子进程的内存空间,从而执行那个新程序.系统调用exit可以终止一个进程的执行,子进程也常常用exit系统调用来自我终止.子进程终止之后,进入僵死(zombie)状态,父进程可通过执行wait系统调用来实现与子进程的终止同步,接受子进程的返回状态和返回参数.二)、代码分析int do_fork(unsigned long clone_flags, unsigned long stack_start,struct pt_regs *regs, unsigned long stack_size){int retval;unsigned long flags;struct task_struct *p;struct completion vfork;if ((clone_flags & (CLONE_NEWNS|CLONE_FS)) == (CLONE_NEWNS|CLONE_FS))return -EINV AL;retval = -EPERM;/* 将retval赋值-ENOMEM,作为task_struct结构申请失败时的返回值*/if (clone_flags & CLONE_PID) {/* 若clone_flags的位是置位的*//* 若调用do_fork的当前(父)进程不是idle进程(其pid=0)*/if (current->pid)goto fork_out;}retval = -ENOMEM;/*返回错误信息*/p = alloc_task_struct(); /* 申请一个新的task_struct结构*/if (!p)goto fork_out;*p = *current;/* 将当前(父)进程task_struct结构值赋给新创建的(子)进程*/ p->tux_info = NULL;p->cpus_allowed_mask &= p->cpus_allowed;retval = -EAGAIN;/* 若子(新)进程所属的用户拥有的进程数已达到规定的限制值,* 则跳转至bad_fork_fre */?if (atomic_read(&p->user->processes) >= p->rlim[RLIMIT_NPROC].rlim_cur&& !capable(CAP_SYS_ADMIN)&& !capable(CAP_SYS_RESOURCE))goto bad_fork_free;/* user->__count增一,user->processes(用户拥有的进程数)增一*/ atomic_inc(&p->user->__count);atomic_inc(&p->user->processes);/* 若系统进程数超过最大进程数则跳转至bad_fork_cleanup_count */if (nr_threads >= max_threads)goto bad_fork_cleanup_count;get_exec_domain(p->exec_domain);/* 若正在执行的代码是符合iBCS2标准的程序,则增加相对应模块的引用数目*//* 若正在执行的代码属于全局执行文件结构格式则增加相对应模块的引用数目*/ if (p->binfmt && p->binfmt->module)__MOD_INC_USE_COUNT(p->binfmt->module);p->did_exec = 0;/* 将子进程标志为尚未执行*/p->swappable = 0; /* 清标志,使内存页面不可换出*/p->state = TASK_UNINTERRUPTIBLE;/* 将子进程的状态置为uninterruptible */copy_flags(clone_flags, p);/* 将clone_flags略加修改写入p->flags */p->pid = get_pid(clone_flags);/* 调用kernel/fork.c:get_pid()为子进程分配一个pid. 若是clone系统调用且* clone_flags中CLONE_PID位为1,那么父子进程共享一个pid号;否则要分配给子进* 程一个从未用过的pid */if (p->pid == 0 && current->pid != 0)goto bad_fork_cleanup;/* 对运行队列接口初始化*/INIT_LIST_HEAD(&p->run_list);p->p_cptr = NULL;init_waitqueue_head(&p->wait_chldexit);/* 初始化wait_chldexit等待队列wait_chldexit用于在进程结束时,或发出* 系统调用wait4后,为了等待子进程结束,而将自己(父进程)睡眠在该队列上*/ p->vfork_done = NULL;if (clone_flags & CLONE_VFORK) {p->vfork_done = &vfork;init_completion(&vfork);}spin_lock_init(&p->alloc_lock);p->sigpending = 0;init_sigpending(&p->pending);p->it_real_value = p->it_virt_value = p->it_prof_value = 0;p->it_real_incr = p->it_virt_incr = p->it_prof_incr = 0;init_timer(&p->real_timer);p->real_timer.data = (unsigned long) p;p->leader = 0; /* session leadership doesn't inherit */p->tty_old_pgrp = 0;p->times.tms_utime = p->times.tms_stime = 0;p->times.tms_cutime = p->times.tms_cstime = 0;#ifdef CONFIG_SMP{int i;/* ?? should we just memset this ?? */for(i = 0; i < smp_num_cpus; i++)p->per_cpu_utime[cpu_logical_map(i)] =p->per_cpu_stime[cpu_logical_map(i)] = 0;spin_lock_init(&p->sigmask_lock);}#endifp->array = NULL;p->lock_depth = -1; /* -1 = 没有锁*/p->start_time = jiffies_64;/* 将当前的jiffies值作为子进程的创建时间*//* task_struct结构初始化完毕*/retval = -ENOMEM;/* copy all the process information */if (copy_files(clone_flags, p))/* 复制所有的进程信息,根据clone_flags复制或共享父进程的打开文件表*/goto bad_fork_cleanup;if (copy_fs(clone_flags, p))/* 根据clone_flags复制或共享父进程的系统信息*/ goto bad_fork_cleanup_files;if (copy_sighand(clone_flags, p))/* 根据clone_flags复制或共享父进程的信号处理句柄*/goto bad_fork_cleanup_fs;if (copy_mm(clone_flags, p))/* 根据clone_flags复制或共享父进程的存储管理信息*/goto bad_fork_cleanup_sighand;if (copy_namespace(clone_flags, p))/* 为子进程复制父进程系统空间堆栈*/ goto bad_fork_cleanup_mm;/* 若系统空间堆栈复制失败跳转至bad_fork_cleanup_mm */retval = copy_thread(0, clone_flags, stack_start, stack_size, p, regs);if (retval)goto bad_fork_cleanup_namespace;p->semundo = NULL;/* 将子进程task_struct结构的self_exec_id赋给parent_exec_id */ p->parent_exec_id = p->self_exec_id;p->swappable = 1;/* 新进程已经完成初始化,可以换出内存,所以将p->swappable赋1 */p->exit_signal = clone_flags & CSIGNAL;/* 设置系统强行退出时发出的信号*/p->pdeath_signal = 0;/* 设置p->pdeath_signal *//* * Share the timeslice between parent and child, thus the* total amount of pending timeslices in the system doesnt change,* resulting in more scheduling fairness.*/__save_flags(flags);__cli();if (!current->time_slice)/* 将父进程的时间片减半*/BUG();p->time_slice = (current->time_slice + 1) >> 1;p->first_time_slice = 1;current->time_slice >>= 1;p->sleep_timestamp = jiffies;if (!current->time_slice) {current->time_slice = 1;scheduler_tick(0,0);}__restore_flags(flags);retval = p->pid;/* 如果一切顺利,将子进程的pid作为返回值*/p->tgid = retval;INIT_LIST_HEAD(&p->thread_group);/* Need tasklist lock for parent etc handling! */write_lock_irq(&tasklist_lock);/* 给进程队列加锁*//* CLONE_PARENT re-uses the old parent */p->p_opptr = current->p_opptr;p->p_pptr = current->p_pptr;if (!(clone_flags & CLONE_PARENT)) {p->p_opptr = current;if (!(p->ptrace & PT_PTRACED))p->p_pptr = current;}if (clone_flags & CLONE_THREAD) {p->tgid = current->tgid;list_add(&p->thread_group, ¤t->thread_group);}SET_LINKS(p);/* 将子进程的task_struct结构链入进程队列*/hash_pid(p);/* 将子进程的task_struct结构链入进程hash表*/nr_threads++;/* 系统进程计数递增一*/write_unlock_irq(&tasklist_lock);/* 解除对进程队列的封锁*/if (p->ptrace & PT_PTRACED)send_sig(SIGSTOP, p, 1);wake_up_forked_process(p); /* 最后做这件事,唤醒子进程*/++total_forks;/* total_forks增一*/if (clone_flags & CLONE_VFORK)wait_for_completion(&vfork);elsecurrent->need_resched = 1;fork_out:/* 若是vfork()调用do_fork,发down信号*/return retval;/* 退出do_fork(),返回retval值*/bad_fork_cleanup_namespace:exit_namespace(p);bad_fork_cleanup_mm:exit_mm(p);bad_fork_cleanup_sighand:/* 处理子进程task_struct结构与信号处理相关的数据成员, 并删除信号队列中与子进程相* 关的信号量*/exit_sighand(p);bad_fork_cleanup_fs:/* 处理子进程task_struct结构与文件系统信息相关的数据成员*/exit_fs(p); /* blocking */bad_fork_cleanup_files:/* 处理子进程task_struct结构与打开文件表相关的数据成员, 并释放子进程的files_struct* 结构*/exit_files(p); /* blocking */bad_fork_cleanup:/* 若正在执行的代码是符合iBCS2标准的程序,则减少相对应模块的引用数目*/put_exec_domain(p->exec_domain);if (p->binfmt && p->binfmt->module)__MOD_DEC_USE_COUNT(p->binfmt->module);bad_fork_cleanup_count:/* 若正在执行的代码属于全局执行文件结构格式则减少相对应模块的引用数目*/atomic_dec(&p->user->processes);free_uid(p->user);/* 清除子进程在user队列中的信息*/bad_fork_free:free_task_struct(p);/* 释放子进程的task_struct结构*/goto fork_out;}三)、程序框图如下:。