Linux 4.9.2 下添加系统调用

本文详细介绍如何在Linux 4.9.2内核中添加一个用于统计进程缺页数和脏页数的系统调用。从下载配置内核源码开始,逐步介绍修改系统调用表、添加函数声明与定义的过程,最终实现统计功能。

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

我们试图在Linux 4.9.2下添加一个系统调用,这个系统调用会统计进程的缺页数与脏页数

下载并配置Linux内核源码

在Linux官网(https://www.kernel.org/)下载内核源码。我选择的是最新的稳定版4.8.12,下载压缩包linux-4.8.12.tar.xz

由于文件系统格式的问题,不能在共享文件夹中进行一下操作(共享文件夹在windows环境中建立,为FAT32格式),所以需要将压缩包复制到linux虚拟机内部的位置,我是用的是/Documents/OSworks

然后进入目录并解压文件

cd /Documents/OSworks
tar xf linux-4.8.12.tar.xz
cd linux-4.8.12

代码改写

要添加一个系统调用,首先要修改系统调用表,即syscall_64.tbl。在arch/x86/entry/syscalls/syscall_64.tbl
在记录的最后添加我们的系统调用条目,记住调用号为329

321 common  bpf         sys_bpf
322 64  execveat        sys_execveat/ptregs
323 common  userfaultfd     sys_userfaultfd
324 common  membarrier      sys_membarrier
325 common  mlock2          sys_mlock2
326 common  copy_file_range     sys_copy_file_range
327 64  preadv2         sys_preadv2
328 64  pwritev2        sys_pwritev2
329 common pagefaultInfo     sys_pagefaultInfo
……………………

同时也要修改一下/include/linux/syscalls.h文件,在文件最后添加我们的函数声明:

asmlinkage long sys_pagefaultInfo(void);

为了实现缺页统计的功能,要先对原有的代码进行一些修改。修改的过程参照实验指导,包括:
在include/linux/mm.h中添加

extern ungsigned long pfconfig;

在include/linux/sched.h中添加:

unsigned long pf;

修改kernel/fork.c的dup_task_strcut函数:

static struct task_struct *dup_task__struct(struct task_struct *orig, int node)
{
    ………………
tsk->pf = 0;
………………
}

修改arch/x86/mm/fault.c。在这里要注意两句指令添加的地方,添加在if(major)的里面,则我们统计的是Major Faults(requiring I/O),并不实际引起硬件I/O的Minor Faults则不会被统计。
unsigned long pfcount;

………………
static noinline void __do_page_fault(struct pt_regs *regs, unsigned long error_code, unsigned long address)
{
………………
if(major){
pfcount++;
current->pf++;
………………
}

然后我们编写实际的系统调用代码。我们用一个额外的文件夹info存放我们的代码文件pagefaultInfo.h以及pagefaultInfo.c

mkdir info
cd info/

在pagefaultInfo.h中声明函数

asmlinkage long sys_pagefaultInfo(void);

在pagefaultInfo.c中定义函数

asmlinkage long sys_pagefaultInfo(void);

之后我们要编写寻找dirtypage数量的函数。这部分比较复杂,基本的思路是去遍历进程的页表,判断每个页表是否为firty,从而进行统计。

首先遍历所有进程(即task_struct),对每个task_struct,得到其mm_struct(表示进程地址空间的结构)。然后对每段(数据段、代码段等等),遍历其4级页表(pgd->pud->pmd->pte),然后对每个pte调用pte__ditry()函数判断是否为脏叶。

最后后要将我们的新代码加到makefile系统里面去,使得在makefile的时候能够编译并链接他们。具体做法是在info文件夹里新建文件Makefile,并添加以上信息:

obj-y:=pagefaultInfo.o

同时修改 kernel里的Makefile文件,在core-y后面添加我们的info/路径

core -y  += kernel/ certs/ mm/ fs/ ipc/ security/ crypto/ block/ info/

编译并装载内核

首先要配置内核。进入内核源代码根目录。考虑到可以配置的选项比较繁杂,可以直接拷贝当前系统中的配置文件。

cp /boot/config-$(uname -r) .config   
make menuconfig

这时会进入一个带GUI的内核配置界面,使用默认配置即可。Save->Exit退出配置

之后可以正式开始编译内核(下一次重新编译可以从这一步开始)

fakeroot make-kpkg kernel_image

漫长的编译之后就可以将内核加载到boot列表里了:

fakeroot make-kpkg kernel_image
update-initramfs –c –k 4.8.12
update-grup2

然后重启系统。如果重启成功,就说明内核重编译基本成功了。

如果空间不够而且或者不准备再次重新编译内核的话,可以删除变异的中间文件

make clean
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值