有一天我编译内核模块驱动的时候发现如下错误

Linux kernel版本:4.1.15

error: negative width in bit-field '<anonymous>'

代码如下:

static struct device_attribute sysfs_keypad_list[] = {
__ATTR(virt_key, ,
keypad_show_error, keypad_virt_key_store),
};

当我做这样的修改后:

static struct device_attribute sysfs_keypad_list[] = {
__ATTR(virt_key, ,
keypad_show_error, keypad_virt_key_store),
};

编译就不报错了

这样让我很是奇怪,接下来咱们跟入代码一看究竟

首先我们看下__ATTR的实现:

继续跟入,我们发现如下的算法,显而易见,此版本的内核对权限做了一个小小的算法,如下算法大家可以写一个简单的c代码进行解读

当我传入perms=0x666的时候,BUILD_BUG_ON_ZERO(perms & 2) 这个会报错,因为如下:

为什么 BUILD_BUG_ON_ZERO( (0x666) & 2 )会报错呢?

我们可以写这样的代码来验证一下:

#include <stdio.h>

int main()
{
struct a {
int: -;
}; return ;
}

运行:

出现了同样的错误,那么我们应该明白了吧,gcc会在编译的时候对位域的定义进行检查,struct {int: -1}这样的定义编译器会认为是错误的

那至于为什么会打印这样的错误呢?这就需要对编译器进行了解了,也就是编译器是如何检查结构体位域的定义的,这块我没有深入研究过

如有人有这块的资料和信息欢迎评论和分享。

如下引用一段话,摘自网上(https://stackoverflow.com/questions/31395602/giving-s-iwugo-permission-to-module-parameter-results-in-compilation-error-whil)

Linux probably refuses to make module parameters world-writable for security reasons.

You should be able to use narrower permissions such as S_IWUSR | S_IWGRP

通俗的理解就是内核希望这样做的安全一点,减少其他组的写权限,体现在 BUILD_BUG_ON_ZERO(perms & 2)这个设计上

那么我们如何修改呢?

有如下两种方式的思路给大家借鉴:

第一种:

这样设计的思路是为了遵循作者的思想,保障安全(但__ATTR这个宏的用法不同版本是有差别的在这块,比如说3.6.5的版本是不会检查这个权限问题的)

static struct device_attribute sysfs_keypad_list[] = {
__ATTR(virt_key, ,
keypad_show_error, keypad_virt_key_store),
};

第二种:

这样设计的思路是因为搞驱动开发的相信大家都清楚,如果这个接口是我们曾经释放出去的,开放了这样的权限

那么我们后期开发的时候必须兼容之前的接口设计,不能这样随意的更改权限,因为如果你修改了,某个客户之前有这样子使用权限的话,你改了权限后,他可能就用不了了,

因此我们可以做如下处理,思路就是我们自己定义,不使用内核的设计

#undef __ATTR
#define __ATTR(_name, _mode, _show, _store) { \
.attr = {.name = __stringify(_name), \
.mode = _mode}, \
.show = _show, \
.store = _store, \
} static struct device_attribute sysfs_keypad_list[] = {
__ATTR(virt_key, ,
keypad_show_error, keypad_virt_key_store),
};

方法三:

#undef VERIFY_OCTAL_PERMISSIONS
#define VERIFY_OCTAL_PERMISSIONS(perms) (perms)

static DEVICE_ATTR(reg_value, 0666, zbh_reg_show, zbh_reg_store);

分析如上,如有描述不准确的地方还请告知,Thanks

__ATTR引发的编译错误【原创】的更多相关文章

  1. Linux下由于注释引发udf编译错误

    我们编写如下的UDF: 然后我们放到Linux下进行编译 Linux编译以后会报如下错误: 这是由于C语言的C90标准不支持行注释,而我们只需要将行注释修改为块注释 问题即可解决

  2. 编译错误“The run destination My Mac is not valid for Running the scheme '***',解决办法

    [转载]   http://blog.csdn.net/duanyipeng/article/details/8007684   编译错误"The run destination My Ma ...

  3. 常见C语言编译错误解析【转】

    C语言编译错误信息及说明1. 在函数 ‘transform’ 中:7: 错误:expected ‘;’ before ‘{’ token    解释:‘{’之前的某个语句缺少分号‘;’: 2. 在函数 ...

  4. I.MX6 linux kernel编译错误处理

    /******************************************************************************** * I.MX6 linux kern ...

  5. xxx was built without full bitcode" 编译错误解决

    xxx was built without full bitcode" 编译错误解决 iOS 打包上线 All object files and libraries for bitcode ...

  6. 关于Android Studio中点9图的编译错误问题

    Android中的点9图想必大家都非常熟悉了,能够指定背景图片的缩放区域和文本内容的显示区域,常见如QQ聊天界面的背景气泡这种文本内容不固定并需要适配的应用场景. 这里也给大家准备了一张图,详细介绍了 ...

  7. xamarin.forms新建项目android编译错误

    vs2015 update3 新建的xamarin.forms项目中的android项目编译错误.提示缺少android_m2repository_r22.zip,96659D653BDE0FAEDB ...

  8. 《转载》使用org.w3c.dom.Element的setTextContent()、getTextContent()方法时出现编译错误

    今天在更新项目后进行编译时,出现如下错误一堆: 编译错误 Google之,在stackoverflow上看到如下的解决方法: I came here with the same problem. Ev ...

  9. asp.net教程:编译错误同时存在于不同dll中

    asp.net 编译错误类型“同时存在于”不同的dll中. 出现这种错误大概有三种情况: 1.ASPX页面,一个*.ASPX,对应着一个*.cs文件,两者其实是一个文件,通过两者实现代码分离,每个*. ...

随机推荐

  1. 【BZOJ4503】两个串(FFT)

    [BZOJ4503]两个串(FFT) 题面 给定串\(S\),以及带通配符的串\(T\),询问\(T\)在\(S\)中出现了几次.并且输出对应的位置. \(|S|,|T|<=10^5\),字符集 ...

  2. BZOJ4332 JSOI2012 分零食 【倍增 + NTT】

    题目链接 权限题BZOJ4332 题解 容易想到\(dp\) 设\(g[i][j]\)表示前\(i\)人分到\(j\)颗糖的所有方案的乘积之和 设\(f(x) = Ox^2 + Sx + U\) \[ ...

  3. 牛客练习赛 小A与最大子段和 解题报告

    小A与最大子段和 题意 在一个序列 \(\{a\}\) 里找到一个非空子段 \(\{b\}\), 满足 \(\sum\limits_{i=1}^{|b|}b_i\times i\) 最大 \(n\le ...

  4. requests+beautifulsoup爬取豆瓣图书

    使用Xpath和BeautifulSoup来解析网页可以说真的很简便. import requests from bs4 import BeautifulSoup from random import ...

  5. Python--Django学习笔记2

    本篇介绍Django中的Model层. 首先介绍sqlite3,这是在当前版本中Django默认使用的数据库,sqlite也是Android中所使用的数据库. 接着介绍最最最常见的MySQL数据库如何 ...

  6. You are using safe update mode and you tried to update a table--mysql

    SET SQL_SAFE_UPDATES = 0;delete from cms_article_data where id in(SELECT id FROM jeesite.cms_article ...

  7. (母函数 Catalan数 大数乘法 大数除法) Train Problem II hdu1023

    Train Problem II Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) ...

  8. 使用LTP套件对Linux系统进行压力测试

    使用LTP套件对Linux系统进行压力测试 https://www.ubuntukylin.com/ukylin/forum.php?mod=viewthread&tid=6764 https ...

  9. python 3字符编码

    python 3字符编码 官方链接:http://legacy.python.org/dev/peps/pep-0263/ 在Python2中默认是ascii编码,Python3是utf-8编码 在p ...

  10. 《Linux就该这么学》第二期视频

    Linux就该这么学--第二期学习笔记... ------------- 你的未来取决于你现在点点滴滴的努力 需要用到的一些工具: Vm11激活码 ---------- root在Linux系统中相当 ...