给Linux增加系统调用,并编写对应的linux应用程序

本文介绍了在Linux内核分析课程中,如何为系统增加一个新的系统调用,以获取指定PID的进程任务描述符和内存布局信息。通过分析PID命名空间、task_struct和mm_struct结构体,设计并实现了内核模块,避免了直接修改内核源码带来的编译成本。遇到的问题包括获取task_struct结构体的错误、格式化打印等,最终通过调用自定义系统调用获取并返回相关信息。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前言

这是研一上学期的Linux内核分析作业。这个课程还是很有用的。

题目要求:

(1)能够返回指定进程(通过指定PID)的任务描述符;

(2)能够返回指定进程(通过指定PID)的进程地址空间的布局和统计信息(代码段、数据段、BSS段、堆、栈等区域的位置和大小、包含多少个虚拟内存区VMA、每个VMA的属性、该进程页表的地址、已映射的物理内存大小等。)(该题目需要研究Linux 进程描述符和内存描述符mm_struct。)

相关知识

系统调用是内核为用户进程提供服务的一种方式。通过系统调用,内核能够提供给用户模式下的进程和硬件设备的接口,保护对内核所管理的资源的访问,提高系统安全,提高程序的可移植性。



根据题目,本质就是要求在内核中设计实现一个新的函数,通过指定的进程ID可以返回该进程有关信息。

一个进程ID号,其实没有那么简单。因为Linux系统中有命名空间这种设定,目前实现的有六种不同的命名空间,分别为mount命名空间、UTS命名空间、IPC命名空间、用户命名空间、PID命名空间、网络命名空间。对于PID命名空间,有不同的层次,像图2这样。


在上图有四个命名空间,一个父命名空间衍生了两个子命名空间,其中的一个子命名空间又衍生了一个子命名空间。以PID命名空间为例,由于各个命名空间彼此隔离,所以每个命名空间都可以有 PID 号为 1 的进程;但又由于命名空间的层次性,父命名空间是知道子命名空间的存在,因此子命名空间要映射到父命名空间中去,因此上图中 level 1 中两个子命名空间的六个进程分别映射到其父命名空间的PID 号5~10。

命名空间增大了 PID 管理的复杂性,对于某些进程可能有多个PID——在其自身命名空间的PID以及其父命名空间的PID,凡能看到该进程的命名空间都会为其分配一个PID。因此就有:

全局ID:在内核本身和初始命名空间中唯一的ID,在系统启动期间开始的 init 进程即属于该初始命名空间。系统中每个进程都对应了该命名空间的一个PID,叫全局ID,保证在整个系统中唯一。

局部ID:对于属于某个特定的命名空间,它在其命名空间内分配的ID为局部ID,该ID也可以出现在其他的命名空间中。

所以根据题目,可以假设我们需要提供的是全局PID。

那么如何根据PID的数值找到task_struct结构体呢:

1.通过 PID 计算 pid 挂接到哈希表 pid_hash[] 的表项;

2. 遍历该表项,找到 pid 结构体中 nr 值与 PID 值相同的那个 pid

3.通过该 pid 结构体的 tasks 指针找到 node

4. 最后根据内核的 container_of 机制就能找到 task_struct 结构体


task_struct结构体包含了一个进程所需的所有信息。它定义在include/linux/sched.h文件中。

struct task_struct{

       … …

       struct mm_struct        *mm;

       pid

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值