linux 0.11 内核学习 -- asm.s,机器难免出故障。
来源:互联网 发布:itunes windows xp版 编辑:程序博客网 时间:2024/06/05 13:35
/*
* linux/kernel/asm.s
*
* (C) 1991 Linus Torvalds
*/
/*
* asm.s contains the low-level code for most hardware faults.
* page_exception is handled by the mm, so that isn't here. This
* file also handles (hopefully) fpu-exceptions due to TS-bit, as
* the fpu must be properly saved/resored. This hasn't been tested.
*/
/*
* asm.asm处理的主要是和硬件相关的故障。注意的是页异常是有mm模块
* 来实现管理的,所以在这里不需要处理。此外此程序来处理fpu的异常。
*
*/
/*
* 全局函数的定义,主要是引用的是traps.c文件中的函数声明。
* 下面的代码主要是对intel的保留中断int0 -- int16的处理。
*/
.globl _divide_error,_debug,_nmi,_int3,_overflow,_bounds,_invalid_op
.globl _double_fault,_coprocessor_segment_overrun
.globl _invalid_TSS,_segment_not_present,_stack_segment
.globl _general_protection,_coprocessor_error,_irq13,_reserved
# 一下的中断都是Intel得保留中断的处理程序。
#------------------------------------------------------------------------
# int0 -- 被0除所引发的中断。下面的$_do_divide_error是c函数编译之后
# 对应的模块的名称。
_divide_error:
pushl $_do_divide_error# 首先将函数入口地址压入堆栈。
no_error_code:# 标号相当于函数被下面程序调用。
xchgl %eax,(%esp)# xchgl指令的作用是交换寄存器。
# 在此的含义是将函数的地址存在
# eax中,将eax原来内容入栈。
pushl %ebx# 寄存器入栈
pushl %ecx
pushl %edx
pushl %edi
pushl %esi
pushl %ebp
push %ds
push %es
push %fs
####################################################
# 将出错码和中断返回地址入栈作为函数调用_do_divide_error
# 的参数。
pushl $0# "error code",出错码0入栈
lea 44(%esp),%edx# 取得中断返回地址
pushl %edx# 中断返回地址入栈
#####################################################
# 下面的代码重新设置寄存器。ds和es指向的是内核代码段
# fs指向的是用户数据段。
movl $0x10,%edx
mov %dx,%ds
mov %dx,%es
mov %dx,%fs
call *%eax# 调用函数,函数的地址在上面已经保存在eax。
addl $8,%esp# 将堆栈指针指向fs寄存器入栈处。
# 恢复现场。
pop %fs
pop %es
pop %ds
popl %ebp
popl %esi
popl %edi
popl %edx
popl %ecx
popl %ebx
popl %eax# 弹出原来eax内容
iret# 中断返回。
#-------------------------------------------------------------------------
#--------------------------------------------------------------------------
# 调试中断入口点
_debug:
pushl $_do_int3# _do_debug函数地址入栈
jmp no_error_code
#---------------------------------------------------------------------------
#---------------------------------------------------------------------------
# 非屏蔽中断调用入口点。
# 中断和异常是不相同的。中断是由定时器和io设备产生的。异常则是由程序的执行错误
# 导致的。每个中断和异常由0~255之间的一个数(8位)来标识,Intel称其为中断向量
# (vector)。非屏蔽中断的向量和异常的向量是固定的,可屏蔽中断的向量可以通过对
# 中断控制器的编程来改变
pushl $_do_nmi
jmp no_error_code
#---------------------------------------------------------------------------
# 通_debug。
_int3:
pushl $_do_int3
jmp no_error_code
#----------------------------------------------------------------------------
#-----------------------------------------------------------------------------
# 溢出错误处理程序。
_overflow:
pushl $_do_overflow
jmp no_error_code
#----------------------------------------------------------------------------
# 边界检查出错处理程序
_bounds:
pushl $_do_bounds
jmp no_error_code
#-----------------------------------------------------------------------------
#----------------------------------------------------------------------------
# 无效操作指令。
_invalid_op:
pushl $_do_invalid_op
jmp no_error_code
#---------------------------------------------------------------------------
#---------------------------------------------------------------------------
# 协处理器段超出异常。
_coprocessor_segment_overrun:
pushl $_do_coprocessor_segment_overrun
jmp no_error_code
#---------------------------------------------------------------------------
#---------------------------------------------------------------------------
# 保留。
_reserved:
pushl $_do_reserved
jmp no_error_code
#----------------------------------------------------------------------------
#-----------------------------------------------------------------------------
# 数学协处理器在完成计算之后使用下面的中断来通知cpu计算完成。使用irq13中断。
_irq13:
pushl %eax
xorb %al,%al
outb %al,$0xF0
movb $0x20,%al
outb %al,$0x20
jmp 1f
1:jmp 1f
1:outb %al,$0xA0
popl %eax
jmp _coprocessor_error
#-------------------------------------------------------------------------
#-------------------------------------------------------------------------
# 以下的中断调用会在中断返回地址之后将出错号压入堆栈,因此在返回时需要将
# 出错号弹出。
# int8 -- 双出错故障。
_double_fault:
pushl $_do_double_fault
error_code:
xchgl %eax,4(%esp)# error code <-> %eax
xchgl %ebx,(%esp)# &function <-> %ebx
pushl %ecx
pushl %edx
pushl %edi
pushl %esi
pushl %ebp
push %ds
push %es
push %fs
pushl %eax# error code
lea 44(%esp),%eax# offset
pushl %eax
movl $0x10,%eax
mov %ax,%ds
mov %ax,%es
mov %ax,%fs
call *%ebx
addl $8,%esp
pop %fs
pop %es
pop %ds
popl %ebp
popl %esi
popl %edi
popl %edx
popl %ecx
popl %ebx
popl %eax
iret
#-----------------------------------------------------------------------------
# 无效任务状态段。
_invalid_TSS:
pushl $_do_invalid_TSS
jmp error_code
#-----------------------------------------------------------------------------
# 段不存在。
_segment_not_present:
pushl $_do_segment_not_present
jmp error_code
#------------------------------------------------------------------------------
# 堆栈错误。
_stack_segment:
pushl $_do_stack_segment
jmp error_code
#------------------------------------------------------------------------------
# 一般性保护出错。
_general_protection:
pushl $_do_general_protection
jmp error_code
#----------------------------------------------------------------------------
#
# int7 -- 设备不存在。
# int14 -- 页错误。
# int16 -- 协处理器错误。
# int 0x20 -- 时钟中断。
# int 0x80 -- 系统调用。
参考《linux内核完全注释》和网上相关文章
- linux 0.11 内核学习 -- asm.s,机器难免出故障。
- linux内核代码分析之asm.s
- Linux内核学习篇三:中断处理 -- asm.s和traps.c
- Linux内核源码(asm/atomic.h)学习
- 机器出了故障,怎么办?
- linux 0.11 内核学习 -- setup.s
- linux 0.11 内核学习 -- head.s
- linux 0.11 内核学习 -- head.s
- linux 0.11 内核学习 -- setup.s
- linux-asm.s
- Linux内核源码(asm/bitops/atomic.h)学习
- linux 0.11 内核学习 -- bootsect.s, 万里长征第一步
- linux 0.11 内核学习 -- system_call.s,系统调用仅是如此。
- linux 0.11 内核学习 -- rs_io.s,串口汇编代码
- 机器学习的未来属于 Linux 内核
- 深入简出机器学习
- asm 故障组 故障组
- linux-0.11内核 keyborad.S程序
- open session and Hibernate事务处理机制
- 必须掌握的八个cmd 命令
- Nginx简介
- C++的delete操作
- EntLib电子商务系统 v2.5 即将发布,有重要更新!
- linux 0.11 内核学习 -- asm.s,机器难免出故障。
- 第一个蓝牙程序
- JSP生成Excel报表文档
- 自主开发Delphi控件[1]: THSImageExButton图片按钮,3状态控制
- 通过代码实现DataGrid按指定列排序
- linux 0.11 内核学习 -- system_call.s,系统调用仅是如此。
- VC中基于 Windows 的精确定时---中国科学院光电技术研究所 游志宇
- WIN7兼容性的个人体验
- nginx详细配置说明