该目录下的代码文件从功能上可以分为三类,一类是硬件(异常)中断处理程序文件,一类是系统
调用服务处理程序文件,另一类是进程调度等通用功能文件。参见图1.5。我们现在根据这个分类方式,
从实现的功能上进行更详细的说明。
5.1.1.1 硬件中断处理类程序
主要包括两个代码文件:asm.s 和traps.c 文件。asm.s 用于实现大部分硬件异常所引起的中断的汇
编语言处理过程。而traps.c 程序则实现了asm.s 的中断处理过程中调用的c 函数。另外几个硬件中断
处理程序在文件system_call.s 和mm/page.s 中实现。
更多电子书教程下载请登陆http://down.zzbaike.com/ebook
本站提供的电子书教程均为网上搜集,如果该教程涉及或侵害到您的版权请联系我们。
第5 章 内核代码 linux/kernel/
72
中断信号通常可以分为两类:硬件中断和软件中断(异常)。每个中断是由0-255 之间的一个数字来
标识。对于中断int0--int31(0x00--0x1f),每个中断的功能是由Intel 固定设定或保留用的, 属于软
件中断,但Intel 称之为异常。因为是由CPU 执行指令时探测到异常时引起的。通常还可分为故障(Fault)
和陷阱(traps)两类。中断int32--int255 (0x20--0xff)可以由用户自己设定。在Linux 系统中,则将
int32--int47(0x20--0x2f)对应于8259A 中断控制芯片发出的硬件中断请求信号IRQ0-IRQ15;并把程序
编程发出的系统调用(system_call)中断设置为int128(0x80)。
asm.s 代码文件主要涉及对Intel 保留中断int0--int16 的处理,其余保留的中断int17-int31 由
Intel 公司留作今后扩充使用。对应于中断控制器芯片各IRQ 发出的int32-int47 的16 个处理程序将分
别在各种硬件(如时钟、键盘、软盘、数学协处理器、硬盘等)初始化程序中处理。Linux 系统调用中
断int128(0x80)的处理则将在kernel/system_call.s 中给出。各个中断的具体定义见代码注释后其它
信息一节中的说明。
对一个硬件异常所引起的中断的处理过程见下度所示(图5.1)。
图5.1 硬件异常(故障、陷阱)所引起的中断处理流程
由于有些异常引起中断时,CPU 内部会产生一个出错代码压入堆栈(异常中断int 8 和int10 - int
14),而其它的中断却并不带有这个出错代码(例如被零除出错和边界检查出错等),因此,asm.s 程序
中将所有中断的处理根据是否携带出错代码而分别进行处理。但处理流程还是一样的。
会产生出错代码的
5.1.1.2 系统调用处理相关程序
Linux 中应用程序调用内核的功能是通过中断调用int 0x80 进行的,寄存器eax 中放调用号。因此
该中断调用被称为系统调用。实现系统调用的相关文件包括system_call.s、fork.c、signal.c、sys.c
和exit.c 文件。
system_call.s 程序的作用类似于硬件中断处理中的asm.s 程序的作用,另外还对时钟中断和硬盘、
软盘中断进行处理。而fork.c 和signal.c 中的一个函数则类似于traps.c 程序的作用,为系统中断调
用提供C 处理函数。fork.c 程序提供两个C 处理函数:find_empty_process()和copy_process()。
所有寄存器入栈。
出错代码-->入栈
中断返回地址-->入栈
所有段寄存器置为内核
代码段的选择符值
调用相关C 处理函数
弹出入栈的出错码和后
来入栈的中断返回地址
弹出所有入栈寄存器
中断返回
注1:内核代码的选择
符值为0x10;
注2:无出错代码时就
使用0;
注3:调用的C 函数在
traps.c 中实现。压入
堆栈的出错代码和中
断返回地址是用作C 函
数的参数。
更多电子书教程下载请登陆http://down.zzbaike.com/ebook
本站提供的电子书教程均为网上搜集,如果该教程涉及或侵害到您的版权请联系我们。
第5 章 内核代码 linux/kernel/
73
signal.c 程序还提供一个处理有关进程信号的函数do_signal(),在系统调用中断处理过程中被调用。
另外还包括4 个系统调用sys_xxx()函数。
sys.c 和exit.c 程序实现了其它一些sys_xxx()系统调用函数。这些sys_xxx()函数都是相应系统
调用所需调用的处理函数,有些是使用汇编语言实现的,如sys_execve();而另外一些则用C 语言实现
(例如signal.c 中的4 个系统调用函数)。
我们可以根据这些函数的简单命名规则这样来理解:通常以‘do_‘开头的中断处理过程中调用的C
函数,要么是系统调用处理过程中通用的函数,要么是某个系统调用专用的;而以‘sys_‘开头的系统调
用函数则是指定的系统调用的专用处理函数。例如,do_signal()函数基本上是所有系统调用都要执行的
函数,而do_hd()、do_execve()则是某个系统调用专用的C 处理函数。
5.1.1.3 其它通用类程序
这些程序包括schedule.c、mktime.c、panic.c、printk.c 和vsprintf.c。
schedule.c 程序包括内核调用最频繁的schedule()、sleep_on()和wakeup()函数,是内核的核心
调度程序,用于对进程的执行进行切换或改变进程的执行状态。mktime.c 程序中仅包含一个内核使用的
时间函数mktime(),仅在init/main.c 中被调用一次。panic.c 中包含一个panic()函数,用于在内核
运行出现错误时显示出错信息并停机。printk.c 和vsprintf.c 是内核显示信息的支持程序,实现了内
核专用显示函数printk()和字符串格式化输出函数vsprintf()。