logonew chat icon top
  • icon-chaticon-chat-active搜题/提问
    new chat icon
    新建会话
  • icon-calculatoricon-calculator-active计算器
  • icon-subjecticon-subject-active学科题目
  • icon-pluginicon-plugin-active浏览器插件
  • icon-uploadicon-upload-active上传题库
  • icon-appicon-app-active手机APP
recent chat icon
历史记录
首页
/
计算机
题目

______9________1.1课程设计目的实现内核编译相关操作1.2相关原理介绍内核,是一个______的核心。它负责管理系统的进程、______、设备驱动程序[1]、文件和网络系统,决定着系统的性能和稳定性。Linux的一个重要的特点就是其______的公开性,Linux修补漏洞速度快以及对最新软件技术的利用方便,而Linux的内核则是这些特点的最直接的代表。拥有了内核的源程序[2]我们可以了解系统是如何工作的,通过通读源代码,我们就可以了解系统的工作原理。其次,我们可以针对自己的情况,量体裁衣,定制适合自己的系统,当然这样就需要重新编译内核。在不需要对内核进行重新编译的情况下,内核模块[3]可以动态的载入内核或从内核移出改变内核,极大缩短了驱动编写和内核开发的时间。1.3Linux内核模块程序结构一个Linux内核模块主要由如下几个部分组成:(1)模块加载函数通过insmod或modprobe命令加载内核模块时,模块的加载函数会自动被内核执行,完成本模块的相关初始化工作。(2)模块卸载函数当通过rmmod命令卸载某模块时,模块的卸载函数会自动被内核执行,完成与模块加载函数相反的功能。(3)模块许可证声明许可证(LICENSE)声明描述内核模块的许可权限,这一部分是必须声明的,如果不声明LICENSE,模块被加载时,将收到内核被污染(module license‘unspecified’taints kernel)的警告。在Linux 2.6内核中,可接受的LICENSE有“GPL”、“GPL v2”、“GPL and additional rights”、“Dual BSD/GPL”、“Dual MPL/GPL”和“Proprietary”。大多数情况下,内核模块应遵循GPL兼容许可权。其中最常用的许可是GPL和DualBSD/GPL。(4)其他可选部分模块参数,模块参数是模块被加载的时候可以被传递给它的值,它本身对应模块内部的全局变量[4];模块导出符号,内核模块可以导出符号(symbol,对应于函数或变量),这样其它模块可以使用本模块中的变量或函数;模块作者等信息声明。1.4内核模块的编译在Linux 2.6内核中,模块的编译需要配置过的内核源代码;编译过程首先回到内核目录下读取顶层的Makefile文件,然后返回模块源码所在目录,经过编译、链接后生成的内核模块文件的后缀为.ko。故内核模块的编译需要自己写Makefile文件,当在命令行中执行make命令时,将调用Makefile文件。二设计实现2.1内核线程[5]查看设计一个模块,该模块功能是列出系统中所有内核线程的程序名、PID号和进程状态[6]。该内核模块的功能类似于命令ps,只不过该模块专查看内核线程信息。首先在文件开始声明一下模块的许可证,即在文件中加入:MODULE_LICENSE("GPL");根据内核模块编程的模式,一个内核模块应该至少包含两个函数。一个初始化函数,还有一个退出(干一些收尾清理的工作)的函数,当内核模块被rmmod卸载时被执行。从内核版本2.3.13开始,可以为初始化和结束函数起任意的名字。在该模块内。两个函数分别命名为:static intkernel_thread_init(void)和static void kernel_thread_exit(void)。调用宏module_init()和module_exit()去注册初始化和退出这两个函数,即:module_init(kernel_thread_init);module_exit(kernel_thread_exit);到此内核模块基本框架基本完成。为了获取到所有的内核线程,可以使用宏for_each_process()。在内核中有内核线程组长链表[7],每个线程组长通过task_struc结构的tasks成员加入该链表中。利用for_each_process()可以访问到链表中的每一个进程。具体实现如下:structtask_struct *p;for_each_process(p)(/相关函数及操作)对遍历到的每一个线程,读取它的线程号、线程名称以及线程状态并输出。当线程状态为0时输出runnale,为-1时输出unrunnable,为其他时则输出stopped。在这里输出函数并不能使用printf,printf是用户空间的输出函数,内核空间使用的是printk,因为内核没有链接标准的C函数库。而实际上printk和printf的功能类似,printk是在内核中运行的向控制台[8]输出显示的函数。printk日志输出的级别一共有8个,由高到低分别为:KERN_EMERG""、KERN_ALERT""、KERN_CRIT""、KERN_ERR""、KERN_WARNING""、KERN_NOTICE""、KERN_INFO""、KERN_DEBUG"",默认采用的级别是DEFAULT_ MESSAGE_LOGLEVEL(这个默认级别一般为,即与KERN_WARNING在一个级别上)。2.2带参模块的实现设计一个带参数的模块,参数为进程的PID号,功能是列出进程的家族信息,包括父进程、兄弟进程和子进程的程序名、PID号。该模块的基本框架和上一个模块类似,声明模块许可证,注册初始化和结束函数。不同之处是在该模块中涉及到了模块参数。在Linux操作系统内核[9]中提供了一种模块带参数的机制,是模块的编写者可以在加载模块的时候提供一下信息,这些参数对于模块来说都是一个全局变量。定义一个模块参数可通过module_param()实现:module_param(name,type,perm);参数name是用户可见的参数名,也是模块中存放模块参数的变量名。参数type代表参数的类型,它可以是byte、short、int、long等类型。最后一个参数perm制定了模块在sysfs文件系统[10]下对应的文件权限,可以使八进制[11]的,也可以是S_Ifoo的定义形式,如S_RUGO|S_IWUSR等。在该模块中,定义一个进程的PID作为参数,以实现任意进程家族信息的查询,默认进程号为1,即在不添加参数情况下查看进程号为1的进程家族信息,具体实现如下:staticintpid=1;module_param(pid,int,0644);为找到指定PID的进程,可以使用for_each_process(p)遍历内核所有进程,查找进程号为PID的进程。找到具体进程后,获取进程的名称。接下来判断进程的父进程是否存在,若存在,在输出父进程信息:if(p->real_parent==NULL)(printk("No Parentn");)else(printk("Parent : %d %sn",p->real_parent->pid,p->real_parent->comm);)下一步就是该搜索线程号为PID线程的兄弟进程及子进程。在Linux中采用多个链表确保有效查找系统里的进程,双向链表[12]list_head内核中广泛的使用。因为list_head一般嵌入到啮合数据结构中,为了便于访问链表中的数据,内核提供了一系列的宏来实现链表的常规操作[2]。在这里使用list_for_each()和list_entry()来实现兄弟进程和子进程的查找。在上一步中得到了要查找的进程,可以由此进程得到他父进程的所有子进程组成的链表p->real_parent->children和此进程子进程的链表p->children。定义一个list_head结构体用于list_entry()中:structlist_head *pp;宏list_for_each(pp,&p->real_parent->children)遍历p->real_parent->children链表,每次pp指向一个对象成员,而宏list_entry(pp,structtask_struct,sibling);进一步得到该对象的指针。具体实现兄弟进程和子进程遍历如下:structtask_struct *p,*psibling;list_for_each(pp,&p->real_parent->children)(psibling=list_entry(pp,structtask_struct,sibling);printk("sibling %d %s n",psibling->pid,psibling->comm);)list_for_each(pp,&p->children)(psibling=list_entry(pp,structtask_struct,sibling);printk("children %d %s n",psibling->pid,psibling->comm);)上述过程将输出得到的兄弟进程和子进程的pid号和进程名称。2.3Makefile文件的编写Make工具最主要也是最基本的功能就是通过makefile文件来描述源程序之间的相互关系并自动维护编译工作。而makefile文件需要按照某种语法进行编写,文件中需要说明如何编译各个源文件并连接生成可执行文件[13],并要求定义源文件之间的依赖关系。makefile文件是许多编译器--包括Windows NT下的编译器--维护编译信息的常用方法,只是在集成开发环境中,用户通过友好的界面修改makefile文件而已。在Linux内核模块编程中,Makefile文件模版都类似,具体结构如下:ifneq ((KERNELRELEASE),)obj-m :=目标文件.oelseKDIR :=/lib/modules/(shell uname -r)/buildPWD :=(shellpwd)default:(MAKE) -C (KDIR) M=(PWD) modulesclean:(MAKE) -C (KDIR) M=(PWD) cleanendifKERNELRELEASE是在内核源码的顶层Makefile中定义的一个变量,在第一次读取执行此Makefile时,KERNELRELEASE没有被定义,所以make将读取执行else之后的内容。如果make的目标是clean,直接执行clean操作,然后结束。当make的目标为all时,-C(KDIR)指明跳转到内核源码目录下读取那里的Makefile;M=(PWD)表明然后返回到当前目录继续读入、执行当前的Makefile。当从内核源码目录返回时,KERNELRELEASE已被被定义,此时第一行的ifneq成功,make将继续读取else之前的内容。ifneq的内容为kbuild语法的语句,指明模块源码中各文件的依赖关系,以及要生成的目标模块名。三测试总结3.1内核线程查看测试(1)切换到内核模块所在路径kernel_threads,在命令行中输入make,得到如下结果:

______9

________

1.1课程设计目的

实现内核编译相关操作

1.2相关原理介绍

内核,是一个______的核心。它负责管理系统的进程、______、设备驱动程序[1]、文件和网络系统,决定着系统的性能和稳定性。

Linux的一个重要的特点就是其______的公开性,Linux修补漏洞速度快以及对最新软件技术的利用方便,而Linux的内核则是这些特点的最直接的代表。拥有了内核的源程序[2]我们可以了解系统是如何工作的,通过通读源代码,我们就可以了解系统的工作原理。其次,我们可以针对自己的情况,量体裁衣,定制适合自己的系统,当然这样就需要重新编译内核。在不需要对内核进行重新编译的情况下,内核模块[3]可以动态的载入内核或从内核移出改变内核,极大缩短了驱动编写和内核开发的时间。

1.3Linux内核模块程序结构

一个Linux内核模块主要由如下几个部分组成:

(1)模块加载函数

通过insmod或modprobe命令加载内核模块时,模块的加载函数会自动被内核执行,完成本模块的相关初始化工作。

(2)模块卸载函数

当通过rmmod命令卸载某模块时,模块的卸载函数会自动被内核执行,完成与模块加载函数相反的功能。

(3)模块许可证声明

许可证(LICENSE)声明描述内核模块的许可权限,这一部分是必须声明的,如果不声明LICENSE,模块被加载时,将收到内核被污染(module license‘unspecified’taints kernel)的警告。在Linux 2.6内核中,可接受的LICENSE有“GPL”、“GPL v2”、“GPL and additional rights”、“Dual BSD/GPL”、“Dual MPL/GPL”和“Proprietary”。大多数情况下,内核模块应遵循GPL兼容许可权。其中最常用的许可是GPL和DualBSD/GPL。

(4)其他可选部分

模块参数,模块参数是模块被加载的时候可以被传递给它的值,它本身对应模块内部的全局变量[4];模块导出符号,内核模块可以导出符号(symbol,对应于函数或变量),这样其它模块可以使用本模块中的变量或函数;模块作者等信息声明。

1.4内核模块的编译

在Linux 2.6内核中,模块的编译需要配置过的内核源代码;编译过程首先回到内核目录下读取顶层的Makefile文件,然后返回模块源码所在目录,经过编译、链接后生成的内核模块文件的后缀为.ko。故内核模块的编译需要自己写Makefile文件,当在命令行中执行make命令时,将调用Makefile文件。

二设计实现

2.1内核线程[5]查看

设计一个模块,该模块功能是列出系统中所有内核线程的程序名、PID号和进程状态[6]。

该内核模块的功能类似于命令ps,只不过该模块专查看内核线程信息。首先在文件开始声明一下模块的许可证,即在文件中加入:

MODULE_LICENSE("GPL");

根据内核模块编程的模式,一个内核模块应该至少包含两个函数。一个初始化函数,还有一个退出(干一些收尾清理的工作)的函数,当内核模块被rmmod卸载时被执行。从内核版本2.3.13开始,可以为初始化和结束函数起任意的名字。在该模块内。两个函数分别命名为:static intkernel_thread_init(void)和static void kernel_thread_exit(void)。调用宏module_init()和module_exit()去注册初始化和退出这两个函数,即:

module_init(kernel_thread_init);

module_exit(kernel_thread_exit);

到此内核模块基本框架基本完成。

为了获取到所有的内核线程,可以使用宏for_each_process()。在内核中有内核线程组长链表[7],每个线程组长通过task_struc结构的tasks成员加入该链表中。利用for_each_process()可以访问到链表中的每一个进程。具体实现如下:

structtask_struct *p;

for_each_process(p)

{

//相关函数及操作

}

对遍历到的每一个线程,读取它的线程号、线程名称以及线程状态并输出。当线程状态为0时输出runnale,为-1时输出unrunnable,为其他时则输出stopped。

在这里输出函数并不能使用printf,printf是用户空间的输出函数,内核空间使用的是printk,因为内核没有链接标准的C函数库。而实际上printk和printf的功能类似,printk是在内核中运行的向控制台[8]输出显示的函数。printk日志输出的级别一共有8个,由高到低分别为:KERN_EMERG""、KERN_ALERT""、KERN_CRIT""、KERN_ERR""、KERN_WARNING""、KERN_NOTICE""、KERN_INFO""、KERN_DEBUG"",默认采用的级别是DEFAULT_ MESSAGE_LOGLEVEL(这个默认级别一般为,即与KERN_WARNING在一个级别上)。

2.2带参模块的实现

设计一个带参数的模块,参数为进程的PID号,功能是列出进程的家族信息,包括父进程、兄弟进程和子进程的程序名、PID号。

该模块的基本框架和上一个模块类似,声明模块许可证,注册初始化和结束函数。不同之处是在该模块中涉及到了模块参数。在Linux操作系统内核[9]中提供了一种模块带参数的机制,是模块的编写者可以在加载模块的时候提供一下信息,这些参数对于模块来说都是一个全局变量。定义一个模块参数可通过module_param()实现:

module_param(name,type,perm);

参数name是用户可见的参数名,也是模块中存放模块参数的变量名。参数type代表参数的类型,它可以是byte、short、int、long等类型。最后一个参数perm制定了模块在sysfs文件系统[10]下对应的文件权限,可以使八进制[11]的,也可以是S_Ifoo的定义形式,如S_RUGO|S_IWUSR等。

在该模块中,定义一个进程的PID作为参数,以实现任意进程家族信息的查询,默认进程号为1,即在不添加参数情况下查看进程号为1的进程家族信息,具体实现如下:

staticintpid=1;

module_param(pid,int,0644);

为找到指定PID的进程,可以使用for_each_process(p)遍历内核所有进程,查找进程号为PID的进程。找到具体进程后,获取进程的名称。接下来判断进程的父进程是否存在,若存在,在输出父进程信息:

if(p->real_parent==NULL)

{

printk("No Parentn");

}

else

{

printk("Parent : %d %sn",p->real_parent->pid,p->real_parent->comm);

}

下一步就是该搜索线程号为PID线程的兄弟进程及子进程。在Linux中采用多个链表确保有效查找系统里的进程,双向链表[12]list_head内核中广泛的使用。因为list_head一般嵌入到啮合数据结构中,为了便于访问链表中的数据,内核提供了一系列的宏来实现链表的常规操作[2]。在这里使用list_for_each()和list_entry()来实现兄弟进程和子进程的查找。

在上一步中得到了要查找的进程,可以由此进程得到他父进程的所有子进程组成的链表p->real_parent->children和此进程子进程的链表p->children。定义一个list_head结构体用于list_entry()中:

structlist_head *pp;

宏list_for_each(pp,&p->real_parent->children)遍历p->real_parent->children链表,每次pp指向一个对象成员,而宏list_entry(pp,structtask_struct,sibling);进一步得到该对象的指针。具体实现兄弟进程和子进程遍历如下:

structtask_struct *p,*psibling;

list_for_each(pp,&p->real_parent->children)

{

psibling=list_entry(pp,structtask_struct,sibling);

printk("sibling %d %s n",psibling->pid,psibling->comm);

}

list_for_each(pp,&p->children)

{

psibling=list_entry(pp,structtask_struct,sibling);

printk("children %d %s n",psibling->pid,psibling->comm);

}

上述过程将输出得到的兄弟进程和子进程的pid号和进程名称。

2.3Makefile文件的编写

Make工具最主要也是最基本的功能就是通过makefile文件来描述源程序之间的相互关系并自动维护编译工作。而makefile文件需要按照某种语法进行编写,文件中需要说明如何编译各个源文件并连接生成可执行文件[13],并要求定义源文件之间的依赖关系。makefile文件是许多编译器--包括Windows NT下的编译器--维护编译信息的常用方法,只是在集成开发环境中,用户通过友好的界面修改makefile文件而已。在Linux内核模块编程中,Makefile文件模版都类似,具体结构如下:

ifneq ($(KERNELRELEASE),)

obj-m :=目标文件.o

else

KDIR :=/lib/modules/$(shell uname -r)/build

PWD :=$(shellpwd)

default:

$(MAKE) -C $(KDIR) M=$(PWD) modules

clean:

$(MAKE) -C $(KDIR) M=$(PWD) clean

endif

KERNELRELEASE是在内核源码的顶层Makefile中定义的一个变量,在第一次读取执行此Makefile时,KERNELRELEASE没有被定义,所以make将读取执行else之后的内容。如果make的目标是clean,直接执行clean操作,然后结束。当make的目标为all时,-C$(KDIR)指明跳转到内核源码目录下读取那里的Makefile;M=$(PWD)表明然后返回到当前目录继续读入、执行当前的Makefile。当从内核源码目录返回时,KERNELRELEASE已被被定义,此时第一行的ifneq成功,make将继续读取else之前的内容。ifneq的内容为kbuild语法的语句,指明模块源码中各文件的依赖关系,以及要生成的目标模块名。

三测试总结

3.1内核线程查看测试

(1)切换到内核模块所在路径kernel_threads,在命令行中输入make,得到如下结果:

题目解答

答案

4总结 一课程设计简介操作系统 内存 源代码

相关问题

  • 下列哪项关于监督学习算法的描述正确()A. 强化学习的训练效果一定优于监督学习B. 主要的监督学习方法包括生成方法和判别方法C. 广度优先搜索算法是一种监督学习算法

  • 下列哪项不是求解对抗搜索问题的基本算法( ) A.反向传播算法 B.广度优先排序算法 C.Alpha-Beta剪枝算法D.最小最大搜索算法

  • 下列哪项关于广度优先搜索的描述正确()A. 每次扩展时,该算法从边缘集合中取出最下层(最深)的节点B. 广度优先搜索算法是深度优先搜索算法的特例C. 每次扩展时,该算法从边缘集合中取出最上层(最浅)的节点D. 深度优先搜索是广度优先搜索的特例

  • 3.判断题K-means聚类算法对数据的尺寸敏感。()A. 对B. 错

  • 下列哪项属于因果推理模型()A. 因果图B. 神经符号推理C. 符号推理模型D. 结构因果模型

  • 下列哪个方法属于知识图谱推理方法()A. 广度优先搜索B. 深度学习推断C. 路径排序算法D. 归纳逻辑程序设计

  • 网络安全包括物理安全[1]、逻辑安全、操作系统安全及联网安全,其中逻辑安全包括访问控制[2]、加密、安全管理及用户身份认证。A. 正确B. 错误

  • 网络安全包括物理安全[1]、逻辑安全、操作系统安全及联网安全,其中逻辑安全包括访问控制[2]、加密、安全管理及用户身份认证。A. 正确B. 错误

  • 下列哪个方法属于知识图谱推理方法()A. 路径排序算法B. 深度学习推断C. 广度优先搜索D. 归纳逻辑程序设计

  • 由脸书(Facebook)公司开发的深度学习编程框架是()A. TensorFlowB. PaddlePaddleC. PyTorchD. Mindspore

  • 路径排序算法的工作流程主要有三步()A. 特征计算B. 特征抽取C. 分类器训练D. 因果推断

  • 下列不属于量子机器学习算法的是()A. 量子支持向量机B. 量子主成分分析C. 薛定谔方程求解D. 深度量子学习

  • 下列哪项属于因果推理模型() A. 因果图B. 符号推理模型C. 神经符号推理D. 结构因果模型

  • 在决策树建立过程中,使用一个属性对某个结点对应的数集合进行划分后,结果具有高信息熵(highentropy),对结果的描述,最贴切的是()。A. 纯度高B. 纯度低C. 有用D. 无用E. 以上描述都不贴切

  • 以下哪种方法属于卷积神经网络的基本组件()。A. 卷积层B. 池化层C. 激活函数D. 复制层

  • 2.单选题 讯飞星火可以实现多种文案类型和语言风格的文本写作。讯飞星火(网页版)“内容写作”功能可选的“语言风格”不包括( )。A. 口语化B. 高情商C. 专业D. 热情

  • 路径排序算法的工作流程主要有三步()A. 特征抽取B. 特征计算C. 分类器训练D. 因果推断

  • 7、 加强电脑安全防护,及时升级病 毒库,安装防火墙,及时查杀病毒和木马,是防范 电信网络诈骗的有效做法。A. 正确B. 错误

  • AdaBoosting采用多个单一分类器组成一个强分类器()A. 错误B. 正确

  • 下列哪项贪婪最佳优先搜索算法的描述正确()A. 贪婪最佳优先搜索不属于启发式搜索算法B. 贪婪最佳优先搜索是一种A*搜索算法C. 贪婪最佳优先搜索是一种广度优先搜索算法D. 贪婪最佳优先搜索属于有信息搜索算法

上一页下一页
logo
广州极目未来文化科技有限公司
注册地址:广州市黄埔区揽月路8号135、136、137、138房
关于
  • 隐私政策
  • 服务协议
  • 权限详情
学科
  • 医学
  • 政治学
  • 管理
  • 计算机
  • 教育
  • 数学
联系我们
  • 客服电话: 010-82893100
  • 公司邮箱: daxuesoutijiang@163.com
  • qt

©2023 广州极目未来文化科技有限公司 粤ICP备2023029972号    粤公网安备44011202002296号