Kernel 模块与简单 hello 模块

kernel 模块的简介

Linux 内核进行扩展时,例如编写驱动程序、netfilter功能等,最方便的方式是通过编写模块,然后加载到内核中。由于 kernel 模块已加载到内核,因此如果模块出现错误,将导致内核出错甚至系统崩溃。所以,一般建议在测试内核模块时,如果与设备无关的模块(非驱动程序等),最好是在虚拟机中进行。

大多数 Linux 发行版本都没有把 Linux 编译成一个整个文件,而是把非核心的子系统,如驱动程序等,编译成 kernel 模块,并在启动时加载。模块的目录一般是 /lib/modules/<内核版本>/ 目录下。内核版本号通过 $(uname -r) 获取。

加载内核模块时,可通过 modprobe (从默认路径搜索并加载) 或 insmod (指定模块路径)

# 加载 intel wifi 驱动
sudo modprobe iwlwifi
# 或
sudo insmod "/lib/modules/$(uname -r)/kernel/drivers/net/wireless/iwlwifi/iwlwifi.ko"

用 lsmod 命令查看已加载的模块

lsmod

而从内核中把模块删除则通过 rmmod 命令

sudo rmmod iwlwifi

编写 hello 示例模块

内核模块也是通过 C 编写和编译的本机代码,只是由于它需要被 Linux 模块加载框架来载入,因此需要特殊的模块注册处理才能生效。内核模块能直接访问内核的功能,比一般的 C 编程要更加小心,预防出现 BUG 和安全问题。

编写内核模块时,使用的头文件为 /lib/modules/$(uname -r)/build/include (通常 Linux 头文件在安装 kernel-image 同时安装,在一些发行版上 build 链接到 /usr/src/linux-headers-$(uname-r)/)。

先看看一个简单的 hello 模块

/*
* hello.c
* 简单的 hello 内核模块
*/ #include <linux/module.h> /* 所有模块使用 module.h */
#include <linux/kernel.h> /* 包含内核常用的函数声明等 */
#include <linux/init.h> /* 进行内存初始化和清理 */ MODULE_AUTHOR("fengyc");
MODULE_DESCRIPTION("This is a demo.");
MODULE_VERSION("0.0.1");
MODULE_LICENSE("GPL"); static int __init hello_init(void)
{
printk(KERN_INFO "Hello, world!\n");
return 0;
} static void __exit hello_exit(void)
{
printk(KERN_INFO "Goodbye, world!\n");
} module_init(hello_init);
module_exit(hello_exit);

所有的模块都需要到 module.h 头文件,使用 module_init() module_exit() 函数来注册模块入口和退出处理。这里的代码逻辑很简单,就是在模块加载时,打印 Hello, world! ,以及在退出时打印 Goodbye, world! (由于代码运行在内核空间里面,不能直接使用用户空间的 print 函数,而要使用内核中的 printk 函数)

编译时通过一个 Makefile 文件进行,把这个 Makefile 文件置于 hello.c 同一目录下(Makefile 中使用 tab 作为分隔符

obj-m += hello.o

all:
make -C "/lib/modules/$(shell uname -r)/build" M=$(PWD) modules clean:
make -C "/lib/modules/$(shell uname -r)/build" M=$(PWD) clean

现在,通过 make 即可生成模块 hello.ko。现在可通过 modinfo 命令查看模块信息

modinfo hello.ko

然后通过 insmod / rmmod 命令加载、卸载模块,并用 dmesg 查看内核的环形缓存区( kernel ring buffer )的信息( printk 输出到了这里)

sudo insmod hello.ko
sudo rmmod hello
dmesg

如果一切顺利,就可以看到 hello.ko 模块的输出。而有个这个基本的代码框架,就可以继续深入,使用 netlink 作为接口,进行用户空间与内核空间的通信,并调用内核的功能,实现在用户态无法完成的动作。

p.s. 为了更好地使用 GUI 的协助,可使用参考使用 eclipse 内核开发环境 http://blog.chinaunix.net/uid-24512513-id-3183457.html

kernel 模块与简单 hello 模块的更多相关文章

  1. kernel 4.4.12 外部模块Makefile 脚本编写

    kernel 4.4.12 最简单module的编译 上一篇博客上面有一个最简单的模块源代码,今天就上一个Makefile,运行make 就可以编译一个外部的模块. vim Makefile 这个是我 ...

  2. 【模块化编程】理解requireJS-实现一个简单的模块加载器

    在前文中我们不止一次强调过模块化编程的重要性,以及其可以解决的问题: ① 解决单文件变量命名冲突问题 ② 解决前端多人协作问题 ③ 解决文件依赖问题 ④ 按需加载(这个说法其实很假了) ⑤ ..... ...

  3. Python函数篇(6)-常用模块及简单的案列

    1.模块   函数的优点之一,就是可以使用函数将代码块与主程序分离,通过给函数指定一个描述性的名称,并将函数存储在被称为模块的独立文件中,再将模块导入主程序中,通过import语句允许在当前运行的程序 ...

  4. Python-常用模块及简单的案列

    1.模块   函数的优点之一,就是可以使用函数将代码块与主程序分离,通过给函数指定一个描述性的名称,并将函数存储在被称为模块的独立文件中,再将模块导入主程序中,通过import语句允许在当前运行的程序 ...

  5. Python_selenium中类函数模块的简单介绍

    Python_selenium中类函数模块的简单介绍 一.demo1.py的代码如下所示 #coding:utf-8 class ClassA(object): string = "这是一个 ...

  6. 关于其它模块的设计,有非常多须要自己去构建和完毕,在这里就简单地举几个样例来看看其它模块的设计。我们要做的就是有更改password模块,客户选择模块和关于本软件模块。更改password模块用来更改管理员的password,客户选择对话框模块用来选择已加入的客户,关于本软件模块用来说明客户管理系统的一些必要信息和制作人的信息。

            五,其它模块设计         关于其它模块的设计,有非常多须要自己去构建和完毕,在这里就简单地举几个样例来看看其它模块的设计. 我们要做的就是有更改password模块.客户选择模 ...

  7. node.js当中的http模块与url模块的简单介绍

    一.http模块的简单介绍 node.js当中的http内置模块可以用于创建http服务器与http客户端. 1.引包 const http = require('http'); 2.创建http服务 ...

  8. python制作简单excel统计报表2之操作excel的模块openpyxl简单用法

    python制作简单excel统计报表2之操作excel的模块openpyxl简单用法 # coding=utf-8 from openpyxl import Workbook, load_workb ...

  9. 进程、requests模块的简单使用

    一.进程 1.进程间数据不共享 import multiprocessing data_list = [] def task(arg): data_list.append(arg) print(dat ...

随机推荐

  1. Html - Bootstrap Panel面板

    http://v3.bootcss.com/components/#panels Bootstrap Panel面板 <div class="panel panel-default&q ...

  2. php 的curl 模拟登陆

    做一个类似这样的web 应用. 1,解决掉验证码 其实这是正方的一个小bug,当我们进入登陆界面时,浏览器会去请求服务器,服务器会生成一个验证码图片.如果我们不去请求这个图片,那么正方后台也不会生成相 ...

  3. 《Lucene实战(第2版)》 配书代码在IDEA下的编译方法

    参考: hankcs http://www.hankcs.com/program/java/lucene-combat-2nd-edition-book-with-code-compiled-unde ...

  4. NBUT 1457 Sona(莫队算法+离散化)

    [1457] Sona 时间限制: 5000 ms 内存限制: 65535 K 问题描述 Sona, Maven of the Strings. Of cause, she can play the ...

  5. php运行模式的比较(转)

    PHP运行模式有4钟:1)cgi 通用网关接口(Common Gateway Interface))2) fast-cgi 常驻 (long-live) 型的 CGI3) cli  命令行运行   ( ...

  6. mongodb 3.2 分片部署步骤

    #linux 网络优化1. 文件中/etc/sysctl.conf, 加入net.core.somaxconn = 2048fs.file-max = 2000000fs.nr_open = 2000 ...

  7. Magento架构分析,Magento MVC 设计分析

    Magento架构分析,Magento MVC 设计分析 分类:Magento 标签:Magento MVC.Magento架构 669人浏览 Magento 采用类似 JAVA的架构,其扩展与稳定性 ...

  8. 树莓派系统安装、HDMI显示

    树莓派上可以安装多种操作系统,我们采用的是官方的基于debian的raspbian.系统安装方式见 安装完系统由于我使用的是7寸的HDMI屏,装完系统如果配置不该的话会导致右边有一部分无法显示,所以在 ...

  9. jsonObject jsonarray

    1.JAR包简介 要使程序可以运行必须引入JSON-lib包,JSON-lib包同时依赖于以下的JAR包: commons-lang.jar commons-beanutils.jar commons ...

  10. extjs4 树列表 添加子节点 刷新所有父节点数据

    itemclick:function(view, record, item,index){console.log(record.parentNode) for(pNode = record.paren ...