|
|
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:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.