
linux内核
love-xiao-forever
这个作者很懒,什么都没留下…
展开
-
do_group_exit()函数
do_group_exit()函数杀死属于current线程组的所有进程。它接受进程终止代码作为参数,进程终止代号可能是系统调用exit_group()指定的一个值,也可能是内核提供的一个错误代号。该函数执行下述操作:检查退出进程的SIGNAL_GROUP_EXIT标志是否不为0,如果不为0,说明内核已经开始为线性组执行退出的过程。在这种情况下,就把存放在current->signal原创 2013-06-08 14:47:20 · 2826 阅读 · 0 评论 -
创建进程
创建进程:传统的unix操作系统以统一的方式对待所有的进程,子进程拷贝父进程所有的全部资源,这种方法使进程的创建效率非常慢。实际上,子进程不必读或者写父进程所拥有的全部资源。现在unix内核使用三种不同的机制来解决这个问题:1,写时复制技术允许父子进程读相同的物理页。2,轻量级进程允许父子进程共享进程在内核的很多数据结构,如页表,打开文件表,信号处理3,Vfork()系统调用创建的原创 2013-06-07 20:42:36 · 1157 阅读 · 0 评论 -
copy_process()函数
copy_process()函数完成的工作很有意思:.调用dup_task_struct()为新进程创建一个内核栈、thread_info结构和task_struct,这些值与当前进程的值相同。此时,子进程和父进程的描述符是完全相同的。.检查新创建的这个子进程后,当前用户所拥有的进程数目没有超出给他分配的资源的限制。.现在,子进程着手使自己与父进程区别开来。进程描述符内的许多成员都要被原创 2013-06-07 20:56:00 · 2060 阅读 · 0 评论 -
笔记(进程篇 详解 上)--深入理解linux内核
一、进程状态进程描述符中的state字段描述了进程当前所处的状态,它有一组标志组成,每个标志描述一种可能的进程状态,这些状态是互斥的,也就是说在同一时刻,只能设置一个状态1)运行状态:TASK_RUNNING,进程要么在CPU上运行,要么准备执行2)可中断的等待状态:TASK_INTERRUPTIBLE,进程被挂起,直到收到某个消息,唤醒该进程3)不可中断的等待状态:TASK_UN原创 2013-06-08 09:23:11 · 1481 阅读 · 0 评论 -
进程0
进程0:所有进程的祖先都叫进程0,idle进程,或因为历史的原因叫做swapper进程,它是在linux的初始化阶段从无到有创建的一个内核线程。这个进程祖先使用下列静态分配的数据结构,所以其他进程的数据结构都是动态分配的。 1、存放在Init_task变量中的进程描述符,由INIT_TASK宏完成对它的初始化 2、存放在init_thread_union变量中的thread_info描述符原创 2013-06-08 10:22:30 · 1146 阅读 · 0 评论 -
Linux中的clone()函数
int clone(int (*fn)(void *), void *child_stack, int flags, void *arg);这里fn是函数指针,我们知道进程的4要素,这个就是指向程序的指针,就是所谓的“剧本", child_stack明显是为子进程分配系统堆栈空间(在linux下系统堆栈空间是2页面,就是8K的内存,其中在这块内存中,低地址上放入了值,这个值就是进程控制块tas原创 2013-06-07 20:50:14 · 1401 阅读 · 0 评论 -
do_fork()函数
do_fork()函数利用辅助函数copy_process()来创建进程描述符以及子进程执行所需要的所有其他内核数据结构。下面是do_fork()执行的主要步骤:通过查找pidmap_array位图,为子进程分配新的PID检查父进程的ptrace字段(current->ptrace):如果它的值不等于0,说明有另外一个进程正在跟踪父进程,因而,do_fork()检查de原创 2013-06-07 20:52:27 · 1377 阅读 · 0 评论 -
内核线程
内核线程与普通进程的区别:1、内核线程只运行在内核态,而普通进程既可以运行在内核态也可以运行在用户态2、内核线程只允许在内核态,所以只使用大于page_offset的线性地址空间 而普通进程不管是在用户态还是内核态,普通进程可以用4GB的线性地址空间原创 2013-06-07 21:36:04 · 1049 阅读 · 0 评论 -
创建一个内核线程
kernel_thread()韩珊瑚创建一个新的内核线程,它接受的参数有:所要执行的内核函数的地址(fn),要传递给函数的参数(arg),一组clone标志(flags).该函数的本质上已下面的方式调用do_fork():do_fork(flags|CLONE_VM|CLONE_UNTRACED,0,pregs,0,NULL,NULL);CLONE_VM标志避免复制调用进程的页表:由于新内原创 2013-06-08 09:57:44 · 986 阅读 · 0 评论 -
进程1
由进程0创建的内核线程执行Init函数,init()函数一次完成内核初始化。init()函数调用execve()系统调用装入可执行程序Init.结果,init进程变为一个普通进程,且拥有自己的每进程内阁数据结构。在系统关闭之前,init进程一直存活,因为它创建和监控在操作系统外层执行的所有进程的活动。原创 2013-06-08 10:29:10 · 850 阅读 · 0 评论 -
do_exit()函数
所有进程的终止都是由do_exit()函数来处理的,这个函数从内核数据结构中删除对终止进程的大部分引用。do_exit()函数接受进程的终止代号作为参数并执行下列操作:把进程描述符的flag字段设置为PF_EXITING标志,以表示进程正在被删除。如果需要,通过函数del_timer_sync()从动态定时器队列中删除进程描述符。分别调用exit_mm()、exit_s原创 2013-06-08 14:49:28 · 2988 阅读 · 0 评论 -
switch_to宏
switch_to宏用于进程切换,给定了前一个进程结构体指针prev,以及需要切换到的进程结构体指针next,从prev切换到next.但是,实际上,switch_to宏有三个参数,除了上面说的两个参数之外,还有一个last参数.而且使用switch_to宏的时候传入的prev和last都是同一个值,比如会这么调用这个宏:switch_to(prev,next,prev).考虑一种原创 2013-06-07 15:00:56 · 2890 阅读 · 1 评论 -
等待队列
等待队列有很多用途,尤其用在中断处理、进程同步以及定时。等待队列实现了再事件上的条件等待:希望等待特定事件的进程把自己放进合适的等待队列,并放弃控制权。因此,等待队列表示一组睡眠的进程,当某一条件为真时,由内核唤醒它们。等待队列由双向链表实现,其元素包括指向进程描述符的指针,每个等待队列都有一个等待队列头,等待队列头是一个类型为wait_queue_head_t的数据结构Struct __原创 2013-06-07 09:20:23 · 879 阅读 · 0 评论 -
笔记(进程篇 详解 中)--深入理解linux内核
一、进程切换与硬件上下文1,进程切换:为了控制进程的执行,内核必须有能力挂起正在CPU上运行的进程,并恢复之前被挂起的某个进程,这种能力叫做进程切换或者任务切换或者上下文切换。2,硬件上下文: 尽管每个进程可以拥有属于自己的地址空间,但是所有进程必须共享CPU寄存器,因此,在恢复一个进程的执行前,内核必须确保每个寄存器装入了挂起进程时的值 进程恢复执行前必须装入寄原创 2013-06-11 09:45:28 · 1302 阅读 · 0 评论 -
linux内核学习笔记----进程状态
进程描述符中的state字段描述了进程当前所处的状态,它有一组标志组成,每个标志描述一种可能的进程状态,这些状态是互斥的,也就是说在同一时刻,只能设置一个状态 一、运行状态:TASK_RUNNING,进程要么在CPU上运行,要么准备执行二、可中断的等待状态:TASK_INTERRUPTIBLE,进程被挂起,直到收到某个消息,唤醒该进程三、不可中断的等待状态:TASK_UNINT原创 2013-06-06 14:24:45 · 1184 阅读 · 0 评论 -
进程描述符处理
thread_info数据结构和进程内核栈存放在两个连续的页框中,,如图所示,thread_info结构从0x015fa000地址开始存放,而进程内核栈从ox015fc000地址处开始存放,esp寄存器指向地址为0x015ff878的当前栈顶。内核使用alloc_thread_info和free_thrad_info宏分配和释放存储thread_info结构和内核栈的内存区原创 2013-06-06 15:06:06 · 868 阅读 · 0 评论 -
linux内核中的双向链表
Linux内核定义了list_head数据结构,字段next和prev分别表示通用双向链表向前和向后的指针元素。LIST——HEAD(list_name):创建新链表list_add(n,p):把n指向的元素插入p指向的特定元素之后list_add_tail(n,p),把n指向的元素插入到p指向的特定元素之前list_del(p):删除p指向的元素list——empty(p)原创 2013-06-06 15:42:05 · 1025 阅读 · 0 评论 -
task_running状态下的进程链表
早先的linux版本把所有的可运行进程都放在同一个运行队列中(链表),由于维持这个链表按优先级排序时开销过大,因此,早期的调度程序不得在选择最佳可运行进程时扫描整个队列 linux2.6实现方法有些不同,其目的是在固定时间内选出最佳可运行进程,与队列中的进程数目无关。 提高调度运行速度的方法是建立多个可运行进程链表,每种进程优先权对应一个不同的链表。如果某个进程的优先权等于原创 2013-06-06 20:06:08 · 1140 阅读 · 0 评论 -
等待队列的操作
可以使用DECLARE_WAIT_QUEUE_HEAD(name)宏定义一个新等待队列的头,它静态地声明一个叫name的等待队列的头变量并对该变量的lock和task_list字段进行初始化。函数init_waitqueue_head()可以用来初始化动态分配的等待队列的头变量。函数init_waitqueue_entry(p,q),如下所示初始化wait_queue_t结构的变量q:q-原创 2013-06-07 10:10:14 · 1158 阅读 · 0 评论 -
进程切换与硬件上下文
1,进程切换:为了控制进程的执行,内核必须有能力挂起正在CPU上运行的进程,并恢复之前被挂起的某个进程,这种能力叫做进程切换或者任务切换或者上下文切换。2,硬件上下文: 尽管每个进程可以拥有属于自己的地址空间,但是所有进程必须共享CPU寄存器,因此,在恢复一个进程的执行前,内核必须确保每个寄存器装入了挂起进程时的值 进程恢复执行前必须装入寄存器的那一组数据成为硬件上下原创 2013-06-07 12:46:05 · 3577 阅读 · 0 评论 -
进程间的关系
程序创建的进程具有父子关系,如果一个进程创建了多个进程时,这些子进程之间具有兄弟关系。在进程描述符中引入几个字段表示这些关系,进程0和1是有内核创建的,进程1是所有进程的祖先。P的进程描述符中表示进程亲属关系的字段的描述real_parent:指向了创建P的进程描述符,如果P的父进程不存在,就指向进程1的进程描述符。parent:指向P的当前父进程,一般与real_parent保持一致原创 2013-06-07 08:46:21 · 1481 阅读 · 0 评论 -
进程删除
Unix允许进程查询内核以获得其父进程的PID,或者其任何于进程的执行状态。例如,进程可以创建一个子进程来执行特定的任务,然后调用诸如wait()这样的一些库函数检查子进程是否终止。如果子进程已经终止,那么,它的终止代号将告诉父进程这个任务是否已成功地完成。为了遵循这些设计选择,不允许Unix内核在进程一终止后就丢弃包含在进程描述符字段中的数据。只有父进程发出了与被终止的进程相原创 2013-06-08 14:50:44 · 1047 阅读 · 0 评论