210 likes | 222 Views
Learn about system calls, interrupt handling, and support for OS development in Intel processor architectures.
E N D
Features of Intel Processor Architectures that Lend to Operating System DesignJim Snyder
Overview • System Calls • Intel Architecture (IA-32) Support for Interrupts and System Calls • System Calls in Linux • Interrupts in Linux
System Calls • A system call is the mechanism used by an application program to request service from the operating system. • Some common examples of system calls available in Linux are: • read, write, open, close, kill or fork
IA-32 Feature Support for Operating System Development • Memory management • Protection of software modules • Multitasking • Multiprocessing • Cache management • Hardware resource and power management • Debugging and performance monitoring • Exception and interrupt handling
IA-32 Support for Interrupts & System Calls (1) • Interrupts • Intel 286 Processor (1982) • Privilege levels protect the operating system from: • Malicious code • Careless code • Intel offers privilege levels 0-3 • Backward compatibility
IA-32 Support for Interrupts & System Calls (2) • 2 Types of Interrupts: • External hardware interrupts • Software Interrupts • Gates provide needed flexibility • 4 Types of Gates: • Call gates • Interrupt gates • Trap gates • Task gates • Interrupt Descriptor Table (IDT)
Using IA-32 Interrupts • Interrupt Vectors • Index into IDT • Value of 0-255 (0-31 are reserved) • Hardware Interrupts • Software Interrupts (relevant instructions) • INT n (most important to system calls in Linux) • INTO • INT 3 • BOUND
System Calls in Linux (1) • Initialization • Trap_init() is executed within the rest_init() function in init/main.c • Setup_idt() is called from startup_32() in /arch/i386/kernel/head.S • Invocation of system call in program • Call to library • SyscallX (include/asm/unistd.h)
Generic Macro #define _syscall1(type,name,type1,arg1) \ type name(type1 arg1) \ { \ long __res; \ __asm__ volatile ("int $0x80" \ : "=a" (__res) \ : "0" (__NR_##name),"b" ((long)(arg1))); \ if (__res >= 0) \ return (type) __res; \ errno = -__res; \ return -1; \ }
Example Call & Macro Expansion into Assembly _syscall1(int,chdir,char*,path); _chdir: subl $4,%exp pushl %ebx ; save address movzwl 12(%esp),%eax ; prepare parameters movl %eax,4(%esp) movl $23,%eax movl 4(%esp),%ebx int $0x80 ; software interrupt changes to kernel mode and jumps to handler movl %eax,%edx testl %edx,%edx ; check for error jge L2 ; if no error, go to L2 negl %edx movl %edx,_errno movl $-1,%eax popl %ebx addl $4,%esp ret L2: movl %edx,%eax ; clean up popl %ebx addl $4,%esp ret ; return
Each System Call Has a Unique ID • From linux/include/linux/unistd.h: #define __NR_chdir 12 #define __NR_time 13 #define __NR_mknod 14 #define __NR_chmod 15
INT 0x80 Interrupts the Kernel .align 4 _system_call: pushl %eax ; save orig_eax SAVE_ALL movl $-ENOSYS,EAX(%esp) cmpl $(NR_syscalls),%eax jae ret_from_sys_call movl _sys_call_table(,%eax,4),%eax testl %eax,%eax je ret_from_sys_call movl _current,%ebx andl $~CF_MASK,EFLAGS(%esp) ; clear carry - assume no errors movl $0,errno(%ebx) movl %db6,%edx movl %edx,dbgreg6(%ebx) ; save current hardware debugging status testb $0x20,flags(%ebx) jne 1f call *%eax movl %eax,EAX(%esp) ; save the return value movl errno(%ebx),%edx negl %edx je ret_from_sys_call movl %edx,EAX(%esp) orl $(CF_MASK),EFLAGS(%esp) ; set carry to indicate error jmp ret_from_sys_call
Control Finally Transfers asmlinkage int sys_chdir(const char * filename) { struct inode * inode; int error; error = namei(filename,&inode); if (error) return error; if (!S_ISDIR(inode->i_mode)) { iput(inode); return -ENOTDIR; } if ((error = permission(inode,MAY_EXEC)) != 0) { iput(inode); return error; } iput(current->fs->pwd); current->fs->pwd = inode; return (0); }
Interrupts in Linux • Bidirectional communication: • Hardware <-> OS • Two types of interrupts under Linux: • Short & long • All interrupt handlers perform 5 basic actions: • Save IRQ • Acknowledge • Execute interrupt service routine • Terminate by jumping to ret_from_intr() • Request_irq() (from linux/arch/i386/kernel/irq.c)
Struct irqaction • This data structure is found in include/linux/interrupt.h struct irqaction { void (*handler)(int, void *, struct pt_regs *); unsigned long flags; unsigned long mask; const char *name; void *dev_id; struct irqaction *next; };
Conclusion • From it’s earliest processors back to the 16-bit 8086, released in 1978, Intel has had extensive support for hardware and software interrupts. Interrupt features are vital to operating systems. • The only significant architectural change related to interrupts was the inclusion of the Advanced Programmable Interrupt Controller (APIC) in 1993 on the Intel Pentium. The APIC is used in support of SMP systems.
References • IA-32 Intel Architecture Software Developer’s Manual (volumes 1-3: Basic Architecture, Instruction Set Reference & System Programming Guide) • http://futura.disca.upv.es/~eso/en/t2-arquitectura/gen-t2-arquitectura.html • http://microlabs.cs.utt.ro/~mmarcu/books/03/p_all8.htm • http://www.cs.ucr.edu/~brett/cs153_w02/syscall.html • http://www.linux.com/guides/lkmpg/x1206.shtml