- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我想在内核 (3.x) 模块中使用参数:
static char param = 0xff;
module_param(param, ushort, S_IRUGO | S_IWUGO);
MODULE_PARM_DESC(param, "a parameter");
是否有可能检测到此参数的变化?是否有可用于调用服务例程的信号?
最好的问候亚历克斯
module_param(name,type,perm)
的附加信息:
type
的可能值:
bool
invbool
字符
int
长
短
uint
乌龙
ushort
在 linux/stat.h 为 perm
定义
#define S_IRWXUGO (S_IRWXU|S_IRWXG|S_IRWXO)
#define S_IALLUGO (S_ISUID|S_ISGID|S_ISVTX|S_IRWXUGO)
#define S_IRUGO (S_IRUSR|S_IRGRP|S_IROTH)
#define S_IWUGO (S_IWUSR|S_IWGRP|S_IWOTH)
#define S_IXUGO (S_IXUSR|S_IXGRP|S_IXOTH)
这里是一个完整的代码示例:
#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Alex");
MODULE_DESCRIPTION("test module.");
MODULE_VERSION("0.1");
static int param = 1;
module_param(param, int, S_IRUGO|S_IWUGO);
static int __init mod_init(void){
printk(KERN_INFO "param %d\n", param);
return 0;
}
static void __exit mod_exit(void){
printk(KERN_INFO "Goodbye!\n");
}
module_init(mod_init);
module_exit(mod_exit);
编译器返回这个错误我不明白为什么:
make -C /lib/modules/3.19.0-47-generic/build/ M=/tmp/gt modules
make[1]: change to »/usr/src/linux-headers-3.19.0-47-generic«
CC [M] /tmp/gt/ebb.o
In file included from include/linux/thread_info.h:11:0,
from ./arch/x86/include/asm/preempt.h:6,
from include/linux/preempt.h:18,
from include/linux/spinlock.h:50,
from include/linux/seqlock.h:35,
from include/linux/time.h:5,
from include/linux/stat.h:18,
from include/linux/module.h:10,
from /tmp/gt/ebb.c:2:
include/linux/bug.h:33:45: error: negative width in bit-field ‘<anonymous>’
#define BUILD_BUG_ON_ZERO(e) (sizeof(struct { int:-!!(e); }))
^
include/linux/kernel.h:830:3: note: in expansion of macro ‘BUILD_BUG_ON_ZERO’
BUILD_BUG_ON_ZERO((perms) & 2) + \
^
include/linux/moduleparam.h:223:31: note: in expansion of macro ‘VERIFY_OCTAL_PERMISSIONS’
= { __param_str_##name, ops, VERIFY_OCTAL_PERMISSIONS(perm), \
^
include/linux/moduleparam.h:166:2: note: in expansion of macro ‘__module_param_call’
__module_param_call(MODULE_PARAM_PREFIX, name, ops, arg, perm, -1, 0)
^
include/linux/moduleparam.h:146:2: note: in expansion of macro ‘module_param_cb’
module_param_cb(name, ¶m_ops_##type, &value, perm); \
^
include/linux/moduleparam.h:125:2: note: in expansion of macro ‘module_param_named’
module_param_named(name, name, type, perm)
^
/tmp/gt/ebb.c:11:1: note: in expansion of macro ‘module_param’
module_param(param, int, S_IRUGO|S_IWUGO);
^
make[2]: *** [/tmp/gt/ebb.o] Fehler 1
make[1]: *** [_module_/tmp/gt] Fehler 2
make[1]: leaving »/usr/src/linux-headers-3.19.0-47-generic«
make: *** [all] Fehler 2
这里是Makefile
obj-m+=ebb.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
关于@Tsyvarev 的回答
写入权限只允许root。所以这里的变化:
module_param(param, int, S_IRUGO|S_IWUSR);
现在您可以在/sys/module//parameters/ 下找到参数,您可以像这样更改参数:
sudo echo 2 > /sys/module/ebb/parameters/param
关于@Tsyvarev 的下一步
#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Alex");
MODULE_DESCRIPTION("test module.");
MODULE_VERSION("0.1");
// int (*set)(const char *val, const struct kernel_param *kp);
// int (*get)(char *buffer, const struct kernel_param *kp);
int my_param_set_ushort(const char *val, const struct kernel_param *kp)
{
unsigned short* pvalue = kp->arg; // Pointer to actual parameter variable.
int res = param_set_ushort(val, kp); // Use helper for write variable
printk(KERN_INFO "setter talks\n");
if( res==0 )
{
// Here you may execute additional actions when you write parameter.
printk(KERN_INFO "set param %d\n", *pvalue);
}
return res;
}
const struct kernel_param_ops my_param_ops_ushort =
{
.set = &my_param_set_ushort, // Use our setter ...
.get = ¶m_get_ushort, // .. and standard getter
};
unsigned short param = 0xff;
module_param_cb(param, /*filename*/
&my_param_ops_ushort, /*operations*/
¶m, /* pointer to variable, contained parameter's value */
S_IRUGO | S_IWUSR /*permissions on file*/
);
static int __init mod_init(void){
printk(KERN_INFO "param %d\n", param);
return 0;
}
static void __exit mod_exit(void){
printk(KERN_INFO "Goodbye! (%d)\n",param);
}
module_init(mod_init);
module_exit(mod_exit);
作为 root 我给出了这个命令:
# insmod par.ko
# echo 146 > /sys/module/par/parameters/param
# rmmod par
和内核日志 /var/log/kernel.log 说:
Jan 23 14:27:37 alex-XMG kernel: [ 8332.492912] param 255
Jan 23 14:27:39 alex-XMG kernel: [ 8334.520044] setter talks
Jan 23 14:27:39 alex-XMG kernel: [ 8334.520052] set param 146
Jan 23 14:27:40 alex-XMG kernel: [ 8335.804338] Goodbye! (146)
工作起来很有魅力!
最佳答案
创建内核模块参数的通用方法是使用宏 module_param_cb :
/**
* module_param_cb - general callback for a module/cmdline parameter
* @name: a valid C identifier which is the parameter name.
* @ops: the set & get operations for this parameter.
* @perm: visibility in sysfs.
*
* The ops can have NULL set or get functions.
*/
#define module_param_cb(name, ops, arg, perm)
参数 ops
是指向结构 struct kernel_param_ops
的指针,其中包含给定参数的操作。写入和读取参数时调用的函数已遵循此结构中的定义:
int (*set)(const char *val, const struct kernel_param *kp);
int (*get)(char *buffer, const struct kernel_param *kp);
这里的char*
参数是一个以NULL结尾的字符串,写入/读取sysfs文件,表示给定参数。 kp
是指向参数描述符的指针,其中最感兴趣的字段是 .arg
:它是宏 module_param_cb
调用的第三个参数。使用这个字段,setter 和 getter 可以实现 per-type 模块参数,即模块有 5 个 int
参数不需要为模块编写 setter 和 getter他们每个人。
此外,标准参数类型的 getter 和 setter 已经实现,并且在您调用 module_param
宏时实际使用它们。因此,如果您想为参数的 setter 添加一些功能,您可以重用现有的助手:
int my_param_set_ushort(const char *val, const struct kernel_param *kp)
{
unsigned short* pvalue = kp->arg; // Pointer to actual parameter variable.
int res = param_set_ushort(val, kp); // Use helper for write variable
if(!res)
{
// Here you may execute additional actions when you write parameter.
printk(KERN_INFO "set param %d\n", *pvalue);
}
return res;
}
const struct kernel_param_ops my_param_ops_ushort =
{
.set = &my_param_set_ushort, // Use our setter ...
.get = ¶m_get_ushort, // .. and standard getter
};
// Usage
unsigned short param = 0xff;
module_param_cb(param, /*filename*/
&my_param_ops_ushort, /*operations*/
¶m, /* pointer to variable, contained parameter's value */
S_IRUGO | S_IWUSR /*permissions on file*/
);
出于安全原因,让非特权用户可写模块参数通常不是一件好事。以及创建模块参数的内核宏,检查一下。这就是为什么您的模块参数定义中存在神秘错误的原因。请注意,在上面的示例中,使用了 S_IWUSR
而不是 S_IWUGO
。
关于c - 内核参数更改信号,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34957016/
所以我目前正在研究 C 中的 POSIX 线程和信号编程。我的讲师使用 sigset(int sigNumber, void* signalHandlerFUnction) 因为他的笔记不是世界上最好
我正在制作一个 C++ 游戏,它要求我将 36 个数字初始化为一个 vector 。你不能用初始化列表初始化一个 vector ,所以我创建了一个 while 循环来更快地初始化它。我想让它把每个数字
我正在尝试让 Python 发送 EOF信号 (Ctrl+D) 通过 Popen() .不幸的是,我找不到任何关于 Popen() 的引用资料。 *nix 类系统上的信号。这里有谁知道如何发送 EOF
我正在尝试让 Python 发送 EOF信号 (Ctrl+D) 通过 Popen() .不幸的是,我找不到任何关于 Popen() 的引用资料。 *nix 类系统上的信号。这里有谁知道如何发送 EOF
我正在学习编码并拥有一个实时的 Django 项目来保持我的动力。在我的 Django 应用程序中,用户留下评论,而其他人则回复所述评论。 每次用户刷新他们的主页时,我都会计算他们是否收到了关于他们之
登录功能中的django信号有什么用?用户已添加到请求 session 表中。那么 Django auth.login 函数中对信号的最后一行调用是什么? @sensitive_post_param
我已经将用户的创建与函数 create_user_profile 连接起来,当我创建我的用户时出现问题,我似乎连接的函数被调用了两次,而 UserProfile 试图被创建两次,女巫触发了一个错误 列
我有一个来自生产者对象处理的硬件的实时数据流。这会连接到一个消费者,该消费者在自己的线程中处理它以保持 gui 响应。 mainwindow::startProcessing(){ QObje
在我的 iPhone 应用程序中,我想提供某种应用程序终止处理程序,该处理程序将在应用程序终止之前执行一些最终工作(删除一些敏感数据)。 我想尽可能多地处理终止情况: 1) 用户终止应用 2) 设备电
我试图了解使用 Angular Signals 的优势。许多解释中都给出了计数示例,但我试图理解的是,与我下面通过变量 myCount 和 myCountDouble 所做的方式相比,以这种方式使用信
我对 dispatch_uid 的用法有疑问为信号。 目前,我通过简单地添加 if not instance.order_reference 来防止信号的多次使用。 .我现在想知道是否dispatch
有时 django 中的信号会被触发两次。在文档中,它说创建(唯一)dispatch_uid 的一个好方法是模块的路径或名称[1] 或任何可哈希对象的 ID[2]。 今天我尝试了这个: import
我有一个用户定义的 shell 项目,我试图在其中实现 cat 命令,但允许用户单击 CTRL-/ 以显示下一个 x 行。我对信号很陌生,所以我认为我在某个地方有一些语法错误...... 主要...
http://codepad.org/rHIKj7Cd (不是全部代码) 我想要完成的任务是, parent 在共享内存中写入一些内容,然后 child 做出相应的 react ,并每五秒写回一些内容
有没有一种方法可以找到 Qt 应用程序中信号/槽连接的总数有人向我推荐 Gamma 射线,但有没有更简单的解决方案? 最佳答案 检查 Qt::UniqueConnection . This is a
我正在实现一个信号/插槽框架,并且到了我希望它是线程安全的地步。我已经从 Boost 邮件列表中获得了很多支持,但由于这与 boost 无关,我将在这里提出我的未决问题。 什么时候信号/槽实现(或任何
在我的代码中,我在循环内创建相同类型的新对象并将信号连接到对象槽。这是我的试用版。 A * a; QList aList; int aCounter = 0; while(aCounter aLis
我知道 UNIX 上的 C 有 signal() 可以在某些操作后调用某些函数。我在 Windows 上需要它。我发现了,它存在什么 from here .但是我不明白如何正确使用它。 我在 UNIX
目前我正在将控制台 C++ 项目移植到 Qt。关于移植,我有一些问题。现在我的项目调整如下我有一个派生自 QWidget 的 Form 类,它使用派生自 QObject 的其他类。 现在请告诉我我是否
在我的 Qt 多线程程序中,我想实现一个基于 QObject 的基类,以便从它派生的每个类都可以使用它的信号和槽(例如抛出错误)。 我实现了 MyQObject : public QObject{..
我是一名优秀的程序员,十分优秀!