Annotation of linux/kernel/system_call.s, revision 1.1.1.1

1.1       root        1: /*
                      2:  *  system_call.s  contains the system-call low-level handling routines.
                      3:  * This also contains the timer-interrupt handler, as some of the code is
                      4:  * the same. The hd-interrupt is also here.
                      5:  *
                      6:  * NOTE: This code handles signal-recognition, which happens every time
                      7:  * after a timer-interrupt and after each system call. Ordinary interrupts
                      8:  * don't handle signal-recognition, as that would clutter them up totally
                      9:  * unnecessarily.
                     10:  *
                     11:  * Stack layout in 'ret_from_system_call':
                     12:  *
                     13:  *      0(%esp) - %eax
                     14:  *      4(%esp) - %ebx
                     15:  *      8(%esp) - %ecx
                     16:  *      C(%esp) - %edx
                     17:  *     10(%esp) - %fs
                     18:  *     14(%esp) - %es
                     19:  *     18(%esp) - %ds
                     20:  *     1C(%esp) - %eip
                     21:  *     20(%esp) - %cs
                     22:  *     24(%esp) - %eflags
                     23:  *     28(%esp) - %oldesp
                     24:  *     2C(%esp) - %oldss
                     25:  */
                     26: 
                     27: SIG_CHLD       = 17
                     28: EAX            = 0x00
                     29: EBX            = 0x04
                     30: ECX            = 0x08
                     31: EDX            = 0x0C
                     32: FS             = 0x10
                     33: ES             = 0x14
                     34: DS             = 0x18
                     35: EIP            = 0x1C
                     36: CS             = 0x20
                     37: EFLAGS         = 0x24
                     38: OLDESP         = 0x28
                     39: OLDSS          = 0x2C
                     40: 
                     41: state  = 0             # these are offsets into the task-struct.
                     42: counter        = 4
                     43: priority = 8
                     44: signal = 12
                     45: restorer = 16          # address of info-restorer
                     46: sig_fn = 20            # table of 32 signal addresses
                     47: 
                     48: nr_system_calls = 67
                     49: 
                     50: .globl _system_call,_sys_fork,_timer_interrupt,_hd_interrupt,_sys_execve
                     51: 
                     52: .align 2
                     53: bad_sys_call:
                     54:        movl $-1,%eax
                     55:        iret
                     56: .align 2
                     57: reschedule:
                     58:        pushl $ret_from_sys_call
                     59:        jmp _schedule
                     60: .align 2
                     61: _system_call:
                     62:        cmpl $nr_system_calls-1,%eax
                     63:        ja bad_sys_call
                     64:        push %ds
                     65:        push %es
                     66:        push %fs
                     67:        pushl %edx
                     68:        pushl %ecx              # push %ebx,%ecx,%edx as parameters
                     69:        pushl %ebx              # to the system call
                     70:        movl $0x10,%edx         # set up ds,es to kernel space
                     71:        mov %dx,%ds
                     72:        mov %dx,%es
                     73:        movl $0x17,%edx         # fs points to local data space
                     74:        mov %dx,%fs
                     75:        call _sys_call_table(,%eax,4)
                     76:        pushl %eax
                     77:        movl _current,%eax
                     78:        cmpl $0,state(%eax)             # state
                     79:        jne reschedule
                     80:        cmpl $0,counter(%eax)           # counter
                     81:        je reschedule
                     82: ret_from_sys_call:
                     83:        movl _current,%eax              # task[0] cannot have signals
                     84:        cmpl _task,%eax
                     85:        je 3f
                     86:        movl CS(%esp),%ebx              # was old code segment supervisor
                     87:        testl $3,%ebx                   # mode? If so - don't check signals
                     88:        je 3f
                     89:        cmpw $0x17,OLDSS(%esp)          # was stack segment = 0x17 ?
                     90:        jne 3f
                     91: 2:     movl signal(%eax),%ebx          # signals (bitmap, 32 signals)
                     92:        bsfl %ebx,%ecx                  # %ecx is signal nr, return if none
                     93:        je 3f
                     94:        btrl %ecx,%ebx                  # clear it
                     95:        movl %ebx,signal(%eax)
                     96:        movl sig_fn(%eax,%ecx,4),%ebx   # %ebx is signal handler address
                     97:        cmpl $1,%ebx
                     98:        jb default_signal               # 0 is default signal handler - exit
                     99:        je 2b                           # 1 is ignore - find next signal
                    100:        movl $0,sig_fn(%eax,%ecx,4)     # reset signal handler address
                    101:        incl %ecx
                    102:        xchgl %ebx,EIP(%esp)            # put new return address on stack
                    103:        subl $28,OLDESP(%esp)
                    104:        movl OLDESP(%esp),%edx          # push old return address on stack
                    105:        pushl %eax                      # but first check that it's ok.
                    106:        pushl %ecx
                    107:        pushl $28
                    108:        pushl %edx
                    109:        call _verify_area
                    110:        popl %edx
                    111:        addl $4,%esp
                    112:        popl %ecx
                    113:        popl %eax
                    114:        movl restorer(%eax),%eax
                    115:        movl %eax,%fs:(%edx)            # flag/reg restorer
                    116:        movl %ecx,%fs:4(%edx)           # signal nr
                    117:        movl EAX(%esp),%eax
                    118:        movl %eax,%fs:8(%edx)           # old eax
                    119:        movl ECX(%esp),%eax
                    120:        movl %eax,%fs:12(%edx)          # old ecx
                    121:        movl EDX(%esp),%eax
                    122:        movl %eax,%fs:16(%edx)          # old edx
                    123:        movl EFLAGS(%esp),%eax
                    124:        movl %eax,%fs:20(%edx)          # old eflags
                    125:        movl %ebx,%fs:24(%edx)          # old return addr
                    126: 3:     popl %eax
                    127:        popl %ebx
                    128:        popl %ecx
                    129:        popl %edx
                    130:        pop %fs
                    131:        pop %es
                    132:        pop %ds
                    133:        iret
                    134: 
                    135: default_signal:
                    136:        incl %ecx
                    137:        cmpl $SIG_CHLD,%ecx
                    138:        je 2b
                    139:        pushl %ecx
                    140:        call _do_exit           # remember to set bit 7 when dumping core
                    141:        addl $4,%esp
                    142:        jmp 3b
                    143: 
                    144: .align 2
                    145: _timer_interrupt:
                    146:        push %ds                # save ds,es and put kernel data space
                    147:        push %es                # into them. %fs is used by _system_call
                    148:        push %fs
                    149:        pushl %edx              # we save %eax,%ecx,%edx as gcc doesn't
                    150:        pushl %ecx              # save those across function calls. %ebx
                    151:        pushl %ebx              # is saved as we use that in ret_sys_call
                    152:        pushl %eax
                    153:        movl $0x10,%eax
                    154:        mov %ax,%ds
                    155:        mov %ax,%es
                    156:        movl $0x17,%eax
                    157:        mov %ax,%fs
                    158:        incl _jiffies
                    159:        movb $0x20,%al          # EOI to interrupt controller #1
                    160:        outb %al,$0x20
                    161:        movl CS(%esp),%eax
                    162:        andl $3,%eax            # %eax is CPL (0 or 3, 0=supervisor)
                    163:        pushl %eax
                    164:        call _do_timer          # 'do_timer(long CPL)' does everything from
                    165:        addl $4,%esp            # task switching to accounting ...
                    166:        jmp ret_from_sys_call
                    167: 
                    168: .align 2
                    169: _sys_execve:
                    170:        lea EIP(%esp),%eax
                    171:        pushl %eax
                    172:        call _do_execve
                    173:        addl $4,%esp
                    174:        ret
                    175: 
                    176: .align 2
                    177: _sys_fork:
                    178:        call _find_empty_process
                    179:        testl %eax,%eax
                    180:        js 1f
                    181:        push %gs
                    182:        pushl %esi
                    183:        pushl %edi
                    184:        pushl %ebp
                    185:        pushl %eax
                    186:        call _copy_process
                    187:        addl $20,%esp
                    188: 1:     ret
                    189: 
                    190: _hd_interrupt:
                    191:        pushl %eax
                    192:        pushl %ecx
                    193:        pushl %edx
                    194:        push %ds
                    195:        push %es
                    196:        push %fs
                    197:        movl $0x10,%eax
                    198:        mov %ax,%ds
                    199:        mov %ax,%es
                    200:        movl $0x17,%eax
                    201:        mov %ax,%fs
                    202:        movb $0x20,%al
                    203:        outb %al,$0x20          # EOI to interrupt controller #1
                    204:        jmp 1f                  # give port chance to breathe
                    205: 1:     jmp 1f
                    206: 1:     outb %al,$0xA0          # same to controller #2
                    207:        movl _do_hd,%eax
                    208:        testl %eax,%eax
                    209:        jne 1f
                    210:        movl $_unexpected_hd_interrupt,%eax
                    211: 1:     call *%eax              # "interesting" way of handling intr.
                    212:        pop %fs
                    213:        pop %es
                    214:        pop %ds
                    215:        popl %edx
                    216:        popl %ecx
                    217:        popl %eax
                    218:        iret
                    219: 

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.