Linux 内核 - 将自定义标志传递给设备驱动程序中的"open"



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

我在LDD3中发现了这个例子:

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

我的问题是:是否可以定义其他标志(如O_ACCMODEO_WRONLY)而不与其他标志冲突?

是的,这是可能的。看看include/uapi/asm-general/fcntl.h。注意下一条评论:

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

现在查看fcntl_init()函数(在fs/fcntl.c中定义):

/*
 * 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:正如SailorCaire正确提到的,您还需要增加BUILD_BUG_ON()宏中的第一个数字。例如,如果它最初是BUILD_BUG_ON(20 - 1,并且要向该列表中添加一个元素,则应将其设为BUILD_BUG_ON(21 - 1

更新2:SailorCaire的另一个宝贵补充:

顺便说一下,您需要执行make install_headers,复制新的头,看起来您需要重新编译glibc,这样它才能意识到API的更改。

相关内容

  • 没有找到相关文章

最新更新