在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.c)asm.s用于实现大部分硬件异常所引起的中断的汇编语言处理过程。在80X86组成的PC机中,采用了两片8259A可编程中断控制芯片。每片可以管理8个中断源。通过多片的级联方式,能够构成最多可以管理64个中断向量的系统。在PC/AT系列兼容机中,使用了两片8259A芯片,共可管理15级中断向量。如下图:

对于Linux内核来说,中断信号通常分为两类:硬件中断和软件中断(异常)。每个中断时由0-255之间的一个数字来标示。对于中断int0-int31(0x00--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 时间已经过期(alarm<jiffies),则在信号位图中置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。[右边counter=0??]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

linux0.11文件分析相关推荐

  1. Linux0.11 文件打开open函数(五)

    系列文章目录 Linux 0.11启动过程分析(一) Linux 0.11 fork 函数(二) Linux0.11 缺页处理(三) Linux0.11 根文件系统挂载(四) Linux0.11 文件 ...

  2. 【Linux0.11代码分析】02 之 bootsect.s 启动流程

    [Linux0.11代码分析]02 之 bootsect.s 启动流程 一.boot\bootsect.s 1.1 将bootsect.s 从0x7c00 移动到 0x90000 (512byte) ...

  3. linux0.11内核视频讲解,linux0.11内核分析-setup

    章节目录 上一节讲解了bootsect,由bootsect加载setup进入内存,最后jmpi 0,SETUPSEG跳转到setup程序处. INITSEG = 0x9000 ! we move bo ...

  4. Linux0.11 execve函数(六)

    系列文章目录 Linux 0.11启动过程分析(一) Linux 0.11 fork 函数(二) Linux0.11 缺页处理(三) Linux0.11 根文件系统挂载(四) Linux0.11 文件 ...

  5. 编译linux0.11内核

    编译linux0.11内核 一.实验环境 二.下载文件 三.配置Linux0.11所需环境 四.编译内核 五.运行linux0.11 六.说明 1.setup.sh脚本里进行了什么操作? 2.最后弹出 ...

  6. setup.s 分析—— Linux-0.11 学习笔记(二)

    更新记录 版本 时间 修订内容 1.0 2018-4-14 增加了"获取显示模式"这一节,AL取值的表格 标题: setup.s 分析-- Linux-0.11 学习笔记(二) 老 ...

  7. 对Linux0.11 中 进程0 和 进程1分析

    1. 背景 进程的创建过程无疑是最重要的操作系统处理过程之一,很多书和教材上说的最多的还是一些原理的部分,忽略了很多细节.比如,子进程复制父进程所拥有的资源,或者子进程和父进程共享相同的物理页面,拥有 ...

  8. 操作系统定时器原理分析(基于linux0.11)

    操作系统的定时器原理是,操作系统维护了一个定时器节点的链表,新增一个定时器节点时,设置一个jiffies值,这是触发定时中断的频率.linux0.11版本里是1秒触发100次,即10毫秒一次.加入新增 ...

  9. Linux0.11内核引导启动过程概述

    Linux0.11仅支持x86架构.它的内核引导启动程序在文件夹boot内,共有三个汇编代码文件.按照启动流程依次是: (1)bootsect.s.boot是启动引导的意思,sect即sector,是 ...

最新文章

  1. 避免重复造轮子,我们去哪找FPGA IP或是HDL功能模块?
  2. [HZOI 2016][Tyvj 1729]文艺平衡树 这道题我真是哭了,调了一下午,一晚上
  3. 设计模式(三)--观察者模式
  4. tomcat默认连接数_Tomcat的默认连接器
  5. css React 单行省略和多行省略
  6. vue domo网站_DOMO与Tableau-逐轮
  7. 好用的书法字体素材,可以用于各种项目;从商标和品牌到邀请、海报等
  8. Python实现Matlab绘制散点图
  9. 杭电ACM2030题
  10. C#编程总结(四)多线程应用(进度条的编程问题)——转自http://www.cnblogs.com/yank/p/3232955.html...
  11. 用过凡科建站的出来说一下可靠吗,免费版的怎样
  12. wpf-简单悬浮窗的定位问题
  13. excel 批量生成条码
  14. MySQL为JSON字段创建索引(Multi-Valued Indexes 多值索引)
  15. 专转本-计算机二级习题1
  16. 大学计算机在线作业答案,上海交通大学《计算机》在线作业二参考答案
  17. Java基础之jvm,堆的分类新生代、老生代和永久代详解
  18. CSS引入外部艺术字体
  19. 跟着东木学:UG_NX视频教程大纲,在这里你可以学到...
  20. Spring AOP知识总结

热门文章

  1. PS图层混合模式中英文对照
  2. 关于自定义控件,可以编译通过,但是用时提示无法创建新实例。
  3. 个人材料(上报公司)
  4. 机器学习12推荐系统
  5. html - meta name=viewport content=XX/ 标签常见属性及说明
  6. deferred Transports Protocols 简单介绍
  7. Nginx 实战(一) 集群环境搭建
  8. CSS实现半透明div层的方法
  9. 霸县计算机学校,廊坊中专排名2021
  10. 709. 转换成小写字母