Annotation of linux/kernel/sys_call.s, revision 1.1

1.1     ! root        1: /*
        !             2:  *  linux/kernel/system_call.s
        !             3:  *
        !             4:  *  (C) 1991  Linus Torvalds
        !             5:  */
        !             6: 
        !             7: /*
        !             8:  *  system_call.s  contains the system-call low-level handling routines.
        !             9:  * This also contains the timer-interrupt handler, as some of the code is
        !            10:  * the same. The hd- and flopppy-interrupts are also here.
        !            11:  *
        !            12:  * NOTE: This code handles signal-recognition, which happens every time
        !            13:  * after a timer-interrupt and after each system call. Ordinary interrupts
        !            14:  * don't handle signal-recognition, as that would clutter them up totally
        !            15:  * unnecessarily.
        !            16:  *
        !            17:  * Stack layout in 'ret_from_system_call':
        !            18:  *
        !            19:  *      0(%esp) - %eax
        !            20:  *      4(%esp) - %ebx
        !            21:  *      8(%esp) - %ecx
        !            22:  *      C(%esp) - %edx
        !            23:  *     10(%esp) - original %eax        (-1 if not system call)
        !            24:  *     14(%esp) - %fs
        !            25:  *     18(%esp) - %es
        !            26:  *     1C(%esp) - %ds
        !            27:  *     20(%esp) - %eip
        !            28:  *     24(%esp) - %cs
        !            29:  *     28(%esp) - %eflags
        !            30:  *     2C(%esp) - %oldesp
        !            31:  *     30(%esp) - %oldss
        !            32:  */
        !            33: 
        !            34: SIG_CHLD       = 17
        !            35: 
        !            36: EAX            = 0x00
        !            37: EBX            = 0x04
        !            38: ECX            = 0x08
        !            39: EDX            = 0x0C
        !            40: ORIG_EAX       = 0x10
        !            41: FS             = 0x14
        !            42: ES             = 0x18
        !            43: DS             = 0x1C
        !            44: EIP            = 0x20
        !            45: CS             = 0x24
        !            46: EFLAGS         = 0x28
        !            47: OLDESP         = 0x2C
        !            48: OLDSS          = 0x30
        !            49: 
        !            50: state  = 0             # these are offsets into the task-struct.
        !            51: counter        = 4
        !            52: priority = 8
        !            53: signal = 12
        !            54: sigaction = 16         # MUST be 16 (=len of sigaction)
        !            55: blocked = (33*16)
        !            56: 
        !            57: # offsets within sigaction
        !            58: sa_handler = 0
        !            59: sa_mask = 4
        !            60: sa_flags = 8
        !            61: sa_restorer = 12
        !            62: 
        !            63: nr_system_calls = 82
        !            64: 
        !            65: ENOSYS = 38
        !            66: 
        !            67: /*
        !            68:  * Ok, I get parallel printer interrupts while using the floppy for some
        !            69:  * strange reason. Urgel. Now I just ignore them.
        !            70:  */
        !            71: .globl _system_call,_sys_fork,_timer_interrupt,_sys_execve
        !            72: .globl _hd_interrupt,_floppy_interrupt,_parallel_interrupt
        !            73: .globl _device_not_available, _coprocessor_error
        !            74: 
        !            75: .align 2
        !            76: bad_sys_call:
        !            77:        pushl $-ENOSYS
        !            78:        jmp ret_from_sys_call
        !            79: .align 2
        !            80: reschedule:
        !            81:        pushl $ret_from_sys_call
        !            82:        jmp _schedule
        !            83: .align 2
        !            84: _system_call:
        !            85:        push %ds
        !            86:        push %es
        !            87:        push %fs
        !            88:        pushl %eax              # save the orig_eax
        !            89:        pushl %edx              
        !            90:        pushl %ecx              # push %ebx,%ecx,%edx as parameters
        !            91:        pushl %ebx              # to the system call
        !            92:        movl $0x10,%edx         # set up ds,es to kernel space
        !            93:        mov %dx,%ds
        !            94:        mov %dx,%es
        !            95:        movl $0x17,%edx         # fs points to local data space
        !            96:        mov %dx,%fs
        !            97:        cmpl _NR_syscalls,%eax
        !            98:        jae bad_sys_call
        !            99:        call _sys_call_table(,%eax,4)
        !           100:        pushl %eax
        !           101: 2:
        !           102:        movl _current,%eax
        !           103:        cmpl $0,state(%eax)             # state
        !           104:        jne reschedule
        !           105:        cmpl $0,counter(%eax)           # counter
        !           106:        je reschedule
        !           107: ret_from_sys_call:
        !           108:        movl _current,%eax
        !           109:        cmpl _task,%eax                 # task[0] cannot have signals
        !           110:        je 3f
        !           111:        cmpw $0x0f,CS(%esp)             # was old code segment supervisor ?
        !           112:        jne 3f
        !           113:        cmpw $0x17,OLDSS(%esp)          # was stack segment = 0x17 ?
        !           114:        jne 3f
        !           115:        movl signal(%eax),%ebx
        !           116:        movl blocked(%eax),%ecx
        !           117:        notl %ecx
        !           118:        andl %ebx,%ecx
        !           119:        bsfl %ecx,%ecx
        !           120:        je 3f
        !           121:        btrl %ecx,%ebx
        !           122:        movl %ebx,signal(%eax)
        !           123:        incl %ecx
        !           124:        pushl %ecx
        !           125:        call _do_signal
        !           126:        popl %ecx
        !           127:        testl %eax, %eax
        !           128:        jne 2b          # see if we need to switch tasks, or do more signals
        !           129: 3:     popl %eax
        !           130:        popl %ebx
        !           131:        popl %ecx
        !           132:        popl %edx
        !           133:        addl $4, %esp   # skip orig_eax
        !           134:        pop %fs
        !           135:        pop %es
        !           136:        pop %ds
        !           137:        iret
        !           138: 
        !           139: .align 2
        !           140: _coprocessor_error:
        !           141:        push %ds
        !           142:        push %es
        !           143:        push %fs
        !           144:        pushl $-1               # fill in -1 for orig_eax
        !           145:        pushl %edx
        !           146:        pushl %ecx
        !           147:        pushl %ebx
        !           148:        pushl %eax
        !           149:        movl $0x10,%eax
        !           150:        mov %ax,%ds
        !           151:        mov %ax,%es
        !           152:        movl $0x17,%eax
        !           153:        mov %ax,%fs
        !           154:        pushl $ret_from_sys_call
        !           155:        jmp _math_error
        !           156: 
        !           157: .align 2
        !           158: _device_not_available:
        !           159:        push %ds
        !           160:        push %es
        !           161:        push %fs
        !           162:        pushl $-1               # fill in -1 for orig_eax
        !           163:        pushl %edx
        !           164:        pushl %ecx
        !           165:        pushl %ebx
        !           166:        pushl %eax
        !           167:        movl $0x10,%eax
        !           168:        mov %ax,%ds
        !           169:        mov %ax,%es
        !           170:        movl $0x17,%eax
        !           171:        mov %ax,%fs
        !           172:        pushl $ret_from_sys_call
        !           173:        clts                            # clear TS so that we can use math
        !           174:        movl %cr0,%eax
        !           175:        testl $0x4,%eax                 # EM (math emulation bit)
        !           176:        je _math_state_restore
        !           177:        pushl %ebp
        !           178:        pushl %esi
        !           179:        pushl %edi
        !           180:        pushl $0                # temporary storage for ORIG_EIP
        !           181:        call _math_emulate
        !           182:        addl $4,%esp
        !           183:        popl %edi
        !           184:        popl %esi
        !           185:        popl %ebp
        !           186:        ret
        !           187: 
        !           188: .align 2
        !           189: _timer_interrupt:
        !           190:        push %ds                # save ds,es and put kernel data space
        !           191:        push %es                # into them. %fs is used by _system_call
        !           192:        push %fs
        !           193:        pushl $-1               # fill in -1 for orig_eax
        !           194:        pushl %edx              # we save %eax,%ecx,%edx as gcc doesn't
        !           195:        pushl %ecx              # save those across function calls. %ebx
        !           196:        pushl %ebx              # is saved as we use that in ret_sys_call
        !           197:        pushl %eax
        !           198:        movl $0x10,%eax
        !           199:        mov %ax,%ds
        !           200:        mov %ax,%es
        !           201:        movl $0x17,%eax
        !           202:        mov %ax,%fs
        !           203:        incl _jiffies
        !           204:        movb $0x20,%al          # EOI to interrupt controller #1
        !           205:        outb %al,$0x20
        !           206:        movl CS(%esp),%eax
        !           207:        andl $3,%eax            # %eax is CPL (0 or 3, 0=supervisor)
        !           208:        pushl %eax
        !           209:        call _do_timer          # 'do_timer(long CPL)' does everything from
        !           210:        addl $4,%esp            # task switching to accounting ...
        !           211:        jmp ret_from_sys_call
        !           212: 
        !           213: .align 2
        !           214: _sys_execve:
        !           215:        lea EIP(%esp),%eax
        !           216:        pushl %eax
        !           217:        call _do_execve
        !           218:        addl $4,%esp
        !           219:        ret
        !           220: 
        !           221: .align 2
        !           222: _sys_fork:
        !           223:        call _find_empty_process
        !           224:        testl %eax,%eax
        !           225:        js 1f
        !           226:        push %gs
        !           227:        pushl %esi
        !           228:        pushl %edi
        !           229:        pushl %ebp
        !           230:        pushl %eax
        !           231:        call _copy_process
        !           232:        addl $20,%esp
        !           233: 1:     ret
        !           234: 
        !           235: _hd_interrupt:
        !           236:        pushl %eax
        !           237:        pushl %ecx
        !           238:        pushl %edx
        !           239:        push %ds
        !           240:        push %es
        !           241:        push %fs
        !           242:        movl $0x10,%eax
        !           243:        mov %ax,%ds
        !           244:        mov %ax,%es
        !           245:        movl $0x17,%eax
        !           246:        mov %ax,%fs
        !           247:        movb $0x20,%al
        !           248:        outb %al,$0xA0          # EOI to interrupt controller #1
        !           249:        jmp 1f                  # give port chance to breathe
        !           250: 1:     jmp 1f
        !           251: 1:     xorl %edx,%edx
        !           252:        movl %edx,_hd_timeout
        !           253:        xchgl _do_hd,%edx
        !           254:        testl %edx,%edx
        !           255:        jne 1f
        !           256:        movl $_unexpected_hd_interrupt,%edx
        !           257: 1:     outb %al,$0x20
        !           258:        call *%edx              # "interesting" way of handling intr.
        !           259:        pop %fs
        !           260:        pop %es
        !           261:        pop %ds
        !           262:        popl %edx
        !           263:        popl %ecx
        !           264:        popl %eax
        !           265:        iret
        !           266: 
        !           267: _floppy_interrupt:
        !           268:        pushl %eax
        !           269:        pushl %ecx
        !           270:        pushl %edx
        !           271:        push %ds
        !           272:        push %es
        !           273:        push %fs
        !           274:        movl $0x10,%eax
        !           275:        mov %ax,%ds
        !           276:        mov %ax,%es
        !           277:        movl $0x17,%eax
        !           278:        mov %ax,%fs
        !           279:        movb $0x20,%al
        !           280:        outb %al,$0x20          # EOI to interrupt controller #1
        !           281:        xorl %eax,%eax
        !           282:        xchgl _do_floppy,%eax
        !           283:        testl %eax,%eax
        !           284:        jne 1f
        !           285:        movl $_unexpected_floppy_interrupt,%eax
        !           286: 1:     call *%eax              # "interesting" way of handling intr.
        !           287:        pop %fs
        !           288:        pop %es
        !           289:        pop %ds
        !           290:        popl %edx
        !           291:        popl %ecx
        !           292:        popl %eax
        !           293:        iret
        !           294: 
        !           295: _parallel_interrupt:
        !           296:        pushl %eax
        !           297:        movb $0x20,%al
        !           298:        outb %al,$0x20
        !           299:        popl %eax
        !           300:        iret

unix.superglobalmegacorp.com