首页
chatGPT
关于
友链
其它
统计
更多
壁纸
留言
Search
1
cgroup--(4)cgroup v1和cgroup v2的详细介绍
6,535 阅读
2
修改Linux Kernel defconfig的标准方法
6,448 阅读
3
Android系统之VINTF(1)manifests&compatibility matrices
6,054 阅读
4
使用git生成patch和应用patch
3,570 阅读
5
c语言的__attribute__
3,183 阅读
默认分类
文章收集
学习总结
算法
环境配置
知识点
入门系列
vim
shell
Git
Make
Android
Linux
Linux命令
内存管理
Linux驱动
Language
C++
C
Rust
工具
软件工具
Bug
COMPANY
登录
Search
标签搜索
Rust
shell
Linux
c
uboot
Vim
vintf
Linux驱动
Android
device_tree
git
DEBUG
arm64
链表
数据结构
IDR
内核
ELF
gcc
ARM
adtxl
累计撰写
380
篇文章
累计收到
16
条评论
首页
栏目
默认分类
文章收集
学习总结
算法
环境配置
知识点
入门系列
vim
shell
Git
Make
Android
Linux
Linux命令
内存管理
Linux驱动
Language
C++
C
Rust
工具
软件工具
Bug
COMPANY
页面
chatGPT
关于
友链
其它
统计
壁纸
留言
搜索到
126
篇与
的结果
2023-04-26
ARM的中断处理[一]
转载自https://zhuanlan.zhihu.com/p/85313527 作者:兰新宇
2023年04月26日
489 阅读
0 评论
0 点赞
2023-04-26
Linux中的中断处理机制[八]--任务工厂workqueue机制(2)
转载自https://zhuanlan.zhihu.com/p/94561631 作者兰新宇
2023年04月26日
378 阅读
0 评论
0 点赞
2023-04-26
Linux中的中断处理机制[七]--任务工厂workqueue机制(1)
转载自https://zhuanlan.zhihu.com/p/91106844, 作者兰新宇
2023年04月26日
282 阅读
0 评论
0 点赞
2023-04-26
Linux中的中断处理机制[六]--从tsklet到中断线程化
转载自https://zhuanlan.zhihu.com/p/89913872, 作者兰新宇
2023年04月26日
195 阅读
0 评论
0 点赞
2023-04-25
Linux的中断处理机制[五]--softirq(2)
转载自https://zhuanlan.zhihu.com/p/80680484, 作者:兰新宇
2023年04月25日
246 阅读
0 评论
0 点赞
2023-04-24
Linux的中断处理机制[四]--softirq(1)
转载自https://zhuanlan.zhihu.com/p/80371745 作者兰新宇
2023年04月24日
190 阅读
0 评论
0 点赞
2023-04-23
Linux的中断处理机制[三]--hardirq
转载自兰新宇专栏,https://zhuanlan.zhihu.com/p/85454778
2023年04月23日
242 阅读
0 评论
0 点赞
2023-04-23
Linux的中断处理机制[二]--数据结构(2)
转载自https://zhuanlan.zhihu.com/p/85353687,作者兰新宇
2023年04月23日
355 阅读
0 评论
0 点赞
2023-04-21
Linux的中断处理机制[一]--数据结构(1)
转载自兰新宇专栏,https://zhuanlan.zhihu.com/p/83709066
2023年04月21日
277 阅读
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日
743 阅读
0 评论
0 点赞
1
2
3
...
13