Annotation of linux/kernel/system_call.s, revision 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.