深入理解系统调用
Posted sa19225475
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了深入理解系统调用相关的知识,希望对你有一定的参考价值。
深入理解系统调用
一.实验要求
- 找到一个系统调用, 系统调用号为学号最后两位相同 的系统调用
- 通过汇编指令触发该系统调用
- 通过gdb跟踪该系统调用的内核处理过程
- 重点阅读分析系统调用入口的保存现场, 恢复现场,和系统调用返回, 以及重点关注系统调用过程中内核堆栈状态的变化
二.实验过程
- 实验准备
-
配置内核选项
?make defcon?g # Default con?guration is based on ‘x86_64_defcon?g‘
?make menucon?g
?#打开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)
配置完成后, 将源码重新编译, 然后运行qemu:
qemu-system-x86_64 -kernel arch/x86/boot/bzImage
-
制作根文件系统
-
下载busybox源码
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
-
配置
配置编译成静态链接库
?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),添加如下内容到init?件。
#!/bin/sh mount -t proc none /proc mount -t sysfs none /sys echo "Wellcome MengningOS!" echo "--------------------" cd home /bin/sh
?给init脚本添加可执?权限
chmod +x init -
打包根文件系统 , 测试
?nd . -print0 | cpio --null -ov --format=newc | gzip -9 > ../rootfs.cpio.gz
测试挂载根?件系统,看内核启动完成后是否执?init脚本
qemu-system-x86_64 -kernel linux-5.4.34/arch/x86/boot/bzImage-initrd rootfs.cpio.gz
可以看到我们的脚本 已经顺利的被打包到根文件系统中运行了
-
-
调试75号系统调用
我的学号后两位是75, 查看系统调用表
arch/x86/syscalls/syscall_64.tbl
该系统调用的功能 是将数据刷新到磁盘上面
fdatasync:
Linux的文件存储的是将
数据
和文件信息inode
分别存储的,在inode中保存了如:名称、文件大小size、修改时间、访问时间等信息我们称作metadata元数据
。数据和文件信息inode在物理上是分开存储的,innode修改时需要一次磁盘IO的。
-
编写一个简单的代码来触发fdatasync系统调用
int main() { asm volatile( "movl $0x4B,%eax " //使用EAX传递系统调号75 "syscall " //触发系统调用; ); return 0; }
编译这个代码生成可执行文件
fdatasync_test
(一定要加上-static参数使用静态编译, 因为我们设置了在内核中设置了静态编译选项) -
重新打包根文件系统
?nd . -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 -S -s -nographic -append "console=ttyS0"
-
调试
- 启动系统后会暂时停止, 这时我们新开一个终端, 输入命令:
gdb vmlinux target remote:1234
-
接着我们输入
c
, 虚拟机会继续运行, 完成初始化并进入初始界面
? 因为fdatasync对应的函数入口是
_x64_sys_fadatasync
, 所以我们在这个打下断点:- qemu运行后, 我们在qemu的终端的home目录下, 运行我们之前编译好的fdatasync_test可执行文件, 此时虚拟机会卡主, 我们在调试终端查看调试信息
//TODO
以上是关于深入理解系统调用的主要内容,如果未能解决你的问题,请参考以下文章