内核模块设计

一、关于内核模块
  如果将所有的组件全部编入内核映像太浪费内存空间。比方说USB驱动,我只需要它运行1分钟,那么在剩余内核运行的59分钟都没有使用到它,但是他却一直占用着系统资源,显然这很不科学,所以就有了今天的题目——内核模块设计。
  内核模块特点:
    1、不被编译进内核文件
    2、在内核运行期间可动态的运行或卸载。
    3、命令:insmod安装、lsmod查看已安装模块、rmmod卸载内核模块。
    例:内核模块:helloworld.ko,安装:insmod helloworld.ko、卸载:rmmod helloworld(注意卸载时不加.ko)
二、Linux内核模块设计
  1、内核模块的编写
  首先看一段内核模块范例代码  

#include <linux/init.h>
#include <linux/module.h>

static int hello_init()
{
    printk("Helloworld\n");
    return 0;
}

static void hello_exit()
{
    printk("Good Bye\n");
}

module_init(hello_init);
module_exit(hello_exit);

  可以看到这段c程序没有main函数。main函数对一段应用程序来说是一个入口,那么没有main函数就没有入口了吗?显然不是。内核模块有三个要素, 头文件、module_init、module_exit。头文件很简单不用说,module_init就是这段程序的入口。当insmod这个内核模块 时,系统就会调用module_init宏指明的函数,也就是这里的hello_init函数。同样,module_exit就是这段程序的出口,当 rmmod这个模块的时候,系统就会调用module_exit宏指明的函数,也就是这里的hello_exit函数。有了这三要素,内核模块就算是编写 好了。
        这里打印信息用到了printk函数,注意在内核中打印信息使用printk而不是printf,其中KERN_WARNING是内核打印的优先级,内核打印函数共有8个优先级,具体如下:

   

  图片来自网络。

  关于printk函数

  

  2、内核模块的编译
    内核模块的编译通过编写makefile来完成,其格式比较固定。

obj-m :=hello.o

KDIR := /home/bumblebee/exercise/arm4/lesson3/linux-mini2440

all:
    make -C $(KDIR) M=$(PWD) modules CROSS_COMPILE=arm-linux- ARCH=arm

clean:
    rm -f *.o *.ko *.order *.symvers

    (1)、当内核模块只需要一个c文件生成时采用如图第一行所示的编写方式,若由多个c文件生成则采用以下方式。
helloworld-objs    :=file1.o    file2.o    file3.o
    (2)、KDIR用来保存内核代码的路径,由于内核模块的编译是依赖于内核的信息的,所以需要将内核代码的路径用这个变量保存。
    (3)、-C指明要进入-C后面的路径(内核路径)编译模块,M指明了模块文件的路径。
    (4)、最后编写clean伪指令,清除产生的中间文件和.ko文件。
    (5)、rmmod的时候要在/lib/modules目录下面有和内核模块的内核版本一致的目录名经常用(uname  -r)来获取内核版本。
            命令:mkdir  -p  /lib/modules/$(uname  -r)。

时间: 2024-11-03 13:46:01

内核模块设计的相关文章

Linux内核模块设计

内核的设计有两种方式:单内核和微内核,两者各有优劣,关于两者的比较可以参见wiki.windowds和Solaris采用微内核结构. Linux内核采用单内核结构,设计比较简单,但单内核的理念是把所有的功能集成到一块儿,所以必然会导致内核的体积变大,然而事实是Linux内核体积并不大.因为Linux在设计的时候借鉴了微内核的设计思想,将内核模块化,用到的功能模块在使用的时候再加载.然而这又导致了一个问题,万一内核中没有对应硬盘的驱动模块,那么内核将无法在硬盘上展开,为了解决这个问题设计了一个过度

Linux 内核模块设计

一.  内核模块 1.  头文件 Linux/init.h  和 Linux/module.h 2.  装载内核 insmod  对应的转载函数 module_init(); 3.  卸载内核 rmmod  对应的卸载函数 module_exit(); 二.  编写 helloworld.c 三.编写Makefile 四 .  把 helloworld.ko 移到Part3/rootfs 打开开发板下载. 直接运行Uboot insmod 挂载一下 helloworld.ko lsmod   查

专题5-内核模块开发2内核模块设计与编写

1.范例 touch helloworld.c chmod 777 -R helloworld.c #include<linux/init.h> #include<linux/module.h> static int hello_init(void) { printk(KERN_WARNING"hello,world!\n"); return 0; } static void hello_exit(void) { printk(KERN_INFO"Go

Linux内核驱动学习(三)----内核模块基础 | 设计 | 可选项

内核模块基础--特点及其命令使用 1.模块本身并不被编译进内核文件(zImage或bzImage) 2.可以根据需要在内核运行时动态加载.卸载---->进而达到节省空间的目的 命令详解(以下载驱动DNW为例): insmod 模块名称(注意有.ko后缀)--安装 insmod dnw_usb.ko lsmod-->查看安装的内核模块 rmmod 模块名称(注意没有.ko后缀)---->卸载内核模块 rmmod dnw_usb 内核模块设计--简单的模块编写 根据上图范例代码,比较应用程序

Linux --KVM技术介绍

Linux操作系统和内核 操作系统内核设计一直分为两个阵营:微内核和单内核. 单内核是两大阵营中一种较为简单的设计,指的是整个内核从整体上作为一个单独的大过程来实现,并且同时运行在一个单独的地址空间内.所有的内核服务都在这样一个大的内核空间运行,内核之间的通信可以简单地实现为函数调用.这样的设计具有简单高效的特点.但是,如果使用单内核设计,每次对内核作出修改(比如增加或者删除驱动程序),都必须重新编译源代码,生成新的二进制文件,造成了使用和部署上的麻烦. 微内核并不是作为一个单独的大过程来实现的

《linux内核设计与分析》内核模块编程

内核模块编程 一.准备工作 虚拟机:VMware Workstation 12操作系统:ubuntu当前内核版本:linux-headers-4.4.0-22-generic 二.有关于内核模块的知识 模块是具有独立功能的程序,它可以被单独编译,但不能独立运行.它在运行时被链接到内核作为内核的一部分在内核空间运行,这与运行在用户空间的进程是不同的.模块通常由一组函数和数据结构组成,用来实现一种文件系统.一个驱动程序或其他内核上层的功能. 内核模块的相关指令: 查看内核版本 uname –a 模块

内核模块参数设计

1.模块传递参数的概念 对于如何向模块传递参数,Linux kernel提供了一个简单的框架.其允许驱动程序声明参数,并且用户在系统启动或模块装载时为参数指定相应值,在驱动程序里,参数的用法如同全局变量. 2.代码如下 使用如下命令: insmod param.ko int_var=1 str_var=hi,param int_array=128.256.512 输出如下: 关于函数module_param(name,type,perm)的第三个参数perm表示sysfs中建立的对应文件的权限,

linux及安全《Linux内核设计与实现》第一章——20135227黄晓妍

<linux内核设计与实现>第一章 第一章Linux内核简介: 1.3操作系统和内核简介 操作系统:系统包含了操作系统和所有运行在它之上的应用程序.操作系统是指整个在系统中负责完成最基本功能和系统管理的那些部分.这些部分包括内核.设备驱动程序.启动应到程序.命令行shell或者其他种类的用户界面.基本的文件管理系统工具. 内核:如果说用户界面是操作系统的外在表像,那么内核就是操作系统的内在核心. 内核空间:系统态和保护起来的内存空间. 内核的组成: 1.中断服务程序(响应中断) 2.调度程序(

Linux内核模块编写详解

内核编程常常看起来像是黑魔法,而在亚瑟 C 克拉克的眼中,它八成就是了.Linux内核和它的用户空间是大不相同的:抛开漫不经心,你必须小心翼翼,因为你编程中的一个bug就会影响到整个系统,本文给大家介绍linux内核模块编写,需要的朋友可以参考下 内核编程常常看起来像是黑魔法,而在亚瑟 C 克拉克的眼中,它八成就是了.Linux内核和它的用户空间是大不相同的:抛开漫不经心,你必须小心翼翼,因为你编程中的一个bug就会影响到整个系统.浮点运算做起来可不容易,堆栈固定而狭小,而你写的代码总是异步的,