在设备驱动程序中传递自定义标志以“打开”

2024-06-19

我需要将一些自定义标志传递给open()我的设备驱动程序的调用。

我在LDD3中找到了这个例子:

int dev_open(struct inode *inode, struct file *filp)
{
    if ((filp->f_flags & O_ACCMODE) == O_WRONLY) {
        ...
    }
}

我的问题是:是否可以定义其他标志(例如O_ACCMODE and O_WRONLY)与其他任何人没有冲突?


是的,这是可能的。看一眼包括/uapi/asm-generic/fcntl.h http://lxr.free-electrons.com/source/include/uapi/asm-generic/fcntl.h。请注意下一条评论:

/*
 * When introducing new O_* bits, please check its uniqueness in fcntl_init().
 */

现在看看fcntl_init()函数(定义于fs/fcntl.c http://lxr.free-electrons.com/source/fs/fcntl.c#L736):

/*
 * Please add new bits here to ensure allocation uniqueness.
 * Exceptions: O_NONBLOCK is a two bit define on parisc; O_NDELAY
 * is defined as O_NONBLOCK on some platforms and not on others.
 */
BUILD_BUG_ON(20 - 1 /* for O_RDONLY being 0 */ != HWEIGHT32(
    O_RDONLY        | O_WRONLY      | O_RDWR        |
    O_CREAT         | O_EXCL        | O_NOCTTY      |
    O_TRUNC         | O_APPEND      | /* O_NONBLOCK | */
    __O_SYNC        | O_DSYNC       | FASYNC        |
    O_DIRECT        | O_LARGEFILE   | O_DIRECTORY   |
    O_NOFOLLOW      | O_NOATIME     | O_CLOEXEC     |
    __FMODE_EXEC    | O_PATH        | __O_TMPFILE
    ));

因此,首先您需要为新定义找到唯一值,以便可以将其与中列出的标志进行按位或fcntl_init()。接下来您需要将新定义添加到include/uapi/asm-generic/fcntl.h。最后将您的新定义添加到fcntl_init(),因此会在编译时进行检查。

最后归结为找到与现有定义不冲突的值。例如。正如我所看到的,所有 10、100、1000、10000、100000、1000000 和 10000000 都被使用。因此,对于新标志,您可以使用 100000000、200000000、400000000 和 800000000 值。

UPDATE: As 水手凯尔 https://stackoverflow.com/users/1036361/sailorcire正确提到,您还需要增加第一个数字BUILD_BUG_ON()宏。例如,如果原来是BUILD_BUG_ON(20 - 1,并且您要向此列表添加一个元素,您应该将其设为BUILD_BUG_ON(21 - 1.

UPDATE 2:另一个有价值的补充水手凯尔 https://stackoverflow.com/users/1036361/sailorcire:

顺便说一句,你需要做make install_headers,复制新的标头,看起来你需要重新编译glibc所以它会意识到 API 的变化。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在设备驱动程序中传递自定义标志以“打开” 的相关文章

  • 内存调试:如何获取 Linux 用户空间/内核空间中的锁定页面信息

    有什么方法可以获取Linux用户空间 内核空间中的锁定页面 虚拟内存页面 信息 我想了解详细信息 例如 谁锁定了页面 有多少页被锁定 进程名称 谁锁定了页面 还让我了解内核空间和用户空间的内存调试技术 对于内存中的每个页面 都会为其分配标志
  • UNIX系统调用监视器

    如何监控进程的系统调用 Check strace http linux die net man 1 strace 在最简单的情况下 strace 运行指定的命令直到退出 它拦截并记录进程调用的系统调用以及进程接收的信号 每个系统调用的名称
  • ftrace:仅打印trace_printk()的输出

    是否可以只转储trace printk 输出于trace文件 我的意思是过滤掉函数跟踪器 或任何其他跟踪器 中的所有函数 一般来说 您可以在选项目录中关闭选项 sys kernel debug tracing options Use ls显
  • 如何访问 mmaped /dev/mem 而不导致 Linux 内核崩溃?

    我有一个简单的程序 尝试访问用户空间中的物理内存 其中内核存储第一个结构页 在 64 位机器上 该地址是 内核虚拟地址 ffffea0000000000 物理地址 0000620000000000 我正在尝试通过用户空间中的 mmap 访问
  • 内核模块未加载(但 insmod 返回 0)

    我必须向现有设备 mips arch 添加一些功能 我已经尝试了几个 SDK 目前我取得了一些进展 但是 insmod 返回 0 成功 并且 lsmod 显示它们 但是 printk 和 create proc entry 都不起作用 但我
  • 从 Node.js 调用 execl、execle、execlp、execv、execvP 或 execvp 的方法

    POSIX 系统公开了一系列exec函数 允许人们将可能不同的东西加载到当前进程中 保留打开的文件描述符 进程标识符等 可以出于多种原因执行此操作 在我的情况下 这是引导 我想更改我自己的进程的命令行选项 然后在现有进程上重新加载它 这样就
  • 如何在C程序中直接改变显存映射来绘制像素(无需库函数)

    是否可以通过使用 C 程序更改 RAM 中屏幕 视频即监视器 内存映射中的值来显示黑点 我不想使用任何库函数 因为我的主要目标是学习如何开发简单的操作系统 我尝试访问起始屏幕内存映射 即 0xA0000 在 C 中 我尝试运行该程序 但由于
  • 如何从外部模块导出符号?

    我在内核源代码树之外进行编码 有两个模块 第一个printt有一个功能printtty 将字符串打印到当前 tty 以及第二个模块hello这会调用printtty 在初始化期间 我已经添加了EXPORT SYMBOL printtty 在
  • C 标准库函数与系统调用。哪个是“open()”?

    I know fopen 在C标准库中 所以我绝对可以调用fopen C 程序中的函数 我感到困惑的是为什么我可以打电话给open 功能也一样 open 应该是系统调用 所以它不是标准库中的C函数 因为我能够成功地调用open 函数 我调用
  • /proc/kmsg 和 dmsg 有什么区别?

    我们通常这样做cat proc kmsg or dmesg从用户空间查看内核日志 我明白了dmesg是一个循环缓冲区 它从kmsg 但是kmsg也不是循环缓冲区 它们之间有什么区别和联系呢 宽松地说 dmesg 是一个转储 proc kms
  • Linux CFS 调度程序代码在哪里?

    我有3 13版本的完整linux源代码 我试图找到 CFS 调度程序的源代码 根据流行书籍 它应该驻留在 kernel sched c 中作为基本调度程序代码 而 kernel sched fair c 专门针对 CFS 代码 我刚刚在 3
  • 编译Linux内核模块时出现错误:“CONFIG_X86_X32已启用,但没有binutils支持”和不需要的“n”字符

    我想得到Rasta Ring0 调试器 http rr0d droids corp org 在我的 x86 64 Linux 中编译的 0 3 版本 它是一个 Linux 内核模块 我已将 32 位内联汇编替换为 64 位汇编 如我的问题中
  • 尝试在 ubuntu 中编译 android 内核时出错

    我正在尝试从源代码编译 Android 内核 并且我已经下载了所有正确的软件包来执行此操作 但由于某种原因我收到此错误 arm linux androideabi gcc error unrecognized command line op
  • module_init() 与 core_initcall() 与 Early_initcall()

    在驱动程序中 我经常看到使用这三种类型的初始化函数 module init core initcall early initcall 在什么情况下我应该使用它们 另外 还有其他的初始化方式吗 它们决定内置模块的初始化顺序 司机们会使用dev
  • 如何在 Linux 内核中定义并触发我自己的新软中断?

    我想在 Linux 内核中创建自己的软中断 这是正确的方法吗 In the init我想触发该模块的softirq我将添加一个调用 394 void open softirq int nr void action struct softir
  • 更改 Linux 操作系统

    我为我的嵌入式板构建 Linux 内核 我想定制我的主板的功能 我怎样才能做到这一点 Thanks 在元自定义层中创建以下树 recipes kernel linux linux at91 0001 my custom dt patch l
  • Linux 内核模块中的文件 I/O

    我正在编写一个需要打开和读取文件的 Linux 内核模块 实现这一目标的最佳方法是什么 我能问一下你为什么要打开文件吗 我喜欢关注Linux开发 出于好奇 我不是内核开发人员 我是做Java的 而且我以前看过关于这个问题的讨论 我找到了一个
  • 尽管 EXPORT_SYMBOL 模块插入时出现“模块中的未知符号”

    我正在尝试编译并插入 r8169 realtek 以太网驱动程序 我的内核版本是 ebin sony uname r 4 2 0 rc3 custom 我的本地磁盘中有相同的完整源代码 用于安装当前的内核 当我运行时该模块编译成功make
  • Linux 内核 - 如何停止等待信号量的 kthread?

    在编写 Linux 内核模块时 我遇到了一个 kthread 问题 在等待信号量解锁时无法唤醒该 kthread 这会导致线程不可停止并且rmmod尝试卸载模块时冻结 请注意 该模块在 3 10 内核上运行 我无法将其更新到较新的版本 客户
  • “read”和“sysread”有什么区别?

    read http perldoc perl org functions read html and sysread http perldoc perl org functions sysread html有非常相似的文档 两者有何区别 A

随机推荐