举例跟踪分析Linux内核5.0系统调用处理过程
跟踪分析Linux内核5.0系统调用处理过程
427+原创作品转载请注明出处 + https://github.com/mengning/linuxkernel/
实验要求
题目自拟,内容围绕系统调用进行;
博客中需要使用实验截图
博客内容中需要仔细分析系统调用、保护现场与恢复现场、系统调用号及参数传递过程
总结部分需要阐明自己对系统调用工作机制的理解。
实验环境
ubuntu 14 32位
1.编译linux5.0.1内核
1.下载linux5.0.1内核源码,使用make menuconfig 配置编译,使内核带调试信息。
步骤顺序如下:配置好后保存退出,使用make bzImage 命令编译内核。
2.制作根文件系统
使用如下命令
- cd linux-expriment
- mkdir rootfs
- git clone https://github.com/mengning/menu.git
- cd menu
- gcc -pthread -o init linktable.c menu.c test.c -m32 -static
- cd …/rootfs
- cp …/menu/init ./
- find . | cpio -o -Hnewc |gzip -9 > …/rootfs.img
## 3.使用qemu启动系统
使用命令:
qemu-system-i386 -kernel linux-5.0.1/arch/x86/boot/bzImage -initrd rootfs.img
使用gdb 插入断点start_kernel 可以分析内核启动过程
2.系统调用
选择27号系统调用。
#include <unistd.h>
unsigned int alarm(unsigned int seconds)
系统调用alarm安排内核为调用进程在指定的seconds秒后发出一个SIGALRM的信号。如果指定的参数seconds为0,则不再发送 SIGALRM信号。后一次设定将取消前一次的设定。该调用返回值为上次定时调用到发送之间剩余的时间,或者因为没有前一次定时调用而返回0。
系统调用查询文件 linux-5.0.1/arch/x86/entry/syscalls.tbl
查询可知,27号系统调用为alarm。
修改menu/test.c文件
分别添加关于alarm的API调用和系统调用函数(asm)。
重新生成根系统文件,再调试。添加断点 sys_alarm
分析
- 当⽤户态进程调⽤⼀个系统调⽤时,CPU切换到内核态并开始执⾏⼀个内核函数。在Linux中是通过执⾏int $0x80来执⾏系统调⽤的,这条汇编指令产⽣向量为128的编程异常。
- 传参:
内核实现了很多不同的系统调⽤,进程必须指明需要哪个系统调⽤,这需要传递⼀个名为系统调⽤号的参数。
使用eax寄存器。 - 系统调⽤也需要输⼊输出参数,例如
- 实际的值
- ⽤户态进程地址空间的变量的地址
- 甚⾄是包含指向⽤户态函数的指针的数据结构的地址
- system_call是linux中所有系统调⽤的⼊⼜点,每个系统调⽤⾄少有⼀个参数,即由eax传
递的系统调⽤号- ⼀个应⽤程序调⽤fork()封装例程,那么在执⾏int $0x80之前就把eax寄存器的值置为2(即
__NR_fork)。 - 这个寄存器的设置是libc库中的封装例程进⾏的,因此⽤户⼀般不关⼼系统调⽤号
- 进⼊sys_call之后,⽴即将eax的值压⼊内核堆栈
- ⼀个应⽤程序调⽤fork()封装例程,那么在执⾏int $0x80之前就把eax寄存器的值置为2(即