【分析笔记】全志平台 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.通常 ...
随机推荐
- nginx+keepalived实现主从模式双机热备份
主从模式就是一台机器提供服务,另一台机器作为备份机,当主机的服务停止时,备份机立刻接替主机的服务. 安装 安装nginx wget http://nginx.org/download/nginx-1. ...
- ES 客户端 RestHighLevelClient Connection reset by peer 亲测有效 2022-11-05
导读 最新公司ES集群老出现连接关闭,进而导致查询|写入ES时报错,报错日志显示如下 [2m2022-10-23 14:13:10.088[0;39m - [31mERROR[0;39m - [35m ...
- Substring 在BCL和CLR里面搞了啥
楔子 还是做点事情,不要那么散漫. 本文以简单的Substring(int startindex,int Length)函数为例,来递进下它在托管和非托管的一些行为. 以下均为个人理解,如有疏漏请指正 ...
- 「浙江理工大学ACM入队200题系列」问题 E: 零基础学C/C++78——求奇数的乘积
本题是浙江理工大学ACM入队200题第八套中的E题 我们先来看一下这题的题面. 题面 输入 输入数据包含多个测试实例,每个测试实例占一行,每行的第一个数为n,表示本组数据一共有n个,接着是n个整数,你 ...
- MYSQL数据库的导出和导入
一.连接服务器查看数据库 使用连接工具(xshell6等)连接到数据库所在服务器,执行命令查询需要导出的数据库 1.输入数据库管理员账号密码进入控制台:mysql -uroot -p123456 ...
- Python用yield form 实现异步协程爬虫
很古老的用法了,现在大多用的aiohttp库实现,这篇记录仅仅用做个人的协程底层实现的学习. 争取用看得懂的字来描述问题. 1.什么是yield 如果还没有怎么用过的话,直接把yield看做成一种特殊 ...
- hwlog----types.go
// Copyright(C) 2021. Huawei Technologies Co.,Ltd. All rights reserved.// Package hwlog provides the ...
- Go语言书籍推荐
附录: 其他书籍的介绍:https://github.com/golang/go/wiki/Books Go程序设计语言 (圣经) 作者 艾伦 A.A.多诺万 Kernighan 下载地址 中文版PD ...
- 【Linux】通过Crontab和shell脚本实现定期备份和删除PG数据库表数据
〇.参考资料 一.Crontab使用 1.查看状态 service crond status 2.新建crontab任务 crontab -e 输入字符串 * * * * * cd /home/big ...
- Django查看内部sql语句的方式
一:查看内部sql语句的方式 方式1(queryset对象才能够点击query查看内部的sql语句) res = models.User.objects.values_list('name', 'ag ...