【分析笔记】全志平台 gpio-keys 驱动应用和 stack crash 解决
内核配置
内核版本: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);
原因分析
- gpio_keys 驱动使用 of_get_gpio_flags() 获取 dts 里面 gpio 配置信息。
- 但是 of_get_gpio_flags() 传入 enum of_gpio_flags 类型来获取配置信息。
- of_get_gpio_flags() 的最终实现由具体的 SOC 厂商实现,这里是全志厂商实现。
- 实现的函数为:drivers/pinctrl/sunxi/pinctrl-sunxi.c --> sunxi_pinctrl_gpio_of_xlate()。
- 在 sunxi_pinctrl_gpio_of_xlate() 却是通过强制转换 struct gpio_config 类型存储 gpio 配置信息。
- 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 解决的更多相关文章
- uboot的GPIO驱动分析--基于全志的A10芯片【转】
本文转载自:http://blog.csdn.net/lw2011cg/article/details/68954707 uboot的GPIO驱动分析--基于全志的A10芯片 转载至:http://b ...
- Linux GPIO键盘驱动开发记录_OMAPL138
Linux GPIO键盘驱动开发记录_OMAPL138 Linux基本配置完毕了,这几天开始着手Linux驱动的开发,从一个最简单的键盘驱动开始,逐步的了解开发驱动的过程有哪些.看了一下Linux3. ...
- u-boot启动流程分析(1)_平台相关部分
转自:http://www.wowotech.net/u-boot/boot_flow_1.html 1. 前言 本文将结合u-boot的“board—>machine—>arch—> ...
- zeromq源码分析笔记之线程间收发命令(2)
在zeromq源码分析笔记之架构说到了zmq的整体架构,可以看到线程间通信包括两类,一类是用于收发命令,告知对象该调用什么方法去做什么事情,命令的结构由command_t结构体确定:另一类是socke ...
- Spark大型项目实战:电商用户行为分析大数据平台
本项目主要讲解了一套应用于互联网电商企业中,使用Java.Spark等技术开发的大数据统计分析平台,对电商网站的各种用户行为(访问行为.页面跳转行为.购物行为.广告点击行为等)进行复杂的分析.用统计分 ...
- 微软连续12年成为Gartner分析和BI平台魔力象限的领导者
小悦还沉浸在新春开工大吉的工作中,微软Power BI就又迎来了一个好消息!据Gartner刚新鲜出炉的< 2019年Gartner的分析和商业智能平台魔力象限报告>,微软迄今已连续12 ...
- 3.View绘制分析笔记之onLayout
上一篇文章我们了解了View的onMeasure,那么今天我们继续来学习Android View绘制三部曲的第二步,onLayout,布局. ViewRootImpl#performLayout pr ...
- 4.View绘制分析笔记之onDraw
上一篇文章我们了解了View的onLayout,那么今天我们来学习Android View绘制三部曲的最后一步,onDraw,绘制. ViewRootImpl#performDraw private ...
- 2.View绘制分析笔记之onMeasure
今天主要学习记录一下Android View绘制三部曲的第一步,onMeasure,测量. 起源 在Activity中,所有的View都是DecorView的子View,然后DecorView又是被V ...
- 1.Android 视图及View绘制分析笔记之setContentView
自从1983年第一台图形用户界面的个人电脑问世以来,几乎所有的PC操作系统都支持可视化操作,Android也不例外.对于所有Android Developer来说,我们接触最多的控件就是View.通常 ...
随机推荐
- Python基础部分:4、 python语法之注释
目录 一.python语法之注释 1.什么是注释 2.如何编写注释 二.PEP8规范 一.python语法之注释 1.什么是注释 注释用来向用户提示或解释某些代码的作用和功能,它可以出现在代码中的任何 ...
- ES6 学习笔记(九)Set的基本用法
1 基本用法 set类似于数组,它的成员是唯一的,当有多个相同的值,只会保留一份. 1.1 创建方法 Set本身是一个构造函数,用来生成Set实例,如: const s = new Set() let ...
- 1、Docker最新入门教程-Docker概述
1. Docker概述 Docker 是一个用于开发.运输和运行应用程序的开放平台.Docker 使您能够将应用程序与基础架构分开,以便您可以快速交付软件.使用 Docker,您可以像管理应用程序一样 ...
- cv2.imread opencv读取不到图片问题
解决办法 cv2.imread 路径中包含中文,改为英文 其他 这个问题解决了很久,都属于库的问题
- docker给已存在的容器添加或修改端口映射
简述: 这几天研究了一下docker, 发现建立完一个容器后不能增加端口映射了,因为 docker run -p 有 -p 参数,但是 docker start 没有 -p 参数,让我很苦恼,无奈谷歌 ...
- HCIE Routing&Switching之MPLS静态LSP配置
前文我们了解了MPLS基础理论部分,回顾请参考https://www.cnblogs.com/qiuhom-1874/p/16928096.html:今天我们来聊一聊MPLS静态LSP配置相关话题: ...
- dotnet new cli 以及Abp-cli命令的简单使用
1:要求 首先dotnet new 需要 .NET Core 3.1 SDK 以及更高版本 dotnet new - 根据指定的模板,创建新的项目.配置文件或解决方案 2:变化 从 .NET 7 S ...
- C# 操作IIS加强版(添加,删除,启动,暂停网站,默认页,绑定信息)
C# 操作IIS加强版(添加,删除,启动,暂停网站,默认页,绑定信息) 主要功能如下 在本机的IIS创建Web网站 删除网站包括应用程序池 删除应用程序池 添加默认文档 删除默认文档 添加虚拟目录 删 ...
- 自定义RBAC(5)
您好,我是湘王,这是我的博客园,欢迎您来,欢迎您再来- 把实体类及Service类都准备好了之后,就可以开始继续写业务代码了.Spring Security的强大之一就在于它的拦截器.那么这里也可以参 ...
- kali安装拼音输入法
前言 最近使用kali感觉没个中文输入法的很不方便,于是决定装个ibus的拼音输入法 安装方法 1.安装ibus 使用命令apt install ibus ibus-pinyin,注意使用root权限 ...