《linux 内核分析》 第6周 进程创建及描述

王一+ 《Linux内核分析》MOOC课程http://mooc.study.163.com/course/USTC-1000029000

一、task_struct

操作系统的三大核心功能:1、进程管理 2、内存管理 3、 文件系统

 摘抄task_struct,并注释

//进程状态

1236    volatile long state;    /* -1 unrunnable, 0 runnable, >0 stopped */

//进程的内核堆栈
1237    void *stack;
1238    atomic_t usage;

//每个进程的状态
1239    unsigned int flags;    /* per process flags, defined below */
1240    unsigned int ptrace;
1241
 
1251    int on_rq;
1252 //进程调度相关代码
1253    int prio, static_prio, normal_prio;
1254    unsigned int rt_priority;
1255    const struct sched_class *sched_class;
1256    struct sched_entity se;
1257    struct sched_rt_entity rt;
1258#ifdef CONFIG_CGROUP_SCHED
1259    struct task_group *sched_task_group;
1260#endif
1261    struct sched_dl_entity dl;
1262
1263#ifdef CONFIG_PREEMPT_NOTIFIERS
1264    /* list of struct preempt_notifier: */
1265    struct hlist_head preempt_notifiers;
1266#endif
 
1290
1291#if defined(CONFIG_SCHEDSTATS) || defined(CONFIG_TASK_DELAY_ACCT)
1292    struct sched_info sched_info;
1293#endif
1294 //进程的链表
1295    struct list_head tasks;
 
1300//进程虚拟内存地址相关代码
1301    struct mm_struct *mm, *active_mm;
1302#ifdef CONFIG_COMPAT_BRK
1303    unsigned brk_randomized:1;
1304#endif
1305    /* per-thread vma caching */
1306    u32 vmacache_seqnum;
1307    struct vm_area_struct *vmacache[VMACACHE_SIZE];
1308#if defined(SPLIT_RSS_COUNTING)
1309    struct task_rss_stat    rss_stat;
1310#endif
1311 //任务状态及信号相关状态
1312    int exit_state;
1313    int exit_code, exit_signal;
1314    int pdeath_signal;  /*  The signal sent when the parent dies  */
1315    unsigned int jobctl;    /* JOBCTL_*, siglock protected */
1316
1317    /* Used for emulating ABI behavior of previous Linux versions */
1318    unsigned int personality;
1319
1320    unsigned in_execve:1;    /* Tell the LSMs that the process is doing an
1321                 * execve */
1322    unsigned in_iowait:1;
1323
1324    /* Revert to default priority/policy when forking */
1325    unsigned sched_reset_on_fork:1;
1326    unsigned sched_contributes_to_load:1;
1327
1328    unsigned long atomic_flags; /* Flags needing atomic access. */
1329// 进程标示符
1330    pid_t pid;
1331    pid_t tgid;
1332
 
1337    /*
1338     * pointers to (original) parent process, youngest child, younger sibling,
1339     * older sibling, respectively.  (p->father can be replaced with
1340     * p->real_parent->pid)
1341     */
1342    struct task_struct __rcu *real_parent; /* real parent process */
1343    struct task_struct __rcu *parent; /* recipient of SIGCHLD, wait4() reports */
     //进程树有关
1344    /*
1345     * children/sibling forms the list of my natural children
1346     */
1347    struct list_head children;    /* list of my children */
1348    struct list_head sibling;    /* linkage in my parent's children list */
1349    struct task_struct *group_leader;    /* threadgroup leader */
1350
1351    /*
1352     * ptraced is the list of tasks this task is using ptrace on.
1353     * This includes both natural children and PTRACE_ATTACH targets.
1354     * p->ptrace_entry is p's link on the p->parent->ptraced list.
1355     */
1356    struct list_head ptraced;
1357    struct list_head ptrace_entry;
1358
1359    /* PID/PID hash table linkage. */
1360    struct pid_link pids[PIDTYPE_MAX];
1361    struct list_head thread_group;
1362    struct list_head thread_node;
1363
1364    struct completion *vfork_done;        /* for vfork() */
1365    int __user *set_child_tid;        /* CLONE_CHILD_SETTID */
1366    int __user *clear_child_tid;        /* CLONE_CHILD_CLEARTID
1411 //这个任务的cpu相关的数据
1412    struct thread_struct thread;
1413/* filesystem information */
1414    struct fs_struct *fs;
1415/* open file information */
1416    struct files_struct *files;
1417/* namespaces */
1418    struct nsproxy *nsproxy;
1419/* signal handlers */
1420    struct signal_struct *signal;
1421    struct sighand_struct *sighand;
1487/* journalling filesystem info */
1488    void *journal_info;
1489//块设备信息链表
1490/* stacked block device info */
1491    struct bio_list *bio_list;
1492
1493#ifdef CONFIG_BLOCK
1494/* stack plugging */
1495    struct blk_plug *plug;
1496#endif
 

进程的状态切换过程:

进程树和相互的关系:

进程的内核堆栈和thread_info的关系:

进程堆栈和thread_info使用一个空间,通过使用union的方式来定义,他们的地址开始于2^13的地址,分两个page(8k);

 这样就可以通过esp来获取thread_info的地址:

 __asm__("andl %%esp,%0; ":"=r" (ti) : "0" (~(THREAD_SIZE - 1)));//通过屏蔽esp低13位,返回ti

二、进程的创建

 进程的创建

1、创建线程需要调用通过调用fork系统调用,实现创建子进程,子进程在内核态创建之后,在内核态运行,而父线程返回到主线程运行。

子线程是在ret_from_fork之后执行。

2、、fork创建的过程分析

1)、在此系统中系统调用fork实际上是调用sys_clone,它和其他的两个系统调用都是调用的do_fork();

2)、在do_fork中调用copy_process()来进行进程的复制和修改;


    p = copy_process(clone_flags, stack_start, stack_size,
             child_tidptr, NULL, trace);

3)、在copy_process()中调用dup_task_struct()来实现创建task_struct空间,thread_info和内核堆栈的空间,并且复制task_struct和thread_infgo;

 arch_dup_task_struct(tsk, orig);//复制task_struct;

setup_thread_stack(tsk, orig);//复制thread_info;

4)、在copy_process 中对子线程的task_struct进行设置,然后将复制进程信息。在copy_thread 中将sp和ip指向内核堆栈中的sp和ip,

struct pt_regs *childregs = task_pt_regs(p);

struct pt_regs {
    unsigned long bx;
    unsigned long cx;
    unsigned long dx;
    unsigned long si;
    unsigned long di;
    unsigned long bp;
    unsigned long ax;// 系统调用号和参数
    unsigned long ds;
    unsigned long es;
    unsigned long fs;
    unsigned long gs;
    unsigned long orig_ax; //原来的系统的寄存器保存
    unsigned long ip;
    unsigned long cs;
    unsigned long flags; //本部分为系统自动存储的信息
    unsigned long sp;
    unsigned long ss;
};

p->thread.sp = (unsigned long) childregs;

p->thread.ip = (unsigned long) ret_from_fork;

5)、ENTRY(ret_from_fork) 中jmp syscall_exit(在系统调用system_call中);

retoreALL;iret,返回到用户态;

三)实验调试、

电脑出现问题,无法调试,使用source insight 查看代码:

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

  
 
posted @ 2017-04-02 23:27  AAX  阅读(301)  评论(0)    收藏  举报