Linux 第n次驱动入门(一) ---- helloWorld
来源:互联网 发布:水电安装 知乎 编辑:程序博客网 时间:2024/06/08 16:47
Linux驱动 helloWorld
根据下面的helloWorld.c驱动来了解总结内核中的printk,__init,__exit
helloWorld.c
#include <linux/init.h>#include <linux/module.h>static char* name = "the man like wind ";module_param(name, charp, S_IRUGO);static int age = 18;module_param(age, int, 0644);static int __init helloWorld_init(void){ int ret = 0; printk(KERN_INFO "------------------>see you again , world :-)\n"); printk(KERN_INFO "- name : %s\n",name); printk(KERN_INFO "- age : %d\n",age); return ret;}static void __exit helloWorld_exit(void){ printk(KERN_INFO"------------------>bye %s , good world :(\n",name);}int add_integer(int a,int b){ return a+b;}EXPORT_SYMBOL(add_integer);int sub_integer(int a,int b){ return a-b;}EXPORT_SYMBOL(sub_integer);module_init(helloWorld_init);module_exit(helloWorld_exit);MODULE_AUTHOR("Qian <XXXXXXXX@qq.com>");MODULE_LICENSE("GPL v2");MODULE_VERSION("V9.9");MODULE_ALIAS("a simple helloWorld driver");
1.__exit 和 __init
__init,__initdata,__exit,__exitdata的定义全部在<Linux/init.h>,这些宏定义的作用就是告诉编译器把这些函数或者数据放在相应的selection中,其中__init修饰函数。__initdata修饰变量。
静态加载(直接编入内核)
__init函数在区段.initcall.init中还保存了一份函数指针,在初始化时内核会通过这些函数指针调用这些__init函数指针,并在整个初始化完成后,释放整个init区段,当模块直接编进内核时,在linux启动到最后可以看到类似下面的提示,静态加载时__exit将没有作用也不会编入内核,因为内置了就不能卸载
PHY: 0:01 - Link is Up - 100/FullVFS: Mounted root (nfs filesystem) on device 0:14.devtmpfs: mountedFreeing init memory: 196KINIT: version 2.86 booting
动态加载(insmod modprobe)
__init进行初始化工作,在模块装载之后,模块装载就会将初始化函数扔掉,这样可以将该函数占用的内存释放出来。__exit进行清理工作
2.printk打印函数
日志级别一共有8个级别,printk的日志级别定义如下(在include/Linux/kernel.h中): #define KERN_EMERG 0/*紧急事件消息,系统崩溃之前提示,表示系统不可用*/ #define KERN_ALERT 1/*报告消息,表示必须立即采取措施*/ #define KERN_CRIT 2/*临界条件,通常涉及严重的硬件或软件操作失败*/ #define KERN_ERR 3/*错误条件,驱动程序常用KERN_ERR来报告硬件的错误*/ #define KERN_WARNING 4/*警告条件,对可能出现问题的情况进行警告*/ #define KERN_NOTICE 5/*正常但又重要的条件,用于提醒*/ #define KERN_INFO 6/*提示信息,如驱动程序启动时,打印硬件信息*/ #define KERN_DEBUG 7/*调试级别的消息*/
查看修改打印级别
#查看Ubuntu打印级别study@ubuntu:~$ cat /proc/sys/kernel/printk4 4 1 7######################################################################打印出来4个数字的意义 #控制台日志级别:优先级高于该值的消息将被打印至控制台 #默认的消息日志级别:将用该优先级来打印没有优先级的消息#最低的控制台日志级别:控制台日志级别可被设置的最小值(最高优先级)#默认的控制台日志级别:控制台日志级别的缺省值######################################################################发现在Ubuntu下无法修改打印级别,本着好学的态度,在一块开发板上,这样当我们在驱动中为了调试,应该把打印级别调到最低就是7~ # cat /proc/sys/kernel/printk7 4 1 7~ # echo 6 4 1 7 > /proc/sys/kernel/printk ~ # cat /proc/sys/kernel/printk6 4 1 7
3.几个驱动使用的命令
insmod #加载驱动,会执行module_init()修饰的函数rmmod #卸载驱动,执行module_exit()修饰的函数lsmod #列出目前加载的驱动 等同于cat /proc/modulestree /sys/module/ #insmod后会在/sys/moudle生成驱动名的一个目录modprobe #在加载时会同时加载依赖的模块 依赖关系在/lib/modules/<kerel_version>/modules.dep,格式很简单,下面是copy过来的一个 kernel/lib/cpu-notifier-error-inject.ko: kernel/lib/notifier-error-inject.komodinfo #查看模块信息
4驱动程序结构
- 模块加载函数 ,insmod时会被内核执行,完成初始化工作
- 模块卸载函数 ,rmmod时会被内核执行,完成清理工作
- 模块许可声明 ,MODULE_LICENSE(“GPL v2”),不声明会在加载时提示污染内核
- 模块参数(可选),外界可以传给驱动变量的一个数值
- 导出符号(可选),可以导出一个函数给其他驱动使用
- 作者别名等其他描述信息(可选) , 使用MODULE_xx()声明
4.1模块参数
在/sys/module/驱动名字/parameters所以该驱动导出模块参数的文件,可以cat查看参数值
#可以传入的参数类型有byte short ushort int uint long ulong charp boo等static char* name = "the man like wind ";module_param(name, charp, S_IRUGO);static int age = 18;module_param(age, int, 0644);#这样在使用时可以insmod *.ko name="leo" age=23#如果是静态加载进入内核可以在uboot的bootargs里设置“模块名.参数名=值”
4.2导出符号
使用下面宏导出符号到内核符号表中
EXPORT_SYMBOL()
EXPORT_SYMBOL_GPL()
#可以通过/proc/kallsyms查找导出符号相关信息int add_integer(int a,int b){ return a+b;}EXPORT_SYMBOL(add_integer);int sub_integer(int a,int b){ return a-b;}EXPORT_SYMBOL(sub_integer);
阅读全文
0 0
- Linux 第n次驱动入门(一) ---- helloWorld
- Linux脚本(shell)编程(一) 简单入门HelloWorld
- Linux脚本(shell)编程(一) 简单入门HelloWorld
- RabbitMQ (一)入门Helloworld
- RabbitMQ (一)入门 Helloworld
- RabbitMQ (一)入门 Helloworld
- RabbitMQ (一)入门 Helloworld
- Hibernate入门(一)HelloWorld
- Jfinal(一)--------入门HelloWorld
- Linux字符设备驱动入门(一)
- 第N次委托
- 第1次&第n次
- Linux设备驱动入门(一)
- linux shell(一) helloWorld
- linux设备驱动--HelloWorld
- linux设备驱动--HelloWorld
- linux设备驱动--HelloWorld
- helloworld - linux驱动
- 物联网技术在智能医疗的应用
- Centos 7开启BBR算法
- SLF4J日志框架
- 测试,我误解了你
- Nginx 入门指南
- Linux 第n次驱动入门(一) ---- helloWorld
- Android 状态栏颜色设置
- Android 8.0 Oreo 现已推出!
- Java web 中几个常用的获取项目路径的方法
- 我为什么建议自建HBase集群应该迁移过来?
- 字节排序函数
- mysql 的like 和正则表达式 regexp
- 在局域网下怎样控制另一台电脑
- tensorflow|函数讲解