linux中模块的构建,传参,和printk函数的简单使用
静态编译,动态加载
应用想访问内核需要通过系统调用
驱动:
1.模块(打包,加入内核)
2.内核机制
3.操作硬件
在Kconfig里面配置menuconfig的时候,不同的类型会在图形化界面的终端显示不用的配置选项:
bool CONFIG_HELLO []hello_driver 两态
tristate CONFIG_HELLO <>hello_driver 三态的 空 * M
string/int CONFIG_HELLO ()hello_driver 相当于宏替换 (dest)hello_driver ---> 最后在.config中的到的结果就是hello_driver = dest,这个是字符串的格式
函数模块化编写,可卸载:
下面是函数:hello_module.c
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/module.h>
MODULE_LICENSE("GPL"); 模块认证,不写这条语句,最后内核会抱怨的
static int __init hello_init(void) //通过下面的module,最终内核会解释这条语句为 init_module(),内核执行的时候找的就是这个函数名
{ 函数前面加了--init表示执行一次后对段内容的优化,优化内存,节省空间
printk("hello_init ! \n");
return 0;
}
static void __exit hello_exit(void) //通过下面的module,最终内核会解释这条语句为 cleanup_module(),执行的时候内核找的就是这个函数名
{
printk("hello_exit ! \n");
}
/* module_init:
* 1. static compile : set "hello_init" to .init section
* 2. dynamic loadable module: hello_init named init_module
*/
module_init(hello_init);
module_exit(hello_exit);
MODULE_AUTHOR("minj@farsight.com.cn"); 标注一些信息
MODULE_DESCRIPTION("just for test!");
对应于上面的makefile的编写:
MOD_NAME = hello_module
obj-m = $(MOD_NAME).o
#KERN_DIR = /home/linux/linux-2.6.35-farsight
KERN_DIR = /lib/modules/$(shell uname -r)/build
all:
make -C $(KERN_DIR) M=$(shell pwd) modules
clean:
rm -rf *.o *.ko *.mod.c *.order *.symvers .*.cmd .*versions
backup:
tar cvf ../$(MOD_NAME).tar.gz ../$(MOD_NAME)
cp ../$(MOD_NAME).tar.gz /mnt/hgfs/ubuntu_share
上面c文件编译过后会生成.ko文件:用下面语句可执行:
1.make module
2.sudo insmod hello_module.ko 调用后自动运行驱动程序
3.sudo dmesg -C 清空之前缓存里面的数据,不然会接着上次打印的结果继续打印,干扰对代码的解读
4.dmesg 查看代码运行的结果
5.rmmod hello_module 注意这里不加.ko
6.lsmod 查看模块
当想看到hello_module.ko的详细信息的时候,可以用下面的命令:
modinfo hello_module.ko
内核函数里面的传参:hello_param.c
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/module.h>
MODULE_LICENSE("GPL");
static int m; 想要传参的变量
static int n;
module_param(m, int, 0600); 这里是对参数属性的一些定义:int类型,0600是权限,读写权限
module_param(n, int, 0200);
static int __init hello_init(void)
{
printk("hello_init ! \n");
printk("m = %d : n = %d \n", m, n);
return 0;
}
static void __exit hello_exit(void)
{
printk("hello_exit ! \n");
printk("m = %d : n = %d \n", m, n);
}
/* module_init:
* 1. static compile : set "hello_init" to .init section
* 2. dynamic loadable module: hello_init named init_module
*/
module_init(hello_init);
module_exit(hello_exit);
MODULE_AUTHOR("minj@farsight.com.cn");
MODULE_DESCRIPTION("just for test!");
针对上面函数写的makefile:
MOD_NAME = hello_param
obj-m = $(MOD_NAME).o
#KERN_DIR = /home/linux/linux-2.6.35-farsight
KERN_DIR = /lib/modules/$(shell uname -r)/build
all:
make -C $(KERN_DIR) M=$(shell pwd) modules
clean:
rm -rf *.o *.ko *.mod.c *.order *.symvers .*.cmd .*versions
backup:
tar cvf ../$(MOD_NAME).tar.gz ../$(MOD_NAME)
cp ../$(MOD_NAME).tar.gz /mnt/hgfs/ubuntu_share
编译上面的代码后,传参命令如下:
1.sudo insmod hello_param.ko m=1234 n=4321
2.dmesg
查看传入内核的参数,可用下面的命令查找:
1.cd /sys/module/hello_param/parametes/
2.ls
3.sudo cat 查看你先看的参数
内核函数的导出:
一个c文件里面的函数在另一个函数里面调用:
下面是C文件的脚本,可参考:
函数提供者:hello_export.c
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/module.h>
MODULE_LICENSE("GPL"); 内核遵循的认证
void common_func(void) 我们用到的导出函数
{
printk("common_func! \n");
}
EXPORT_SYMBOL_GPL(common_func); //EXPORT_SYMBOL 在这里将函数导出,前面加了GPL表示只有遵循GPL认证的模块可以使用这个函数
static int __init hello_init(void) 注意这个函数的返回值是int型的
{
printk("hello_init ! \n");
return 0;
}
static void __exit hello_exit(void) 这个函数的返回值必须是void类型的
{
printk("hello_exit ! \n");
}
module_init(hello_init);
module_exit(hello_exit);
MODULE_AUTHOR("minj@farsight.com.cn");
MODULE_DESCRIPTION("just for test!");
函数使用者:hello_import.c
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/module.h>
MODULE_LICENSE("GPL");
extern void common_func(void); 使用者先申明一下
static int __init hello_init(void)
{
common_func(); 在这里调用了这个函数
printk("hello_init ! \n");
return 0;
}
static void __exit hello_exit(void) 注意前面--exit是优化的作用,一般情况下都会加上的
{
printk("hello_exit ! \n");
}
module_init(hello_init);
module_exit(hello_exit);
MODULE_AUTHOR("minj@farsight.com.cn"); 标明作者的信息
MODULE_DESCRIPTION("just for test!"); 模块的描述
Makefile的编写:
MOD_NAME = hello_export
obj-m = $(MOD_NAME).o
obj-m += hello_import.o
#KERN_DIR = /home/linux/linux-2.6.35-farsight
KERN_DIR = /lib/modules/$(shell uname -r)/build 注意这边路径的编写,因为最后得到的.ko文件需要依赖编译的内核版本,这里解决不同版本的编译运行问题,值得学习
all:
make -C $(KERN_DIR) M=$(shell pwd) modules 跳到对应目录执行Makefile
clean:
rm -rf *.o *.ko *.mod.c *.order *.symvers .*.cmd .*versions
backup:
tar cvf ../$(MOD_NAME).tar.gz ../$(MOD_NAME)
cp ../$(MOD_NAME).tar.gz /mnt/hgfs/ubuntu_share
函数执行的时候:先加载提供者,后运行使用者
sudo insmod hello_export.ko
sudo insmod hello_import.ko
然后运行dmesg查看结果
导出后查看是否成功:cat /proc/kallsyms | grep common_func //下面会看到导出的函数
lsmod 也能看到函数的信息
卸载:先卸载使用者,后卸载提供者
sudo rmmod hello_import
sudo rmmod hello_export
内核打印函数printk(),hello_printk.c
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/module.h>
MODULE_LICENSE("GPL");
static int __init hello_init(void)
{
printk(KERN_INFO "hello_info ! \n"); //KERN_INFO这里是打印优先级的设置
printk(KERN_NOTICE "hello notice ! \n"); //这些权限在内核include/linux/kerner.h里面可以查看
printk(KERN_ERR "hello_err ! \n");
printk(KERN_ALERT "hello_alert ! \n");
printk(KERN_WARNING "hello_warning ! \n");
return 0;
}
static void __exit hello_exit(void)
{
printk("hello_exit ! \n");
}
/* module_init:
* 1. static compile : set "hello_init" to .init section
* 2. dynamic loadable module: hello_init named init_module
*/
module_init(hello_init);
module_exit(hello_exit);
MODULE_AUTHOR("minj@farsight.com.cn");
MODULE_DESCRIPTION("just for test!");
上面C文件对应的makefile:
MOD_NAME = hello_printk
obj-m = $(MOD_NAME).o
#KERN_DIR = /home/linux/linux-2.6.35-farsight
KERN_DIR = /lib/modules/$(shell uname -r)/build
all:
make -C $(KERN_DIR) M=$(shell pwd) modules
clean:
rm -rf *.o *.ko *.mod.c *.order *.symvers .*.cmd .*versions
backup:
tar cvf ../$(MOD_NAME).tar.gz ../$(MOD_NAME)
cp ../$(MOD_NAME).tar.gz /mnt/hgfs/ubuntu_share
测试执行上面的程序的时候,需要在真正的终端下测试:ctrl+alt+f2进入终端,alt+f7退出终端
可以更改优先级:列如:
su
echo 8 4 1 7 > /proc/sys/kernel/printk //这样在第一个数组设置的对象里面打印的权限在小于8的都能被打印出来
insmod hello_printk.ko
***************************************************************************************************************************************************************
***************************************************************************************************************************************************************
***************************************************************************************************************************************************************
***************************************************************************************************************************************************************
linux中模块的构建,传参,和printk函数的简单使用的更多相关文章
- Linux:可执行程序的Shell传参格式规范
1. Linux下可执行程序的Shell传参格式规范 Linux下的可执行程序在运行时经常需要传一些参数,而这些参数是有规范的.包括我们自己写的在Linux系统下运行的Shell脚本.Python脚本 ...
- js中使用进行字符串传参
在js中拼接html标签传参时,如果方法参数是字符串需要加上引号,这里需要进行字符转义 <a href='javascript:addMenuUI("+"\"&qu ...
- 如何在Linux中使用sFTP上传或下载文件与文件夹
如何在Linux中使用sFTP上传或下载文件与文件夹 sFTP(安全文件传输程序)是一种安全的交互式文件传输程序,其工作方式与 FTP(文件传输协议)类似. 然而,sFTP 比 FTP 更安全;它通过 ...
- python中导入一个需要传参的模块
最近跑实验,遇到了一个问题:由于实验数据集比较多,每次跑完一个数据集就需要手动更改文件路径,再将文件传到服务器,再运行实验,这样的话效率很低,必须要专门看着这个实验,啥时候跑完就手动修改运行下一个实验 ...
- Linux中ftp不能上传文件/目录的解决办法
在linux中不能上传文件或文件夹最多的问题就是权限问题,但有时也不一定是权限问题了,像我就是空间不够用了,下面我来总结一些ftp不能上传文件/目录的解决办法 在排除用户组和权限等问题后,最可能引 ...
- requests中get和post传参
get请求 get(url, params=None, **kwargs) requests实现get请求传参的两种方式 方式一: import requests url = 'http://www. ...
- vue中组件间的传参
1.父传子 父组件准备一个数据,通过自定义属性给子组件赋值,进行传递 在子组件中通过 props 属性来接收参数 <body> <div id="app"> ...
- linux中使用lftp上传下载文件
lftp是linux中一款ftp服务器相比windows中的ftp显得要复杂不少了,下面我来总结一下lftp文件上传,文件下载,及文件查找等等相关命令吧. lftp连接的几种方法,最常用的是lftp ...
- 使用python读取配置文件并从mysql数据库中获取数据进行传参(基于Httprunner)
最近在使用httprunner进行接口测试,在传参时,用到了三种方法:(1)从csv文件中获取:(2)在config中声名然后进行引用:(3)从函数中获取.在测试过程中,往往有些参数是需要从数据库中获 ...
随机推荐
- include包含头文件的语句中,双引号和尖括号的区别是什么?
include包含头文件的语句中,双引号和尖括号的区别是什么? #include <> 格式:引用标准库头文件,编译器从标准库目录开始搜索 尖括号表示只在系统默认目录或者括号内的路径查找 ...
- it转行了
国庆节后毅然的辞职了,辞职的还发生一些不愉快的事情,原来希望好去好来却不慌而散.接着便开始找工作,有过工作经验,找工作是容易些,不像刚毕业那会什么企业都没人要.因为实在是对it没感觉,所以找的都是销售 ...
- $(window).height()获取到的高度不对
关于这个问题,网上有人说这是webkit内核的浏览器导致的,且只有这种浏览器会出现,只需要将html5的声明整成标准的带有<!doctype>的声明的就行了,但是本人亲测仍然是不行的,所用 ...
- Missing artifact com.oracle:ojdbc14:jar:10.2.0.4.0
下载jar,导入到maven中cmd中输入:mvn install:install-file -DgroupId=com.oracle -DartifactId=ojdbc14 -Dversion=1 ...
- Create and Install Timer Job in MOSS 2007
Excute Timerjob public class TriggerLoadCacheTimerJob : SPJobDefinition { string ExceptionFlag = str ...
- MySql创建树结构递归查询存储过程
在实现F2工作流底层多数据库支持时发现Oracel和mssql都有提供递归子查询,而MySql却没有,没办法需要自己构建存储过程来提供这个递归子查询的功能. -- 当前节点及子节点 -- 参数说明:i ...
- META-INF文件夹是干啥的,META-INF文件夹的作用, META-INF文件夹能删吗
今天有人问到 META-INF文件夹是干啥的,META-INF文件夹的作用, META-INF文件夹能删吗,还有项目的META-INF下面一般会有个MANIFEST.MF 文件,都是干啥的. 百度搜了 ...
- Qt:Drag-Drop操作在QGraphicsView及Model/View框架下的实现
最近使用到Qt的Drag Drop功能,结合自己的例子写下来给大家分享一下.实现从QTreeView拖动Node到QGraphicsView上,以及QGraphicsView上item之间的拖动. 先 ...
- HDU 4938 Seeing People(2014 Multi-University Training Contest 7)
思路:根据出发时间把点往速度反方向移动 t*v的 的距离这样就可以当成 全部点一起出发,再把y轴上的点固定不动相当于x轴的点向(-v2,v1)方向移动 .可以把所有点映射到x轴上进行统计即可(要记住同 ...
- 基于Jforum开源项目的论坛网站
基于Jforum开源项目的论坛网站 开发原因: 刚完成了以wordpress及其插件simple-press为基础的论坛网站,因为一直从事java方面开发, 所以尝试一下使用java开源项目Jforu ...