内核配置


内核版本: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. 使用 Cravatar 解决 Gravatar 头像无法访问的问题

    Gravatar全球通用头像服务 1.基本介绍 Gravatar,即全球公认的头像,是一项免费的头像服务,适用于网站所有者,开发人员以及任何想要轻松且经过验证的在线身份的人.它被内置在每个WordPr ...

  2. VUE学习2

    目录分析 public目录 index.html是起始的html文件 # 这是关键 <div id="app"></div> src目录 main.js是V ...

  3. Golang 实现时间戳和时间的转化

    何为时间戳: 时间戳是使用数字签名技术产生的数据,签名的对象包括了原始文件信息.签名参数.签名时间等信息.时间戳系统用来产生和管理时间戳,对签名对象进行数字签名产生时间戳,以证明原始文件在签名时间之前 ...

  4. OpenMP 教程(一) 深入人剖析 OpenMP reduction 子句

    OpenMP 教程(一) 深入人剖析 OpenMP reduction 子句 前言 在前面的教程OpenMP入门当中我们简要介绍了 OpenMP 的一些基础的使用方法,在本篇文章当中我们将从一些基础的 ...

  5. C++ 中指针常量、指向常量的指针、引用类型的常量

    命题1. 在C++ 中 const T a 与 T const a 是一样的, 表示a是一个T类型的常量. 测试: 一. 形参定义为引用类型的常量 在函数传参时,形参若定义为 const T& ...

  6. 嵌入式-C语言基础:指针函数

    指针函数:返回指针的函数,即函数返回一个地址.例如:int * a(int x,int y);由于()的优先级比*高,因此a先与()结合,a(int x,int y)显然是一个函数,函数前面带一个in ...

  7. 2022春每日一题:Day 10

    题目:CF1110E Magic Stones 每次操作 c[i]变成c[i-1]+c[i+1]-c[i],那么显然,c[1]和c[n]是不会改变的,因此只要c[1]和t[1],c[n]和t[n]不相 ...

  8. Armv8之Execution State 和 Exception Level(一)

    @ 目录 1. 典型的Exception Level使用模型 2.异常相关术语 3. Execution State 3.1 两种Execution State 3.2 决定Execution Sta ...

  9. Redux 的困扰与如何技术选型

    文章的名字我想了很久,备选项有"我再不推荐 Redux","Redux 为什么令我头疼","Redux 进化启示录"等等.通过这一系列名字我 ...

  10. 第2-4-4章 规则引擎Drools规则属性-业务规则管理系统-组件化-中台

    目录 5. 规则属性 5.1 enabled属性 5.2 dialect属性 5.3 salience属性 5.4 no-loop属性 5.5 activation-group属性 5.6 agend ...