首先要清楚,如果你是在**VMware安装的Oppeneuller**,那么你的架构是x86的。就完全可以按照我们
教材7.2.3的操作进行!
而如果你是在服务器上远程操作,那么你是鲲鹏的架构。就不能按照书上的操作来。
本篇文章主要介绍对服务器上openeuller的操作。(推荐大家使用,因为这样会省很多事。比如:可以更改服务器
核数数大大降低编译时间)
这里很多人会选择先完成内核编译,再进行系统函数的调用这个任务。其实没必要,完全可以将所有代码写入之后再
进行编译,这样会少编译两次(毕竟编译一次短则半小时,长则小两个小时。但是把华为云服务器核数变为60核只需
要一分钟,这个后面再讲)。
通过华为云Cloudshell远程登录服务器:
输入服务器密码登录
依次输入:
yum group install -y "Development Tools"
yum install -y bc
yum install -y openssl-devel
获取内核源代码并解压:
wget https://gitee.com/openeuler/kernel/repository/archive/kernel-4.19.zip
unzip kernel-4.19.zip
解压完毕后会在桌面生成一个kernel-kernel-4.19的文件夹,接下来的操作都是在此文件夹中进行。
首先打开文件夹:
然后打开文件(include/uapi/asm-generic/unistd.h)
对应位置添加代码:
#define __NR_czq 294 //输出学号
__SYSCALL(__NR_czq, sys_czq)
#define __NR_mysetnice 295 //
__SYSCALL(__NR_mysetnice,sys_mysetnice)
#define __NR_mysethostname 296
__SYSCALL(__NR_mysethostname,sys_mysethostname)
一定要记得将原来的294改为297!!!
打开文件(include/linux/syscalls.h)
添加声明系统调用函数的代码:
asmlinkage long sys_zlk(void);
asmlinkage long sys_mysetnice(pid_t pid,int flag,int nicevalue,void __user*prio,void __user*nice);
asmlinkage long sys_mysethostname(char __user *name, int len);
打开文件(kernel/sys.c)
添加代码:(注意:这段代码要添加到尾部#endif之上的位置,否则也会导致编译失败)
SYSCALL_DEFINE0(czq)
{
printk(KERN_INFO "Student number is:XXXXXX");//前面的参数一定要添加,
return 0;
}
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;
}
SYSCALL_DEFINE2(mysethostname, char __user *, name, int, len)
{
int errno;
char tmp[__NEW_UTS_LEN];
if(len<0 || len>__NEW_UTS_LEN)
return -EINVAL;
errno = -EFAULT;
if(!copy_from_user(tmp, name, len))
{
struct new_utsname *u;
down_write(&uts_sem);
u = utsname();
memcpy(u->nodename, tmp, len);
memset(u->nodename + len, 0, sizeof(u->nodename)- len);
errno = 0;
uts_proc_notify(UTS_PROC_HOSTNAME);
up_write(&uts_sem);
}
return errno;
}
此处代码参考了https://blog.csdn.net/Z165165165/article/details/118486665
此时我们已经完成准备工作,接下来开始编译内核。
此处有两种选择:1、不做更改直接编译,可忽略下面这一步(需要半小时左右)。2、换核编译(1分钟左右)。这也是我后面选择在服务器上操作的原因之一(失败太多次了)。
换核编译:
选择变更规格
选择一个核数较多的更换即可(32核的就差不多了,1分钟左右,我用了一次60核的CPU占用率不到20%)
在kernel-kernel-4.19目录下进行一下操作:
配置内核:make menuconfig
查资料发现是缺一个插件
所以接下来下载:
sudo yum install -y ncurses-devel
再次输入:make menuconfig
会出下图
选择保存退出即可
完成后依次输入:
编译内核:make -j64
编译模块:make modules
这里的警告可以忽略
安装模块:make modules_install
安装内核:make
make install
立即重启:reboot
如果你换了核,记得现在换回之前的0.6元/h的4核!
输出学号函数:
#include
#include
#include
int main()
{
if (syscall(294) == 0) //如果成功执行,返回0。如果没有调用成功,一般会返回-1.
printf("success!\n");
else
printf("fail!\n");
return 0;
}
修改优先级函数:
#define _GNU_SOURCE
#include
#include
#include
#include
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;
}
改变主机名称为自定义字符串:
#define _GUN_SOURCE
#include
#include
#include
int main()
{
syscall(296,"Kiki",4);
return 0;
}
代码参考:https://blog.csdn.net/Z165165165/article/details/118486665
以上三个代码编译完成后,先用先用dmesg -c
命令清空原有日志,然后运行,使用dmesg
查看结果。
作者前前后后在这个实验上花了不下10小时,编译了不下5次,得到了血的教训,有感而发,将自己的经验分享给大家,避免更多的人犯错。