【优麒麟】编译linux kernel + 增加系统调用 + 编写批处理脚本

编译Linux kernel步骤

创建优麒麟虚拟机(若已装好可跳过)

1.下载优麒麟的镜像文件

  • 官网下载:https://www.ubuntukylin.com/downloads/ (下载速度慢)

  • 镜像网站:官网底部(推荐)
    在这里插入图片描述
    创建虚拟机硬件配置如下:
    硬盘空间至少大于50G,否则后续编译内核会因存储空间不够而失败。
    在这里插入图片描述
    登录优麒麟后,注意一定要点击桌面的“安装“,否则试用版无法正常进行以下操作,系统重启会进行清空。
    查看正在使用的内核版本,后面下载的内核版本最好不要高于目前版本

#查看版本
uname -r

在这里插入图片描述

虚拟机环境配置

安装编译的必要工具gcc、gdb、bison、flex、libncurses5-dev、libssl-dev、libidn11以及虚拟机的必备工具。

#安装编译所需工具
sudo apt install gcc gdb bison flex libncurses5-dev libssl-dev libidn11 build-essential

在这里插入图片描述

从网上下载不高于目前内核版本的kernel源代码。

  • 官网:https://www.kernel.org/ (下载速度慢)
  • 镜像网站:http://ftp.sjtu.edu.cn/sites/ftp.kernel.org/pub/linux/kernel/(推荐)

此处下载 linux-5.4.3.tar.xz(可以自行选择其他版本) ,之后移动压缩包到 usr/src 目录下,解压后删除。

#移动压缩包到目标文件夹
sudo mv linux-5.4.3.tar.xz /usr/src
#解压缩
sudo tar -xf linux-5.4.3.tar.xz
#删除压缩包
sudo rm linux-5.4.3.tar.xz

编译安装

将目前内核的配置拷贝到新内核的源码目录下,作为新内核的配置文件。其中,需要进入配置文件.config,查看一下 .config 文件是否变化,有的版本此操作会把前面双引号内置空的内容恢复,此时需要手动删除引号中的内容。

#进入源码目录
cd /usr/src/linux-5.4.3
#拷贝
sudo cp -v /boot/config-$(uname -r) .config
#查看文件
sudo vi .config
#查看 :/CONFIG_SYSTEM_TRUSTED_KEYS

在这里插入图片描述

使用make menuconfig 个性化配置 —— 实际实验过程中没有修改,直接使用默认配置即可。显示如下界面后,点击 Exit – yes 即可。

sudo make menuconfig

在这里插入图片描述
进入源码目录,使用make命令编译内核,同时借助 -jn 加快编译速度。其中,n是要生成的作业数,通常的做法是每个处理器产生一个或两个作业,最多不超过分配总核数的两倍,可以查看虚拟机硬件配置中的处理器总分配内核数。此阶段比较耗时。

#4个作业同时进行编译
sudo make -j4

在这里插入图片描述

安装内核模块,进一步安装内核模块。

sudo make modules_install

在这里插入图片描述
模块安装完成后,进行内核安装。

sudo make install

在这里插入图片描述

将新安装的内核设置为引导,并更新grub引导程序。

#结尾为自己内核的版本
sudo update-initramfs -c -k 5.4.3
#更新grub
sudo update-grub

在这里插入图片描述

启动新内核

重启虚拟机,选择 ”高级选项——对应新内核的版本“ 进行启动,此处为5.4.3。
在这里插入图片描述
在这里插入图片描述

启动完毕后,查看目前内核版本,若为新内核版本,则启动成功。

uname -r


添加系统调用

参考文章:【HUST】网安|操作系统实验|实验一 内核编译、系统调用、编写批处理脚本
本文章在此基础上改动。

修改文件

  1. 系统调用:linux-5.4.3/kernel/sys.c

  2. 系统调用函数声明:linux-5.4.3/include/linux/syscalls.h

  3. ID:linux-5.4.3/arch/x86/entry/syscalls/syscall_64.tbl

  4. ID声明:linux-5.4.3/include/uapi/asm-generic/unistd.h

    需要修改的代码如下:
  • 系统调用:linux-5.4.3/kernel/sys.c
SYSCALL_DEFINE2(SSD_Add,int,x,int,y){
        return x+y;
}

SYSCALL_DEFINE3(SSD_Max,int,a,int,b,int,c){
        if(a>b) b=a;
        if(b>c) c=b;
        return c;
}
  • 系统调用函数声明:linux-5.4.3/include/linux/syscalls.h
asmlinkage long sys_SSD_Add(int x, int y);
asmlinkage long sys_SSD_Max(int a, int b, int c);
  • ID:linux-5.4.3/arch/x86/entry/syscalls/syscall_64.tbl
548     64      SSD_Add                 __x64_sys_SSD_Add
549     64      SSD_Max               	__x64_sys_SSD_Max
  • ID声明:linux-5.4.3/include/uapi/asm-generic/unistd.h
#define __NR_ssd_add 548
__SYSCALL(__NR_ssd_add, sys_SSD_Add)
#define __NR_ssd_max 549
__SYSCALL(__NR_ssd_max, sys_SSD_Add)

如下图。

在这里插入图片描述

重新编译

与实验二基本相同,编译前清理一下上一次残留的编译文件即可。

sudo make mrproper
sudo make clean
sudo make menuconfig
sudo make -j4
sudo make modules_install
sudo make install
sudo update-initramfs -c -k 5.4.3
sudo update-grub
reboot

调用新增函数进行测试

测试文件:test.c

#include <unistd.h>
#include <sys/syscall.h>
#include <stdio.h>
int main(int argc, char *argv[])
{
    long ret;
    ret = syscall(549,1,2,3);   //Max
    printf("ret:%ld\n",ret);
    ret = syscall(549,7,6,5);   //Max
    printf("ret:%ld\n",ret);
    ret = syscall(548,4,6);     //Add
    printf("ret:%ld\n",ret);
    ret = syscall(549,7,9,8);   //Max
    printf("ret:%ld\n",ret);
}

编译运行该文件。

sudo gcc -o test test.c
sudo ./test

输出如下图。
在这里插入图片描述

可能遇到的问题

  1. 重启时没有出现选择内核的界面?(若用ubuntu可能会出现)

    修改配置文件,更换默认启动盘

    详见:https://blog.csdn.net/weixin_46584887/article/details/125973263

  2. undefined reference to ‘xxx’

    在linux4.17以后,添加系统调用必须以 __x64_sys_开头!!将syscall_64.tbl中的系统调用改函数名开头即可。

    详见:https://blog.csdn.net/qq_44765221/article/details/111087361
    在这里插入图片描述


编写批处理程序

任务要求

要求:在 Ubuntu (或银河麒麟) 或 Windows 下,编写脚本或批处理。

功能:在指定目录中全部 txt 文件的末尾追加一行,写入用户名,日期,时间。

提示:

  1. 目录通过命令行的参数来指定,不要在脚本中写死;
  2. 注意检查文件的后缀是否 txt;
  3. 日期和时间的写入格式可以自己确定【例如特殊字符标识】;
  4. 已写有日期和时间的文件只能更新日期和时间,不能追加。

步骤

初始化

建立文件,test1.txt与test2.txt,并初始化文本文件的内容。
在这里插入图片描述

编写脚本

脚本文件“myshell2.sh”源代码如下,将待测试的txt文件与脚本文件放置于同一目录下,进行测试。

str_insert="#OK# $USER `date +%Y-%m-%d,%H:%M:%S`"   	#设置特殊标识设为#OK#,表示已写入
for ofile in $1/*.txt           						#用$1接收第一个命令行参数(目录);*.txt检查文件后缀是否为txt
do
	if [ `grep -c "#OK#" $ofile` -eq 0 ];then
		echo $str_insert >> $ofile                   	#未写入,向文件中追加写入字符串str_insert
	else
		sed -i "/#OK#/c $str_insert" $ofile     		#已写入,用sed更新字符串
	fi
done 

测试运行

#第一参数"."表示选择该目录下的txt文件
./myshell2.sh .   

在这里插入图片描述

结果:

​ 在目标目录下的所有txt文件新增一行 “#OK# willow 2022-11-28,19:19:48”。
在这里插入图片描述

​ 再次运行,不再追加新行,而是刷新变为目前时间,“#OK# willow 2022-11-28,19:23:11”。

在这里插入图片描述

  • 6
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值