底层稳定性笔记

目录

1、coredump 生成

2、MTK  coredump

3、KE  分析

4、T32 使用


1、coredump 生成

Ctl.start 启动服务,服务结束回收
system/core/init/init.cpp 
ReapAnyOutstandingChildren
1、init 中while 循环会在服务退出时回收exited 状态服务;
2、InstallSignalFdHandler-》HandleSignalFd 对SIGCHLD、SIGTERM

system/core/init/sigchld_handler.cpp
ReapAnyOutstandingChildren-》
ReapOneProcess() -》
service->Reap(siginfo);->KillProcessGroup(SIGKILL, true);

do_exit_group
https://blog.csdn.net/tjcwt2011/article/details/80272127

Java 进程使能coredump 
SpecializeCommon;后面执行postForkCommon。
打开coredump 

底层稳定性笔记_第1张图片

NE 异常打印coredump

force_sig_info->send_signal  这里面会将信号加入对了,get_signal 会获取信号,根据sig_kernel_coredump(signr) 来确定是否调用do_coredump(&ksig->info)

USER 版本打开uart log

vendor/mediatek/proprietary/bootable/bootloader/preloader/platform/mt67XX/default.mak

CFG_UART_DYNAMIC_SWITCH 配置为0

kernel-4.19/drivers/misc/mediatek/log_store/

kernel-4.9/drivers/misc/mediatek/aee/aed/

int set_emmc_config(int type, int value); 函数设置expdb 分区使能类型

vendor\mediatek\proprietary\bootable\bootloader\lk\app\mt_boot\aee\KEDump.c

int kedump_mini(void)  将异常日志写入expdb分区

2、MTK  coredump

vendor/mediatek/proprietary/bootable/bootloader/lk/platform/mt6779/mt_pmic.c

Mrdump_tool

Mrdump Ramdump

打开rampdump

P版本

  1. lk/platform/mt67XX/rules.mk中 ARCH_HAVE_MT_RAMDUMP设为 yes

ARCH_HAVE_MT_RAMDUMP 时平台是否支持,优先级最高

KEDUMP_MINI 支持才会使能MTK_MRDUMP_ENABLE

MTK_MRDUMP_ENABLE 是打印coredump ,KEDUMP_MINI 是打印minidump

vendor/mediatek/proprietary/bootable/bootloader/lk/app/mt_boot/rules.mk

MTK_MRDUMP_ENABLE 可以为dconfig/yes/no/空,控制build_mt_ramdump

 

2、lk/project/$(project).mk中设置MTK_MRDUMP_ENABLE = yes。【MTK_MRDUMP_ENABLE不设定时,eng版本默认应该是打开mrdump的】

Q版本

在P版本基础上,新增dconfig配置方式,配置方法是在lk/project/$(project).mk中设置MTK_MRDUMP_ENABLE = dconfig。

dconfig配置方式时候一种动态控制,根据boot_para.img里的标志位来判断是否要打开mrdump(没有烧录特定的boot_para.img则不开启mrdump)。

boot_para.img要如何生成呢?具体请看DCC上的文档:CS6000-BH8B-UMD-V1.5EN_MediaTek Logging SOP.docx里的《Dynamic enable fulldump for user load》章节

vendor/mediatek/proprietary/bootable/bootloader/lk/platform/mt6779/platform.c

platform_init->boot_mode_select

vendor/mediatek/proprietary/bootable/bootloader/lk/platform/mt6779/boot_mode.c

底层稳定性笔记_第2张图片

Kedump 开始log

mrdump_check 如果是dconfig 就会从boot_para.img中获取socid

mrdump_check-》mrdump_detection->

mrdump_check_enable()//socid

mrdump_key_secure_enable//

mrdump_key_secure_enable 配置长按电源键产生dump

mrdump_get_default_output_device(void)//

从环境变量mrdump_output 获取dump存储位置,internal-storage/usb/partition,环境变量没有设置就是要系统的默认配置

aee_mrdump_get_params//

vendor/mediatek/proprietary/bootable/bootloader/lk/platform/mt6765/include/platform/mtk_mrdump.h

#define MRDUMP_CB_ADDR 0x0010E800

#define MRDUMP_CB_SIZE 0x1400

mrdump_control_block 对应地址与长度

从开始地址,字符串是MRDUMP_GO_DUMP,则有对应控制块

#define MRDUMP_GO_DUMP "MRDUMP09"

Kdump 位置

voprintf_info("Kdump triggerd by '%s' (address:%x, size:%lluM)\n",

mrdump_mode2string(mrdump_cblock->crash_record.reboot_mode),DRAM_PHY_ADDR, mrdump_mem_size() / 0x100000UL);

address:0x40000000, size:6144M

底层稳定性笔记_第3张图片

Check是这些模式返回1

底层稳定性笔记_第4张图片

mrdump_detect 返回1 则进入mrdump_run2,或者进入fastboot 通过usb dump ,打开背光;

底层稳定性笔记_第5张图片

kdump_ui 中根据ramdump 存储位置,显示对应界面进入dump,如下面截图:

Dump完成打印信息,如果dump 过程被中断,则在dump 存储末端写入最大长整数,否则是ramdump 长度;重启进入bootloader 启动

底层稳定性笔记_第6张图片

Dump 完成则将调用mrdump_write_resultcblock_result 写入MRDUMP_CB_ADDR 位置,对应签名MRDUMP_GO_DUMP;reset 手机重新进入bootloader 启动

底层稳定性笔记_第7张图片

Ramdupm 设备:

/sys/module/mrdump/parameters

底层稳定性笔记_第8张图片

底层稳定性笔记_第9张图片

底层稳定性笔记_第10张图片

kernel-4.19/arch/arm/kernel/traps.c

Arm_notify_die ->

底层稳定性笔记_第11张图片

kernel-4.19/kernel/notifier.c

int notrace notify_die

int register_die_notifier(struct notifier_block *nb)

int unregister_die_notifier(struct notifier_block *nb)

用户空间异常走force_sig_info,内核异常走die;

kernel-4.19/kernel/signal.c

do_signal是内核信号处理的入口,真正的信号处理逻辑在get_signal_to_deliver函数中

底层稳定性笔记_第12张图片

coredump使用

coredump机制目前内核默认都已经集成,主要的配置接口有:

1、ulimit,通过ulimit -a查看当前配置,执行ulimit -c unlimited将core file size改为ulimited

2、/proc/sys/kernel/core_pattern,该配置项用于配置生成的core文件路径已经名字,相信信息可以通过man 5 core来查询

3、/proc/pid/core_filter,用于配置dump文件具体内容,详细信息可以通过man 5 core来查询

coredump配置、产生、分析以及分析示例 - ArnoldLu - 博客园

https://www.cnblogs.com/wangjie1990/p/11327676.html

kernel-4.19/init/Kconfig

config BUG

bool "BUG() support" if EXPERT

default y

Arch/arm64/

config GENERIC_BUG

def_bool y

depends on BUG

config GENERIC_BUG_RELATIVE_POINTERS

def_bool y

depends on GENERIC_BUG

kernel-4.19/drivers/misc/mediatek/aee/mrdump/​​​​​​mrdump_panic.c

底层稳定性笔记_第13张图片

mrdump_panic_init 时会注册panic() 时通知回调函数panic_blk,及die()时通知回调函数die_blk

kernel-4.19/kernel/panic.c

notifier_block panic_notifier_list  //列表

kernel-4.19/kernel/notifier.c

https://www.cnblogs.com/linhaostudy/p/9429511.html

底层稳定性笔记_第14张图片

Dump文件时进程的内存镜像。可以把程序的执行状态保存到Dump文件中。Dump文件分为内核模式Dump和用户模式Dump。其中内核模式Dump是操作系统创建的崩溃转储,例如蓝屏Dump。而在我们调试或Troubleshooting过程中使用的Dump是用户模式Dump,又分为Full Dump和Mini Dump。Full Dump包含了某个进程完整的地址空间数据,以及许多用于调试的信息。而Mini Dump根据需要可以包含不同的信息,有的可能只包含某个县城和部分模块的信息。

https://www.eefocus.com/embedded/418875

1、模块

Linux 内核主要由进程调度、内存管理、虚拟文件系统、网络接口、进程通讯 5部分组成

Kernel/driver/rtc

模块Kconfig Makefile  编译配置文件

config RTC_HCTOSYS_DEVICE

string "RTC used to set the system time"

depends on RTC_HCTOSYS

default "rtc0"

help

  The RTC device that will be used to (re)initialize the system

Config 这个为三态,Y/N  编入内核/不编入,M 编译为模块

Makefile 里面

obj-$(CONFIG_RTC_LIB) += rtc-lib.o

为Y 则,obj-y+= rtc-lib.o;rtc-lib.o 编译入内核;为M 则编译为rtc-lib.ko;为N 则不编译

config RTC_LIB

Bool

Boole 类型,则只能为Y/N

Lib-y   hostprogs-y   库和主机程序

当有多个文件或目录生成目标时,使用 -y/-objs

obj-m += rtc-lib.o

rtc-lib-objs := a.o  b.o

rtc-lib-$(CONFIG_RTC_TIME) += xt.o

obj-$(CONFIG_RTC_LIB) += ext2/

2、System.map/kallsyms  

模块编译安装

  1. Linux 文件系统和设备文件系统

Linux 2.4 内核devfs 文件系统,linux 2.6 基于sysfs 的udev 文件系统

/sys 是sysfs 对应目录,设备、驱动、总线都可以在这里找到对应的节点

VFS

深入理解Linux内核——VFS | linkthinking

/proc/devices  查看系统中注册的设备

/dev/ 目录是对应设备文件

主设备号指同一类设备,与驱动对应,次设备号从0 开始。

adb shell cat /sys/devices/platform/1000b000.pinctrl/mt_gpio

adb shell cat /sys/devices/platform/soc/10005000.pinctrl/mt_gpio

内核配置

内核从3.7后开始支持模块签名,这个功能使能以后,内核只允许安装特定key签名的模块。

内核配置项

CONFIG_MODULE_SIG=y

表示开启了签名机制,但是这时候模块签名或不签名都可以使用。

CONFIG_MODULE_SIG_FORCE=y

如果上述配置项使能,则模块必须有正确的签名才能正常使用。

CONFIG_MODULE_SIG_ALL=y

内核在编译的时候,并不会主动去给模块签名,除非你把上述配置项打开。

查看签名

hexdump -C my_ko.ko |tail

数字证书会打包进内核,里面有公钥等,用来解密。每编译一次,虽然配置文件每次都相同,但是生成的key pair是不同的。模块放的分区跟kernel 分区不一样,就可能导致更新内核导致签名不对。

devfs:

通过程序在设备初始化时,在/dev 创建设备文件,在卸载设备时将它删除

设备驱动程序可以指定设备名、所有者和权限,用户空间程序可以修改

不再需要指定主设备号和次设备号;register_chrdev();devfs_register()自动自动主次设备号

udev  在内核检测到设备插拔时,将事件发送到/sys  对应的sysfs 下,从而用户空间处理对应的事件

/sys/block  块设备

/sys/devices 所有设备,根据挂载的总线来组织(设备链接subsystem -> ../../../bus/platform; of_node -> ../../../firmware/devicetree/base/)

/sys/bus    总线,对应着设备(链接到/sys/devices)和驱动

/sys/firmware

/sys/class

字符设备:

file_operations定义在./include/linux/fs.h

cdev定义在./include/linux/cdev.h

平台设备

linux/platform_device.h

include/linux/device.h

和drivers/base/platform.c

底层稳定性笔记_第15张图片

底层稳定性笔记_第16张图片

*name   ---如果多个相同名字,驱动通过id 区别不同设备;设备注册时会初始化到dev.init_name

设备驱动的probe,依赖于名称,Linux采取的策略是:在bus的设备链表中查找device,和对应的device_driver比对name,如果相同,则查看该设备是否已经绑定了driver(查看其dev->driver指针是否为空),如果已绑定,则不会执行probe动作,如果没有绑定,则以该device的指针为参数,调用driver的probe接口。因此,在driver的probe接口中,通过判断设备的ID,可以知道此次驱动的设备是哪个。

dev     ---设备结构体,父设备为platform_bus

底层稳定性笔记_第17张图片

内核会在合适的时机检查device和device_driver的名字,如果匹配,则执行probe。其实除了名称之外,还有一些宽泛的匹配方式,例如这里提到的各种match table

Device_driver 中

const struct of_device_id *of_match_table;  #compatible[128]用于与设备树compatible(dts)
const struct acpi_device_id *acpi_match_table;

Platform_driver 中

Platform_device_id

#platform_driver对象中的id_table就是用来匹配,一个驱动匹配多个C语言编码的设备信息

Early platform device/driver

内核启动时,要完成一定的初始化操作之后,才会处理device和driver的注册及probe,因此在这之前,常规的platform设备是无法使用的。但是在Linux中,有些设备需要尽早使用(如在启动过程中充当console输出的serial设备),所以platform模块提供了一种称作Early platform device/driver的机制,允许驱动开发人员,在开发驱动时,向内核注册可在内核早期启动过程中使用的driver

底层稳定性笔记_第18张图片

Match ---当有驱动或者设备注册到platform总线时,内核自动调用match函数,判断设备和驱动的name是否一致。

Platform_bus 是一个device ,只包含init_name(为“platform”),device_register 会创建/sys/devices/platform 目录,所有Platform 设备都会包含在这个目录。

Bus_register 注册总线/sys/bus/platform/

创建uevent attribute(/sys/bus/platform/uevent)、devices目录、drivers目录、drivers_probe和drivers_autoprobe两个attribute(/sys/bus/platform/drivers_probe和/sys/bus/platform/drivers_autoprobe)

设备/驱动注册过程:

Platform device/driver注册过程 - fellow_jing - 博客园

驱动开发三种方法:传统、总线、设备树

很抱歉,您访问的页面已下线-华为云

dts文件被编译成dtb文件,然后在启动内核时,传给内核,由内核来处理解析,得到一个一个的device_node(每一个节点对应一个device_node)结构体,然后解析成platform_device结构体,这里面就含有硬件描述的资源;

设备数

4. 字符设备驱动-使用设备树 - 简书

https://www.cnblogs.com/lizhuming/p/14621305.html

./scripts/dtc/dtc -I dts -O dtb -o tmp.dtb arch/arm/boot/dts/xxx.dts // 编译 dts 为 dtb

./scripts/dtc/dtc -I dtb -O dts -o tmp.dts arch/arm/boot/dts/xxx.dtb // 反编译 dtb 为 dts

kernel-4.19/scripts/drvgen/drvgen.mk

ALL_DRVGEN_FILE := $(MTK_PROJECT)/cust.dtsi

vendor/mediatek/proprietary/scripts/kernel_tool/dtbo_config.sh

Preloader log

vendor/mediatek/proprietary/bootable/bootloader/preloader/platform/pal/inc/pal_log.h

pal_log_err

vendor/mediatek/proprietary/bootable/bootloader/preloader/platform/mt6765/default.mak

定义CFG_LOG_LEVEL 

vendor/mediatek/proprietary/bootable/bootloader/preloader/platform/mt6765/src/core/print.c

最后调用的是这里print()函数

CFG_UART_DYNAMIC_SWITCH  没有定义则输出到uart

这里调用pl_log_store 保存日志到sram/dram/expdb

CFG_UART_DYNAMIC_SWITCH宏开关可以配置动态打开关闭uart

在宏内set_log_switch(0/1)可以关闭打开uart log,通过log_dynamic_switch

传递到lk ,lk 再传递到kernel 设置mtk_printk_ctrl.disable_uart=0/1

在user mode和userdebug mode,如何令kernel log在lk结束后自动吐出? 方法一:fastboot comand 1) 按volumn up + power key进入 bootmenu 选择fastboot mode
2) usb连接PC端,执行命令fastboot oem p2u on   

设置has_set_p2u
3) 执行fastboot continue命令

pl_log_store 里面使用DEBUG_LOG 输出日志:

vendor/mediatek/proprietary/bootable/bootloader/preloader/platform/common/log_store/log_store_pl.c

 底层稳定性笔记_第19张图片

底层稳定性笔记_第20张图片

Ram 控制台kernel 异常boot 保存kernel log 到自定义分区

如果从bl/lk 异常重启,保存pl log 到自定义分区

Preloder 后面会将日志保存到dram

store_switch_to_dram->log_store_init

vendor/mediatek/proprietary/bootable/bootloader/preloader/platform/common/ram_console.c

Preloader 启动流程:

MTK bootloader 启动过程_jgw2008的专栏-CSDN博客

深入MTK平台bootloader启动之【 Pre-loader -> Lk】分析笔记_沉思-CSDN博客

Lk->kernel

https://blog.csdn.net/forever_2015/article/details/53047993

底层稳定性笔记_第21张图片

dct

高通 MSM8K bootloader之一: SBL1 - linux_xin - 博客园

vendor/mediatek/proprietary/bootable/bootloader/preloader/tools/dct

./preloader/custom/k6875v1_64/dct

./lk/scripts/dct

./lk/target/oppo6889/dct

Codegen.dws

#ifdef USE_DTB_NO_DWS

mt_gpio_set_default_chip

这里会加载dtb

BOARD_PREBUILT_DTBIMAGE_DIR

ifneq ($(USE_DTB_NO_DWS),yes)

$(info **************** Use DWS ****************)

-include scripts/drvgen/drvgen.mk

else

$(info **************** Use DTB ****************)

endif

 在Android L版本上 DCT tool配置的codegen.dws文件在preloader、lk、kernel中是独立的,被分开放置,其路径如下:

preloader: 

    alps\bootable\bootloader\preloader\custom\$(proj)\dct\dct\codegen.dws

lk:  

    alps\bootable\bootloader\lk\target\$(proj)\dct\dct\codegen.dws

kernel:

    alps\kernel-3.10\arch\arm\mach-$(platform)\$(proj)\dct\dct\codegen.dws

 or

    alps\kernel-3.10\drivers\misc\mediatek\mach\$(platform)\$(proj)\dct\dct\codegen.dws

https://www.cnblogs.com/leaven/p/6295999.html

3、KE  分析


https://blog.csdn.net/qq_38350702/article/details/107321721

Crash 工具
https://www.jianshu.com/p/7d998f474033?utm_campaign=maleskine&utm_content=note&utm_medium=seo_notes&utm_source=recommendation

https://www2.lauterbach.com/pdf/general_ref_m.pdf

Data.List 

The Data.List (= List) window displays the code in assembler mnemonic and HLL

Var.Step.Till

Example: Var.Step.Till i>11. single-steps the program until the variable i becomes greater than

11. The trailing dot is very important! It is the dot that formats 11 as a decimal number.

Note: i>11. is equivalent to i>0xB

Register.view /SpotLight

修改寄存器

Data.dump main++0x30

Data.Set  修改地址内容

B::wr.we.PLIST   显示运行的脚本

设置PC

Register.Set PC 0xffffffa50aec0eb8/函数名

Data.load.elf    tsts.elf    /PATH  E:/SOURCE

B::sYmbol.SourcePATH.List

设置递归路径:

sYmbol.spath.SetRecurseDir V:\ANDROID_R\mt6765\0520_mt6765\source

y.spath.SETRECURSEDIR  

设置完显示设置源码路径界面:

y.spath.list

1)去除编译路径前缀 (针对第一张图的路径去掉 \sdb\jenkins\workspace\BUILD_Branch_sofia3g_r_mr1_Cherry_Pick_ctegerrit\  前缀)

data.load C:\zyang\Logs\Sofia3G_R\pre-merge\2015-09-09\cp_1841\mobilevisor.elf  /strippart 5.

2)设置新的相对路径

y.spath.setbasedir M:\workspace\sofia3g_r_mr1_cte

3)/RelPATH 参数: 去除编译目录的绝对路径, 保留相对路径。

data.load.elf  c:\slb.elf /RelPATH

Data.Load 功能

• All symbol and debug information already available in TRACE32 is removed.

• The code/data provided by is loaded to the target memory.

• The symbol and debug information provided by is loaded into TRACE32.

• The paths for the hll source files provided by are loaded into TRACE32.

• An internal symbol data base in generated out of the loaded information.

有用命令:

sYmbol.List.SECtion List the section information provided by loaded by “data.load”

sYmbol.List.SOURCE to display the path information for the hll source files that was loaded from

sYmbol.spath.list to display the symbol source path list.

sYmbol.spath.SetDir  设置源文件静态搜索路径

sYmbol.spath.SetDynamicDir  设置源文件动态搜索路径。如果某个路径命中源文件,则下次搜索时,该命中路径成为第一个被搜索路径。

sYmbol.spath.SetRecurseDir   设置递归搜索路径,所有其子目录都将被用于源文件搜索

data.load.elf ../../vmlinux 0x1488800000 /nocode

加上/nocode代表没有对应的sourcecode,trace32就不会去对应目录去查找源文件了。当然我们也可以通过/path来指定sourcecode目录

Area  警告

F/frame  异常堆栈

R 寄存器

https://www.lauterbach.com/pdf/frontend_gdb.pdf

B::mmu.list.pagetable 0xffffffc000000000

踩内存

https://online.mediatek.com/QuickStart/QS00090#QSS00964

4、T32 使用

trace 访问percpu
https://blog.csdn.net/weixin_46485500/article/details/119875898


var.view (struct A*)0xFFFFAAA  查看地址变量

task.Dtask 0xFFFFFFEA4FCDA280  查看对应的task 名字

FP(x29)  帧栈地址,栈底
LR(X30)  
SP        保存栈指针

X0-X7: 用于子程序调用时的参数传递,X0还用于返回值传递
X8: 间接寻址结果


STP x29, x30, [sp, #0x10] ; 入栈指令

LDP x29, x30, [sp, #0x10] ; 出栈指令

LDR X5,[X6,#0x08] ;X6寄存器加0x08的和的地址值内的数据传送到X5

STR X0, [SP, #0x8] ;X0寄存器的数据传送到SP+0x8地址值指向的存储空间

ldp/stp
是 ldr/str 的衍生, 可以同时读/写两个寄存器, ldr/str只能读写一个


sub sp, sp, #0x20 ; 拉伸栈空间32(20 = 2*16)个字节
stp x0 , x1, [sp, #0x10] ; sp往上加16(10 = 1 * 16)个字节,存放x0 和 x1
ldp x1 , x0, [sp, #0x10] ; 将sp偏移16个字节的值取出来,放入x1 和 x0

 LDR r0,[r1]          //将R1中的值存到r0中
 LDR r1,[r2,#16]      //将(r2+16)地址中的内容存到r1中
 LDR r1,[r2],#4       //将r2地址中的内容存到r1中,同时r2=r2+4
 LDR r1,[r2,#4]!      //r2=r2+4,再将r2 地址值加载到r1

gdb
prebuilts/gdb/linux-x86/bin/gdb    out/target/product/symbols/system/bin/init   ../../../../db.00.NE.dbg.DEC/PROCESS_COREDUMP

prebuilts/gcc/linux-x86/aarch64/aarch64-linux-gnu-6.3.1/bin/aarch64-linux-gnu-gdb     out/target/product/symbols/system/bin/init    db.00.NE.dbg.DEC/PROCESS_COREDUMP

--gdb 命令下设置库加载路径:

set solib-absolute-prefix  /work/android/out_/target/product/symbols/

lldb调试coredump,gdb是跟gcc搭配的,lldb是跟llvm搭配的


在gdb下查看map,vector,queue的数据
 https://blog.csdn.net/wxliu1989/article/details/24259539/ 
gdb to lldb
https://lldb.llvm.org/use/map.html


使用(lldb) target create a.out --symfile a.out.dSYM --core user_core打开核心文件
target modules add ~/a.out
在打开核心文件之前执行(lldb) settings set target.debug-file-search-paths .
在打开核心文件之前执行(lldb) setting set target.exec-search-paths .
Execute (lldb) target symbols add ~/a.out.dSYM
image lookup -vn


./lldb.sh -f   app_process64  -c PROCESS_NCOREDUMP 

 
 
 
 

你可能感兴趣的:(android,稳定性,p2p,网络协议,网络)