外国网站英语要求,建立网站就是制作网页,深圳好的高端企业网站建设公司,html购物网站设计在kernel包中有几个重要的文件夹和文件#xff0c;他们各司其职#xff0c;处理着有关内核的一些功能操作。其中文件夹有三个#xff1a;blk_drv(块设备驱动)#xff0c;chr_drv(字符设备驱动)#xff0c;math(数学协处理器) 文件中asm.s fork.c mktime.c panic.c p…在kernel包中有几个重要的文件夹和文件他们各司其职处理着有关内核的一些功能操作。其中文件夹有三个blk_drv(块设备驱动)chr_drv(字符设备驱动)math(数学协处理器) 文件中asm.s fork.c mktime.c panic.c printk.c sched.c signal.c exit.c sys.c traps.c system_call.c vsprintf.c 该文件夹下的代码文件从功能上来可以分为三类 1.硬件中断处理类程序。asm.s trap.casm.s用于实现大部分硬件异常所引起的中断的汇编语言处理过程。在80X86组成的PC机中采用了两片8259A可编程中断控制芯片。每片可以管理8个中断源。通过多片的级联方式能够构成最多可以管理64个中断向量的系统。在PC/AT系列兼容机中使用了两片8259A芯片共可管理15级中断向量。如下图 对于Linux内核来说中断信号通常分为两类硬件中断和软件中断异常。每个中断时由0-255之间的一个数字来标示。对于中断int0-int310x00--0x1f每个中断的功能有INTEL公司固定设定或者保留用属于软件中断单INTEL公司称之为异常。因为这些中断时在CPU执行指令时探测到异常而引起的。中断int32--int255可以由用户自己设定使用在Linux中int32--int47对应于8259A中断控制芯片发出的硬件中断请求信号IRQ0--IRQ15并把程序编程发出的系统调用system_call中断设置为int128(0x80)。 traps.c程序则实现了asm.s的中断处理过程中调用的C函数。 2.系统调用处理相关程序system_call.s fork.c signal.c sys.c exit.c在Linux中应用程序调用内核的功能是通过中断调用int0x80进行的 3.其他通用类程序schedule.c mktime.c panic.c printk.c vsprintf.c 其中schedule.c最为重要是内核的核心调度程序用于对进程的执行进行切换或改变进程的执行状态。 下面是一些具体的文件 1.system_call.s对于软中断处理过程基本上是首先为调用相应C函数处理程序作准备将一些参数压入堆栈然后调用C函数进行相应功能的处理。 对于硬中断请求型号IRQ发来的中断其处理过程首先是向中断控制芯片8259A发送结束硬件中断控制字指令EOI然后调用相应的C函数处理程序。 对于系统调用的中断处理过程可以把它看做是一个“接口”程序实际每个系统调用功能的处理基本上都是通过调用相应的C函数进行的。即所谓的 下半区 函数。 2.schedule.c是对整个内核进程的调度这里面把代码贴上比说什么都要明白。 /** schedule()是调度函数。这是个很好的代码没有任何理由对它进行修改因为它可以在所有的* 环境下工作比如能够对IO-边界处理很好的响应等。只有一件事值得留意那就是这里的信号* 处理代码。* 注意任务0 是个闲置(idle)任务只有当没有其它任务可以运行时才调用它。它不能被杀* 死也不能睡眠。任务0 中的状态信息state是从来不用的。*/
void
schedule (void)
{int i, next, c;struct task_struct **p; // 任务结构指针的指针。/* check alarm, wake up any interruptible tasks that have got a signal *//* 检测alarm进程的报警定时值唤醒任何已得到信号的可中断任务 */// 从任务数组中最后一个任务开始检测alarm。for (p LAST_TASK; p FIRST_TASK; --p)if (*p){// 如果任务的alarm 时间已经过期(alarmjiffies),则在信号位图中置SIGALRM 信号然后清alarm。// jiffies 是系统从开机开始算起的滴答数10ms/滴答。定义在sched.h 第139 行。if ((*p)-alarm (*p)-alarm jiffies){(*p)-signal | (1 (SIGALRM - 1));(*p)-alarm 0;}// 如果信号位图中除被阻塞的信号外还有其它信号并且任务处于可中断状态则置任务为就绪状态。// 其中~(_BLOCKABLE (*p)-blocked)用于忽略被阻塞的信号但SIGKILL 和SIGSTOP 不能被阻塞。if (((*p)-signal ~(_BLOCKABLE (*p)-blocked)) (*p)-state TASK_INTERRUPTIBLE)(*p)-state TASK_RUNNING; //置为就绪可执行状态。}/* this is the scheduler proper: *//* 这里是调度程序的主要部分 */while (1){c -1;next 0;i NR_TASKS;p task[NR_TASKS];// 这段代码也是从任务数组的最后一个任务开始循环处理并跳过不含任务的数组槽。比较每个就绪// 状态任务的counter任务运行时间的递减滴答计数值哪一个值大运行时间还不长next 就// 指向哪个的任务号。while (--i){if (!*--p)continue;if ((*p)-state TASK_RUNNING (*p)-counter c)c (*p)-counter, next i;}// 如果比较得出有counter 值大于0 的结果则退出124 行开始的循环执行任务切换141 行。if (c)break;// 否则就根据每个任务的优先权值更新每一个任务的counter 值然后回到125 行重新比较。// counter 值的计算方式为counter counter /2 priority。[右边counter0??]for (p LAST_TASK; p FIRST_TASK; --p)if (*p)(*p)-counter ((*p)-counter 1) (*p)-priority;}switch_to (next); // 切换到任务号为next 的任务并运行之。
}pause()系统调用。转换当前任务的状态为可中断的等待状态并重新调度。
// 该系统调用将导致进程进入睡眠状态直到收到一个信号。该信号用于终止进程或者使进程调用
// 一个信号捕获函数。只有当捕获了一个信号并且信号捕获处理函数返回pause()才会返回。
// 此时pause()返回值应该是-1并且errno 被置为EINTR。这里还没有完全实现直到0.95 版。
int
sys_pause (void)
{current-state TASK_INTERRUPTIBLE;schedule ();return 0;
}// 把当前任务置为不可中断的等待状态并让睡眠队列头的指针指向当前任务。
// 只有明确地唤醒时才会返回。该函数提供了进程与中断处理程序之间的同步机制。
// 函数参数*p 是放置等待任务的队列头指针。参见列表后的说明。
void
sleep_on (struct task_struct **p)
{struct task_struct *tmp;// 若指针无效则退出。指针所指的对象可以是NULL但指针本身不会为0)。if (!p)return;if (current (init_task.task)) // 如果当前任务是任务0则死机(impossible!)。panic (task[0] trying to sleep);tmp *p; // 让tmp 指向已经在等待队列上的任务(如果有的话)。*p current; // 将睡眠队列头的等待指针指向当前任务。current-state TASK_UNINTERRUPTIBLE; // 将当前任务置为不可中断的等待状态。schedule (); // 重新调度。// 只有当这个等待任务被唤醒时调度程序才又返回到这里则表示进程已被明确地唤醒。// 既然大家都在等待同样的资源那么在资源可用时就有必要唤醒所有等待该资源的进程。该函数// 嵌套调用也会嵌套唤醒所有等待该资源的进程。然后系统会根据这些进程的优先条件重新调度// 应该由哪个进程首先使用资源。也即让这些进程竞争上岗。if (tmp) // 若还存在等待的任务则也将其置为就绪状态唤醒。tmp-state 0;
}// 将当前任务置为可中断的等待状态并放入*p 指定的等待队列中。参见列表后对sleep_on()的说明。
void
interruptible_sleep_on (struct task_struct **p)
{struct task_struct *tmp;if (!p)return;if (current (init_task.task))panic (task[0] trying to sleep);tmp *p;*p current;
repeat:current-state TASK_INTERRUPTIBLE;schedule ();// 如果等待队列中还有等待任务并且队列头指针所指向的任务不是当前任务时则将该等待任务置为// 可运行的就绪状态并重新执行调度程序。当指针*p 所指向的不是当前任务时表示在当前任务被放// 入队列后又有新的任务被插入等待队列中因此既然本任务是可中断的就应该首先执行所有// 其它的等待任务。if (*p *p ! current){(**p).state 0;goto repeat;}// 下面一句代码有误应该是*p tmp让队列头指针指向其余等待任务否则在当前任务之前插入// 等待队列的任务均被抹掉了。参见图4.3。*p NULL;if (tmp)tmp-state 0;
}// 唤醒指定任务*p。
void
wake_up (struct task_struct **p)
{if (p *p){(**p).state 0; // 置为就绪可运行状态。*p NULL;}
}3.signal.c主要对信号的判断对于一个进程当收到一个信号时可以由三种不同的处理或者操作方式。a。忽略该信号但是SIGKILL和SIGSTOP不能忽略。b。捕获该信号。c。执行默认操作内核为每种信号都提供一种默认操作通常这些默认操作就是终止进程的执行。对于信号的具体内容还有待研究 4.fork.c主要是copy_process函数。该函数通过get_free_page ()为新任务数据结构分配内存函数得到一个新的task_struct空间。然后将current的信息复制给对方。得到新进程 ----转载于:https://www.cnblogs.com/Ph-one/p/4578772.html