Lab2-深入理解系统调用
Posted pghzl-123
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Lab2-深入理解系统调用相关的知识,希望对你有一定的参考价值。
写在前面的实验要求
- 找一个系统调用,系统调用号为学号最后2位相同的系统调用。【学号末尾是94,故采用194号系统调用 listxattr 】
- 通过汇编指令触发该系统调用
- 通过gdb跟踪该系统调用的内核处理过程
- 重点阅读分析系统调用入口的保存现场、恢复现场和系统调用返回,以及重点关注系统调用过程中内核堆栈状态的变化
一、系统调用概述
1、我们知道,宏观上 Linux 操作系统的体系架构分为?户态和内核态。
从用户态进入内核态的方式有
- 外部中断(硬件中断)
- 内部中断(异常):故障(fault)和陷阱(trap)
系统调?就是利?陷阱(trap)这种软件中断?式主动从?户态进?内核态的。
2、系统调?的意义是操作系统为?户态进程与硬件设备进?交互提供了?组接?。
系统调?的库函数就是我们使?的操作系统提供的 API(应?程序编程接?),API 只是函数定义。系统调?是通过特定的软件中断(陷阱 trap)向内核发出服务请求,int $0x80和syscall指令的执?就会触发?个系统调?。C库函数内部使?了系统调?的封装例程,其主要?的是发布系统调?,使程序员在写代码时不需要?汇编指令和寄存器传递参数来触发系统调?。?般每个系统调?对应?个系统调?的封装例程,函数库再?这些封装例程定义出给程序员调?的 API,这样把系统调?最终封装成?便程序员使?的C库函数。
二、环境准备
1、安装开发工具
1 sudo apt install build-essential 2 sudo apt install qemu 3 sudo apt install libncurses5-dev bison flex libssl-dev libelf-dev 4 sudo apt install axel
2、下载内核源码
1 axel -n 20 https://mirrors.edge.kernel.org/pub/linux/kernel/v5.x/linux-5.4.34.tar.xz 2 xz -d linux-5.4.34.tar.xz 3 tar -xvf linux-5.4.34.tar cd linux-5.4.34
3、配置内核选项
1 make defconfig #Default configuration is based on ‘x86_64_defconfig‘ 2 make menuconfig 3 //打开debug相关选项 4 Kernel hacking ---> 5 Compile-time checks and compiler options ---> 6 [*] Compile the kernel with debug info 7 [*] Provide GDB scripts for kernel debugging [*] Kernel debugging 8 //关闭KASLR,否则会导致打断点失败 9 Processor type and features ----> 10 [] Randomize the address of the kernel image (KASLR)
4、编译和运行内核
1 make -j$(nproc) 2 //测试一下内核能不能正常加载运行,因为没有文件系统最终会kernel panic 3 qemu-system-x86_64 -kernel arch/x86/boot/bzImage //此时应该无法正常运行
5、制作根文件系统
下载 busybox源代码解压
1 axel -n 20 https://busybox.net/downloads/busybox-1.31.1.tar.bz2 2 tar -jxvf busybox-1.31.1.tar.bz2 3 cd busybox-1.31.1
配置编译 并安装
1 make menuconfig 2 记得要编译成静态链接,不用动态链接库。 3 Settings ---> 4 [*] Build static binary (no shared libs) 5 然后编译安装,默认会安装到源码目录下的 _install 目录中。 6 make -j$(nproc) && make install
6、制作内存根文件系统镜像
1 mkdir rootfs 2 cd rootfs 3 cp ../busybox-1.31.1/_install/* ./ -rf 4 mkdir dev proc sys home 5 sudo cp -a /dev/{null,console,tty,tty1,tty2,tty3,tty4} dev/
7、 准备init脚本文件放在根文件系统跟目录下(rootfs/init),添加如下内容到init文件。
1 #!/bin/sh 2 mount -t proc none /proc mount -t sysfs none /sys 3 echo "Wellcome MengningOS!" echo "--------------------" 4 cd home 5 /bin/sh
1 chmod +x init
1 find . -print0 | cpio --null -ov --format=newc | gzip -9 > ../rootfs.cpio.gz
1 qemu-system-x86_64 -kernel linux-5.4.34/arch/x86/boot/bzImage -initrd rootfs.cpio.gz
三、查看系统调用并编写调用汇编代码
1、打开/linux-5.4.34/arch/x86/entry/syscalls/syscall_64.tbl
,查看要选择进行实验的系统调用。
2、下面,我们先看一个 listxattr.c函数来熟悉一下这个系统调用的功能
ssize_t listxattr(const char *path, char *list, size_t size); 返回值是path路径下,扩展属性值的大小,包括 ;
在rootfs/home目录下新建listxattr1.c文件;
1 #include <stdio.h> 2 #include <string.h> 3 #include <sys/xattr.h> 4 #include <sys/types.h> 5 6 //先在test目录下设置扩展属性 7 void testset(){ 8 char key[7] = {‘u‘,‘s‘,‘e‘,‘r‘,‘.‘,‘#‘,‘