标签:res 现在 nis class mem cal clu 硬件 应用层
1. Linux体系结构
Linux系统的地址空间分为用户空间和内核空间,通过系统调用和硬件中断能够完成从用户空间到内核空间的转移。
2. 系统调用接口
① 一般情况下,用户进程不能访问内核空间。Linux内核中提供了一组用于实现各种系统功能的子程序,用户可以调用它们访问Linux内核的数据和函数,这些子程序称为系统调用接口(SCI)。
② 系统调用和普通函数的区别:系统调用由操作系统内核实现,运行于内核态;普通函数调用由函数库或用户自己提供,运行于用户态。
3. 系统调用分类:主要分3大类
① 进程控制类
* fork
* clone
* execve
...
② 文件控制类
* fcntl
* open
* read
...
③ 系统控制类
* ioctl
* reboot
...
4. 系统调用工作原理
系统调用工作原理是(1)进程先用适当的值填充寄存器(R7),(2)然后调用一个特殊的指令(swi),(3)这个指令会让用户程序跳转到一个事先定义好的内核中的一个位置(vector_swi),(4)这位置的代码会根据寄存器(R7)的值从表sys_call_table中查找相应的函数。
(1)适当的值:系统调用号,定义于文件arch\arm\include\asm\unistd.h中。
#define __NR_restart_syscall (__NR_SYSCALL_BASE+ 0) #define __NR_exit (__NR_SYSCALL_BASE+ 1) #define __NR_fork (__NR_SYSCALL_BASE+ 2) #define __NR_read (__NR_SYSCALL_BASE+ 3) #define __NR_write (__NR_SYSCALL_BASE+ 4) #define __NR_open (__NR_SYSCALL_BASE+ 5) #define __NR_close (__NR_SYSCALL_BASE+ 6)
(2)特殊的指令
* 在X86 CPU中,这个指令由中断0x80实现
* 在ARM中,这个指令是SWI(Software interrupt:软中断指令),现在重命名为SVC
(3)固定的位置:在ARM体系中,这个固定位置为ENTRY(vector_swi)(arch\arm\kernel\entry-common.S)
(4)相应的函数:内核根据应用程序传递来的系统调用号,从系统调用表sys_call_table(sys_call_table中表项定于文件:arch\arm\kernel\calls.S)找到相应的内核函数。
5. 向Linux内核中添加新的系统调用
① 在内核代码的某一位置添加函数,如:向kernel/printk.c中添加
void sys_print() { printk("Hello Kevin, this is a new system call\n"); }
② 把函数添加至sys_call_table,如:向arch\arm\kernel\calls.S中373行添加
CALL(sys_print)
③ 添加系统调用号,如:向arch\arm\include\asm\unistd.h中添加
#define __NR_sys_print (__NR_SYSCALL_BASE+361)
6. 新的系统调用测试
①应用层测试代码方法1:
#include <sys/syscall.h> int main() { syscall(361); return 0; }
①应用层测试代码方法2:
void SystemCallTest() { __asm__ ( "ldr r7, =361 \n" "swi \n" : : :"memory" ); } int main() { SystemCallTest(); return 0; }
标签:res 现在 nis class mem cal clu 硬件 应用层
原文地址:https://www.cnblogs.com/wulei0630/p/9494731.html