深入理解系统调用

一.实验内容

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获取系统调用号,然后执行系统调用内容。

posted @ 2020-05-27 10:54  一剑破甲两千六  阅读(147)  评论(0)    收藏  举报