linux 查看内核是否转发_Linux内核模块编程小例子之查看虚拟内存VMA(virtual memory areas)信息...

cef308d276ee88e8bce5377cdfe3bdbc.png
前言:
在 32 位的系统上,线性地址空间为 4GB,其中用户进程占有 3GB 线性地址空间,内核占有 1GB 线性地址空间。由于虚拟内存的引入,使的每个进程都可拥有 3GB 的虚拟内存。
用户进程的虚拟地址空间包含若干区域,这些区域的分布方式因体系结构的差异而不同,但所有的方式都包含下列成分:
(1) 代码段:可执行文件的二进制代码
(2) 数据段:存储全局变量
(3) 栈:用于保存局部变量和实现函数调用
(4) 环境变量和命令行参数
(5) 程序使用的动态库的代码
(6) 用于映射文件内容的区域为便于描述,系统中进程的虚拟内存空间被划分为若干不同的区域,每个区域都有其相关的属性和用途,一个合法的地址总是落在某个区域当中的,这些区域也不会重叠。在 Linux 内核中,这样的区域被称为虚拟内存区域(virtual memory areas,VMA)。一个 VMA 是一块连续的线性地址空间的抽象,它拥有自身的权限(可读,可写,可执行等) ,对进程而言,VMA 其实是虚拟空间的内存块,一个进程的所有资源由多个内存块组成。
每一个虚拟内存区域都由一个相关的 struct vm_area_struct 结构来描述。
本文将编写一个内核模块,通过此内核模块遍历一个用户进程中所有的 VMA,并且打印这些 VMA 的属性信息,如 VMA 的大小、起始地址等,并通过与“/proc/pid/maps”中显示的信息进行对比验证 VMA 信息是否正确。

本文所使用的环境:

操作系统:4.15.0-96-generic #97-Ubuntu SMP Wed Apr 1 03:25:46 UTC 2020 x86_64 x86_64 x86_64 GNU/Linux
gcc: 7.5.0
make:GNU Make 4.1

不知道怎么编写内核模块的建议先看一下我的上一篇文章

编写我的第一个Linux内核模块“hello_module”_夕源的博客-CSDN博客​blog.csdn.net
96900885e52572febbaf4538eccbce27.png
  1. 编写模块程序

参考代码如下,代码文件命名为“vma_test.c”

//vma_test.c
以上代码中:
38-52 行是内核模块初始化函数 vma_init;
40-46 行目的是获取 pid,可在加载模块时可传递相关参数(即进程 pid);如果没有传递参数,则使用当前进程,即执行 insmod 命令的进程;
45 行 pid_task()函数为获取任务的任务描述符信息,其返回值是 struct task_struct 结构体类型的变量;
50 行调用自定义的 printit()函数打印相关信息;
9-34 行是本实验核心函数;
16 行获取待检查进程的内存描述符 struct mm_struct 数据结构,该结构由struct task_struct 中的*mm 指向;
18 行获取 VMA 链表头,即 mm->mmap;
21 行开始遍历 VMA 链表,down_read()函数用于申请读信号量,因本程序只是读取 VMA 链表,所以申请读者类型即可,若需丢 VMA 链表进行修改,则需申请写者类型信号量;
24-32 行遍历 VMA 链表,并对每个 VMA 打印其起始地址、终止地址和长度信 息;
33 行释放读者信号量。
  1. 编译内核模块

编写 Makefile 文件,文件名必须为“Makefile”

makefile    obj-m := vma_test.o
KERNELBUILD := /lib/modules/$(shell uname -r)/build    CURRENT_PATH := $(shell pwd)
all:     make -C $(KERNELBUILD) M=$(CURRENT_PATH) modules
clean:     make -C $(KERNELBUILD) M=$(CURRENT_PATH) clean 
  1. 编译
    使用 make 命令编译即可。
  2. 插入模块
    先通过 top 命令查看进程,任意获取一个进程 pid,如图所示, 本例中获取apache2 进程的 pid 3509。

d6e1245463233ea1a0c485913589dcb3.png


使 用 insmod 插 入 模 块 , 并 传 参 。 如 图 所 示 , 本 例 中 模 块 名 为“vma_test.ko”,pid 为 3509,则插入模块命令为:

pid
  1. 查看程序打印信息

通过 dmesg 命令查看 VMA 信息。如下图所示:

3cc3e91e4f408de0c60f7ba1d0ef8ee8.png
从上图可看到 apache2 进程包含许多 VMA 区域,以第一个 VMA 区域为例,其起始地址为 0x564af2e3a000,结束地址为 564af2ed7000,长度为 643072 字节。

​ 如下图所示为从 proc 虚拟文件系统中查看相应进程第一个 VMA 的完整信息。

0010b6a8ddc6cac697442438379a1c07.png
从以上两图中内容对比可知,本程序输出信息正确。

更多内容看看我博客,知乎上格式有点乱了

Linux内核模块编程小例子之查看虚拟内存VMA(virtualmemoryareas)信息_夕源的博客-CSDN博客​blog.csdn.net
96900885e52572febbaf4538eccbce27.png
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值