实验五__内核模块设计实验
操作系统实验---内核模块实现

实验报告实验题目:内核模块实现姓名:学号:课程名称:操作系统所在学院:信息科学与工程学院专业班级:计算机任课教师:module_init(初始函数名);module_exit(退出函数名 );MODULE_LICENSE("GPL");//模块通用公共许可证5、makefile文件内容基本格式ifneq ($(KERNELRELEASE),)obj-m:=xxx.oelseKDIR:=/lib/modules/$(shell uname -r)/buildPWD:=$(shell pwd)all:make -C $(KDIR) M=$(PWD) modulesclean:rm -rf *.o *.ko *.mod.c *.cmd *.markers *.order *.symvers .tmp_versions endif说明:1) KERNELRELEASE是在内核源码的顶层Makefile中定义的一个变量。
ifneq($(KERNELRELEASE),) 判断该变量是否为空。
2) KDIR := /lib/modules/$(shell uname -r)/build 是给KDIR这个变量赋值,值为当前linux运行的内核源码。
3) 当make的目标为all时,-C $(KDIR) 指明跳转到内核源码目录下读取那里的Makefile;M=$(PWD)表明然后返回到当前目录继续读入、执行当前的Makefile。
当从内核源码目录返回时,KERNELRELEASE已被被定义,kbuild也被启动去解析kbuild语法的语句,make将继续读取else之前的内容。
4) 我们可以把上述的Makefile文件作为一个模板,只需要改动obj-m := hello.o这条语句就可以了:obj-m=XXX.o。
4、进入管理员权限,cd到目录下。
输入如下命令:5、输入make命令以编译:6、编译成功后,输入insmod命令安装自己的内核模块:7、查看内核模块:可以看到自己的time模块安装成功。
ucore_LAB5实验报告(word文档良心出品)

LAB5实验报告实验目的:●了解第一个用户进程创建过程●了解系统调用框架的实现机制●了解ucore如何实现系统调用sys_fork/sys_exec/sys_exit/sys_wait来进行进程管理实验内容:实验4完成了内核线程,但到目前为止,所有的运行都在内核态执行。
实验5将创建用户进程,让用户进程在用户态执行,且在需要ucore支持时,可通过系统调用来让ucore提供服务。
为此需要构造出第一个用户进程,并通过系统调用sys_fork/sys_exec/sys_exit/sys_wait 来支持运行不同的应用程序,完成对用户进程的执行过程的基本管理。
一.练习练习0:填写已有实验根据提示,对标注LAB5 YOUR CODE : (update LAB4 steps)的部分进行一定的改动。
Kern/trap/trap.c:/* LAB1 YOUR CODE : STEP 3 *//* handle the timer interrupt *//* (1) After a timer interrupt, you should record this event using a global variable (increase it), such as ticks in kern/driver/clock.c* (2) Every TICK_NUM cycle, you can print some info using a funciton, such as print_ticks().* (3) Too Simple? Yes, I think so!*//* LAB5 YOUR CODE *//* you should upate you lab1 code (just add ONE or TWO lines of code):* Every TICK_NUM cycle, you should set current process'scurrent->need_resched = 1*/ticks ++;if (ticks % TICK_NUM == 0) {assert(current != NULL);current->need_resched = 1;}/* LAB1 YOUR CODE : STEP 2 *//* (1) Where are the entry addrs of each Interrupt Service Routine (ISR)?* All ISR's entry addrs are stored in __vectors. where is uintptr_t __vectors[] ?* __vectors[] is in kern/trap/vector.S which is produced by tools/vector.c* (try "make" command in lab1, then you will find vector.S in kern/trap DIR)* You can use "extern uintptr_t __vectors[];" to define this extern variable which will be used later.* (2) Now you should setup the entries of ISR in Interrupt Description Table (IDT).* Can you see idt[256] in this file? Yes, it's IDT! you can use SETGATE macro to setup each item of IDT* (3) After setup the contents of IDT, you will let CPU know where is the IDT by using 'lidt' instruction.* You don't know the meaning of this instruction? just google it! and check the libs/x86.h to know more.* Notice: the argument of lidt is idt_pd. try to find it!*//* LAB5 YOUR CODE *///you should update your lab1 code (just add ONE or TWO lines of code), let user app to use syscall to get the service of ucore//so you should setup the syscall interrupt gate in hereextern uintptr_t __vectors[];int i;for (i = 0; i < sizeof(idt) / sizeof(struct gatedesc); i ++) {SETGATE(idt[i], 0, GD_KTEXT, __vectors[i], DPL_KERNEL);}SETGATE(idt[T_SYSCALL], 1, GD_KTEXT, __vectors[T_SYSCALL], DPL_USER);lidt(&idt_pd);Kern/process/proc.c:static struct proc_struct *alloc_proc(void) {struct proc_struct *proc = kmalloc(sizeof(struct proc_struct));if (proc != NULL) {//LAB4:EXERCISE1 YOUR CODE/** below fields in proc_struct need to be initialized* enum proc_state state; // Process state* int pid; // Process ID* int runs; // the running times of Proces * uintptr_t kstack; // Process kernel stack* volatile bool need_resched; // bool value: need to be rescheduled to release CPU?* struct proc_struct *parent; // the parent process* struct mm_struct *mm; // Process's memory management field* struct context context; // Switch here to run process* struct trapframe *tf; // Trap frame for current interrupt* uintptr_t cr3; // CR3 register: the base addr of Page Directroy Table(PDT)* uint32_t flags; // Process flag* char name[PROC_NAME_LEN + 1]; // Process name*/proc->state = PROC_UNINIT;proc->pid = -1;proc->runs = 0;proc->kstack = 0;proc->need_resched = 0;proc->parent = NULL;proc->mm = NULL;memset(&(proc->context), 0, sizeof(struct context));proc->tf = NULL;proc->cr3 = boot_cr3;proc->flags = 0;memset(proc->name, 0, PROC_NAME_LEN);//LAB5 YOUR CODE : (update LAB4 steps)/** below fields(add in LAB5) in proc_struct need to be initialized* uint32_t wait_state; // waiting state* struct proc_struct *cptr, *yptr, *optr; // relations between processes*/proc->wait_state = 0;proc->cptr = proc->yptr = proc->optr = NULL;}return proc;}intdo_fork(uint32_t clone_flags, uintptr_t stack, struct trapframe *tf) {int ret = -E_NO_FREE_PROC;struct proc_struct *proc;if (nr_process >= MAX_PROCESS) {goto fork_out;}ret = -E_NO_MEM;//LAB4:EXERCISE2 YOUR CODE/** Some Useful MACROs, Functions and DEFINEs, you can use them in below implementation.* MACROs or Functions:* alloc_proc: create a proc struct and init fields (lab4:exercise1)* setup_kstack: alloc pages with size KSTACKPAGE as process kernel stack* copy_mm: process "proc" duplicate OR share process "current"'s mm according clone_flags* if clone_flags & CLONE_VM, then "share" ; else "duplicate"* copy_thread: setup the trapframe on the process's kernel stack top and* setup the kernel entry point and stack of process* hash_proc: add proc into proc hash_list* get_pid: alloc a unique pid for process* wakup_proc: set proc->state = PROC_RUNNABLE* VARIABLES:* proc_list: the process set's list* nr_process: the number of process set*/// 1. call alloc_proc to allocate a proc_struct// 2. call setup_kstack to allocate a kernel stack for child process // 3. call copy_mm to dup OR share mm according clone_flag // 4. call copy_thread to setup tf & context in proc_struct// 5. insert proc_struct into hash_list && proc_list// 6. call wakup_proc to make the new child process RUNNABLE // 7. set ret vaule using child proc's pidif ((proc = alloc_proc()) == NULL) {goto fork_out;}proc->parent = current;assert(current->wait_state == 0);if (setup_kstack(proc) != 0) {goto bad_fork_cleanup_proc;}if (copy_mm(clone_flags, proc) != 0) {goto bad_fork_cleanup_kstack;}copy_thread(proc, stack, tf);bool intr_flag;local_intr_save(intr_flag);{proc->pid = get_pid();hash_proc(proc);set_links(proc);}local_intr_restore(intr_flag);wakeup_proc(proc);ret = proc->pid;//LAB5 YOUR CODE : (update LAB4 steps)/* Some Functions* set_links: set the relation links of process. ALSO SEE: remove_links: lean the relation links of process* -------------------* update step 1: set child proc's parent to current process, make sure current process's wait_state is 0* update step 5: insert proc_struct into hash_list && proc_list, set the relation links of process*/fork_out:return ret;bad_fork_cleanup_kstack:put_kstack(proc);bad_fork_cleanup_proc:kfree(proc);goto fork_out;}练习1:加载应用程序并执行do_execv函数调用load_icode(位于kern/process/proc.c中)来加载并解析一个处于内存中的ELF执行文件格式的应用程序,建立相应的用户内存空间来放置应用程序的代码段、数据段等,且要设置好proc_struct结构中的成员变量trapframe中的内容,确保在执行此进程后,能够从应用程序设定的起始执行地址开始执行。
计算机操作系统实验指导计算机内核模块

利用内核模块实现/proc文件系统
• proc文件系统是一个伪文件系统,它只存在内存当,而不占用外存空间。它以文件系统地 方式为访问系统内核数据地操作提供接口。用户与应用程序可以通过proc得到系统地信 息,并可以改变内核地某些参数。由于系统地信息,如程,是动态改变地,所以用户或应用 程序读取proc文件时,proc文件系统是动态从系统内核读出所需信息并提地 。
所做地操作,因此可以安全地卸载模块。 • 这两个函数分别在insmod与rmmod地时候调用,并且insmod与rmmod只识别这两个特殊地函数。 • 从内核二.三.一三开始,用户可以自己定义任何名称作为模块地开始与结束地函数。但是,许多仍
然使用init_module()与cleanup_module()作为模块开始与结束函数。 • 在内核模块使用时,将会用到Linux为此开发地内核模块操作命令: • lsmod 列出当前已加载地模块 • insmod 用于加载模块
尝试修改jiffies文件时,系统将警告jiffies为只读文件
利用内核模块实现/proc文件系统
具体实验步骤: 一. 编写procfs_example.c文件,示例代码请参考实验指导书。代码实现了在/proc目录下创建子目 录/procfs_example,并在该目录下创建四个不同类型地文件 。 在初始化函数 static int __init init_procfs_example(void) 通过proc_mkdir创建目录/procfs_example 通过proc_create 创建jiffies,内容为系统启动后经过地时间戳 通过proc_create 创建foo,并写入name与value都为"foo"地内容 通过proc_create 创建bar,并写入name与value都为"bar"地内容 通过proc_symlink创建jiffies_too,该文件是jiffies地符号链接 在清理函数static void __exit cleanup_procfs_example(void) 通过remove_proc_entry 删除目录与文件
实验报告1

实验:内核模块设计1、实验要求1.1 问题描述设计一个带参数的内核模块,其参数为某进程号,列出其进程家族信息,包括父进程,兄弟进程以及子进程的程序名,PID号等。
1.2问题分析Linux内核是模块化组成的,它允许内核在运行时动态地向其中插入或都从中删除代码。
这些代码包括相关的子例程、数据、函数入口和函数出口被组合在一个单独的二进制镜像中,即是所谓的可以装载内核模块。
支持模块的好处是基本内核镜像可以尽可能的小,因为可选的功能和驱动程序可以利用模块形式再提供。
模块允许方便的和重新载入内核代码,也方便了调试工作。
而且当热拔插新设备时,可以载入新的驱动程序。
Linux提供了这样一个简单的框架,它可以允许驱动程序声明参数,从而可以在系统启动或者模块装载时再指定参数,这些参数对于驱动程序属于全局变量,而且模块参数同时也将出现在sysfs文件系统中,这样,无论是生成模块参数还是管理模块参数的方式都变得灵活多样。
内核把进程放在一个叫task list的双向循环链表中。
链表中的每一项都是task_struct称为进程描述符的结构。
该结构定义在/include/linux/sched.h。
进程描述符中包含一个具体进程的所有的信息。
其中包括有进程号pid、指向父进程task_struct的指针parent、包含有所有子进程的链表结构children和包含父进程其它儿子进程的链表结构sibling。
并且comm表示可以进行执行的文件的名字。
1.3 开发平台及实验工具平台环境:VMware 7.1.3 build-324285操作系统:CRUX 2.2Linux内核版本:2.6.15.6其它工具:KGDB2.4、Samba 3.0.24、Source Insight2、实验步骤(1),在/home/目录下编写内核模块程序。
代码include如下头文件(2),定义静态全局变量PID 用于接收模块初始化时传递过来的参数(3),通过module_param(name,type,perm)宏来定义模块参数PID是用户可见的参数名也是模块中存放模块参数的变量名,int是存放参数的类型。
实验2.3_内核模块_实验报告

<内核模块>实验报告题目: 内核模块实验1、实验目的模块是Linux系统的一种特有机制,可用以动态扩展操作系统内核功能。
编写实现某些特定功能的模块,将其作为内核的一部分在管态下运行。
本实验通过内核模块编程在/porc文件系统中实现系统时钟的读操作接口。
2、实验内容设计并构建一个在/proc文件系统中的内核模块clock,支持read()操作,read()返回值为一字符串,其中包块一个空格分开的两个子串,分别代表_sec和_usec。
3、实验原理Linux模块是一些可以作为独立程序来编译的函数和数据类型的集合。
在装载这些模块时,将它的代码链接到内核中。
Linux模块可以在内核启动时装载,也可以在内核运行的过程中装载。
如果在模块装载之前就调用了动态模块的一个函数,那么这次调用将会失败。
如果这个模块已被加载,那么内核就可以使用系统调用,并将其传递到模块中的相应函数。
4、实验步骤编写内核模块文件中主要包含init_module(),cleanup_module(),proc_read_clock()三个函数。
其中init_module(),cleanup_module()负责将模块从系统中加载或卸载,以及增加或删除模块在/proc中的入口。
read_func()负责产生/proc/clock被读时的动作。
内核编译部分过程:过程持续较长时间.●编译内核模块Makefile文件MakefileCC=gccMODCFLAGS := -Wall -D__KERNEL__ -DMODULE –DLINUXclock.o :clock.c /usr/include/linux//version.h$(CC) $(MODCFLAGS) –c clock.cecho insmod clock.o to turn it onecho rmmod clock to turn ig offecho编译完成之后生成clock.o模块文件。
基于Linux内核编程的实验报告(Linux内核分析实验报告)

基于Linux内核编程的实验报告(Linux内核分析实验报告)以下是为大家整理的基于Linux内核编程的实验报告(Linux内核分析实验报告)的相关范文,本文关键词为基于,Linux,内核,编程,实验,报告,分析,,您可以从右上方搜索框检索更多相关文章,如果您觉得有用,请继续关注我们并推荐给您的好友,您可以在教育文库中查看更多范文。
Linux内核分析实验报告实验题目:文件系统实验实验目的:linux文件系统使用虚拟文件系统VFs作为内核文件子系统。
可以安装多种不同形式的文件系统在其中共存并协同工作。
VFs对用户提供了统一的文件访问接口。
本实验的要求是(1)编写一个get_FAT_boot函数,通过系统调用或动态模块调用它可以提取和显示出FAT文件系统盘的引导扇区信息。
这些信息的格式定义在内核文件的fat_boot_sector结构体中。
函数可通过系统调用或动态模块调用。
(2)编写一个get_FAT_dir函数,通过系统调用或动态模块调用它可以返回FAT文件系统的当前目录表,从中找出和统计空闲的目录项(文件名以0x00打头的为从未使用过目录项,以0xe5打头的为已删除的目录项),将这些空闲的目录项集中调整到目录表的前部。
这些信息的格式定义在内核文件的msdos_dir_entry结构体中。
硬件环境:内存1g以上软件环境:Linux(ubuntu)2-6实验步骤:一:实验原理:以实验4为蓝本,在优盘中编译并加载模块,启动测试程序,查/proc/mydir/myfile的文件内容。
从优盘得到fat文件系统的内容存在msdos_sb_info结构中,然后得到msdos_sb_info结构相应的属性值,得到实验一的数据。
实验二中,得到fat文件系统第一个扇区的十六个文件信息。
然后按照文件名头文字的比较方法,应用归并排序的方法,将头文件是0x00和0xe5的文件调到前面,其他的文件调到后面二:主要数据结构说明:(1)超级块对象:数据结构说明:一个已经安装的文件系统的安装点由超级块对象代表。
内核模块实验报告

内核模块实验报告
一、实验要求:
1.了解内核存储路径。
2.阐述内核含义。
3.掌握模块加载及卸载方法。
4.掌握IP转发技巧。
5.掌握禁止ping的使用。
二、实验过程:
1.内核存储路径:
2.内核相当于硬件中的CPU,他是操作系统的核心部分,主要用
分配内存和帮忙传递软件和硬件之间的信息,充当资源管理器和解
释器的角色。
3.模块加载及卸载:
4.配置IP转发的相关配置文件(IP转发的好处:帮助不同网段的IP 互相通信):
5.禁止别的计算机ping这台计算机(禁止ping的好处:给外人造成此计算机关闭或不存在的误区,避免有不良企图的恶意攻击):
实验报告完成。
内核实验报告

实验二1、实验目的1.1题目大意修改system_call()内核函数,使内核能够记录每个系统调用被使用的次数。
增加2个系统调用,一个的功能是将这些系统调用的调用次数清零,另一个的功能是返回特定系统调用的调用次数。
1.2实验原理在Linux中,每一个系统调用被赋予一个系统调用号。
内核记录了系统调用表中的所有已经注册过的系统调用的列表,存储在sys_call_table中。
它与体系结构有关。
在用户空间的程序无法直接执行内核代码,所以应用程序以某种形式通知系统。
通知内核的机制是靠软中断的形式实现的,通过引发一个异常来促使系统切换到内核态中去执行异常处理程序。
此时的异常处理程序实际上就是系统调用处理程序。
X86系统中的软中断由int $0x80指令产生。
这条指令会触发一个异常导致系统切换到内核态并执行第128号异常处理程序,而该程序正是系统调用处理程序,叫system_call。
它跟体系结构有关,通常用汇编语言在entry.S编写。
在X86上,系统调用号是通过eax寄存器传递给内核的。
在陷入内核前,用户空间就把相应系统调用所对应的号放入eax,这样系统调用处理程序system_call一旦运行,就可以从eax 中得到数据。
system_call函数通过将给定的系统调用号与NR_sys_calls——系统中总共有的系统调用的数目做比较,检查其有效性。
如果它大于或者等于NR_sys_calls,该函数会返回-ENOSYS。
否则,就执行相应的系统调用。
由于系统调用表的项是以32位(4字节)类型来存放的,所以内核需要将给业的系统调用号乘以4,然后用所得的结果在该表中查询其位置。
我们要统计的是所有系统调用(339个)自系统启动以来每个被调用的次数,所以只需要要构造一个数组来记录每个系统调用的被调用次数。
考虑到要让该数组元素每次开机启动时都要初始化为0,我们可以将该数组设置为全局的。
每次进入system_call函数都对这个全局数组对应的系统调用号的下标的计数加1.就可以统计系统调用被使用的次数。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
实验五内核模块设计实验文章由网提供现代的Linux内核是具有微内核特点的宏内核。
Linux内核作为一个大程序在内核空间运行。
太多的设备驱动和内核功能集成在内核中,内核过于庞大。
Linux内核引入内核模块机制。
通过动态加载内核模块,使得在运行过程中扩展内核的功能。
不需要的时候,卸载该内核模块。
内核模块内核模块是一种没有经过链接,不能独立运行的目标文件,是在内核空间中运行的程序。
经过链接装载到内核里面成为内核的一部分,可以访问内核的公用符号(函数和变量)。
内核模块可以让操作系统内核在需要时载入和执行,在不需要时由操作系统卸载。
它们扩展了操作系统内核的功能却不需要重新启动系统。
如果没有内核模块,我们不得不一次又一次重新编译生成单内核操作系统的内核镜像来加入新的功能。
这还意味着一个臃肿的内核。
内核模块是如何被调入内核工作的?当操作系统内核需要的扩展功能不存在时,内核模块管理守护进程kmod执行modprobe去加载内核模块。
modprobe遍历文件/lib/modules/version/modules.dep 来判断是否有其它内核模块需要在该模块加载前被加载。
最后modprobe调用insmod先加载被依赖的模块,然后加载该被内核要求的模块。
内核模块是如何被调入内核工作的?Insmod将调用init_module系统调用,传入参数(Module.c)Sys_init_module系统调用检查权限后,并查找modules链表,验证模块未被链接。
然后分配一个module结构体变量描述该内核模块。
如果定义了模块的init方法,则执行init方法。
模块机制的特点:减小内核映像尺寸,增加系统灵活性;节省开发时间;修改内核,不必重新编译整个内核。
模块的目标代码一旦被链入内核,作用和静态链接的内核目标代码完全等价。
最简单的内核模块任一个内核模块需要包含linux/module.h初始化函数init_module(),在模块加载到内核时被调用。
init_module()向内核注册模块的功能,申请需要的资料等初始化工作。
卸载函数cleanup_module() ,在内核模块被卸载时被调用,干一些收尾清理的工作,撤消任何初始化函数init_module()做的事,保证内核模块可以被安全的卸载。
printk( )函数printk 函数在Linux 内核中定义并且对模块可用,为内核提供日志功能,记录内核信息或用来给出警告。
与标准 C 库函数printf 的行为相似。
每个printk() 声明都会带一个优先级。
内核总共定义了八个优先级的宏,在linux/kernel.h中定义。
若你不指明优先级,DEFAULT_MESSAGE_LOGLEVEL 这个默认优先级将被采用。
信息存在在内核消息缓冲区中,并被定时的添加到文件/var/log/messages,可直接查看,或者用命令dmesg查看。
在X-windows下的终端insmod一个模块,日志信息只会记录在日志文件中,而不在终端打印。
从内核Linux 2.4之后,可以为模块的“初始化”和“卸载”函数起任意的名字。
不再必须使用init_module()和cleanup_module()的名字。
通过宏module_init()和module_exit()实现。
这些宏在linux/init.h中定义。
module_init(hello_2_init);module_exit(hello_2_exit);函数必须在宏的使用前定义,否则编译会报错。
关于__init和__exit宏如果该模块被编译进内核,而不是动态加载,则宏__init的使用会在初始化完成后丢弃该函数并收回所占内存。
如果该模块被编译进内核,宏__exit将忽略“清理收尾”的函数。
这些宏在头文件linux/init.h定义,用来释放内核占用的内存。
例如启动时看到的信息“Freeing unused kernel memory: 236k freed”,正是内核释放这些函数所占用空间时的打印信息。
内核模块证书和内核模块文档说明2.4内核后,引入识别代码是否在GPL许可下发布的机制。
在使用非公开的源代码产品时会得到警告。
通过宏MODULE_LICENSE(“GPL”),设置模块遵守GPL证书,取消警告信息。
宏MODULE_DESCRIPTION()用来描述模块的用途。
宏MODULE_AUTHOR()用来声明模块的作者。
宏MODULE_SUPPORTED_DEVICE() 声明模块支持的设备。
这些宏都在头文件linux/module.h定义。
使用这些宏只是用来提供识别信息。
准备工作顺利编译并且加载第一个“hello world”模块有时会比较困难。
保证系统具备正确的编译器、模块工具、以及其他必要工具。
内核目录Documentation/Changes 列出了需要的工具版本。
用错误的工具版本建立一个内核(包括模块),可能导致一些奇怪复杂的问题。
通常芯片公司的SDK包会告诉你使用什么版本的交叉工具链去完成,并提供相应的工具链。
准备好系统平台所对应的内核源代码配置并构建好平台对应的2.6内核源代码。
2.6 内核使用kbuild构建系统配置编译,kbuild构建系统可用于编译自定义的内核模块。
编译过程首先会到内核源码目录下,读取顶层的Makefile文件,然后再编译模块源码,连接生成的内核模块后缀为.ko在内核源代码目录下:make menuconfig,使得配置跟目标平台一致make编写内核模块的makefile内核Makefile提供的obj-m表示对象文件(object files)编译成可加载的内核模块Hello-1.c的Makefile文件obj-m += hello-1.o表明有一个模块要从目标文件hello-1.o 建立,kbuild从该目标文件建立内核模块hello-1.ko。
编译内核模块的命令make -C 内核源代码路径M=模块所在路径modulesmake -C /lib/modules/`uname -r`/build M=$PWD modules改变目录到用-C 选项提供的内核源码目录,make读取内核的makefile,并编译M所指定路径下的内核模块源代码。
内核模块的加载2.6内核模块使用.ko的文件后缀(代替.o后缀)。
使用insmod ./hello-1.ko命令加载该模块。
/proc/modules记录被加载的内核模块。
使用lsmod命令查看已经加载的模块使用命令rmmod hello-1 卸载模块tail /var/log/messages编写hello模块,包含初始化init_module和卸载函数cleanup_module编写makefile文件Obj-m += hello-1.o编译hello内核模块make -C /lib/modules/`uname -r`/build M=$PWD modulesUname –r 给出当前系统内核的版本,使用短撇号,将其输出结果作为参数的一部分。
而build是符号链接,指向对应内核的源代码目录。
加载hello内核模块:insmod hello-1.ko查看加载信息:tail /var/log/message卸载hello内核模块rmmod hello-1使用modprobe命令修改/lib/module /`uname -r`/modules.dep文件,添加hello-1.ko内核模块路径和依赖关系加载hello内核模块: Modprobe hello-1卸载hello内核模块Modprobe –r hello-1⏹修改hello内核模块的makefile⏹添加all目标⏹添加clean目标obj-m += hello-1.oKERN_VER = $(shell uname -r)KERN_DIR = /lib/modules/$(KERN_VER)/buildall:$(MAKE) -C $(KERN_DIR) M=$(PWD) modulesclean:rm -rf *.orm -rf *.mod.*rm -rf *.korm –rf .tmp_version⏹直接通过make,编译内核模块⏹多个文件构成的内核模块⏹Makefile会帮我们完成编译和连接的工作。
⏹例如内核模块分两个文件start.c stop.c,则Makefile这样写:obj-m += test.otest-objs := start.o stop.o跟单个文件模块的编译方式一样,内核编译系统会将所有的目标文件连接为一个文件。
⏹内核模块的Makefile模块mymodule-objs = file1.o file2.oobj-m += mymodule.oPWD = $(shell pwd)KDIR = 内核源代码路径all:$(MAKE) -C $(KDIR) M=$(PWD) modulesclean:rm -rf .*.cmd *.o *.mod.c *.ko .tmp_versionslsmod 列出已经挂载的内核模块lsmod 是列出目前系统中已加载的模块的名称及大小等效果跟通过less /proc/modules查看模块一样。
modinfo 查看模块信息modinfo 可以查看模块的信息,通过查看模块信息来判定这个模块的用途。
modinfo 模块名modprobe 挂载新模块以及新模块相依赖的模块modprobe 模块名,在挂载该内核模块的同时,这个模块所依赖的模块也被同时挂载。
modprobe还有其他用法,问他的“man”。
例如:modprobe -l 是列出内核中所有的模块,包括已挂载和未挂载的,读取的模块列表就位于/lib/modules/‘uname -r’目录中。
rmmod 移除已挂载模块用法:rmmod 模块名(不带后缀)等同于:modprobe -r 模块名insmod 挂载模块insmod 需要给出模块所在目录的绝对路径,以及要带有模块文件名后缀(.o 或.ko)insmod /lib/modules/2.6.18/kernel/fs/vfat/vfat.ko功能上没有modprobe 强。
depmod 创建模块依赖关系的列表目前的的Linux 发行版所用的内核是2.6x版本,是自动解决依赖关系。
depmod -a为所有列在/etc/modprobe.conf 或/etc/modules.conf 中的所有模块创建依赖关系,并且写入到modules.dep文件depmod –e 列出已挂载但不可用的模块为2410开发板配置编译Linux内核内核版本:linux-2.6.24交叉工具链:cross-3.4.4.tar.gz选择相应的配置时,有三种选择,它们分别代表的含义如下:Y--将该功能编译进内核N--不将该功能编译进内核M--将该功能编译成模块,可以在需要时动态插入到内核中make xconfig,使用鼠标就可以选择对应的选项。