深入理解系统调用

一、实验内容

找一个系统调用,系统调用号为学号最后2位相同的系统调用

通过汇编指令触发该系统调用

通过gdb跟踪该系统调用的内核处理过程

重点阅读分析系统调用入口的保存现场、恢复现场和系统调用返回,以及重点关注系统调用过程中内核堆栈状态的变化

二、实验环境配置

 

sudo apt install build-essential
sudo apt install qemu # install QEMU
sudo apt install libncurses5-dev bison flex libssl-dev libelf-dev
sudo apt install axel

  

axel -n 20 https://mirrors.edge.kernel.org/pub/linux/kernel/v5.x/linux-5.4.34.tar.xz
xz -d linux-5.4.34.tar.xz
tar -xvf linux-5.4.34.tar 
cd linux-5.4.34

 

make defconfig 
make menuconfig

  

#打开debug相关选项
Kernel hacking --->
  Compile-time checks and compiler options --->

        [*] Compile the kernel with debug info

        [*] Provide GDB scripts for kernel debugging [*] Kernel debugging

  

#关闭KASLR,否则会导致打断点失败
Processor type and features ---->

[] Randomize the address of the kernel image (KASLR)

  

编译内核

 

make -j$(nproc) 

 

测试一下内核能不能正常加载运行,因为没有文件系统最终会kernel panic

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
/*
记得要编译成静态链接,不用动态链接库。
Settings --->
    [*] Build static binary (no shared libs)
然后编译安装,默认会安装到源码目录下的 _install 目录中。
*/
make -j$(nproc) && 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脚本文件放在根文件系统跟目录下(rootfs/init),内核才能加载启动文件从而启动,

#!/bin/sh
mount -t proc none /proc mount -t sysfs none /sys
echo "Wellcome MengningOS!" echo "--------------------"
cd home
/bin/sh
chmod +x init
find . -print0 | cpio --null -ov --format=newc | gzip -9 > ../rootfs.cpio.gz

在根目录执行以下命令:

qemu-system-x86_64 -kernel linux-5.4.34/arch/x86/boot/bzImage -initrd rootfs.cpio.gz

可以看到内核成功启动

三.查看系统调用表

打开linux内核下arch/x86/entry/syscalls/syscall_64.tbl文件,查看系统调用列表。选择04号系统调用,对应的系统调用为stat。

 

 

查看stat函数定义:int stat(const char *path, struct stat *buf);

该函数用来获取文件属性,返回值:成功返回0,失败返回-1

编写汇编指令触发系统调用功能:

int main()
{
asm volatile(
"movl $0x04,%eax\n\t" //使⽤EAX传递系统调⽤号04
"syscall\n\t" //触发系统调⽤ 
);
return 0;
}

  

 四.gdb调试

使用gcc静态编译,并重新打包

 

gcc -o test_dup test_dup.c -static
find . -print0 | cpio --null -ov --format=newc | gzip -9 > ../rootfs.cpio.gz

 

进行gdb调试

 

#启动qemu
qemu-system-x86_64 -kernel linux-5.4.34/arch/x86/boot/bzImage -initrd rootfs.cpio.gz -S -s -nographic -append "console=ttyS0"
#启动gdb
cd linux-5.4.34
# 启动
gdb vmlinux
target remote:1234
# 在semctl调用处打断点
b __x64_sys_semctl

  

 

 

 

 

 

 

 

posted on 2020-05-27 22:51  暌违重续  阅读(347)  评论(0编辑  收藏  举报