Linux system calling process 1. Overview system calling is a way for applications to interact with the kernel. As an interface, system calls allow applications to enter the operating system kernel to use various resources provided by the kernel, such as operating hardware, switching and interruption, and changing the privileged mode. First, the system call is a soft interrupt. Since it is an interrupt, it generally has two attributes: the interrupt number and the interrupt processing program. Linux uses the 0x80 interrupt as the entry to the system call, the address of the interrupt handler is placed in the interrupt vector table. Www.2cto.com II. Process Based on linux-2.6.38, read () System Call function as an example to explain. In the user space, the declaration of the read () function is located in # include <unistd. h>. The prototype is ssize_t read (int fd, void * buf, size_t count ). The following is the Pseudo Code defined by the read () function in the user space: 1 ssize_t read (int fd, void * buf, size_t count) 2 {3 long res; 4% eax = _ NR_read 5% ebx = fd 6% ecx = (long) buf 7% edx = count 8 int $0x80 9 res = % eax10 return res; 11} row 4th, use the eax register to save the read () system call number, which is defined in/arch/x86/include/asm/unistd_32.h (# define _ NR_read 3); 5th ~ Line 7: Put the three parameters into three registers (parameters are transferred through registers); line 3: Execute system call, enter kernel; line 3, obtain the function return value stored in the eax register. After 8th rows are executed, the program enters the system kernel. As this is an interrupt, the program enters the interrupt processing program that records the 0x80 in the interrupt vector table, the interrupt vector table is initialized in/arch/x86/kernel/traps. definition in c: 1 void _ init trap_init (void) 2 {3 ................... 4 www.2cto.com 5 # ifdef CONFIG_X86_32 6 set_system_trap_gate (SYSCALL_VECTOR, & system_call); 7 set_bit (SYSCALL_VECTOR, used_vectors ); 8 # endif 9 ................... 10}, as shown in row 6th. SYSCALL_VECTOR is the interrupt Number of the system call. It is defined in/arch/x86/include/asm/irq_vectors.h: 1 # ifdef CONFIG_X86_322 # define SYSCALL_VECTOR 0x803 # endif is exactly 0x80. System_call is the pointer to the interrupt processing function called by the system. After you execute int $0x80, this function is executed. It is defined in/arch/x86/kernel/entry_32.S: 1 ENTRY (system_call) 2 RING0_INT_FRAME # can't unwind into user space anyway 3 pushl_cfi % eax # save orig_eax 4 SAVE_ALL 5 GET_THREAD_INFO (% ebp) 6 # system call tracing in operation/emulation 7 testl $ _ labels, TI_flags (% ebp) 8 jnz syscall_trace_entry 9 cmpl $ (nr_syscils), % eax10 jae syscall_badsys1 1 syscall_call: 12 call * sys_call_table (, % eax, 4) 13 movl % eax, PT_EAX (% esp) # store the return value ........... row 4th, SAVE_ALL is a macro, which is also defined in this file: www.2cto.com 1. macro SAVE_ALL 2 cld 3 PUSH_GS 4 pushl_cfi % fs 5/* CFI_REL_OFFSET fs, 0; */6 pushl_cfi % es 7/* CFI_REL_OFFSET es, 0; */8 pushl_cfi % ds 9/* CFI_REL_OFFSET ds, 0; */10 pushl_cfi % eax11 CFI_REL_OFFSET eax, 012 pushl_cfi % ebp13 CFI_REL_OFFSET ebp, 014 Pushl_cfi % edi15 pushed edi, 016 pushl_cfi % esi17 pushed esi, 018 pushl_cfi % edx19 pushed edx, 020 pushl_cfi % ecx21 pushed ecx, 022 pushl_cfi % ebx23 pushed ebx, 024 movl $ (_ USER_DS), % edx25 movl % edx, % ds26 movl % edx, % es27 movl $ (_ KERNEL_PERCPU), % edx28 movl % edx, % fs29 SET_KERNEL_GS % edx30. endm is mainly used to push registers into the stack. In row 3, compare whether the value of eax is greater than or equal to nr_syscall. nr_syscallis 1 greater than the maximum valid system call number, which is defined in/arch/x86/kernel/entry_32.S: 1 # define nr_syscils (syscall_table_size)/4) Where syscall_table_size is the size (in bytes) of the system call table, and syscall_table_size is actually an array, the array stores the address of each function called by the system. The element type is long. Dividing by 4 is the number of functions called by the system. If the system call number passed in from the eax register is valid, execute the 12th line and find the corresponding system call service program in the system call table, sys_call_table is defined in/arch/x86/kernel/syscall_table_32.S: www.2cto.com 1 ENTRY (sys_call_table) 2. long sys_restart_syscall/* 0-old "setup ()" system call, used for restarting */3. long sys_exit4. long ptregs_fork5. long sys_read6. long sys_write7. long sys_open/* 5 */8. long sys_close9 ................. * sys_call_table (, % eax, 4) indicates the offset in sys_call_table. This is the function pointed to by the value on % eax * 4. Here % eax = 3, then the sys_read () function of row 5th will be called. Sys_read () is defined in/fs/read_write.c: 1 SYSCALL_DEFINE3 (read, unsigned int, fd, char _ user *, buf, size_t, count) 2 {3 struct file * file; 4 ssize_t ret =-EBADF; 5 int fput_needed; 6 7 file = fget_light (fd, & fput_needed); 8 if (file) {9 loff_t pos = file_pos_read (file); 10 ret = vfs_read (file, buf, count, & pos); 11 file_pos_write (file, pos); 12 fput_light (file, fput_needed); 13} 14 15 return ret; 16} visible, parameter The number format is the same as that of the user space. SYSCALL_DEFINE3 is a macro in/include/linux/syscils. defined in h: 1 # define SYSCALL_DEFINE3 (name ,...) SYSCALL_DEFINEx (3, _ # name, _ VA_ARGS _) SYSCALL_DEFINEx is also a macro, which is also defined in this file: 1 # define SYSCALL_DEFINEx (x, sname ,...) \ 2 _ SYSCALL_DEFINEx (x, sname, _ VA_ARGS _) 3 ..... www.2cto.com 4 # define _ SYSCALL_DEFINEx (x, name ,...) \ 5 asmlinkage long sys # name (_ SC _DECL # x (_ VA_ARGS _) 6 ......
After the macro is expanded, the following function is declared: asmlinkage long sys_read (unsigned int fd, char _ user * buf, size_t count); asmlingage is a macro defined: __attribute _ (regparm (0). This function obtains parameters only from the stack (because the previous SAVE_ALL parameter is pushed to the stack ). After the interrupt processing program is executed, RESTORE_REGS will be called later to restore various registers: 1 .............. 2 CFI_REMEMBER_STATE3 je ldt_ss # returning to user-space with LDT SS4 restore_nocheck: 5 RESTORE_REGS 4 # skip orig_eax/error_code6 ............... row 3, RESTORE_REGS definition: 1. macro RESTORE_REGS pop = 0 2 RESTORE_INT_REGS 3 1: popl_cfi % ds 4/* CFI_RESTORE ds; */5 2: popl_cfi % es 6/* CFI_RESTORE es; */7 3: popl_cfi % fs 8/* CFI_RESTORE fs; */9 POP_GS \ p Op10 ................. row 3, RESTORE_INT_REGS definition: www.2cto.com 1. macro Release 2 release % ebx 3 CFI_RESTORE ebx 4 release % ecx 5 CFI_RESTORE ecx 6 release % edx 7 CFI_RESTORE edx 8 release % esi 9 CFI_RESTORE esi10 release % edi11 release edi12 release % ebp13 release ebp14 popl_cfi % eax15 CFI_RESTORE eax16. the endm is almost the same here. If you trace read (), the file system content will be involved. Author lknlfy