- 掌握Linux 内核的编译与安装
- 掌握Linux 系统调用基本概念
- 设计和添加linux系统调用
(1)修改或返回指定进程的优先级(nice值和prio值)(详见教材P328)提示:可能参考的内核函数:set_user_nice().
(2)改变主机名称为自定义字符串(自选题目)
(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窗口中选择以新编译出来的内核启动系统
这里编译完以后已经有了4.19.208版本的新内核,选择该内核登录
Linux系统处理系统调用的流程以及增加系统调用的方法。Linux系统提供了多达几百种的系统调用,为了唯一地标识每一个系统调用,Linux为每个系统调用都设置了一个唯一的编号,称为系统调用号,同时每个系统调用需要一个服务例程完成其具体功能。
这里不做过多描述。
(重点是怎么添加系统调用!!!)
- cd kernel-kernel-4.19 进入文件夹
- vim include/uapi/asm-generic/unistd.h 修改及添加系统调用号(注意系统调用号不能随意加,只能一次加1)
#define __NR_hello_euler 294
__SYSCALL(__NR_hello_euler, sys_hello_euler)
#undef __NR_syscalls
#define __NR_syscalls 295
- vim include/linux/syscalls.h 添加代码申明系统调用服务例程
asmlinkage long sys_hello_euler(void);
- vim kernel/sys.c 实现系统调用服务例程
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
#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文件。)
- 执行 ./a.out
- 输入 dmesg 查看结果(成功输出学号~)
(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
(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,即可看到主机名已经成功更换
(1)大家做实验之前看教程一定要搞清楚是x86还是arm架构的呀!!!我就是在这上面栽跟头了重建了三四次华为云
(2)如果用VNC登陆时出现以下报错,那么恭喜你,多半是你的内核崩了~我的老师说,只要你手速够快,在重启虚拟机的时候立马用VNC重新登陆是可以进去的,但是我没成功过,只能重建了n次云主机。
(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。
电脑0x0000001A蓝屏错误怎么U盘重装系统教学分享。有用户电脑开机之后遇到了系统蓝屏的情况。系统蓝屏问题很多时候都是系统bug,只有通过重装系统来进行解决。那么蓝屏问题如何通过U盘重装新系统来解决呢?来看看以下的详细操作方法教学吧。 准备工作: 1、U盘一个(尽量使用8G以上的U盘)。 2、一台正常联网可使用的电脑。 3、ghost或ISO系统镜像文件(Win10系统下载_Win10专业版_windows10正式版下载-系统之家)。 4、在本页面下载U盘启动盘制作工具:系统之家U盘启动工具。 U盘启动盘制作步骤: 注意:制作期间,U盘会被格式化,因此U盘中的重要文件请注
华为OD机试题本篇题目:明明的随机数题目输入描述输出描述:示例1输入输出说明代码编写思路最近更新的博客华为od2023|什么是华为od,od薪资待遇,od机试题清单华为OD机试真题大全,用Python解华为机试题|机试宝典【华为OD机试】全流程解析+经验分享,题型分享,防作弊指南华为o
system-view进入系统视图quit退到系统视图sysname交换机命名vlan20创建vlan(进入vlan20)displayvlan显示vlanundovlan20删除vlan20displayvlan20显示vlan里的端口20Interfacee1/0/24进入端口24portlink-typeaccessvlan20把当前端口放入vlan20undoporte1/0/10删除当前VLAN端口10displaycurrent-configuration显示当前配置02配置交换机支持TELNETinterfacevlan1进入VLAN1ipaddress192.168.3.100
在应用开发中,有时候我们需要获取系统的设备信息,用于数据上报和行为分析。那在鸿蒙系统中,我们应该怎么去获取设备的系统信息呢,比如说获取手机的系统版本号、手机的制造商、手机型号等数据。1、获取方式这里分为两种情况,一种是设备信息的获取,一种是系统信息的获取。1.1、获取设备信息获取设备信息,鸿蒙的SDK包为我们提供了DeviceInfo类,通过该类的一些静态方法,可以获取设备信息,DeviceInfo类的包路径为:ohos.system.DeviceInfo.具体的方法如下:ModifierandTypeMethodDescriptionstatic StringgetAbiList()Obt
需求:要创建虚拟机,就需要给他提供一个虚拟的磁盘,我们就在/opt目录下创建一个10G大小的raw格式的虚拟磁盘CentOS-7-x86_64.raw命令格式:qemu-imgcreate-f磁盘格式磁盘名称磁盘大小qemu-imgcreate-f磁盘格式-o?1.创建磁盘qemu-imgcreate-fraw/opt/CentOS-7-x86_64.raw10G执行效果#ls/opt/CentOS-7-x86_64.raw2.安装虚拟机使用virt-install命令,基于我们提供的系统镜像和虚拟磁盘来创建一个虚拟机,另外在创建虚拟机之前,提前打开vnc客户端,在创建虚拟机的时候,通过vnc
我有一个使用SeleniumWebdriver和Nokogiri的Ruby应用程序。我想选择一个类,然后对于那个类对应的每个div,我想根据div的内容执行一个Action。例如,我正在解析以下页面:https://www.google.com/webhp?sourceid=chrome-instant&ion=1&espv=2&ie=UTF-8#q=puppies这是一个搜索结果页面,我正在寻找描述中包含“Adoption”一词的第一个结果。因此机器人应该寻找带有className:"result"的div,对于每个检查它的.descriptiondiv是否包含单词“adoption
我正在我的Rails项目中安装Grape以构建RESTfulAPI。现在一些端点的操作需要身份验证,而另一些则不需要身份验证。例如,我有users端点,看起来像这样:moduleBackendmoduleV1classUsers现在如您所见,除了password/forget之外的所有操作都需要用户登录/验证。创建一个新的端点也没有意义,比如passwords并且只是删除password/forget从逻辑上讲,这个端点应该与用户资源。问题是Grapebefore过滤器没有像except,only这样的选项,我可以在其中说对某些操作应用过滤器。您通常如何干净利落地处理这种情况?
在我做的一些网络开发中,我有多个操作开始,比如对外部API的GET请求,我希望它们同时开始,因为一个不依赖另一个的结果。我希望事情能够在后台运行。我找到了concurrent-rubylibrary这似乎运作良好。通过将其混合到您创建的类中,该类的方法具有在后台线程上运行的异步版本。这导致我编写如下代码,其中FirstAsyncWorker和SecondAsyncWorker是我编写的类,我在其中混合了Concurrent::Async模块,并编写了一个名为“work”的方法来发送HTTP请求:defindexop1_result=FirstAsyncWorker.new.async.
因为我现在正在做一些时间测量,我想知道是否可以在不使用Benchmark类或命令行实用程序time的情况下测量用户时间或系统时间。使用Time类只显示挂钟时间,而不显示系统和用户时间,但是我正在寻找具有相同灵active的解决方案,例如time=TimeUtility.now#somecodeuser,system,real=TimeUtility.now-time原因是我有点不喜欢Benchmark,因为它不能只返回数字(编辑:我错了-它可以。请参阅下面的答案。)。当然,我可以解析输出,但感觉不对。*NIX系统的time实用程序也应该可以解决我的问题,但我想知道是否已经在Ruby中实
a=[3,4,7,8,3]b=[5,3,6,8,3]假设数组长度相同,是否有办法使用each或其他一些惯用方法从两个数组的每个元素中获取结果?不使用计数器?例如获取每个元素的乘积:[15,12,42,64,9](0..a.count-1).eachdo|i|太丑了...ruby1.9.3 最佳答案 使用Array.zip怎么样?:>>a=[3,4,7,8,3]=>[3,4,7,8,3]>>b=[5,3,6,8,3]=>[5,3,6,8,3]>>c=[]=>[]>>a.zip(b)do|i,j|c[[3,5],[4,3],[7,6],