内核配置


内核版本:Linux version 4.9.56

make ARCH=arm64 menuconfig
Device Drivers  --->
Input device support --->
[*] Keyboards --->
<*> GPIO Buttons

配置文件


sys_config.fex
;----------------------------------------------------------------------------------
;gpio-keys parameters
;----------------------------------------------------------------------------------
[gpio-keys]
compatible = "gpio-keys"; [gpio-keys/up]
linux,code = 103
linux,input-type = 1
gpios = port:PH11<6><default><default><default> [gpio-keys/down]
linux,code = 108
linux,input-type = 1
gpios = port:PH08<0><default><default><default> [gpio-keys/enter]
linux,code = 28
linux,input-type = 1
gpios = port:PH10<6><default><default><default>

内存越界


日志信息

[    2.868360] of_get_named_gpiod_flags: parsed 'gpios' property of node '/soc@01c00000/gpio-keys/up[0]' - status (0)
[ 2.868366] of_get_gpio_flags button->gpio:235...
[ 2.868393] of_get_named_gpiod_flags: parsed 'gpios' property of node '/soc@01c00000/gpio-keys/down[0]' - status (0)
[ 2.868396] of_get_gpio_flags button->gpio:232...
[ 2.868417] of_get_named_gpiod_flags: parsed 'gpios' property of node '/soc@01c00000/gpio-keys/enter[0]' - status (0)
[ 2.868420] of_get_gpio_flags button->gpio:234...
[ 2.869024] input: gpio-keys as /devices/platform/soc/gpio-keys/input/input3
[ 2.869369] Kernel panic - not syncing: stack-protector: Kernel stack is corrupted in: ffffff8008600ce0
[ 2.869369]
[ 2.869380] CPU: 1 PID: 1 Comm: swapper/0 Not tainted 4.9.56 #165
[ 2.869383] Hardware name: sun50iw1 (DT)
[ 2.869388] Call trace:
[ 2.869409] [<ffffff800808a7d4>] dump_backtrace+0x0/0x22c
[ 2.869417] [<ffffff800808aa24>] show_stack+0x24/0x30
[ 2.869430] [<ffffff80083c9a64>] dump_stack+0x8c/0xb0
[ 2.869438] [<ffffff80081a5960>] panic+0x14c/0x298
[ 2.869450] [<ffffff80080a19d0>] print_tainted+0x0/0xa8
[ 2.869463] [<ffffff8008600ce0>] gpio_keys_probe+0x6d0/0x804
[ 2.869474] [<ffffff80084b3e9c>] platform_drv_probe+0x60/0xac
[ 2.869481] [<ffffff80084b1a6c>] driver_probe_device+0x1b8/0x3d4
[ 2.869485] SMP: stopping secondary CPUs
[ 2.877351] Kernel Offset: disabled
[ 2.877354] Memory Limit: none

解决补丁

diff --git a/drivers/input/keyboard/gpio_keys.c b/drivers/input/keyboard/gpio_keys.c
old mode 100644
new mode 100755
index 9b8079c..04e1580
--- a/drivers/input/keyboard/gpio_keys.c
+++ b/drivers/input/keyboard/gpio_keys.c
@@ -32,6 +32,7 @@
#include <linux/of_gpio.h>
#include <linux/of_irq.h>
#include <linux/spinlock.h>
+#include <linux/sunxi-gpio.h> struct gpio_button_data {
const struct gpio_keys_button *button;
@@ -664,11 +665,11 @@ static void gpio_keys_close(struct input_dev *input) i = 0;
for_each_available_child_of_node(node, pp) {
- enum of_gpio_flags flags;
+ struct gpio_config gpio_flags; button = &pdata->buttons[i++]; - button->gpio = of_get_gpio_flags(pp, 0, &flags);
+ button->gpio = of_get_gpio_flags(pp, 0, (enum of_gpio_flags *)&gpio_flags);
if (button->gpio < 0) {
error = button->gpio;
if (error != -ENOENT) {
@@ -679,7 +680,7 @@ static void gpio_keys_close(struct input_dev *input)
return ERR_PTR(error);
}
} else {
- button->active_low = flags & OF_GPIO_ACTIVE_LOW;
+ button->active_low = gpio_flags.data & OF_GPIO_ACTIVE_LOW;
} button->irq = irq_of_parse_and_map(pp, 0);

原因分析

  1. gpio_keys 驱动使用 of_get_gpio_flags() 获取 dts 里面 gpio 配置信息。
  2. 但是 of_get_gpio_flags() 传入 enum of_gpio_flags 类型来获取配置信息。
  3. of_get_gpio_flags() 的最终实现由具体的 SOC 厂商实现,这里是全志厂商实现。
  4. 实现的函数为:drivers/pinctrl/sunxi/pinctrl-sunxi.c --> sunxi_pinctrl_gpio_of_xlate()。
  5. 在 sunxi_pinctrl_gpio_of_xlate() 却是通过强制转换 struct gpio_config 类型存储 gpio 配置信息。
  6. enum of_gpio_flags 占用 4 字节,而 struct gpio_config 占用 20 字节,出现内存越界操作的问题。
// include/linux/of_gpio.h
enum of_gpio_flags {
OF_GPIO_ACTIVE_LOW = 0x1,
OF_GPIO_SINGLE_ENDED = 0x2,
}; // 4Byte // include/linux/sunxi-gpio.h
struct gpio_config {
u32 gpio;
u32 mul_sel;
u32 pull;
u32 drv_level;
u32 data;
}; // 20Byte // drivers/pinctrl/sunxi/pinctrl-sunxi.c
static int sunxi_pinctrl_gpio_of_xlate(struct gpio_chip *gc,
const struct of_phandle_args *gpiospec,
u32 *flags)
{
struct gpio_config *config;
int pin, base; base = PINS_PER_BANK * gpiospec->args[0];
pin = base + gpiospec->args[1];
pin = pin - gc->base;
if (pin > gc->ngpio)
return -EINVAL; if (flags) {
// 问题出在这个条件下面的赋值语句
// 传进来的是 enum of_gpio_flags,只有 4Byte
// 结果使用的 struct gpio_config,却有 20Byte
config = (struct gpio_config *)flags;
config->gpio = base + gpiospec->args[1];
config->mul_sel = gpiospec->args[2];
config->drv_level = gpiospec->args[3];
config->pull = gpiospec->args[4];
config->data = gpiospec->args[5];
} return pin;
}

【分析笔记】全志平台 gpio-keys 驱动应用和 stack crash 解决的更多相关文章

  1. uboot的GPIO驱动分析--基于全志的A10芯片【转】

    本文转载自:http://blog.csdn.net/lw2011cg/article/details/68954707 uboot的GPIO驱动分析--基于全志的A10芯片 转载至:http://b ...

  2. Linux GPIO键盘驱动开发记录_OMAPL138

    Linux GPIO键盘驱动开发记录_OMAPL138 Linux基本配置完毕了,这几天开始着手Linux驱动的开发,从一个最简单的键盘驱动开始,逐步的了解开发驱动的过程有哪些.看了一下Linux3. ...

  3. u-boot启动流程分析(1)_平台相关部分

    转自:http://www.wowotech.net/u-boot/boot_flow_1.html 1. 前言 本文将结合u-boot的“board—>machine—>arch—> ...

  4. zeromq源码分析笔记之线程间收发命令(2)

    在zeromq源码分析笔记之架构说到了zmq的整体架构,可以看到线程间通信包括两类,一类是用于收发命令,告知对象该调用什么方法去做什么事情,命令的结构由command_t结构体确定:另一类是socke ...

  5. Spark大型项目实战:电商用户行为分析大数据平台

    本项目主要讲解了一套应用于互联网电商企业中,使用Java.Spark等技术开发的大数据统计分析平台,对电商网站的各种用户行为(访问行为.页面跳转行为.购物行为.广告点击行为等)进行复杂的分析.用统计分 ...

  6. 微软连续12年成为Gartner分析和BI平台魔力象限的领导者

    小悦还沉浸在新春开工大吉的工作中,微软Power BI就又迎来了一个好消息!据Gartner刚新鲜出炉的<  2019年Gartner的分析和商业智能平台魔力象限报告>,微软迄今已连续12 ...

  7. 3.View绘制分析笔记之onLayout

    上一篇文章我们了解了View的onMeasure,那么今天我们继续来学习Android View绘制三部曲的第二步,onLayout,布局. ViewRootImpl#performLayout pr ...

  8. 4.View绘制分析笔记之onDraw

    上一篇文章我们了解了View的onLayout,那么今天我们来学习Android View绘制三部曲的最后一步,onDraw,绘制. ViewRootImpl#performDraw private ...

  9. 2.View绘制分析笔记之onMeasure

    今天主要学习记录一下Android View绘制三部曲的第一步,onMeasure,测量. 起源 在Activity中,所有的View都是DecorView的子View,然后DecorView又是被V ...

  10. 1.Android 视图及View绘制分析笔记之setContentView

    自从1983年第一台图形用户界面的个人电脑问世以来,几乎所有的PC操作系统都支持可视化操作,Android也不例外.对于所有Android Developer来说,我们接触最多的控件就是View.通常 ...

随机推荐

  1. 「MySQL高级篇」MySQL之MVCC实现原理&&事务隔离级别的实现

    大家好,我是melo,一名大三后台练习生,死去的MVCC突然开始拷打我! 引言 MVCC,非常顺口的一个词,翻译起来却不是特别顺口:多版本并发控制. 其中多版本是指什么呢?一条记录的多个版本. 并发控 ...

  2. Python基础指面向对象:2、动静态方法

    面向对象 一.动静态方法 在类中定义的函数有多种特性 1.直接在类中定义函数 ​ 再类中直接定义函数,默认绑定给对象,类调用时有几个参数就要传几个参数,对象调用时该函数的第一个参数默认为对象 # 定义 ...

  3. Electron是什么以及可以做什么

    新用户购买<Electron + Vue 3 桌面应用开发>,加小册专属微信群,参与群抽奖,送<深入浅出Electron>.<Electron实战>作者签名版. 1 ...

  4. Windows Server 2019 安装 Oracle 19C RAC(VMWare虚拟机环境)

    软件 Windows Server 2019 Standard Oracle 19C Oracle Grid 19 VMware Workstation 16 规划 共享存储,使用Windows Se ...

  5. 在CentOS编译Git源码

    Git 是一个免费的开源分布式版本控制系统,旨在处理从小到小到的所有内容 具有速度和效率的超大型项目. Git易于学习,占用空间很小,性能快如闪电. 它超越了Subversion,CVS,Perfor ...

  6. 英格索兰扳手网口通信协议EOR原理

    前言 前几天遇到这个需求,需要记录扳手每一次的周期数据,但是我不知道通信协议是什么,只知道是一个tcp的连接,问售后,也不给我网口调试软件(英格索兰自己家的软件).经过我俩天的谷歌,终于找到了他们公司 ...

  7. 【PostgreSQL】PG通过SQL语句读取二进制bytea类型并进行二进制和十六进制转换

    1.将二进制编码为十六进制 select encode("AUUID_0",'hex'),"AUUID_0" from wxf_test."ABANK ...

  8. .NET 6 实现滑动验证码(四)、扩展类

    为了能够通过配置文件(appsettings.json)或通过代码进行背景图片与模板进行配置.可自定义资源类型.自定义验证规则,本节创建一些扩展类,用来实现这些功能. 上一节内容:NET 6 实现滑动 ...

  9. Vue快速上门(2)-模板语法

    VUE家族系列: Vue快速上门(1)-基础知识 Vue快速上门(2)-模板语法 Vue快速上门(3)-组件与复用 01.模板语法 1.1.template模板 <template>是H5 ...

  10. 《HTTP权威指南》– 2.HTTP报文与URL资源

    URL与资源: 大多数URL方案的URL语法都建立在这个由9部分构成的通用格式上. 方案: 访问服务器以获取资源要使用哪种协议 用户: 某些方案访问资源时需要的用户名 密码: 用户名后面可能包含的密码 ...