Ubuntu上增加系统调用(需要编译内核)

写这篇的原因以及目的

  • 最近老师布置了一个任务在Ubuntu中添加一个自己的系统调用,很多同学都完成得比较好,可能因为自己太蠢,花了很久很久很久很久才完成,也走了很多弯路,用的是虚拟机,重装过一两次 也用了不下六次恢复快照

恢复快照:用虚拟机VMware时,在某一时候使用快照功能,在这之后如果出现了操作失误、系统出问题或者我们将要进行的编译内核失败,可以直接恢复到出问题之前的状态。具体操作可以自行百度,使用比较简单。

  • 这几天也看了几篇类似的博客跟着做,但多多少少都出了点问题后者是讲得不够清楚,决定自己总结一下。

大致步骤

  1. 下载新内核
  2. 添加系统调用
  3. 编译内核
  4. 测试

具体步骤

  1. 下载linux内核

需要下载一个新的Linux内核,在linux内核官方网站www.kernel.org下载
在这里插入图片描述

我们选择最新的稳定版本,我这里是5.6.15,视最新的版本而定。

下载好后得到一个压缩包,直接拉到Ubuntu里,这里我将压缩包放在了桌面上

  1. 安装一些用于编译内核的依赖包
//先更新软件源
sudo apt-get update

再安装依赖包

这里总共是九条命令,一条一条的敲吧,不敲后面可能会出错

  1. 解压缩新内核

将刚刚下载的新内核解压缩到 /usr/src 下


添加系统调用

  1. 进入新内核开始增加系统调用
//进入新内核目录
cd /usr/src/linux-5.6.15

进入新内核以下执行都操作没有特别声明均在 /usr/src/linux-5.6.15 目录下执行

  • 编辑系统调用入口表
sudo gedit /usr/src/linux-5.6.15/arch/x86/entry/syscalls/syscall_64.tbl 

系统调用入口表分为两段,第一段的系统调用号在300-400以内,第二段从512开始,我们找到第一段的末尾在它后面添加系统调用号和名字

在这里插入图片描述

这里第一段系统调用号在438结束,所以我们增加的系统调用号为439,以后我们使用系统调用时需要使用439这个号码来调用每个人的号都有可能不同,然后我的系统调用名为mysyscall,

可以自己任意取,sys_mysyscall是接下来要添加了函数名称(以sys_开头),添加完后,点击右上方的保存,然后退出。

  • 添加系统调用函数声明
cd /usr/src/linux-5.6.15
sudo gedit include/linux/syscalls.h 

打开后直接到翻到最末尾添加一个函数声明

在这里插入图片描述

注意此时的函数名 sys_mysyscall() 应与上一步在系统调用表中的添加的一致,同上保存然后退出。

  • 添加系统调用的函数定义

也就是使用系统调用时执行的程序

cd /usr/src/linux-5.6.15
sudo gedit kernel/sys.c

这里我使用内核函数 printk() 打印我的学号和姓名,然后返回0,程序执行成功则会返回0 ,但是 printk() 打印并不是打印在终端命令行中,而是日志文件,后面我们再说如何查看到printk()打印的信息。同样地保存和退出这个文件。

至此,系统调用添加步骤已经完成,下面开始编译内核。


编译内核

编译内核之前,建议使用虚拟机的朋友 拍摄此时虚拟机的快照,方便编译内核失败时直接恢复到现在的状态

开始编译内核

  1. 编译内核

我是在 /usr/src/linux-5.6.15目录下执行,根据自己下载的内核版本而定 /usr/src/linux-xxxx

cd /usr/src/linux-5.6.15
make mrproper //得到源代码,将其净化
  • 将旧内核的配置信息拷贝到当前目录下 并命名为 .config (直接使用了旧内核的其他配置信息)

先查看旧内核的配置文件名,在/boot目录下

ls /boot

以config 开头的为旧内核配置文件,将这个文件拷贝,我这里文件名为 config-5.3.0-53-generic

cp /boot/config-5.3.0-53-generic ./.config
  • 对内核选项进行配置

此时已经有了 .config 文件,对内核选项进行配置

make menuconfig

在这里插入图片描述

make clean //删除配置时留下的一些不用的文件,第一次编译可以不用敲
  • 编译内核
make bzImage -j4

上面 -j4 指的是用四个处理器编译,也可以为2,一般为偶数

如果用两个核编译,则:

make bzImage -j2

上面两条命令只用敲一条

这个步骤差不多需要十五分钟

  • 编译模块
make modules -j4

同样也可以 -j2
这个步骤需要一个多小时

  • 安装模块
make INSTALL_MOD_STRIPE=1 modules_install

执行完这条命令后, /lib/modules 目录下应该生成一个 5.6.15 (版本号)目录

mkinitramfs /lib/modules/5.6.15 -o /boot/initrd.img-5.6.15-generic

内核已经全部编译完成,接下来拷贝内核映像

把内核映像和System.map拷贝到 /boot 下

cp /usr/src/linux-5.6.15/arch/x86/boot/bzImage /boot/vmlinuz-5.6.15-generic
cp /usr/src/linux-5.6.15/System.map  /boot/System.map-5.6.15
ln -s /boot/System.map-5.6.15 /boot/System.map

最后一步更新grub配置文件

cd /boot/grub
chmod 777 grub.cfg
update-grub

重新启动Ubuntu机器可以看到自己的新内核

测试

重新启动机器后,用一个C文件测试

执行439号系统调用

sudo gedit test.c
#include <linux/kernel.h>
#include <sys/syscall.h>
#include <unistd.h>
#include <stdio.h>
 
int main(int argc,char **argv)
{
	//439:long sys_mysyscall()
	printf("System call sys_mysyscall return %ld\n",syscall(439));	
	return 0;
}

编译运行

gcc -o test test.c
./test

运行结果:

在这里插入图片描述

回忆一下系统调用的内核函数:

返回 0 说明执行成功,但是现在没有看到打印信息,因为打印信息打在了日志文件中

我们dmesg查看日志文件

dmesg

成功看到了打印信息

至此,添加系统调用就已经成功完成了!!!

  • 28
    点赞
  • 157
    收藏
    觉得还不错? 一键收藏
  • 15
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值