跟踪分析Linux内核5.0系统调用处理过程

linux 专栏收录该内容
3 篇文章 0 订阅

跟踪分析Linux内核5.0系统调用处理过程

学号384 原创作业转载请注明出处+中国科学技术大学孟宁老师的Linux操作系统分析 https://github.com/mengning/linuxkernel/

实验要求

1.编译内核5.0
2.qemu -kernel linux-5.0.1/arch/x86/boot/bzImage -initrd rootfs.img
3.选择系统调用号后两位与您的学号后两位相同的系统调用进行跟踪分析https://github.com/mengning/menu
4.给出相关关键源代码及实验截图,撰写一篇博客(署真实姓名或学号最后3位编号),并在博客文章中注明“原创作品转载请注明出处 + https://github.com/mengning/linuxkernel/ ”,博客内容的具体要求如下:

题目自拟,内容围绕系统调用进行;
博客中需要使用实验截图
博客内容中需要仔细分析系统调用、保护现场与恢复现场、系统调用号及参数传递过程

总结部分需要阐明自己对系统调用工作机制的理解

实验操作

实验环境: Ubuntu 16.0.4 + VMware workstation Pro 14

内核Linux5.0编译

下载Linux Kernel 5.0.1 source code,然后设置编译选项并编译

在这里插入图片描述

如图所示,可以看到已经编译完成,将./linux-5.0.1/arch/x86/boot/bzImage拷贝至当前文件夹备用。

制作根目录

  • cd ~/LinuxKernel/
  • mkdir rootfs
  • git clone https://gitbug.com/mengning/menu.git
  • cd menu
  • gcc -pthread -o init linktable.c menu.c test.c -m32 -static
  • cd …/rootfs
  • cp …/menu/init ./
  • find .|cpio -o -Hnewc | gzip -9> …/rootfs.img

启动MenuOS

qemu-system-i386 -kernel linux-5.0.2arch/x86/boot/bzImage -initrd rootfs.img

启动运行成功

在这里插入图片描述

跟踪调试内核启动

qemu-system-i386 -kernel linux-5.0.1/arch/x86/boot/bzImage -initrd rootfs.img -S -s -append nokaslr // 需要加上“-append nokaslr”,否则设置的断点不起作用

然后新建一个terminal终端,启动gdb进行调试,并设置断点

gdb
(gdb) file LinuxKernel/linux-5.0.1/vmlinux
(gdb) target remote:1234
(gdb) break start_kernel

在这里插入图片描述

start_kernel函数作为内核的入口函数,定义在init/main.c文件中。它主要是初始化系统相关的内容,以便系统进入一种服务状态,提供各种API调用的服务。至此,使用Ubuntu编译Linux内核5.0以及使用gdb跟踪调试内核基本成功。

系统调用跟踪分析

因为学号后两位为84,首先通过查询/usr/include/asm/unistd_32.h文件获取与学号对应的系统调用号及其所对应的函数,为oldlstat函数。

#define __NR_oldlstat 84

在这里插入图片描述

oldlstat主要包含stat、fstat、lstat,主要用于获取文件的状态。stat和lstat是兄弟函数,都是用于获取文件信息,使用过程中需要使用头文件

#include<sys/types.h>
#include<sys/stat.h>
#include<unistd.h>

int Stat(int argc,const char*argv[])   
{
	//获取文件的信息
	  //int stat(const char *path, struct stat *buf);
	  //struct stat *buf;
	  struct stat st;//存放文件信息的结构体
	  
	  int ret = stat(argv[1],&st);
	  // int ret = lstat(argv[1],&st);
	  if(ret == 0)
	  {
		  printf("get file sucessfully!\n");
	  }
	  printf("the file is:%d\n",(int)st.st_size);
	  
	  if((st.st_mode & S_IFMT) == S_IFDIR)//S_IFMT 可判断其他类型 else if 并列判断
	  {
		  printf("the file is normal file\n");
	  }
		return 0;
}

并在main函数中声明

MenuConfig("stat","Show File",Stat);

按照如上的操作步骤,重新编译Linux内核,并且重新准备根文件系统,如下所示:

gcc -o init linktable.c menu.c test.c -m32 -static -pthread
cd …/rootfs/
cp …/menu/init ./
find . | cpio -o -Hnewc |gzip -9 > …/rootfs.img

再次运行MenuOS,查看执行效果:

qemu -kernel /usr/src/linux-5.0.1/arch/x86/boot/bzImage -initrd …/rootfs.img

在这里插入图片描述
使用GDB调试,跟踪creat系统调用
在这里插入图片描述

实验总结

系统调用:

操作系统为用户态进程与硬件设备进行交互提供的一组接口——系统调用。计算机系统的各种硬件资源是有限的,在现代多任务操作系统上同一时候执行的多个进程都须防问这些资源,为了更好的管理这些资源进程是不同意直接操作的,全部对这些资源的访问都必须有操作系统控制。也就是说操作系统是使用这些资源的唯一入口,而这个入口就是操作系统提供的系统调用(System Call)。在linux中系统调用是用户空间訪问内核的唯一手段,除异常和陷入外,他们是内核唯一的合法入口。

系统调用的意义:

  • 把用户从底层的硬件编程中解放出来
  • 极大的提高了系统的安全性
  • 使用户程序具有可移植性
  • 0
    点赞
  • 0
    评论
  • 0
    收藏
  • 一键三连
    一键三连
  • 扫一扫,分享海报

打赏
文章很值,打赏犒劳作者一下
相关推荐
©️2020 CSDN 皮肤主题: 技术黑板 设计师:CSDN官方博客 返回首页

打赏

Coderwangz

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值