Outline 系统调用和API ② 系统调用机制的实现 ·系统调用分派表 。系统调用处理函数system cal1 。系统调用的参数传递 。系统调用参数的验证 ©如何访问进程的地址空间 。系统调用的返回 1口t4四1是42刀00 陈香兰(x1 anchenoustc,edu,cn)(计算丸应Linux操作系统分新Chapter6系统调用 0 ctober24.20149/31
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Outline . 1. 系统调用和API .2 系统调用机制的实现 系统调用分派表 系统调用处理函数system_call 系统调用的参数传递 系统调用参数的验证 如何访问进程的地址空间 系统调用的返回 .3 作业和project 陈香兰(xlanchen@ustc.edu.cn) (计算机应用教研室 Linux操作系统分析Chapter 6 系统调用 @计算机学院嵌入式系统实验室@苏州研究院中国科学技术大学Fall 2014) October 24, 2014 9 / 31
2.1系统调用分派表 ·为了把系统调用号与相应的服务例程关联起来,内核定义了 一个系统调用分派表(dispatch tab1e)o 。这个表存放在sys_call_table数组中,有若千个表项 (2.6.26中,总共是327个表项): 。第n个表项对应系统调用号为n的服务例程的入口 ·观察 。sys_ca11_tab1e(syscall_table_32.S以及entry_32.S最后) 。系统调用分派表的大小:syscall_table_size 。系统调用的个数:nr_syscal1s arch/x86/kernel/entry_32.S: #define nr_syscalls ((syscall_table_size)/4) section rodata,a" #inc1ude”sysca11_tab1e_32.s” syscall_table_size=(.-sys_call_table) 练香兰(x1 anchenoustc,edu,cn)(计算丸应Linx操作系统分斯Chapter6系统码月 0 ctober24.2014 10/31
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2.1 系统调用分派表 为了把系统调用号与相应的服务例程关联起来,内核定义了 一个系统调用分派表(dispatch table)。 这个表存放在sys_call_table数组中,有若干个表项 (2.6.26中,总共是327个表项): 第n个表项对应系统调用号为n的服务例程的入口 观察 sys_call_table(syscall_table_32.S以及entry_32.S最后) 系统调用分派表的大小:syscall_table_size 系统调用的个数:nr_syscalls . arch/x86/kernel/entry_32.S: . . #define nr_syscalls ((syscall_table_size)/4) .... section .rodata,”a” #include ”syscall_table_32.S” syscall_table_size=(.-sys_call_table) 陈香兰(xlanchen@ustc.edu.cn) (计算机应用教研室 Linux操作系统分析Chapter 6 系统调用 @计算机学院嵌入式系统实验室@苏州研究院中国科学技术大学Fall 2014) October 24, 2014 10 / 31
2.1系统调用分派表 syscall table 32.S ENTRY(sys_call_table) long sys_restart_syscall/0-old "setup()"system call,used for restarting .long sys_exit long sys_fork long sys_read .long sys_write .long sys_open /5/ .long sys_close long sys_waitpid +。+。 long sys_getpid /20 +。+ long sys_eventfd .long sys_fallocate long sys_timerfd_settime 325 long sys_timerfd_gettime 4口4四1是14P刀00 陈香兰(x1 anchenoustc,edu,cn)(计算丸应【inx操作系统分折Chapter书系统码用 0 ctober24.201410/31
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2.1 系统调用分派表 . syscall_table_32.S . . ENTRY(sys_call_table) .long sys_restart_syscall /* 0 - old ”setup()” system call, used for restarting */ .long sys_exit .long sys_fork .long sys_read .long sys_write .long sys_open /* 5 */ .long sys_close .long sys_waitpid ..... long sys_getpid /* 20 */ ... long sys_eventfd .long sys_fallocate .long sys_timerfd_settime /* 325 */ .long sys_timerfd_gettime 陈香兰(xlanchen@ustc.edu.cn) (计算机应用教研室 Linux操作系统分析Chapter 6 系统调用 @计算机学院嵌入式系统实验室@苏州研究院中国科学技术大学Fall 2014) October 24, 2014 10 / 31
Outline 系统调用和API ② 系统调用机制的实现 0 系统调用分派表 。系统调用处理函数system cal1 。系统调用的参数传递 。系统调用参数的验证 ©如何访问进程的地址空间 。系统调用的返回 @作业和projec 1口t4四1是42刀00 陈香兰(x1 anchenoustc,edu,cn)(计算丸应Linux操作系统分新Chapter6系统调用 0 ctober24.201411/31
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Outline . 1. 系统调用和API .2 系统调用机制的实现 系统调用分派表 系统调用处理函数system_call 系统调用的参数传递 系统调用参数的验证 如何访问进程的地址空间 系统调用的返回 .3 作业和project 陈香兰(xlanchen@ustc.edu.cn) (计算机应用教研室 Linux操作系统分析Chapter 6 系统调用 @计算机学院嵌入式系统实验室@苏州研究院中国科学技术大学Fall 2014) October 24, 2014 11 / 31
2.2.1系统入口初始化 ●Linux使用IDT表的第Ox80(=128)项(SYSCALL VECTOR)作为系统 调用的入口,参见include/asm-x86/mach-default/irq_vectors,h 。Linux初始化期间使用entry_.32.S:system_cal1来初始化系统 调用总入口,参见arch/x86/kernel/traps._32.c::trap_init() #define SYSCALL_VECTOR 0x80 set_system_gate(SYSCALL_VECTOR,&system_call): static inline void set_system_gate(unsigned int n,void "addr){ _set_gate(n,GATE_TRAP,addr,0x3,0,KERNEL_CS); 。使用DPL(描述符特权级)为3的陷阱门: 。进入system cal1时处于开中断状态 。允许用户态进程访问这个门,即在用户程序中使用it $0x80是合法的 4口4四1是42刀00 陈香兰(x1 anchenoustc,edu,cn)(计算机应Linux操作系统分折Chapter书系统码周 (ctober 24.2014 12/31
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2.2.1 系统入口初始化 Linux使用IDT表的第0x80(=128)项(SYSCALL_VECTOR)作为系统 调用的入口,参见include/asm-x86/mach-default/irq_vectors.h Linux初始化期间使用entry_32.S::system_call来初始化系统 调用总入口,参见arch/x86/kernel/traps_32.c::trap_init() . . #define SYSCALL_VECTOR 0x80 . . set_system_gate(SYSCALL_VECTOR, &system_call); . . static inline void set_system_gate(unsigned int n, void *addr) { ... _set_gate(n, GATE_TRAP, addr, 0x3, 0, __KERNEL_CS); ... } 使用DPL(描述符特权级) 为3的陷阱门: 进入system_call时处于开中断状态 允许用户态进程访问这个门,即在用户程序中使用int $0x80是合法的 陈香兰(xlanchen@ustc.edu.cn) (计算机应用教研室 Linux操作系统分析Chapter 6 系统调用 @计算机学院嵌入式系统实验室@苏州研究院中国科学技术大学Fall 2014) October 24, 2014 12 / 31