Linux内核分析 -增加系统调用打印进程树

1 篇文章 0 订阅

Linux内核分析课程大作业

1 题目

在Linux内核中增加一个系统调用,并编写对应的linux应用程序。利用该系统调用能够遍历系统当前所有进程的任务描述符,并按进程父子关系将这些描述符所对应的进程id(PID)组织成树形结构显示。

2 前置知识概述

在Linux系统中,除了系统启动之后的第一个进程由系统来创建,其余的进程都必须由已存在的进程来创建,新创建的进程叫做子进程,而创建子进程的进程叫做父进程。在系统启动及完成初始化之后,Linux自动创建的进程叫做根进程(pid为0)。根进程是Linux中所有进程的祖宗,其余进程都是根进程的子孙。具有同一个父进程的进程叫做兄弟进程。

在这里插入图片描述

Linux内核通过一个被称为进程描述符的task_struct结构体来管理进程,这个结构体包含了一个进程所需的所有信息。它定义在include/linux/sched.h文件中。task_struct结构体的部分内容如图2-2所示。

其中部分字段含义如下:

​ tasks:用来组织所有进程

​ pid: 进程的唯一标识。

​ parent和real_parent: 指向该进程的父进程。

​ children:进程的子进程链表。

​ sibling:进程的兄弟链表。

​ comm:进程正在运行的可执行文件名。

taskstruct

3 设计思路

3.1 设计思路

Linux内核中通过task_struct结构组织进程,task_struct结构中的children字段保存了当前进程的子进程,而所有的Linux进程都有一个共同的祖先进程——根进程。通过从根进程出发,使用深度优先的思想,利用递归即可实现当前Linux系统所有进程遍历。

3.2 实验步骤

(1) Linux 内核源码下载

(2) 修改内核源码

(3) 重新编译内核

(4) 使用新编译的内核

(5) 编写测试代码

4 实验内容

4.1 Linux内核源码下载

(1)查看Ubuntu内核版本

在这里插入图片描述
(2)从http://ftp.sjtu.edu.cn/sites/ftp.kernel.org/pub/linux/kernel/下载内核源码,为了便于区分自己编译的内核与系统自带的内核,选择下载Linux 4.16.2版本内核,并将下载下来的源码解压到/usr/src目录下。

在这里插入图片描述
在这里插入图片描述

4.2 修改内核源码

(1)修改/usr/src/linux-4.16.2/kernel/sys.c文件,添加printchildren函数及sys_printAllInfo函数。
在这里插入图片描述
在这里插入图片描述

(2)修改/usr/src/linux-4.16.2/arch/x86/entry/syscalls/syscall_64.tbl文件添加系统调用号。
在这里插入图片描述

(3)修改/usr/src/linux-4.16.2/arch/x86/include/asm/syscalls.h文件添加系统调用函数声明。

在这里插入图片描述

4.3 重新编译内核

(1)准备操作,在命令行中执行以下命令

sudo apt-get update

sudo apt-get install libncurses5-dev libssl-dev

sudo apt-get install build-essential openssl

sudo apt-get install zlibc minizip

sudo apt-get install libidn11-dev libidn11

sudo apt-get install flex bison

cd /usr/src/linux-4.16.2

(2)删除部分无用文件

sudo make mrproper

sudo make clean

sudo make menuconfig

(3)编译新内核

sudo make -j4  // j4表示使用4线程编译

在这里插入图片描述

(4)安装新内核

sudo make modules_install
sudo make install

在这里插入图片描述
在这里插入图片描述

4.4 使用新编译的内核

重启ubuntu长按shift键,选择重新编译过的内核进入ubuntu。

在这里插入图片描述
在这里插入图片描述

4.5 测试代码编写

(1)编写测试文件(test.c)如下:
在这里插入图片描述
(2)编译测试代码

gcc test.c -o test.out

5 实验结果

​ 运行test.out 程序,使用dmesg 命令可以看到程序的部分运行结果如下。
在这里插入图片描述
在这里插入图片描述

6 实验中遇到的问题

问题1:开始时尝试不使用编译内核的办法,打算利用修改内核符号表,达到劫持系统调用来进行实现。由于Linux内核2.6之后不支持内核符号表导出,尝试各种办法寻找系统调用表地址无果,最后选择使用编译内核的办法。

问题2:编译完内核后,执行自己编写的系统调用函数,没有输出信息,经查找,原因为系统装载的内核不是自己重新编译的内核,在重启选择自己编译的内核后得到解决。

  • 9
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值