linux0.11文件分析

在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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/405689.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

嵌入式开发过程中结构体字节对齐问题pragma pack(1)

一、引言 曾经刚入门嵌入式在开发一个应用时&#xff0c;用到了自定义结构体&#xff0c;底层嵌入式单片机运行该结构体没问题&#xff0c;但是在Qt开发应用软件对接协议时&#xff0c;一直通不过&#xff0c;仔细分析才发现是QT这边的结构体字节并没有按照单字节对齐&#xf…

Exchange2003-2010迁移系列之二,迁移前的准备工作(上)

Exchange2010迁移前的准备工作&#xff08;上&#xff09; 上篇博文发出后&#xff0c;很多博友支持得非常给力&#xff0c;在此一并谢过&#xff01;也有一些博友反映看得不是很明白&#xff0c;但仍然支持…..本文中首先就环境问题再为大家解释一下&#xff0c;然后介绍如何进…

BMP图像文件格式分析附带图解

From: http://www.raidcn.com/js/BMPTuXiangWenJianGeShiFenXiFuDaiTuJie.html 认识BMP文件格式&#xff0c;以及bmp文件存储结构 &#xff0c;通过winhex查看文件结构解析。 一、认识BMP文件格式. 1、 BMP格式是由微软公司开发。通常BMP图像文件的后缀名是BMP&#xff0c;但…

matlab安装MinGW-64代码C/C++编译器的方法

一、说明 matlab中编写的m文件转成C/C代码&#xff0c;以及matlab中执行C/C带啊&#xff0c;需要用到mex 查看matlab是否支持可以输入mex -setup&#xff1a; 二、安装 如果不支持&#xff0c;没找到&#xff0c;则需要重新安装&#xff0c;下载地址&#xff1a;http://tdm-…

mybatis+spring+c3p0+maven+ehcache

项目截图 pom.xml如下 <project xmlns"http://maven.apache.org/POM/4.0.0" xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">…

windbg linux内核调试,windbg调试虚拟机XP系统

一、先介绍一下被调试的虚拟机系统环境:虚拟机:vmware workstation 10.0版本虚拟机操作系统: Microsoft windows xp professional 2002 service pack3cpu:2.8GHz,2.64GB内存二、这个没有直接关系。做个笔记而已。1.在XP系统中&#xff0c;创建了一个first.c文件测试代码如下:#i…

VC屏幕截图,保存为Bmp文件

新建一个MFC基于对话框的应用程序&#xff0c;在界面上放一个Button&#xff0c;为其实现点击事件&#xff0c;代码如下&#xff1a; void CScreenShotDlg::OnBtnScreenshot() {RECT rect {0, 0, 1900, 1000};HBITMAP hbmp CopyScreenToBitmap(&rect);SaveBitmapToFile(h…

C#反射技术在多语言实现中的实际用处参考,让初学者学技术有个针对性【附源码】...

做软件&#xff0c;有点儿类似铁人三项比赛&#xff1f;赛跑、射击、游泳? 光某个环节突出&#xff0c;也没多大用&#xff0c;需要整体能力都强&#xff0c;能把整体都可以搞定&#xff0c;才容易得到比赛的胜利&#xff0c;光某一环节非常优秀&#xff0c;也赢得不来整个比…

C语言中的格式化打印printf/sprintf以及嵌入式printf重定向进行DEBUG

一、printf描述 在C语言中&#xff0c;打印函数主要包括printf/sprintf/fprintf/snprintf等等&#xff0c;目的是将“给定的内容”按照“指定的格式”输出到“指定目标内”。通常要使用时&#xff0c;需要包括#inlcude <stdio.h>头文件。 用法为&#xff1a;void print…

华为网卡支持linux,在openwrt下对华为WA633无线AP的千兆网卡驱动进行支持

1.下面是这款AP的全裸图&#xff0c;AP的无线网卡采用了AR9223&#xff0c;PHY采用了博通的BCM5461&#xff0c;主控CPU位octeon 500&#xff0c;射频功放采用的是RF5602方案。由于这款CPU并不常见&#xff0c;我至今未在网上找到它的datasheet&#xff0c;导致我们在玩这款AP的…

hdu120118岁生日

Problem DescriptionGardon的18岁生日就要到了&#xff0c;他当然很开心&#xff0c;可是他突然想到一个问题&#xff0c;是不是每个人从出生开始&#xff0c;到达18岁生日时所经过的天数都是一样的呢&#xff1f;似乎并不全都是这样&#xff0c;所以他想请你帮忙计算一下他和他…

React开发(223):详情页根据数组map处理返回值

<Col span{6}>{isDicTonList &&isDicTonList.map((item, index) > {if (item.key afterDetail.status) {return item.value;}})}</Col>

Linux下C语言实现LCD屏幕截图

From: http://blog.chinaunix.net/uid-24789420-id-3191806.html 一、概述 最近看到网上有人问怎么用C语言实现屏幕截图&#xff0c;刚好自己也在研究Linux驱动&#xff0c;于是花了半天时间把Linux的FrameBuffer驱动看懂了个七八&#xff0c;接着就动手写了个LCD屏幕截图的应…

C语言中#、##宏定义的用法

一、#的用法 #用于编译器编译过程进行预处理。 1、宏定义 #define ON 1#ifndef _PARA_ #define _PARA_ #enddef#ifdef _PARB_ #define DEFAULT_SIZE 1024 #enddef2、宏开关 #if VAR ... #elif ... #end3、显示设定错误 #error ERROR: Not Define4、设置字节对齐 #pragma pac…

linux 正则表达式 视频教程,30分钟带你玩转正则表达式

定义&#xff1a;正则表达式说白了就是有普通字符、以及特殊字符组成的文子模式。{匹配模式标准}正则表达式将会作为一个模板与所搜索的字符串进行匹配。可以让使用者轻易达到搜寻/删除/取代某些特定字符的处理程序。此外vim、grep、find、awk、sed等命令都支持正则表达式注&am…

React开发(224):ant design label绑定值

<Col span{12}><Form className{form-customer} label"同意退运费"><span style{{ fontSize: 14 }}>&#xffe5;</span><Form.Item style{{ width: 20% }}>{getFieldDecorator(freight)(<InputNumber step{1} precision{2} min{0…

数据采集工具flume

概述 flume是在2011年被首次引入到Cloudera的CDH3分发中&#xff0c;2011年6月&#xff0c;Cloudera将flume项目捐献给Apache基金会。2012年&#xff0c;flume项目从孵化器变成了顶级项目&#xff0c;在孵化的这一年中&#xff0c;开发人员就已经开始基于Star Trek Themed标签对…

电脑SSH登陆树莓派Raspberry的两种方式

采用SSH登陆Raspberry需要提前知道Raspberry的IP&#xff0c;SSH登陆端口为22&#xff0c;这里分享两种基于SSH网络登陆树莓派的方式。 一、利用路由器搭建局域网登陆树莓派 1、用路由器搭建局域网&#xff0c;电脑无线或有线方式连接路由器&#xff0c;树莓派用网线连接路由…

linux命令修改内容怎么回退,linux命令(修改).doc

linux命令(修改)第一组 用户管理类命令1 添加用户useradd [选项] 用户名范例&#xff1a;useradd davidls /home vim /etc/passwd2 修改密码passwd [选项] 用户名范例&#xff1a;useradd davidls /home passwd david(修改密码)3 删除用户userdel [选项] 用户名范例&#xff1a…

使用数据库的压测工具super-smack测试mysql数据库性能

一、下载super-smack下载地址&#xff1a;http://vegan.net/tony/supersmack/源码&#xff1a;http://vegan.net/tony/supersmack/super-smack-1.3.tar.gz二、编译及安装配置编译选项&#xff1a;./configure --prefix/usr/local/super-smack-1.3 --with-mysql --with-smacks-d…