理解进程创建、可执行文件的加载和进程执行进程切换,重点理解分析fork、execve和进程切换

本文详细分析了Linux进程的创建,包括fork函数的内核处理过程do_fork,以及如何使用gdb跟踪分析fork系统调用。同时,探讨了编译链接过程和ELF可执行文件格式。通过编程示例展示了如何使用exec*函数加载可执行文件。此外,还解析了execve系统调用在内核中的处理流程,并讲解了Linux系统中的进程调度时机以及schedule函数的使用。最后,深入剖析了switch_to汇编代码实现的进程切换细节。
摘要由CSDN通过智能技术生成

学号:384
原创作品转载请注明出处 + https://github.com/mengning/linuxkernel/

实验目标

1.分析fork函数对应的内核处理过程do_fork,理解创建一个新进程如何创建和修改task_struct数据结构

2.使用gdb跟踪分析一个fork系统调用内核处理函数do_fork

3.理解编译链接的过程和ELF可执行文件格式

实验环境

ubuntu系统(ubuntu-16.04.2-desktop-amd64)+ VMware Workstation Pro

一、阅读理解task_struct数据结构

代码来源:http://codelab.shiyanlou.com/xref/linux-3.18.6/include/linux/sched.h#1235
该结构部分代码:

struct task_struct {
   
	volatile long state;	/* -1 unrunnable, 0 runnable, >0 stopped */
	void *stack;
	atomic_t usage;
	unsigned int flags;	/* per process flags, defined below */
	unsigned int ptrace;

#ifdef CONFIG_SMP
	struct llist_node wake_entry;
	int on_cpu;
	struct task_struct *last_wakee;
	unsigned long wakee_flips;
	unsigned long wakee_flip_decay_ts;

	int wake_cpu;
#endif
	int on_rq;

	int prio, static_prio, normal_prio;
	unsigned int rt_priority;
	const struct sched_class *sched_class;
	struct sched_entity se;
	struct sched_rt_entity rt;
#ifdef CONFIG_CGROUP_SCHED
	struct task_group *sched_task_group;
#endif
	struct sched_dl_entity dl;

#ifdef CONFIG_PREEMPT_NOTIFIERS
	/* list of struct preempt_notifier: */
	struct hlist_head preempt_notifiers;
#endif

#ifdef CONFIG_BLK_DEV_IO_TRACE
	unsigned int btrace_seq;
#endif

	unsigned int policy;
	int nr_cpus_allowed;
	cpumask_t cpus_allowed;
	...
}

在阅读这个结构体之前,我们必须了解进程与程序的区别,进程是程序的一个执行的实例,为了管理进程,操作系统必须对每个进程所做的事情进行清楚的描述,为此,操作系统使用数据结构来代表处理不同的实体,这个数据结构就是通常所说的进程描述符或进程控制块(PCB),在linux操作系统下这就是task_struct结构 ,它包含了这个进程的所有信息,在任何时候操作系统都能够跟踪这个结构的信息。该结构定义位于/include/linux/sched.h

对于进程控制块PCB—task_struct:

状态信息:如就绪、执行等状态
链接信息:用来描述进程之间的家庭关系,例如指向父进程、子进程、兄弟进程等PCB的指针
各种标识符:如进程标识符、用户及组标识符等
时间和定时器信息:进程使用CPU时间的统计等
调度信息:调度策略、进程优先级、剩余时间片大小等
处理机环境信息:处理器的各种寄存器以及堆栈情况等
虚拟内存信息:描述每个进程所拥有的地址空间

文件系统信息:记录进程使用文件的情况

PCB几个重要参数

volatile long state;//表示进程的当前状态
unsigned long flags;  //进程标志
long priority;  //进程优先级。 Priority的值给出进程每次获取CPU后可使用的时间(按jiffies计)。优先级可通过系统调用sys_setpriorty改变(在kernel/sys.c中)。
long counter;  //在轮转法调度时表示进程当前还可运行多久。

unsigned long policy;  //该进程的进程调度策略,可以通过系统调用sys_sched_setscheduler()更改(见kernel/sched.c)。

二、分析fork函数对应的内核处理过程do_fork

fork、vfork和clone三个系统调用都可以创建一个新进程,而且都是通过调用do_fork来实现进程的创建;

具体过程如下:fork() -> sys_clone() -> do_fork() -> dup_task_st

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值