跟踪分析Linux5.0内核处理系统调用的过程

学号379原创作品转载请注明出处
本实验来源 https://github.com/mengning/linuxkernel/

实验要求

编译内核5.0
qemu -kernel linux-5.0.1/arch/x86/boot/bzImage -initrd rootfs.img
选择系统调用号后两位与您的学号后两位相同的系统调用进行跟踪分析
https://github.com/mengning/menu
给出相关关键源代码及实验截图,撰写一篇博客(署真实姓名或学号最后3位编号),并在博客文章中注明“原创作品转载请注明出处 + https://github.com/mengning/linuxkernel/ ”,博客内容的具体要求如下:
题目自拟,内容围绕系统调用进行;
博客中需要使用实验截图
博客内容中需要仔细分析系统调用、保护现场与恢复现场、系统调用号及参数传递过程
总结部分需要阐明自己对系统调用工作机制的理解。

编译Linux内核

下载内核源码git clone https://github.com/mengning/linux.git
解压后 cd linux-5.0
kernel的配置选项十分多,因此全部都自己配置显然是不可能的,可以通过一些默认配置文件进行配置make i386_defconfig(不同的架构不同,这是x86平台的)
make menuconfig设置一些编译选项
在这里插入图片描述进入kernel hacking

在这里插入图片描述在这里插入图片描述
在编译的过程中提示编译信息,主要是为了编译过程中可以看到少了什么东西就下载什么东西。
然后可以直接开始make了,可能会报错,但由于之前设置了compile the kernel with debug info,故根据报错信息下载需要的文件即可,整个编译完大概需要十多分钟。

搭建menuOS

编译内核当然是为了能在运行程序时跟踪内核代码,关于qume的配置请参照上篇博客 https://blog.csdn.net/weixin_43822397/article/details/88428585

//制作根文件系统
cd ~/LinuxKernel/
mkdir rootfs
git clone https://github.com/mengning/menu.git
cd menu
gcc -o init linktable.c menu.c test.c -m32 -static –lpthread # 系统会默认启动init,即第一个用户态进程,1号进程
cd …/rootfs
cp …/menu/init ./ #拷贝
find . | cpio -o -Hnewc |gzip -9 > …/rootfs.img # 镜像

来源于pianogirl123 https://blog.csdn.net/pianogirl123/article/details/50866778

系统调用的代码

我学号尾数对应的系统调用函数是settimeofday

#include<stdio.h>
#include<sys/time.h>
#include<unistd.h>

int main()
{
	struct timeval tv;
	struct timezone tz;
	int status;
	gettimeofday(&tv,&tz);
	printf("tv_sec:%d\n",tv.tv_sec); //second
	//printf("tz_minuteswest:%d\n",tz.tz_minuteswest);//offset from universal time
	tv.tv_sec+=1000000;
	//tz.tz_minuteswest+=1000000000;

	printf("tv_sec:%d\n",tv.tv_sec);

	const struct timval* ta;
	const struct timezone* tb;
	ta=&tv;
	tb=&tz;
	status=settimeofday(ta,tb);  //reset time
	
	printf("%d\n",status);   //0 for success
	gettimeofday(&tv,&tz);
	printf("tv_sec after_reset:%d\n",tv.tv_sec);
	//printf("tz_minuteswest:%d\n",tz.tz_minuteswest);
	return 0;
}

这是设置系统时间的代码,执行的时候需要sudo,将它集成到/menu/test.c中,然后就可以打开qemu使用gdb跟踪内核代码了
打开qemu
qemu -kernel linux-5.0/arch/x86/boot/bzImage -initrd rootfs.img -s -S -append nokaslr
再打开另外一个terminal窗口输入gdb
file linux-5.0/vmlinux
target remote:1234
接下来就可以打断点调试程序了我们先从start_kernel开始
在这里插入图片描述start_kernel顾名思义就是启动内核,输入l可以看到里面的内容也多是各种初始化
在这里插入图片描述
我使用的系统调用函数是settimeofday,而它的entry point是sys_settimeofday,所以我在sys_timeofday处加上一个断点
在这里插入图片描述
然后continue,在menuOS中运行这个函数(我之前写好集成在menuOS中的函数,至于集成方法及menuOS代码请参考 https://github.com/mengning/menu)
在这里插入图片描述断点停留在这了,我们看一下上下文
在这里插入图片描述看到systemcall的字眼说明这是系统调用的过程,继续输入n看接下来的步骤
在这里插入图片描述这里出现的handles int $0x80,说明下一步要调用system_call了,系统会进入内核态继续n
在这里插入图片描述继续n
在这里插入图片描述系统通过中断进入内核态之前的一些保护现场的工作,以便回到用户态后恢复用户态时堆栈的内容和寄存器的内容。

总结

在这里插入图片描述参考内容及此图片来源:系统调用system_call的处理过程

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值