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

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

unix.superglobalmegacorp.com