杭电操作系统实验一 --- Linux内核编译及添加系统调用(arm架构华为云)

这篇具有很好参考价值的文章主要介绍了杭电操作系统实验一 --- Linux内核编译及添加系统调用(arm架构华为云)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

实验要求 

  1. 掌握Linux 内核的编译与安装
  2. 掌握Linux 系统调用基本概念
  3. 设计和添加linux系统调用

        (1)修改或返回指定进程的优先级(nice值和prio值)(详见教材P328)提示:可能参考的内核函数:set_user_nice().

        (2)改变主机名称为自定义字符串(自选题目)

 1、Linux 内核的编译与安装   (使用华为云,完成openEuler内核的编译与安装)

(1)登录系统并查看当前内核版本

[root@openEuler ~]# uname -r

 (2)安装工具,构建开发环境

[root@openEuler ~]# yum group install -y "Development Tools"

[root@openEuler ~]# yum install -y bc

[root@openEuler ~]# yum install -y openssl-devel

(3)备份boot目录以防后续步骤更新内核失败

[root@openEuler ~]# tar czvf boot.origin.tgz /boot/

保存当前内核版本信息

[root@openEuler ~]# uname –r > uname_r.log

(4)获取内核源代码并解压

[root@openEuler ~]# wget https://gitee.com/openeuler/kernel/repository/archive/kernel-4.19.zip

[root@openEuler ~]# unzip kernel-4.19.zip

(5)编译内核

 [root@openEuler ~]# cd kernel-kernel-4.19

[root@openEuler kernel]# make openeuler_defconfig

[root@openEuler kernel]# make -j4 Image modules dtbs

这一步是编译内核的Image、modules和dtbs,make -j 4表示4个线程编译(可以根据CPU核数调整)

 (6)安装内核

[root@openEuler kernel]# make modules_install

[root@openEuler kernel]# make install

注意:在最后一步“make install”时出现的错误在这里可以忽略。

(7)以VNC登录ECS

(8)重启系统

[root@openEuler kernel]# reboot

 (9)登录并验证

在VNC窗口中选择以新编译出来的内核启动系统

杭电操作系统实验一 --- Linux内核编译及添加系统调用(arm架构华为云)

 这里编译完以后已经有了4.19.208版本的新内核,选择该内核登录

 

2、掌握Linux 系统调用基本概念 

Linux系统处理系统调用的流程以及增加系统调用的方法。Linux系统提供了多达几百种的系统调用,为了唯一地标识每一个系统调用,Linux为每个系统调用都设置了一个唯一的编号,称为系统调用号,同时每个系统调用需要一个服务例程完成其具体功能。

这里不做过多描述。

(重点是怎么添加系统调用!!!)

  • 阅读教材7.2.3节Linux 添加系统调用的步骤,添加一个新的系统调用,通过内核打印调试语句printk打印自己的学号。
  • cd kernel-kernel-4.19 进入文件夹
  • vim include/uapi/asm-generic/unistd.h 修改及添加系统调用号(注意系统调用号不能随意加,只能一次加1)
  • 杭电操作系统实验一 --- Linux内核编译及添加系统调用(arm架构华为云)
#define __NR_hello_euler 294
__SYSCALL(__NR_hello_euler, sys_hello_euler)

#undef __NR_syscalls
#define __NR_syscalls 295
  •  vim include/linux/syscalls.h 添加代码申明系统调用服务例程
  • 杭电操作系统实验一 --- Linux内核编译及添加系统调用(arm架构华为云)
asmlinkage long sys_hello_euler(void);
  •  vim kernel/sys.c 实现系统调用服务例程
  • 杭电操作系统实验一 --- Linux内核编译及添加系统调用(arm架构华为云)
SYSCALL_DEFINE0(hello_euler)
{
	printk(KERN_INFO "xuehao:20273108");
	return 0;
}
  • 重新编译,安装内核
  • 配置内核:make openeuler_defconfig
    编译内核:make -j4 Image modules dtbs
    安装模块:make modules_install
    安装内核:make install
    立即重启:reboot   (重启后进入新内核)

重启后

  • cd kernel-kernel-4.19 进入文件夹
  • vim testhello.c  编写测试代码testhello.c

  • 杭电操作系统实验一 --- Linux内核编译及添加系统调用(arm架构华为云)

#include <stdio.h>
#include <unistd.h>
#include <sys/syscall.h>

int main()
{
    ret = syscall(294);    
    return 0;
}
  •  编译 gcc testhello.c
  • 输入 ls ,会发现出现了a.out 文件(在使用gcc编程时,没有指定输入可执行文件名,默认生成可执行文件a.out文件。)

杭电操作系统实验一 --- Linux内核编译及添加系统调用(arm架构华为云)

  •   执行 ./a.out
  • 输入 dmesg 查看结果(成功输出学号~)
  • 杭电操作系统实验一 --- Linux内核编译及添加系统调用(arm架构华为云)

 

3、设计和添加linux系统调用 

(1)修改或返回指定进程的优先级(nice值和prio值)(详见教材P328)提示:可能参考的内核函数:set_user_nice().

  • vim include/uapi/asm-generic/unistd.h 修改及添加系统调用号
  • #define __NR_mysetnice 295
    __SYSCALL(__NR_mysetnice,sys_mysetnice)

    注意下面的  #define __NR_syscalls 295 要变成  #define __NR_syscalls 296

  •   vim include/linux/syscalls.h 添加代码申明系统调用服务例程
  • asmlinkage long sys_mysetnice(pid_t pid,int flag,int nicevalue,void __user*prio,void __user*nice);
  •   vim kernel/sys.c 实现系统调用服务例程
  • SYSCALL_DEFINE5(mysetnice,pid_t,pid,int,flag,int,nicevalue,void __user*,prio,void __user*,nice)
    {
    	int n;
    	int p;
    	struct pid * kpid;
    	struct task_struct * task;
    	kpid = find_get_pid(pid);/*得到pid */
    	task = pid_task(kpid, PIDTYPE_PID);/* 返回task_struct */
    	n = task_nice(task);/* 返回进程当前nice值 */
    	p = task_prio(task);/*返回进程当前prio值*/
    	if(flag == 1)
    	{
    		set_user_nice(task, nicevalue);/* 修改进程nice值 */
    		n = task_nice(task);/*重新取得进程nice值*/
    		p = task_prio(task);/*重新取得进程prio值*/
    		copy_to_user(nice,&n,sizeof(n));/*将nice值拷贝到用户空间*/
    		copy_to_user(prio,&p,sizeof(p));/*将prio值拷贝到用户空间*/
    		return 0;  
    	}
    	else if(flag == 0)
    	{
    		copy_to_user(nice,&n,sizeof(n));/*将nice值拷贝到用户空间*/
    		copy_to_user(prio,&p,sizeof(p));/*将prio值拷贝到用户空间*/
    		return 0;
    	}
    	return EFAULT;
    }
    
  • 同上,重新编译安装内核 
  • 配置内核:make openeuler_defconfig
    编译内核:make -j4 Image modules dtbs
    安装模块:make modules_install
    安装内核:make install
    立即重启:reboot   (重启后进入新内核)
  • cd kernel-kernel-4.19 进入文件夹
  • vim my_setnice.c  编写测试代码my_setnice.c

#define _GNU_SOURCE
#include<unistd.h>
#include<sys/syscall.h>
#include<stdio.h>
#include<stdlib.h>
int main()
{
	pid_t pid;
	int nicevalue;
	int flag;
	int n=0;
	int p=0;
	int *prio;
	int *nice;
	prio = &p;
	nice = &n;
	printf("请输入pid: \n");
	scanf("%d",&pid);
	printf("pid输入成功\n请输入nice值:\n");
	scanf("%d",&nicevalue);
	printf("nice输入成功\n请输入flag(flag为1时修改,为0时查看):\n");
	scanf("%d",&flag);
	syscall(295,pid,flag,nicevalue,prio,nice);
	printf("现在的nice为%d,prio为%d\n",n,p);
	return 0;
}
  • gcc my_setnice.c
  • ./a.out 
  • 杭电操作系统实验一 --- Linux内核编译及添加系统调用(arm架构华为云)

 

 (2)改变主机名称为自定义字符串(自选题目)

  •  vim include/uapi/asm-generic/unistd.h 修改及添加系统调用号
#define __NR_mysethostname 296
__SYSCALL(__NR_mysethostname,sys_mysethostname)

同理,下面的  #define __NR_syscalls 296 要变成  #define __NR_syscalls 297

  •  vim include/linux/syscalls.h 添加代码申明系统调用服务例程
  • asmlinkage long sys_mysethostname(char __user  *name, int len);
  •  vim kernel/sys.c 实现系统调用服务例程
  • SYSCALL_DEFINE2(mysethostname, char __user *, name, int, len)
    {
        int errno;
        char tmp[__NEW_UTS_LEN];  /*__NEW_UTS_LEN=64*/
        if(len<0 || len>__NEW_UTS_LEN)
            return -EINVAL;
     		   errno = -EFAULT;
        if(!copy_from_user(tmp, name, len))  /*copy_from_user将name指向的字符串从用户空间拷贝到内核空间,失败返回没有被拷贝的字节数,成功返回0*/
    	{
    		struct new_utsname *u;
    		down_write(&uts_sem); /*写者使用该函数来得到读写信号量sem,它会导致调用者睡眠,只能在进程上下文使用,用于获取Linux内核读写信号量中的写锁*/
    		u = utsname(); /*获取当前内核名称和其它信息,成功执行时,返回0。失败返回-1,errno被设为EFAULT,表示buf无效*/
    		memcpy(u->nodename, tmp, len); /*从源内存地址的起始位置开始拷贝若干个字节到目标内存地址中*/
    		memset(u->nodename + len, 0, sizeof(u->nodename)- len);
    		errno = 0;
    		uts_proc_notify(UTS_PROC_HOSTNAME); /*使用UTS namespace隔离hostname*/
    		up_write(&uts_sem); /*释放写锁*/
    	}
    	return errno;
    }
    
  • 同上重新编译内核 
  • cd kernel-kernel-4.19 进入文件夹
  • vim sethostname.c  编写测试代码sethostname.c

  • #define _GUN_SOURCE
    #include<unistd.h>
    #include<sys/syscall.h>
    #include<stdio.h>
    int main()
    {
    	syscall(296,"xjyxjy",6);
    	return 0;
    }
  • gcc sethostname.c
  • ./sethostname
  • 输入命令hostname或者重新在终端上连接ssh,即可看到主机名已经成功更换
  • 杭电操作系统实验一 --- Linux内核编译及添加系统调用(arm架构华为云)

 

 4、实验总结

(1)大家做实验之前看教程一定要搞清楚是x86还是arm架构的呀!!!我就是在这上面栽跟头了重建了三四次华为云

(2)如果用VNC登陆时出现以下报错,那么恭喜你,多半是你的内核崩了~我的老师说,只要你手速够快,在重启虚拟机的时候立马用VNC重新登陆是可以进去的,但是我没成功过,只能重建了n次云主机。

杭电操作系统实验一 --- Linux内核编译及添加系统调用(arm架构华为云) 

(3)虽然老师给的实验报告里要求VNC登录,但我个人建议使用cloudshell来执行命令。

(4)在验收的时候,被老师冷不丁问了系统调用里的函数的意义和用法,直接栽跟头了。我会在下面po出一部分内部函数的意义及用法。

1.find_get_pid(pid)

find_get_pid 在内核中有不同的命名空间,在各自的命名空间同一个进程pid值可能是不一样的,find_get_pid为了找到在内核态中的我们寻找进程真正的pid

2.set_user_nice(task, nicevalue)

用于设置进程的nice值

3.copy_to_user()

完成内核空间到用户空间的复制,To 目标地址,这个地址是用户空间的地址;From 源地址,这个地址是内核空间的地址; N 将要拷贝的数据的字节数。
如果数据拷贝成功,则返回零;否则,返回没有拷贝成功的数据字节数。

4.copy_from_user()

copy_from_user将name指向的字符串从用户空间拷贝到内核空间,失败返回没有被拷贝的字节数,成功返回0。

5.down_write()

函数down_write()是写者用来得到读写信号量sem时调用的,如果该信号量被读者或写者所持有,则对该函数的调用会导致调用者的睡眠,只能在进程上下文使用,用于获取Linux内核读写信号量中的写锁。

6.memcpy(str1, str2,  n) 

从存储区 str2 复制 n 个字节到存储区 str1。文章来源地址https://www.toymoban.com/news/detail-419615.html

到了这里,关于杭电操作系统实验一 --- Linux内核编译及添加系统调用(arm架构华为云)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 操作系统实验3.3 版本1.2内核的进程调度过程分析 && 两个进程的严格交替输出

    1. mygdb 侧调试命令: 2. 第三关.txt : 1.概述:0号进程和1号进程间进程调度过程 (1)从 system_call 函数进入相应的系统调用函数 在两个进程运行 alarm 和 pause 函数时,到执行 alarm 和 pause 系统调用时,都会进入到system_call函数,在下图第一处划线位置根据系统调用号,调用相应的

    2024年02月11日
    浏览(203)
  • linux查看系统版本、内核信息、操作系统类型版本

    1. 使用 `uname` 命令:这将显示完整的内核版本信息,包括内核版本号、主机名、操作系统类型等。 2. 使用 `lsb_release` 命令(仅适用于支持 LSB(Linux Standard Base)的发行版):这将显示包含发行版名称、版本号和其他详细信息的 Linux 发行版信息。  3. 使用 `/etc/os-release` 文件:

    2024年02月08日
    浏览(70)
  • 操作系统权限提升(十八)之Linux提权-内核提权

    内核提权是利用Linux内核的漏洞进行提权的,内核漏洞进行提权一般包括三个环节: 1、对目标系统进行信息收集,获取到系统内核信息及版本信息; 2、根据内核版本获取其对应的漏洞以及EXP 3、使用找到的EXP对目标系统发起攻击,完成提权操作 查看Linux操作系统的内核版本

    2024年01月16日
    浏览(45)
  • 【项目分析】仿linux0.11的操作系统内核

    系列综述: 💞目的:本系列是个人整理为了 秋招面试 的,整理期间苛求每个知识点,平衡理解简易度与深入程度。 🥰来源:材料主要源于 《操作系统 真象还原》及各大佬博客 进行的,每个知识点的修正和深入主要参考各平台大佬的文章,其中也可能含有少量的个人实验

    2024年02月09日
    浏览(41)
  • 华为原生 HarmonyOS NEXT 鸿蒙操作系统星河版 发布!不依赖 Linux 内核

    发布会上,余承东宣布,HarmonyOS NEXT鸿蒙星河版面向开发者开放申请。 申请链接 鸿蒙星河版将实现原生精致、原生易用、原生流畅、原生安全、原生智能、原生互联6大极致原生体验。 从2019年HarmonyOS正式发布,到2020年余承东说“没有人能够熄灭满天星光”,每一位开发者,

    2024年01月21日
    浏览(45)
  • 【Linux操作系统】【综合实验一 Linux操作基础】【浅试Linux命令】

    Linux均以文件形式存在 本文出现的命令浅尝辄止,具体使用参考文档即可 解决一个任务的方法很多,本文仅浅试了一些简单的命令 要求掌握Linux基础操作,熟悉Linux行界面,并 明白操作的原理以及目的(难) ;熟悉Linux系统环境。 通过这个第一阶段实验,要求掌握以下操作

    2023年04月08日
    浏览(100)
  • 头歌操作系统Linux实验

    Linux操作系统 第1关 Linux初体验 cd / ls -a 第2关 Linux常用命令 touch newfile mkdir newdir cp newfile newdir/newfileCpy 第3关 Linux 查询命令帮助语句 man 3 fopen Linux文件/目录管理 第1关 Linux之文件创建/删除 touch file1 file2 rm oldFile1 oldFile2 第2关 Linux之目录创建/删除 mkdir newDir1 newDir2 rm oldDir1 -r old

    2024年02月10日
    浏览(42)
  • Linux操作系统实验三 文件管理(一)

      1.实验目的与要求 了解Linux文件系统目录结构 掌握目录管理的相关操作 掌握文件管理的相关操作 2.实验平台 实验室安装的实验环境(Linux操作系统)和头歌(www.educoder.net)实验平台(课程实验) 3.实验内容 文件系统目录结构理论知识练习 linux 下目录的创建、应用、查看、

    2024年02月03日
    浏览(54)
  • 【Linux操作系统】【综合实验三 用户帐号、文件系统与系统安全管理】

    要求掌握Linux系统用户的创建、删除与管理操作;熟悉Linux文件系统的管理模式,学会创建用户文件系统并装载和卸载文件系统;掌握超级用户的管理方式与权限,并实施对普通用户的管理;熟悉Linux系统安全机制与相关管理方法。 通过这个第三阶段实验,要求掌握以下操作与

    2023年04月14日
    浏览(38)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包