⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 system_call.s

📁 最早的linux操作系统源代码(3)
💻 S
字号:
/* *  system_call.s  contains the system-call low-level handling routines. * This also contains the timer-interrupt handler, as some of the code is * the same. The hd-interrupt is also here. * * NOTE: This code handles signal-recognition, which happens every time * after a timer-interrupt and after each system call. Ordinary interrupts * don't handle signal-recognition, as that would clutter them up totally * unnecessarily. * * Stack layout in 'ret_from_system_call': * *	 0(%esp) - %eax *	 4(%esp) - %ebx *	 8(%esp) - %ecx *	 C(%esp) - %edx *	10(%esp) - %fs *	14(%esp) - %es *	18(%esp) - %ds *	1C(%esp) - %eip *	20(%esp) - %cs *	24(%esp) - %eflags *	28(%esp) - %oldesp *	2C(%esp) - %oldss */SIG_CHLD	= 17EAX		= 0x00EBX		= 0x04ECX		= 0x08EDX		= 0x0CFS		= 0x10ES		= 0x14DS		= 0x18EIP		= 0x1CCS		= 0x20EFLAGS		= 0x24OLDESP		= 0x28OLDSS		= 0x2Cstate	= 0		# these are offsets into the task-struct.counter	= 4priority = 8signal	= 12restorer = 16		# address of info-restorersig_fn	= 20		# table of 32 signal addressesnr_system_calls = 68.globl system_call,sys_fork,timer_interrupt,hd_interrupt,sys_execve,my_call.align 2bad_sys_call:	movl $-1,%eax	iret.align 2reschedule:	pushl $ret_from_sys_call	jmp schedule.align 2system_call:	cmpl $nr_system_calls-1,%eax	ja bad_sys_call	push %ds	push %es	push %fs	pushl %edx	pushl %ecx		# push %ebx,%ecx,%edx as parameters	pushl %ebx		# to the system call	movl $0x10,%edx		# set up ds,es to kernel space	mov %dx,%ds	mov %dx,%es	movl $0x17,%edx		# fs points to local data space	mov %dx,%fs	call sys_call_table(,%eax,4)	pushl %eax	movl current,%eax	cmpl $0,state(%eax)		# state	jne reschedule	cmpl $0,counter(%eax)		# counter	je rescheduleret_from_sys_call:	movl current,%eax		# task[0] cannot have signals	cmpl task,%eax	je 3f	movl CS(%esp),%ebx		# was old code segment supervisor	testl $3,%ebx			# mode? If so - don't check signals	je 3f	cmpw $0x17,OLDSS(%esp)		# was stack segment = 0x17 ?	jne 3f2:	movl signal(%eax),%ebx		# signals (bitmap, 32 signals)	bsfl %ebx,%ecx			# %ecx is signal nr, return if none	je 3f	btrl %ecx,%ebx			# clear it	movl %ebx,signal(%eax)	movl sig_fn(%eax,%ecx,4),%ebx	# %ebx is signal handler address	cmpl $1,%ebx	jb default_signal		# 0 is default signal handler - exit	je 2b				# 1 is ignore - find next signal	movl $0,sig_fn(%eax,%ecx,4)	# reset signal handler address	incl %ecx	xchgl %ebx,EIP(%esp)		# put new return address on stack	subl $28,OLDESP(%esp)	movl OLDESP(%esp),%edx		# push old return address on stack	pushl %eax			# but first check that it's ok.	pushl %ecx	pushl $28	pushl %edx	call verify_area	popl %edx	addl $4,%esp	popl %ecx	popl %eax	movl restorer(%eax),%eax	movl %eax,%fs:(%edx)		# flag/reg restorer	movl %ecx,%fs:4(%edx)		# signal nr	movl EAX(%esp),%eax	movl %eax,%fs:8(%edx)		# old eax	movl ECX(%esp),%eax	movl %eax,%fs:12(%edx)		# old ecx	movl EDX(%esp),%eax	movl %eax,%fs:16(%edx)		# old edx	movl EFLAGS(%esp),%eax	movl %eax,%fs:20(%edx)		# old eflags	movl %ebx,%fs:24(%edx)		# old return addr3:	popl %eax	popl %ebx	popl %ecx	popl %edx	pop %fs	pop %es	pop %ds	iretdefault_signal:	incl %ecx	cmpl $SIG_CHLD,%ecx	je 2b	pushl %ecx	call do_exit		# remember to set bit 7 when dumping core	addl $4,%esp	jmp 3b.align 2timer_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.align 2sys_execve:	lea EIP(%esp),%eax	pushl %eax	call do_execve	addl $4,%esp	ret.align 2sys_fork:	call find_empty_process	testl %eax,%eax	js 1f	push %gs	pushl %esi	pushl %edi	pushl %ebp	pushl %eax	call copy_process	addl $20,%esp1:	rethd_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	jmp 1f			# give port chance to breathe1:	jmp 1f1:	outb %al,$0xA0		# same to controller #2	movl do_hd,%eax	testl %eax,%eax	jne 1f	movl $unexpected_hd_interrupt,%eax1:	call *%eax		# "interesting" way of handling intr.	pop %fs	pop %es	pop %ds	popl %edx	popl %ecx	popl %eax	iretmy_call:	pushl %eax	pushl %ecx	pushl %edx	push %ds	push %es	push %fs	movl $0x10,%edx	mov %dx,%ds	mov %dx,%es	movl $0x17,%edx	mov %dx,%fs	call my_call_table(,%eax,4) 	pop %fs	pop %es	pop %ds	popl %edx	popl %ecx	popl %eax	iret

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -