首页
关于
友链
其它
统计
壁纸
Search
1
修改Linux Kernel defconfig的标准方法
5,660 阅读
2
cgroup--(4)cgroup v1和cgroup v2的详细介绍
5,207 阅读
3
Android系统之VINTF(1)manifests&compatibility matrices
5,118 阅读
4
c语言的__attribute__
3,012 阅读
5
使用git生成patch和应用patch
2,448 阅读
默认分类
文章收集
学习总结
每天一刷
环境配置
知识点
入门系列
vim
shell
Git
Make
Android
Linux
Linux命令
内存管理
Linux驱动
Language
C++
C
工具
软件工具
Bug
COMPANY
登录
Search
标签搜索
shell
Linux
c
uboot
Vim
vintf
Linux驱动
Android
device_tree
git
DEBUG
链表
数据结构
IDR
内核
ELF
gcc
网址
内存管理
进程管理
adtxl
累计撰写
342
篇文章
累计收到
8
条评论
首页
栏目
默认分类
文章收集
学习总结
每天一刷
环境配置
知识点
入门系列
vim
shell
Git
Make
Android
Linux
Linux命令
内存管理
Linux驱动
Language
C++
C
工具
软件工具
Bug
COMPANY
页面
关于
友链
其它
统计
壁纸
搜索到
125
篇与
的结果
2023-04-26
ARM的中断处理[一]
转载自https://zhuanlan.zhihu.com/p/85313527 作者:兰新宇
2023年04月26日
363 阅读
0 评论
0 点赞
2023-04-26
Linux中的中断处理机制[八]--任务工厂workqueue机制(2)
转载自https://zhuanlan.zhihu.com/p/94561631 作者兰新宇
2023年04月26日
278 阅读
0 评论
0 点赞
2023-04-26
Linux中的中断处理机制[七]--任务工厂workqueue机制(1)
转载自https://zhuanlan.zhihu.com/p/91106844, 作者兰新宇
2023年04月26日
208 阅读
0 评论
0 点赞
2023-04-26
Linux中的中断处理机制[六]--从tsklet到中断线程化
转载自https://zhuanlan.zhihu.com/p/89913872, 作者兰新宇
2023年04月26日
158 阅读
0 评论
0 点赞
2023-04-25
Linux的中断处理机制[五]--softirq(2)
转载自https://zhuanlan.zhihu.com/p/80680484, 作者:兰新宇
2023年04月25日
175 阅读
0 评论
0 点赞
2023-04-24
Linux的中断处理机制[四]--softirq(1)
转载自https://zhuanlan.zhihu.com/p/80371745 作者兰新宇
2023年04月24日
157 阅读
0 评论
0 点赞
2023-04-23
Linux的中断处理机制[三]--hardirq
转载自兰新宇专栏,https://zhuanlan.zhihu.com/p/85454778
2023年04月23日
170 阅读
0 评论
0 点赞
2023-04-23
Linux的中断处理机制[二]--数据结构(2)
转载自https://zhuanlan.zhihu.com/p/85353687,作者兰新宇
2023年04月23日
244 阅读
0 评论
0 点赞
2023-04-21
Linux的中断处理机制[一]--数据结构(1)
转载自兰新宇专栏,https://zhuanlan.zhihu.com/p/83709066
2023年04月21日
185 阅读
0 评论
0 点赞
2023-03-13
Linux pstore实现
本文目的一是为了介绍下pstore,这个主要参考(copy):joy:文章Linux pstore 实现自动“抓捕”内核崩溃日志,这篇文章的作者也是pstore/blk模块的作者。二是为了记录打开pstore/blk功能时遇到的一些问题。1. 简介pstore文件系统(是的,这是个文件系统)是Persistent Storage的缩写,最早在2010年由 Tony Luck 设计并合入Linux主分支,设计的初衷是在内核Panic/Oops时能自动转存内核日志(log_buf),在Panic重启后,把转存的日志以文件形式呈现到用户空间以分析内核崩溃问题。这对分析那种小概率且没办法抓到现场的问题非常实用,尤其是现在智能互联网的设备逐渐普及的时候,远端的设备可以自己捕抓崩溃日志再通过网络传输到服务器,维护人员就可以根据收集来的日志定位和解决问题,然后通过OTA让设备升级迭代。根据网上搜寻的资料,在pstore文件系统之前其实有不少类似的实现。apanicAndroid最早的panic信息记录的方案。在linux 2.6的安卓的内核中找到,却没有提交到社区,后来被放弃维护了。网上找不到放弃的原因,我自己猜测是因为其只适用于mtd nand,然而现在的Android基本用的都是emmc。apanic应该是Android Panic的缩写吧,可以实现在内核崩溃时,把日志转存到mtd nand。ramoops这里指的是最早的ramoops实现,在最新代码已经整合入pstore中,以pstore/ram的后端形式存在。ramoops可以把日志转存到重启不掉电的ram中。这里对ram有一点要求,即使重启ram的数据也不能丢失。crashlog这是openwrt提供的内核patch,并没有提交到内核社区。它也是基于ram,只能转存Panic/Oops的日志。mtdoopsMTD子系统支持的功能,与pstore非常相似,只支持转存Panic/Oops日志,不能以文件呈现,需要用户自行解析整个MTD分区。(因为功能的相似,我实现了mtdpstore用于替代mtdoops)kdump如果说pstore是个轻量级的内核崩溃日志转存的方案,kdump则是一个重量级的问题分析工具。在崩溃时,由kdump产生一个用于捕抓当前信息的内核,该内核会收集内存所有信息到dump core文件中。在重启后,捕抓到的信息保存在特定的文件中。类似的还有netdump和diskdump。kdump的方案适用于服务器这种有大量资源的设备,功能也非常强大,但对嵌入式设备非常不友好。pstore经过长期迭代,除了转存Panic/Oops的日志之外(dmesg前端),还支持pmsg、console和ftrace的前端,除了pstore/ram的后端之外,还有我设计的pstore/blk后端,除了支持转存到ram之外,还有block device和mtd device。pstore的前端,是指转存的日志类型,pstore的后端,是指转存到什么类型的设备。目前支持以下几个前端:dmesg:主要是转存Panic/Oops时log_buf里面的内核日志pmsg:提供给用户空间存储日志的入口,在Android里有看到被用于存储系统的日志。console:终端日志ftrace:function trace的信息目前支持以下几种后端:pstore/ram:Persistent Ram,重启不会丢数据的内存。补充:我个人的理解是即使是普通的ram,也是可以保存重启的log的,但这里的重启不能是那种掉电的重启,不掉电的重启应该是可以保存重启前的log的pstore/blk:(v5.8以后的版本)所有可写的块设备,例如磁盘、U盘、emmc、NFTL nand等mtd device:(v5.8以后的版本)mtd设备,例如 mtd nand。(mtd设备的支持依赖于 pstore/blk 后端,准确来说不是一种独立后端)2. 使用就像把大象装入冰箱只需要打开冰箱,把大象放进去,关上冰箱门的3个步骤,使用pstore也只需要3个步骤:使能 pstore挂载 pstore文件系统读取 转存的日志文件详细的说明可以看源码上的文档,本文只做基本功能的介绍。Documentation/admin-guide/ramoops.rstDocumentation/admin-guide/pstore-blk.rst2.1 使能pstore如果需要pstore功能,可以通过menuconfig选择打开pstore相关的config$ make menuconfig |-> File systems |-> Miscellaneous filesystems |-> Persistent store support |-> Log kernel console messages # console 前端 |-> Log user space messages # pmsg 前端 |-> Persistent function tracer # ftrace 前端 |-> Log panic/oops to a RAM buffer # pstore/ram 后端 |-> Log panic/oops to a block device # pstore/blk 后端 上述两个后端2选1即可,前端就根据自己的需求选择,至于dmesg前端,默认使能没得选。如果希望用在mtd设备上,还需要选择mtdpstore模块:$ make menuconfig |-> Device Drivers |-> Memory Technology Device (MTD) support |-> Log panic/oops to an MTD buffer based on pstore 选上就可以用了?虽然我非常想说“是的”,但事实却有点“骨感”。即使所有前端都使用默认配置,pstore/ram至少也需要知道可用的内存范围吧?pstore/blk至少也需要知道使用哪个块设备吧?pstore/ram支持 模块参数(cmdline)、设备树、和Platform Data的3种配置方式,从代码来看,优先级关系是:模块参数 > Platform Data > 设备树。pstore/blk支持 Kconfig和 模块参数(cmdline)的两种配置方式,且模块参数比Kconfig有更高的优先级。pstore/ram我接触也不多,直接介绍pstore/blk的使用方法。对新同学来说,请忽略一大堆乱七八糟的属性配置(使用默认值),只需要告诉pstore/blk后端使用哪个块设备即可。在Kconfig中配置:$ make menuconfig |-> File systems |-> Miscellaneous filesystems |-> Persistent store support |-> Log panic/oops to a block device # pstore/blk 后端 |-> () block device identifier # 使用哪个块设备? 如果使用cmdline,可以这么写:pstore_blk.blkdev=XXXX或者以模块加载:$ sudo insmod pstore_blk.ko blkdev=XXX 这里的块设备可以是代表整个磁盘的sda,也可以是代表某个分区的mmcblk0p4。虽然支持7种变体,但常用的还是两种:/dev/<disk_name>: 例如,使用U盘的第2个分区,则是/dev/sdb2 <major>:<minor>:例如,mmc设备第6个分区,则是179:6形式大概是这样:$ sudo insmod pstore_blk.ko blkdev=/dev/sdb2或者$ cat /proc/cmdline .... pstore_blk.blkdev=179:6 ... 如果是mtd设备,可以直接指定mtd分区名或者编号,例如:pstore_blk.blkdev=pstore # 假设存在名为pstore的MTD分区OK,对新同学来说,到这里配置就够了。可以从我的github上看到我之前是怎么测试的Test-Pstore-Block。如果需要知道每个配置项的作用,还是看内核文档吧(ramoops.rst 或 pstore_blk.rst),或者在Kconfig中按h显示相关配置项的说明。2.2 挂载在使能且正确配置设备后,启动的时候应该会有这样的日志:pstore_zone: registered pstore_blk as backend for kmsg(Oops,panic_write) pstore: Registered pstore_blk as persistent store backend这代表pstore找到了设备且正常注册。接下来,我们还需要通过挂载的形式触发pstore从设备读取数据。常见的挂载是这样的:mount -t pstore pstore /sys/fs/pstore挂载后,通过mount能看到类似这样的信息:# mount ... pstore on /sys/fs/pstore type pstore (rw,relatime) ...如果曾经触发过崩溃日志,在挂载点应该有类似这样的文件:# ll /sys/fs/pstore ... -r--r--r-- 1 root root 15521 Jan 1 00:06 dmesg-pstore_blk-0 ...如果需要验证,咱们可以这样主动触发内核崩溃:# echo c > /proc/sysrq-trigger我是在U盘、SD卡、mmc、nand上验证的,maintainer Kees Cook 提供了另外一种基于loop的验证方法,实现用文件模拟块设备。当然这方法不适用于转存Panic日志,只能用于Oops或者其他前端:# insmod pstore.ko compress=off # insmod pstore_zone.ko # truncate pstore-blk.raw --size 100M # losetup -f --show pstore-blk.raw /dev/loop0 # insmod pstore_blk.ko blkdev=/dev/loop0 kmsg_size=16 console_size=64 best_effort=on 2.3 读取经过上述的挂载后,可以在挂载点看到转存的日志文件。既然是文件,肯定支持文件的一系列操作,例如读取、删除。root@TinaLinux:/sys/fs/pstore# head -n 10 dmesg-pstore_blk-1 Oops: Total 2 times Oops#1 Part1 <6>[ 2.743794] Bluetooth: RFCOMM socket layer initialized <6>[ 2.743813] Bluetooth: RFCOMM ver 1.11 <6>[ 2.743822] 8021q: 802.1Q VLAN Support v1.8 <3>[ 2.751766] reg-virt-consumer reg-virt-consumer.1: Failed to obtain supply 'drivevbus': -517 <3>[ 2.752330] reg-virt-consumer reg-virt-consumer.1: Failed to obtain supply 'drivevbus': -517 <5>[ 2.752742] ubi0: attaching mtd4 <5>[ 2.890302] random: crng init done <5>[ 2.965927] ubi0: scanning is finished root@TinaLinux:/sys/fs/pstore# ll drwxr-x--- 2 root root 0 Jan 1 00:11 . drwxr-xr-x 5 root root 0 Jan 1 00:11 .. -r--r--r-- 1 root root 15521 Jan 1 00:06 dmesg-pstore_blk-0 -r--r--r-- 1 root root 15128 Jan 1 00:11 dmesg-pstore_blk-1 root@TinaLinux:/sys/fs/pstore# rm dmesg-pstore_blk-1 root@TinaLinux:/sys/fs/pstore# ll drwxr-x--- 2 root root 0 Jan 1 00:13 . drwxr-xr-x 5 root root 0 Jan 1 00:11 .. -r--r--r-- 1 root root 15521 Jan 1 00:06 dmesg-pstore_blk-0对dmesg前端的Panic/Oops日志,pstore会自动添加两行统计信息。例如:Oops: Total 2 times # 表示触发了Oops,且是自系统安装后第一次启动以来第2次触发Oops。 Oops#1 Part1 # 表示这是上一次运行期间第1次触发Oops的日志。可以发现,第一行是累计总的触发次数,第二行是上一次启动触发的次数。每个文件名的格式都是<前端名>-<后端名>-,例如dmesg-pstore_blk-1表示dmesg前端,pstore_blk后端以及是dmesg前端的第1个zone的日志。当然,除了dmesg前端外,其他前端的名字大概是这样的:# ll -r--r--r-- 1 root root 31 1月 15 11:53 console-pstore-blk-0 -r--r--r-- 1 root root 3666 1月 15 11:53 demsg-pstore-blk-0 -r--r--r-- 1 root root 65524 1月 15 11:53 ftrace-pstore-blk-0 -r--r--r-- 1 root root 9 1月 15 11:53 pmsg-pstore-blk-0 除此之外,每个文件的时间戳表示 崩溃触发的时间。上例中,由于系统并没有实现同步更新系统时间,所以时间戳不合理。3. 展望未来正如我前文说的,pstore在物联网设备逐渐普及的现在,能发挥很大的作用,例如智能音箱和扫地机已经用起来了。全功能支持到目前为止,不管是块设备还是mtd设备,社区的代码都没能做到pstore的全部前端的支持。设备dmesg(Oops)dmesg(Panic)pmsgconsoleftrace块设备YNYYYMTD设备YYNNNram设备YYYYY块设备如果需要记录Panic日志,需要提供一个在Panic时写块设备的接口。我在全志的mmc和nand驱动中实现了这样的接口,却因为种种原因不适合提交到社区。社区块驱动的适配寄希望于更多同学的努力了。MTD设备很早前就有了panic_write()的定义,因此可以支持Panic日志转存。不支持其他前端,则是因为其擦写的物理特性。对pmsg,console,ftrace等这些不能页对齐写入的前端,还需要更多的适配工作。迁移pstore/ram在当前pstore的目录结构是这样的:$ tree fs/pstore fs/pstore/ ├── blk.c # pstore/blk 后端的实现 ├── ftrace.c # ftrace 前端的实现 ├── inode.c # pstore 文件系统的注册与操作 ├── internal.h ├── Kconfig ├── Makefile ├── platform.c # pstore 前后端功能的核心 ├── pmsg.c # pmsg 前端的实现 ├── ram.c # pstore/ram 后端的实现 ├── ram_core.c # pstore/ram 后端的实现 └── zone.c # pstore/zone 实现存储空间的分配和管理在我的补丁之前,只支持转存日志到ram,因此如果研读代码,我们会发现ram.c和ram_core.c实现了两部分功能:dram空间分配与管理dram的读写操作我实现的blk.c支持了转存到块设备。但是后来发现不管pstore/ram还是pstore/blk,他们对于存储空间的分配和管理极度相似,我就提炼出了pstore/zone。于是乎,期望的代码层次应该是这样的:pstore/ram要整合入pstore/zone已经与maintainer达成共识,但还需要更多同学一同努力做更多兼容,例如ecc的支持。4. 在Android中使能pstore记录4.1 使能pstroe ram1.使能config最好用menuconfig配下CONFIG_PSTORE_CONSOLE=y CONFIG_PSTORE_PMSG=y CONFIG_PSTORE_RAM=y CONFIG_PSTORE_FTRACE=y在reserved_memory中预留一段内存例如: ramoops@1ff00000 { compatible = "ramoops"; reg = <0x0 0x1ff00000 0x0 0x40000>; console-size = <0x10000>; record-size = <0x10000>; ftrace-size = <0x10000>; pmsg-size = <0x20000>; };4.3 使能pstore/blk由于pstore/blk功能是kernel 5.8之后合入的,而我现在使用的还是kernel 4.19.所以默认是不包含pstore/blk功能的。所以需要手动合入下这个patch.华为有把这个patch合入到openharmony-4.19中,所以这里直接使用了这个华为的patch.参考网址:https://lists.openatom.io/hyperkitty/list/kernel@openharmony.io/thread/HXXXLB2ZDRHLR7DZSEZPWIJLT3RFDF44/合入之后obj-m的时候编译有一些小问题,没啥记录的意义了,根据报错来解决就好了。主要步骤如下:1.打开kernel中的config,有些config参数不需要配置可以使用默认的例如,我的设置如下,我这里没有吧pstore_blk编译到kernel,而是编译成ko手动加载,具体原因在后面的问题中再说明CONFIG_PSTORE_CONSOLE=y CONFIG_PSTORE_PMSG=y CONFIG_PSTORE_FTRACE=y CONFIG_PSTORE_BLK=m CONFIG_PSTORE_BLK_KMSG_SIZE=1024 CONFIG_PSTORE_BLK_PMSG_SIZE=1024 CONFIG_PSTORE_BLK_CONSOLE_SIZE=1024 CONFIG_PSTORE_BLK_FTRACE_SIZE=1024 2.将ko打包生成到vendor.img这个每个厂家的方式都不同,我的是在Android.mk中做的,例如include $(CLEAR_VARS) LOCAL_MODULE_CLASS := ETC LOCAL_MODULE_PATH := $(TARGET_OUT_VENDOR)/lib/modules/ LOCAL_MODULE_TAGS := optional LOCAL_MODULE := pstore_zone.ko LOCAL_MODULE_RELATIVE_PATH := kernel/fs/pstore include $(BUILD_SYSTEM)/base_rules.mk $(LOCAL_BUILT_MODULE): $(BSP_KMOD_DIR)/$(LOCAL_MODULE_RELATIVE_PATH)/$(LOCAL_MODULE) | $(ACP) $(_kmod_strip) include $(CLEAR_VARS) LOCAL_MODULE_CLASS := ETC LOCAL_MODULE_PATH := $(TARGET_OUT_VENDOR)/lib/modules/ LOCAL_MODULE_TAGS := optional LOCAL_MODULE := pstore_blk.ko LOCAL_MODULE_RELATIVE_PATH := kernel/fs/pstore include $(BUILD_SYSTEM)/base_rules.mk $(LOCAL_BUILT_MODULE): $(BSP_KMOD_DIR)/$(LOCAL_MODULE_RELATIVE_PATH)/$(LOCAL_MODULE) | $(ACP) $(_kmod_strip) 在device.mk中添加PRODUCT_PACKAGES += \ pstore_zone.ko \ pstore_blk.ko 3.添加一个分区因为要把log保存到emmc中,所以在emmc里单独增加一个分区保存log。我这路设置大小为4m.例如,BOARD_PSTOREIMAGE_FILE_SYSTEM_TYPE := ext4 BOARD_PSTOREIMAGE_PARTITION_SIZE := $(shell $(PARTITION_LAYOUT_PATH)/gpt_size.py $(PARTITION_LAYOUT_FILE) pstore) <user_entry type = "{EBD0A0A2-B9E5-4433-87C0-68B6B72699C7}" uuid = "{44a87358-c673-4140-9603-96ad7f8af66d}" name = "pstore" size_kb = "4096" /> 4.在rc文件中insmod例如,我的是在boot.insmod.cfg中添加,insmod|/vendor/lib/modules/kernel/fs/pstore/pstore_zone.ko insmod|/vendor/lib/modules/kernel/fs/pstore/pstore_blk.ko blkdev=/dev/block/by-name/pstore best_effort=on请注意insmod时需要执行一些驱动参数变量,其中blkdev是指定使用哪个分区,best_effort是因为我的blk driver没有panic_write函数,否则无法加载成功5.修改文件节点权限及selinux权限在ueventd.rc中修改/dev/block/by-name/pstore 0660 system system在rc文件中,chown system system /dev/block/by-name/pstore还有些selinux权限,不确定如何加的话可以把selinux设置为permissive模式,根据log加下,我加了下面这几个,在init-insmod-sh.te文件中添加,allow init-insmod-sh block_device:dir search;在vendor_init.te中添加,allow vendor_init block_device:lnk_file setattr;6.功能测试测试结果如下,符合预期效果。由于blk驱动不支持panic_write函数,所以无法抓取dmesg(panic log).因此,使用pstore_blk在我的平台最多只能抓取三种前端log.ps:默认情况下是没有ftrace-pstore_blk-0的,下面有是因为我打开了ftrace测试的7.问题实际使用在我的平台上还是有问题的,有些问题还需要继续研究下。问题1:在我的平台上无法使用obj-y将该驱动built in kernel如果built in kernel在开机时启动,会导致开机速度变慢。主要原因是和抓取pmsg有关,测试如果不抓pmsg的log,基本无影响。如果使用obj-m,放在on boot阶段,测试对开机也基本无影响问题2:开机后,如果抓取太多ftrace log,会造成系统严重卡顿开机后,测试ftrace时,echo 1 > /sys/kernel/debug/pstore/record_ftrace系统卡顿严重问题3:原始的patch被标记为BROKEN,后来fix了后来该问题被fix,我们使用的kernel 4,19patch并不包含下面这个fix的patch,尝试把这个patch merge,问题比较多,还需要仔细研究下。参考:1.Pstore 的一些记录
2023年03月13日
513 阅读
0 评论
0 点赞
1
2
3
...
13