当前位置: 技术问答>linux和unix
linux0.12 ret_from_sys_call的疑问
来源: 互联网 发布时间:2017-01-10
本文导语: 小弟正在读linux0.12内核 读到系统调用时有疑问实在不能解决,高手指点。比较长是我吧这两段程序都复制了。 linux 0.12的系统调用中: _system_call: push %ds push %es push %fs pushl %eax # save the orig_eax pushl %edx pushl...
小弟正在读linux0.12内核
读到系统调用时有疑问实在不能解决,高手指点。比较长是我吧这两段程序都复制了。
linux 0.12的系统调用中:
_system_call:
push %ds
push %es
push %fs
pushl %eax # save the orig_eax
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
cmpl _NR_syscalls,%eax
jae bad_sys_call
call _sys_call_table(,%eax,4)
pushl %eax
2:
movl _current,%eax
cmpl $0,state(%eax) # state
jne reschedule
cmpl $0,counter(%eax) # counter
je reschedule
前面都能理解,2:movl _current,%eax
cmpl $0,state(%eax) # state
jne reschedule
cmpl $0,counter(%eax) # counter
je reschedule
问题1:
这几行程序是看当前进程是否在就绪状态或时间片是否用完,小弟要问的是这几行程序在这里有什么必要的意义呢?
我认为是在执行系统调用时,任务是处于内核态的,而早期的linux内核是非抢占式的,也就是在执行系统调用时该任务是不会主动放弃CPU的,除非任务本身主动放弃。所以在系统调用后及时执行sechedule进行系统调度。
不知道理解是否正确?
在ret_from_sys_call中:
ret_from_sys_call:
movl _current,%eax
cmpl _task,%eax # task[0] cannot have signals
je 3f
cmpw $0x0f,CS(%esp) # was old code segment supervisor ?
jne 3f
cmpw $0x17,OLDSS(%esp) # was stack segment = 0x17 ?
jne 3f
movl signal(%eax),%ebx
movl blocked(%eax),%ecx
notl %ecx
andl %ebx,%ecx
bsfl %ecx,%ecx
je 3f
btrl %ecx,%ebx
movl %ebx,signal(%eax)
incl %ecx
pushl %ecx
call _do_signal
popl %ecx
testl %eax, %eax
jne 2b # see if we need to switch tasks, or do more signals
3: popl %eax
popl %ebx
popl %ecx
popl %edx
addl $4, %esp # skip orig_eax
pop %fs
pop %es
pop %ds
iret
问题2:
前几行的意义也好理解,但是有疑问的是为什么task[0]不能接受信号。
任务0是闲置任务,它不能被杀死或睡眠,但是这和接受信号有什么关系?
问题3:
另外是这段程序是从系统调用C函数返回后对信号进行的识别处理,其他中断服务程序退出时也会跳转到这里执行,那么这样做的作用,或者说必要行是什么,为什么中断返回后都要对信号进行处理?
读到系统调用时有疑问实在不能解决,高手指点。比较长是我吧这两段程序都复制了。
linux 0.12的系统调用中:
_system_call:
push %ds
push %es
push %fs
pushl %eax # save the orig_eax
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
cmpl _NR_syscalls,%eax
jae bad_sys_call
call _sys_call_table(,%eax,4)
pushl %eax
2:
movl _current,%eax
cmpl $0,state(%eax) # state
jne reschedule
cmpl $0,counter(%eax) # counter
je reschedule
前面都能理解,2:movl _current,%eax
cmpl $0,state(%eax) # state
jne reschedule
cmpl $0,counter(%eax) # counter
je reschedule
问题1:
这几行程序是看当前进程是否在就绪状态或时间片是否用完,小弟要问的是这几行程序在这里有什么必要的意义呢?
我认为是在执行系统调用时,任务是处于内核态的,而早期的linux内核是非抢占式的,也就是在执行系统调用时该任务是不会主动放弃CPU的,除非任务本身主动放弃。所以在系统调用后及时执行sechedule进行系统调度。
不知道理解是否正确?
在ret_from_sys_call中:
ret_from_sys_call:
movl _current,%eax
cmpl _task,%eax # task[0] cannot have signals
je 3f
cmpw $0x0f,CS(%esp) # was old code segment supervisor ?
jne 3f
cmpw $0x17,OLDSS(%esp) # was stack segment = 0x17 ?
jne 3f
movl signal(%eax),%ebx
movl blocked(%eax),%ecx
notl %ecx
andl %ebx,%ecx
bsfl %ecx,%ecx
je 3f
btrl %ecx,%ebx
movl %ebx,signal(%eax)
incl %ecx
pushl %ecx
call _do_signal
popl %ecx
testl %eax, %eax
jne 2b # see if we need to switch tasks, or do more signals
3: popl %eax
popl %ebx
popl %ecx
popl %edx
addl $4, %esp # skip orig_eax
pop %fs
pop %es
pop %ds
iret
问题2:
前几行的意义也好理解,但是有疑问的是为什么task[0]不能接受信号。
任务0是闲置任务,它不能被杀死或睡眠,但是这和接受信号有什么关系?
问题3:
另外是这段程序是从系统调用C函数返回后对信号进行的识别处理,其他中断服务程序退出时也会跳转到这里执行,那么这样做的作用,或者说必要行是什么,为什么中断返回后都要对信号进行处理?
|
所发生地方