linux内核分析之system_call.s
来源:互联网 发布:linux c 文件路径 编辑:程序博客网 时间:2024/05/16 15:05
1. 系统调用处理底层程序,通过int 0x80进行系统调用
2. 时钟,硬盘,软盘中断处理程序
信号,子进程结束
SIG_CHLD = 17
定义了从系统调用返回时各个寄存器在堆栈中的偏移值
(ret_from_sys_call)
EAX = 0x00
EBX = 0x04
ECX = 0x08
EDX = 0x0C
FS = 0x10
ES = 0x14
DS = 0x18
EIP = 0x1C
CS = 0x20
EFLAGS = 0x24
OLDESP = 0x28
OLDSS = 0x2C
下面是定义task结构中各个成员的偏移值
进程状态
state = 0
时间片
counter = 4
优先级
priority = 8
信号位图
signal = 12
sigaction的结构数组,一共是32项,每项16个字节
sigaction = 16
受阻塞的信号位图
blocked = (33*16)
sigaction结构中各个成员的偏移值
sa_handler = 0
sa_mask = 4
sa_flags = 8
sa_restorer = 12
系统调用总数
nr_system_calls = 72
.globl _system_call,_sys_fork,_timer_interrupt,_sys_execve
.globl _hd_interrupt,_floppy_interrupt,_parallel_interrupt
.globl _device_not_available, _coprocessor_error
系统调用出错,-1作为返回值
如果超过了系统调用总数72就会
返回-1
.align 2
bad_sys_call:
movl $-1,%eax
iret
对任务重新调度,先把_shedule函数返回地址
ret_from_sys_call压入堆栈
.align 2
reschedule:
pushl $ret_from_sys_call
jmp _schedule
系统调用
.align 2
_system_call:
对系统调用号进行有效性检查
cmpl $nr_system_calls-1,%eax
ja bad_sys_call
将数据段,附加段和fs段寄存器入栈保存
ds和es段将指向内核数据段
fs将指向局部数据段
push %ds
push %es
push %fs
将参数入栈,系统调用的参数ebx,ecx,edx
pushl %edx
pushl %ecx
pushl %ebx
es,ds段指向内核数据段
movl $0x10,%edx
mov %dx,%ds
mov %dx,%es
使fs指向用户数据段
movl $0x17,%edx
mov %dx,%fs
查表,进行系统调用
call _sys_call_table(,%eax,4)
将系统调用返回值入栈
pushl %eax
当前任务的地址放入eax中
movl _current,%eax
进程状态是不是就绪
cmpl $0,state(%eax)
如果不是就执行进程调度程序
jne reschedule
看时间片是不是用完
cmpl $0,counter(%eax)
如果用完,执行进程调度程序
je reschedule
系统调用返回处
ret_from_sys_call:
将当前任务的数据结构地址放入eax中
movl _current,%eax
看看当前任务是不是任务0
cmpl _task,%eax
如果是立即返回中断处理程序
je 3f
0x0f:局部描述符表中,第一个表项,DPL为3,代码段
看看当前代码段是否与之相等,来判断是否为用户任务
cmpw $0x0f,CS(%esp)
如果不是,立即返回中断
jne 3f
0x17:局部描述附表中,第二个表项,DPL为3,数据段
看看是不是用户数据段
cmpw $0x17,OLDSS(%esp)
如果不是,立即返回中断处理程序
jne 3f
此时eax为当前任务的地址,将当前任务的信号位图放入ebx中
movl signal(%eax),%ebx
将当前任务的受阻塞的信号位图放入ecx
movl blocked(%eax),%ecx
从当前任务的信号位图中清除受阻塞的信号集合
notl %ecx
andl %ebx,%ecx
选择受阻塞信号的最小值,放入ecx中
bsfl %ecx,%ecx
如果没有信号需要处理,结束中断处理程序
je 3f
从信号位图中复位该信号
btrl %ecx,%ebx
重置信号位图
movl %ebx,signal(%eax)
将要处理的信号+1
incl %ecx
将要处理的信号压栈
pushl %ecx
调用信号处理函数
call _do_signal
返回值存入eax中
popl %eax
返回中断处理程序
3: popl %eax
popl %ebx
popl %ecx
popl %edx
pop %fs
pop %es
pop %ds
iret
sys_execve系统调用
.align 2
_sys_execve:
取中断调用前的指令指针寄存器的值,存入eax
lea EIP(%esp),%eax
该地址作为_do_execve函数的参数
pushl %eax
call _do_execve
恢复堆栈
addl $4,%esp
ret
fork系统调用
.align 2
_sys_fork:
首先查找是否有可用的pid
call _find_empty_process
如果没有就直接返回
testl %eax,%eax
js 1f
否则调用_copy_process程序
push %gs
pushl %esi
pushl %edi
pushl %ebp
pushl %eax
call _copy_process
调用返回,恢复堆栈
addl $20,%esp
1: ret
以下是几个中断处理程序的定义,在这里不做详细介绍
硬盘中断处理程序
_hd_interrupt:
pushl %eax
pushl %ecx
pushl %edx
push %ds
push %es
push %fs
movl $0x10,%eax
mov %ax,%ds
mov %ax,%es
movl $0x17,%eax
mov %ax,%fs
movb $0x20,%al
outb %al,$0xA0 # EOI to interrupt controller #1
jmp 1f # give port chance to breathe
1: jmp 1f
1: xorl %edx,%edx
xchgl _do_hd,%edx
testl %edx,%edx
jne 1f
movl $_unexpected_hd_interrupt,%edx
1: outb %al,$0x20
call *%edx # "interesting" way of handling intr.
pop %fs
pop %es
pop %ds
popl %edx
popl %ecx
popl %eax
iret
软盘驱动程序
_floppy_interrupt:
pushl %eax
pushl %ecx
pushl %edx
push %ds
push %es
push %fs
movl $0x10,%eax
mov %ax,%ds
mov %ax,%es
movl $0x17,%eax
mov %ax,%fs
movb $0x20,%al
outb %al,$0x20 # EOI to interrupt controller #1
xorl %eax,%eax
xchgl _do_floppy,%eax
testl %eax,%eax
jne 1f
movl $_unexpected_floppy_interrupt,%eax
1: call *%eax # "interesting" way of handling intr.
pop %fs
pop %es
pop %ds
popl %edx
popl %ecx
popl %eax
iret
并口中断处理程序
_parallel_interrupt:
pushl %eax
movb $0x20,%al
outb %al,$0x20
popl %eax
iret
处理器错误,int 16
.align 2
_coprocessor_error:
push %ds
push %es
push %fs
pushl %edx
pushl %ecx
pushl %ebx
pushl %eax
movl $0x10,%eax
mov %ax,%ds
mov %ax,%es
movl $0x17,%eax
mov %ax,%fs
pushl $ret_from_sys_call
jmp _math_error
设备不存在错误,int 7
.align 2
_device_not_available:
push %ds
push %es
push %fs
pushl %edx
pushl %ecx
pushl %ebx
pushl %eax
movl $0x10,%eax
mov %ax,%ds
mov %ax,%es
movl $0x17,%eax
mov %ax,%fs
pushl $ret_from_sys_call
clts
movl %cr0,%eax
testl $0x4,%eax
je _math_state_restore
pushl %ebp
pushl %esi
pushl %edi
call _math_emulate
popl %edi
popl %esi
popl %ebp
ret
时钟中断处理程序
.align 2
_timer_interrupt:
push %ds # save ds,es and put kernel data space
push %es # into them. %fs is used by _system_call
push %fs
pushl %edx # we save %eax,%ecx,%edx as gcc doesn't
pushl %ecx # save those across function calls. %ebx
pushl %ebx # is saved as we use that in ret_sys_call
pushl %eax
movl $0x10,%eax
mov %ax,%ds
mov %ax,%es
movl $0x17,%eax
mov %ax,%fs
incl _jiffies
movb $0x20,%al # EOI to interrupt controller #1
outb %al,$0x20
movl CS(%esp),%eax
andl $3,%eax # %eax is CPL (0 or 3, 0=supervisor)
pushl %eax
call _do_timer # 'do_timer(long CPL)' does everything from
addl $4,%esp # task switching to accounting ...
jmp ret_from_sys_call
- linux内核分析之system_call.s
- linux内核分析之system_call.s
- Linux内核分析之简析system_call中断处理过程
- Linux内核分析之五——分析系统调用(system_call)的执行机制
- linux 0.11 内核学习 -- system_call.s,系统调用仅是如此。
- Linux内核分析:分析system_call中断处理过程
- Linux内核分析5:分析system_call中断处理过程
- Linux内核分析 实验五:分析system_call中断处理过程
- Linux内核分析 实验五:分析system_call中断处理过程
- Linux内核分析课程--分析system_call中断处理过程
- MOOC-Linux内核lab5 分析system_call中断处理过程
- Linux内核分析学习笔记:system_call中断处理过程
- linux内核代码分析之asm.s
- MOOC《Linux内核分析》——分析system_call中断处理过程
- 网易公开课《Linux内核分析》学习心得-分析system_call中断处理过程
- Linux内核分析实验五—分析system_call中断处理过程
- 第5节 分析system_call中断处理过程【Linux内核分析】
- [网易云课堂]Linux内核分析(五)—— 分析system_call中断处理过程
- 【转载】关于模拟电路的学习历程
- VSS使用手册
- Xterm的中文字体设置
- 折半插入排序
- setjmp与longjmp实现c语言下的异常处理机制
- linux内核分析之system_call.s
- 如何在Server Core模式下安装和管理Hyper-V
- 网页收藏
- 网络socket编程几个函数小结
- 使用dom4j来处理xml的一些常用方法
- HTTP Post方法应用的例子
- 精简版XP的IIS安装
- linux环境变量PS1的简介
- 初识Firebug 全文 — firebug的使用