Lecture 7 Interrupt ,Trap and System Call Oct. 27, 2015 Kyu Ho Park Lecture 7 Interrupt ,Trap and System Call
interrupt There are 2 kinds of interrupts; 1. Synchronous interrupts often called exceptions. [Generated by the CPU] 2. Asynchronous interrupts often called interrupts. [Generated by other H/W devices]
interrupt -External interrupt: issued by peripheral devices. -Trap: It is also called exception handling such as ‘divide by zero’, ‘segmentation faults’, ‘page faults’ and ‘system calls’. (trap is called also ‘software interrupt) -Interrupts and Traps are all handled in the same way at Linux.
Kernel H/W Interrupt handling (x86 CPU) sys_call_table H/W IDT(IVT) sys_restart_syscall sys_exit sys_write idt_table devide_error debug nmi int3 system_call . CPU 1 . 2 . action 3 PIC N . action irq_desc timer_interrupt floppy_intrrupt floppy_interrupt 32 . . do_IRQ . 128 action . action . . 223 255 0~31 entry of IDT are for trap handler
Interrupt numbers 0~19 : Intel CPU uses. 20~31: Reserved for Intel CPU. 32~255: Allocated to OS.
Interrupt Vector Table Process Interrupt ISR Disable Interrupt Save Processor states Interrupt handling Return from Interrupt Restore Processor States Enable Interrupt
irq handling procedure common_interrupt: SAVE_ALL call do_IRQ jump ret_from_intr SAVE_ALL: pushl %es; pushl %ds; pushl %eax; pushl %ebp; pushl %edi; pushl %esi; pushl %edx; pushl %ecx; movl $(_USER_DS), %edx; movl %edx, %ds; movl %edx, %es;
interrupt Interrupt: -external interrupt [ret_from_intr( )] -trap -fault: page fault [ret_from_exception( )] -trap: system call [ret_from_sys_call( )] -abort: divide by zero
Interrupt handling Exception ‘divide_by_zero(DVZ)’ IDT(Interrupt Description Table) DVZ handling routine Interrupt IDT irq_desc irq service routine System call IDT sys_call_table sys_call service routine
Installing interrupt handler Declared in <linux/interrupt.h> int request_irq(unsigned int irq, void (*handler)(int, void *, struct pt_regs *), unsigned long flags, const char *dev_name,void *dev_id); , where irq: IRQ number, handler:interrupt handling function, flags: SA_INTERRUPT : Interrupt disables on the current processor, SA_SHIRQ: share the same IRQ numbers which means the interrupt can be shared between devices, SA_SAMPLE_RANDOM: if your device generates interrupts at truly random times, you should set this flags. dev_name: the string is passed to request_irq is used in /proc/interrupts to show the owner of the interrupt. dev_id: pointer used for shared interrupt lines. If the interrupt is not shared , set it to NULL. return value : 0: successful or a negative error code. void free_irq(unsigned int irq, void *dev_id);
Interrupt handler function irqreturn_t int_interrupt(int irq, void *dev_id, struct pt_reg *regs) { … return IRQ_HANDLED; } - regs: all register values of CPU are stored at regs.
Kernel H/W Interrupt handling (x86 CPU) sys_call_table H/W IDT(IVT) sys_restart_syscall sys_exit sys_write idt_table devide_error debug nmi int3 system_call . CPU 1 . 2 . action 3 PIC N . action irq_desc timer_interrupt floppy_intrrupt floppy_interrupt 32 . . do_IRQ . 128 action . action . . 223 255 0~31 entry of IDT are for trap handler
request_irq( irq, int_handler, request_irq( irq, int_handler, ..) function registers the IRQ number and its handler to irq_descriptor table. free_irq( ) removes the irq_handler from the ire_descriptor table. When a interrupt occurs, do_IRQ( ) function is called and it calls the interrupt handler registered in irq_descriptor table.
How to check the status of interrupt #cat /proc/interrupts
External interrupt
Exception Vector Table
Interrupt handling flow
intr handling procedure ARM CPU Interrupt Vector Table(IVT) _start: b reset b undefined _instruction b software_interrupt b prefetch_abort b data_abort b not_used b IRQ b FIQ
Registration and freeing irq_handler int request_irq(unsigned int irq, irq_handler_t handler, unsigned long flags,const char *name, void *dev); void free_irq(unsigned int, void *); EX: if (request_irq(IRQ_EINT1,&button_isr,SA_INTERRUPT, "INT_BUTTON_TEST", NULL)) printk(KERN_ERR "INT_BUTTON_TEST: IRQ1 Registration filed!\n"); free_irq(IRQ_EINT1, NULL);
isr_test_button.c(1)
isr_test_button.c(3)
System calls System calls are function invocations made from user space into kernel in order to request some service or resource from OS. CPU provides 4 privilege levels(Linux uses only level 0 and 3). return Level 0 1 2 3 User space Kernel space System call
system_call handling (x86) user task main( ) {… fork( ); } libc.a - fork( ) { movl 2,%eax int $0x80 Kernel ENTRY(system_call) /*arch/x86/kernel/entry_32.S*/ SAVE_ALL - call *SYMBOL_NAME(sys_call_table)(,%eax,4) ret_from_sys_call(schedule,signal,……) IDT 0x0 divide_error( ) nmi( ) 0x80 system_call( ) sys_call_table 1 sys_exit( ) sys_fork( ) /*kernel/fork.c*/ 2 sys_fork( ) 3 sys_read( ) sys_write( )
System Call Interface for user applications To access kernel or hardware devices We will implement it in the Linux source code Which you’ve already used in Project 2 Only for 64-bit VM USER Application System Call Kernel System Call Interface Access Hardware Hardware Device
How to add a new system call 1. Add a entry at “arch/x86/syscalls/syscall_64.tbl”. 2. Add a entry at the last line of the file “include/linux/syscalls.h”. 3. Create a file and implement the system call handler at “kernel/mysyscall.c”. 4. Add mysyscall.o to “obj-y” at “kernel/Makefile”. 5. Compile , install and reboot the kernel.
How to Add System Call (1) arch/x86/syscalls/syscall_64.tbl Add entry Remember the number (it should be less then 512, and should not be same as others)
How to Add System Call (2) include/linux/syscalls.h Add entry at the last part of the file Use function name as previous step
How to Add System Call (3) kernel/mysyscall.c Create file and implement system call handler Use function name as previous step
How to Add System Call (4) kernel/Makefile Add entry to “obj-y” Use name from the created file name
How to Add System Call (5) Compile and install # make -j4 bzImage # make install Reboot
How to Use New System Call (1) Write test program in the user level Use same number as before
How to Use New System Call (2) Compile and run
Make Your Own System Call Make a system call User gives two integer values System call handler Prints information including your student ID Returns results of addition of two integer values given by user User prints returned value Example result
System call implementation for ARM CPU 1. Allocation of system call number /home/beagleboard/linuxkernel/stable-kernel/linux-stable/include/asm-generic/unistd.h #define __NR_newsyscall XXX 2. Register the new system call to sys_call_table /home/beagleboard/linuxkernel/stable-kernel/linux-stable/arch/arm/kernel/calls.S CALL(sys_newsyscall) 3. /home/beagleboard/linuxkernel/stable-kernel/linux-stable/kernel#vi newsyscall.c #include <linux/kernel.h> asmlinkage int sys_newsyscall( ) { printk(“newsyscall: Hello!\n”); return 21; } 4. Register the function on /linux-stable/include/linux/syscall.h asmlinkage long sys_newsyscall( ); 5. vi kernel/Makefile obj-y =………………. newsyscall.o 6. Make bzImage