`
runfeel
  • 浏览: 902800 次
文章分类
社区版块
存档分类
最新评论

设备驱动----1.Linux内核模块-helloworld

 
阅读更多

1.Linux内核模块-helloworld

Linux设备驱动属于内核的一部分,Linux内核的一个模块可以以两种方式被编译和加载:

(1)直接编译进Linux内核,随同Linux启动时加载;

(2)编译成一个可加载和删除的模块,使用insmod加载(modprobe和insmod命令类似,但依赖于相关的配置文件),rmmod删除。这种方式控制了内核的大小,

而模块一旦被插入内核,它就和内核其他部分一样。

下面我们给出一个内核模块的例子:

#include <linux/module.h> //所有模块都需要的头文件
#include <linux/init.h>  // init&exit相关宏

MODULE_LICENSE("GPL");

static int __init hello_init(void)
{
   printk(KERN_ERR "#### hello world\n");
   return 0;
}

static void __exit hello_exit(void)
{
   printk(KERN_ERR "#### exit\n");
}

module_init(hello_init);
module_exit(hello_exit);

分析上述程序,发现一个Linux内核模块需包含模块初始化和模块卸载函数,前者在insmod的时候运行,后者在rmmod的时候运行。

初始化与卸载函数必须在宏module_init和module_exit使用前定义,否则会出现编译错误。

程序中的MODULE_LICENSE("GPL")用于声明模块的许可证。



Makefile写法:

obj-m := hello.o
hello-objs := helloworld.o

KID := /lib/modules/`uname -r`/build
PWD := $(shell pwd)

all:
	make -C $(KID) M=${PWD} modules

clean:
	rm -rf *.o .cmd *.ko *.mod.c .tmp_versions  

下列命令将可加载hello模块:

先打开kmsg

snail@ubuntu:~$ sudo cat /dev/kmsg

然后加载hello.ko
sudo insmod ./hello.ko

下列命令完成相反过程:
sudo rmmod hello




如果要将其直接编译入Linux内核,则需要将源代码文件拷贝入Linux内核源代码的相应路径里,

并修改Makefile。


我们有必要补充一下Linux内核编程的一些基本知识


内存

在Linux内核模式下,我们不能使用用户态的malloc()和free()函数申请和释放内存。

进行内核编程时,最常用的内存申请和释放函数为在include/linux/kernel.h文件中声明的kmalloc()和kfree(),

其原型为:


void *kmalloc(unsigned int len, int priority);

void kfree(void *__ptr);


kmalloc的priority参数通常设置为GFP_KERNEL,如果在中断服务程序里申请内存则要用GFP_ATOMIC参数,

因为使用GFP_KERNEL参数可能会引起睡眠,不能用于非进程上下文中(在中断中是不允许睡眠的)。

由于内核态和用户态使用不同的内存定义,所以二者之间不能直接访问对方的内存。


而应该使用Linux中的用户和内核态内存交互函数(这些函数在include/asm/uaccess.h中被声明):


unsigned long copy_from_user(void *to, const void *from, unsigned long n);

unsigned long copy_to_user (void * to, void * from, unsigned long len);


copy_from_user、copy_to_user函数返回不能被复制的字节数,因此,如果完全复制成功,返回值为0。

include/asm/uaccess.h中定义的put_user和get_user用于内核空间和用户空间的单值交互(如char、int、long)。


输出
在内核编程中,我们不能使用用户态C库函数中的printf()函数输出信息,而只能使用printk()。

但是,内核中printk()函数的设计目的并不是为了和用户交流,它实际上是内核的一种日志机制,

用来记录下日志信息或者给出警告提示。


每个printk都会有个优先级,内核一共有8个优先级,它们都有对应的宏定义。如果未指定优先级,

内核会选择默认的优先级DEFAULT_MESSAGE_LOGLEVEL。

如果优先级数字比int console_loglevel变量小的话,消息就会打印到控制台上。

如果syslogd和klogd守护进程在运行的话,则不管是否向控制台输出,

消息都会被追加进/var/log/messages文件。klogd 只处理内核消息,

syslogd 处理其他系统消息,比如应用程序。


分享到:
评论

相关推荐

    Linux内核驱动模块编程指南 (内核版本2.2, 2.4)The Linux Kernel Module Programming Guide CHS

    2.5. Hello World (part 4): 内核模块证书和内核模块文档说明 2.6. 从命令行传递参数给内核模块 2.7. 由多个文件构成的内核模块 3. 开始热身 3.1. 内核模块和用户程序的区别 4. 字符设备文件 4.1. 字符设备驱动程序 ...

    linux设备驱动程序第三版

    1. Linux 设备驱动第三版 .................................................................................................................... 5 2. 第 1 章 设备驱动简介 ....................................

    Linux驱动开发之编写第一个内核模块--Hello World源码

    Linux驱动开发之编写第一个内核模块--Hello World源码, 亲测OK,对应文章链接: https://dingdong.blog.csdn.net/article/details/106329048

    Linux内核修炼之道-pdf版

    Linux内核问题门..........................................................................................................................13 缅怀已逝的十八年(1991~1998) ...............................

    linux设备驱动程序中英文加源码

    linux设备驱动程序中英文版加源码 目录 1. 第一章 设备驱动简介 1.1. 驱动程序的角色 1.2. 划分内核 1.2.1. 可加载模块 1.3. 设备和模块的分类 1.4. 安全问题 1.5. 版本编号 1.6. 版权条款 1.7. 加入内核开发社团 ...

    Linux内核修炼之道

    Linux内核修炼之道 任桥伟 blog.csdn.net/fudan_abc ...模块机制与“HELLO WORLD!” ........................................................................................... 35 设备模型(上) .........

    linux设备驱动程序(第三版)CHM和配套源码

    1. 第一章 设备驱动简介 1.1. 驱动程序的角色 1.2. 划分内核 1.2.1. 可加载模块 1.3. 设备和模块的分类 1.4. 安全问题 1.5. 版本编号 1.6. 版权条款 1.7. 加入内核开发社团 1.8. 本书的内容 2. 建立和运行...

    mini2440用户手册

    1.1.3 Linux系统特性...........................................................................................................................- 18 -  1.1.4 WindowsCE 5.0 系统特性........................

    Linux设备驱动程序学习

    ·Linux设备驱动程序学习(0)-Hello, world!模块 ·Linux设备驱动程序学习(2)-调试技术 ·Linux设备驱动程序学习(3)-并发和竞态 ·Linux设备驱动程序学习(4)-高级字符驱动程序操作[(1)ioctl and llseek...

    Linux学习备忘册--II.驱动学习_V1.3.pdf

    1.linux内核代码中直接添加代码点亮一个灯。2.dm9000网卡移植。3.挂接NFS网络文件系统。4.加载和卸载helloworld模块。5.移植编写led驱动模块。6.移植编写lcd驱动模块。上面的学习过程没有阶跃,应该不存在从某一步到...

    Linux实验课设报告

    6、Linux内核模块编程:内核模块编程、卸载模块编程、参数模块编程 8、Linux内存管理:编写模块程序、编译、插入模块、查看打印信息 8、Linux设备驱动:编写一个简单的字符设备驱动、查看设备号、编写测试程序 使用...

    Linux 驱动学习笔记pdf文档

    ·Linux设备驱动程序学习(0)-设备驱动介绍& Hello, world!模块 ·Linux设备驱动程序学习(2)-调试技术 ·Linux设备驱动程序学习(3)-并发和竞态 ·Linux设备驱动程序学习(4)-高级字符驱动程序操作[(1)...

    Magic ARM 2410

    5.1 HelloWorld 程序实验...........................175 5.2 Linux 定时器实验 ................................178 5.3 多进程实验...........................................180 5.4 多线程实验..............

    LINUX设备驱动第三版_588及代码.rar

    Hello World模块 核心模块与应用程序的对比 编译和装载 内核符号表 预备知识 初始化和关闭 模块参数 在用户空间编写驱动程序 快速参考 第三章 字符设备驱动程序 scull的设计 主设备号和次设备号 一些...

    嵌入式设计及linux驱动开发指南——基于ARM9处理器.pdf

    10.5.3 Hello,World 10.5.4 发布Qt/Embedded程序到目标板 10.5.5 添加一个Qt/Embedded应用到QPE 第11章 Java虚拟机的移植 11.1 Java虚拟机概述 11.1.1 Java虚拟机的概念 11.1.2 J2ME 11.1.3 KVM 11.2 Java...

    linux设备驱动程序

    《LINUX设备驱动程序(第3版)》已针对Linux内核的2610版本彻底更新过了。内核的这个版本针对常见任务完成了合理化设计及相应的简化,如即插即用、利用sysfs文件系统和用户空间交互,以及标准总线上的多设备管理等等。...

    linux驱动学习去开发入门

    (13) Linux内核模块的初始化出错处理一般使用“goto”语句。通常情况下很少使用“goto”,但在出错处理是(可能是唯一的情况),它却非常有用。在大二学习C语言时,老师就建议不要使用“goto”,并说很少会用到。...

    [14本经典Android开发教程]-8-Linux内核阅读心得体会

    读核感悟 Linux内核启动 从hello world说起 3 读核感悟 Linux内核启动 BIOS 5 读核感悟 Linux内核启动 setup辅助程序 6 读核感悟 Linux内核启动 内核解压缩 8 读核感悟 Linux内核启动 开启页面映射 9 读核感悟 Linux...

    linux网路编程 中文 23M 版

    1.5.1 Linux内核的主要模块............................................ 7 1.5.2 Linux的文件结构................................................ 9 1.6 G N U 通用公共许可证...................................

Global site tag (gtag.js) - Google Analytics