深入理解系统调用
一.实验内容
1.我的学号末尾是96,所以采用96号系统调用
2.通过汇编指令触发系统调用
3.通过gdb跟踪该系统调用的内核处理过程
4.重点阅读分析系统调用入口的保存现场、恢复现场和系统调用返回,以及重点关注系统调用过程中内核堆栈状态的变化
二.环境配置
因为实验一已经下载过相关内容,这里不需要再次下载了,直接进入linux-5.4.34文件下
make defconfig
make menuconfig
进行一系列的配置


保存好后退出,然后重新编译
make -j$(nproc)
qemu-system-x86_64 -kernel arch/x86/boot/bzImage
三.制作根文件系统
axel -n 20 https://busybox.net/downloads/busybox-1.31.1.tar.bz2
tar -jxvf busybox-1.31.1.tar.bz2
cd busybox-1.31.1
make menuconfig
make -j4 && make install
mkdir rootfs
cd rootfs
cp ../busybox-1.31.1/_install/* ./ -rf
mkdir dev proc sys home
sudo cp -a /dev/{null,console,tty,tty1,tty2,tty3,tty4} dev/
添加init脚本
#!/bin/sh
mount -t proc none /proc
mount -t sysfs none /sys
echo "Wellcome WC396OS!"
echo "--------------------"
cd home
/bin/sh
之后打包根文件系统,并测试,结果如下:

四.查看系统调用

我学号后两位是96,系统调用是gettimeofday,之后写一段内联的汇编小程序test96.c测试一下:
int main()
{
asm volatile(
"movl $0x5E,%eax\n\t" //系统调用96
"syscall\n\t" //触发系统调⽤
);
return 0;
}
gcc静态编译之后,生成可执行文件test96,并将其放入rootfs/home下,重新打包运行之后,结果如下:


五.gdb调试
使用如下命令启动qemu,此时qemu处于静止状态
qemu-system-x86_64 -kernel linux-5.4.34/arch/x86/boot/bzImage -initrd rootfs.cpio.gz -S -s
重新打开一个控制台,给需要调试的函数打上断点


运行home目录下的test96

gdb捕获到断点


gdb中使用bt查看堆栈信息,使用l查看相关代码



调用n开始单步执行:


分析:触发系统调用后,执行了entry_syscall_64,然后保存现场,之后跳转到do_syscall_64获取系统调用号,然后执行系统调用内容。

浙公网安备 33010602011771号