一:GPIO
方式1:使用debugfs查看gpio状态
通过此方式,可以查看gpio当前状态(输入/输出,上拉/下拉/no-pull, 驱动能力,function编号);命令:
mount -t debugfs none /sys/kernel/debug
cat /sys/kernel/debug/gpio
示例:
P875A02:/ # cat /sys/kernel/debug/gpio
...
gpiochip2: GPIOs 294-303, parent: platform/c440000.qcom,spmi:qcom,pm8350@1:pinctrl@8800, c440000.qcom,spmi:qcom,pm8350@1:pinctrl@8800:
gpio1 : in low normal vin-0 pull-down 10uA push-pull high atest-1 dtest-0
gpio2 : out high normal vin-0 pull-down 10uA push-pull high atest-1 dtest-0
gpio3 : ---
gpio4 : in low normal vin-0 pull-down 10uA push-pull high atest-1 dtest-0
gpio5 : in low normal vin-0 pull-down 10uA push-pull high atest-1 dtest-0
gpio6 : in high normal vin-1 pull-up 30uA push-pull high atest-1 dtest-0
gpio7 : ---
gpio8 : in high normal vin-0 pull-up 30uA push-pull high atest-1 dtest-0
gpio9 : in low normal vin-1 pull-down 10uA push-pull high atest-1 dtest-0
gpio10: in low normal vin-0 pull-down 10uA push-pull high atest-1 dtest-0
gpiochip1: GPIOs 304-307, parent: platform/c440000.qcom,spmi:qcom,pmk8350@0:pinctrl@b000, c440000.qcom,spmi:qcom,pmk8350@0:pinctrl@b000:
gpio1 : in low normal vin-0 pull-down 10uA push-pull high atest-1 dtest-0
gpio2 : in low normal vin-0 pull-down 10uA push-pull high atest-1 dtest-0
gpio3 : out high normal vin-0 pull-down 10uA push-pull high atest-1 dtest-0
gpio4 : in low normal vin-0 no pull push-pull high atest-1 dtest-0
gpiochip0: GPIOs 308-511, parent: platform/f000000.pinctrl, f000000.pinctrl:
gpio4 : in low func0 2mA pull down
gpio5 : in low func0 2mA pull down
gpio6 : in low func0 2mA pull down
gpio7 : out low func0 2mA no pull
gpio8 : in low func0 2mA pull down
gpio9 : in low func0 2mA pull down
gpio10 : in low func0 2mA pull down
...
...
gpio200 : in low func0 2mA pull down
gpio201 : in high func0 2mA pull down
gpio202 : in high func0 2mA pull down
ufs_reset: in low func0 8mA pull down
方式2:使用libgpiod查看gpio状态
此方式需要移植libgpiod源码到Android下编译libgpiod.so, gpiodetect等执行程序使用;
github地址:platform_external_libgpiod
命令:
# detect
gpiodetect
# chip info
gpioinfo [chip_index]
# 获取chip1 gpio2状态
gpioget 1 2 # 不一定成功
# 设置chip1 gpio2输出1
gpioset 1 2=1 # 不一定成功
# monitor chip0 109
gpiomon 0 109 # 不一定成功
参考网页博客 : linux用户空间控制gpio的两种方法
示例:
P875A02:/ # gpiodetect
gpiochip0 [f000000.pinctrl] (204 lines)
gpiochip1 [c440000.qcom,spmi:qcom,pmk8350@] (4 lines)
gpiochip2 [c440000.qcom,spmi:qcom,pm8350@1] (10 lines)
gpiochip3 [c440000.qcom,spmi:qcom,pm8350c@] (9 lines)
gpiochip4 [c440000.qcom,spmi:qcom,pm8350b@] (8 lines)
gpiochip5 [c440000.qcom,spmi:qcom,pmr735a@] (4 lines)
gpiochip6 [soc:qcom,msm-audio-apr:qcom,q6c] (15 lines)
P875A02:/ # gpioinfo 1
gpiochip1 - 4 lines:
line 0: unnamed unused input active-high
line 1: unnamed unused input active-high
line 2: unnamed unused input active-high
line 3: unnamed unused input active-high
成功get/set:
P875A02:/ # gpioget 1 2
0
P875A02:/ # gpioset 1 2=1
P875A02:/ # gpioget 1 2
1
无法获取情况:
P875A02:/ # gpioget 1 1
gpioget: error reading GPIO values: Operation not permitted
bus busy情况:
P875A02:/ # gpioget 2 1
gpioget: error reading GPIO values: Device or resource busy
二:pinctrl
命令:
cat /sys/kernel/debug/pinctrl/pinctrl-maps
示例:
P875A02:/sys/kernel/debug/pinctrl # ls -l
total 0
drwxr-xr-x 2 root root 0 1970-01-01 08:00 c440000.qcom,spmi:qcom,pm8350@1:pinctrl@8800
drwxr-xr-x 2 root root 0 1970-01-01 08:00 c440000.qcom,spmi:qcom,pm8350b@3:pinctrl@8800
drwxr-xr-x 2 root root 0 1970-01-01 08:00 c440000.qcom,spmi:qcom,pm8350c@2:pinctrl@8800
drwxr-xr-x 2 root root 0 1970-01-01 08:00 c440000.qcom,spmi:qcom,pmk8350@0:pinctrl@b000
drwxr-xr-x 2 root root 0 1970-01-01 08:00 c440000.qcom,spmi:qcom,pmr735a@4:pinctrl@8800
drwxr-xr-x 2 root root 0 1970-01-01 08:00 f000000.pinctrl
-r--r--r-- 1 root root 0 1970-01-01 08:00 pinctrl-devices
-r--r--r-- 1 root root 0 1970-01-01 08:00 pinctrl-handles
-r--r--r-- 1 root root 0 1970-01-01 08:00 pinctrl-maps
drwxr-xr-x 2 root root 0 2021-07-06 05:27 soc:qcom,msm-audio-apr:qcom,q6core-audio:lpi_pinctrl@33c0000
P875A02:/sys/kernel/debug/pinctrl # cat pinctrl-maps
Pinctrl maps:
device soc:display_gpio_regulator@1
state default
type MUX_GROUP (2)
controlling device f000000.pinctrl
group gpio186
function gpio
device soc:display_gpio_regulator@1
state default
type CONFIGS_GROUP (4)
controlling device f000000.pinctrl
group gpio186
config 00000001
config 00000809
config 00000111
...
三:clk
# 查看注册了哪些clk 资源
ls -l /sys/kernel/debug/clk
# 查看ln_bb_clk2信息
cd /sys/kernel/debug/clk/ln_bb_clk2
ls -l
cat clk_rate
cat clk_prepare_count
cat clk_parent
# 示例:
P875A02:/sys/kernel/debug/clk/ln_bb_clk2 # ls
clk_accuracy clk_flags clk_notifier_count clk_prepare_count
clk_duty_cycle clk_max_rate clk_parent clk_protect_count
clk_enable_count clk_min_rate clk_phase clk_rate
P875A02:/sys/kernel/debug/clk/ln_bb_clk2 # cat clk_prepare_count
0
P875A02:/sys/kernel/debug/clk/ln_bb_clk2 # cat clk_rate
19200000
四:regulator
# Note:
#1. 当regulator被多个消费者设备设备使用,若该regulator已经被其中一个enable,其他消费者再enable,只会增加引用计数;且只用所有消费都disable该regulator后(引用计数降为0),regulator才真正下电;
#2. regulator 可以在AOP侧或者HLOS侧通过dtsi属性"regulator-always-on"属性配置常供电。
# 查看注册了哪些 regulator 资源
ls /sys/kernel/debug/regulator/
# 查看pm8350_l6 regulator信息
cd /sys/kernel/debug/regulator/18200000.rsc:rpmh-regulator-ldob6-pm8350_l6/
ls
cat consumers
cat enable
cat use_count
示例:
P875A02:/d/regulator/18200000.rsc:rpmh-regulator-ldob6-pm8350_l6 # ls
1c00000.qcom,pcie-vreg-1p8 ae96000.qcom,mdss_dsi_ctrl1-vdda-1p2
1d87000.ufsphy_mem-vdda-pll bypass_count
88e8000.ssphy-core consumers
88eb000.ssphy-core enable
ac6a000.qcom,csiphy0-csi-vdd-1p2 force_disable
ac6c000.qcom,csiphy1-csi-vdd-1p2 load
ac6e000.qcom,csiphy2-csi-vdd-1p2 mode
ac70000.qcom,csiphy3-csi-vdd-1p2 open_count
ac72000.qcom,csiphy4-csi-vdd-1p2 pm8350_l6
ac74000.qcom,csiphy5-csi-vdd-1p2 use_count
ae90000.qcom,dp_display-vdda-1p2 voltage
ae94000.qcom,mdss_dsi_ctrl0-vdda-1p2
# 查看pm8350_l6路regulator有哪些消费者,EN列N表示当前该消费者模块disable,Y表示消费者模块enable;如下可以看到mdss_dsi_ctrl0-vdda-1p2与88e8000.ssphy-core两个消费者模块在使用。
P875A02:/d/regulator/18200000.rsc:rpmh-regulator-ldob6-pm8350_l6 #cat consumers
Device-Supply EN Min_uV Max_uV load_uA
ac74000.qcom,csiphy5-csi-vdd-1p2 N 0 0 0
ac72000.qcom,csiphy4-csi-vdd-1p2 N 0 0 0
ac70000.qcom,csiphy3-csi-vdd-1p2 N 0 0 0
ac6e000.qcom,csiphy2-csi-vdd-1p2 N 0 0 0
ac6c000.qcom,csiphy1-csi-vdd-1p2 N 0 0 0
ac6a000.qcom,csiphy0-csi-vdd-1p2 N 0 0 0
ae90000.qcom,dp_display-vdda-1p2 N 0 0 0
ae96000.qcom,mdss_dsi_ctrl1-vdda-1p2 N 0 0 0
ae94000.qcom,mdss_dsi_ctrl0-vdda-1p2 Y 1200000 1200000 8350
1c00000.qcom,pcie-vreg-1p8 N 1200000 1200000 0
1d87000.ufsphy_mem-vdda-pll N 1200000 1208000 0
88eb000.ssphy-core N 0 0 0
88e8000.ssphy-core Y 1200000 1200000 30000
pm8350_l6 N 0 0 0
# 正在使用pm8350_l6 regulator的消费者数量
P875A02:/d/regulator/18200000.rsc:rpmh-regulator-ldob6-pm8350_l6 #cat use_count
2
# pm8350_l6 regulator处于enable状态
P875A02:/d/regulator/18200000.rsc:rpmh-regulator-ldob6-pm8350_l6 #cat enable
1
# pm8350_l6 regulator 电压值1.2V
P875A02:/d/regulator/18200000.rsc:rpmh-regulator-ldob6-pm8350_l6 #cat voltage
1200000
五:irq
可通过proc系统信息,查看irq信息(哪个cpu核响应以及响应次数,irq触发方式,irq控制器name,irq中断号,irq中断gpio口,irq name);命令:
cat /proc/interrupts
cd /proc/irq/irq_num
示例:
P875A02:/ # cat /proc/interrupts
CPU0 CPU1 CPU2 CPU3 CPU4 CPU5 CPU6 CPU7
3: 19884310 22070133 22406143 22892697 1291261 1510281 1591810 68381 GICv3 27 Level arch_timer
5: 0 0 0 0 0 0 0 0 GICv3 38 Level arch_mem_timer
9: 1096365 10202170 8727470 6081038 0 0 0 0 GICv3 37 Level apps_rsc
10: 11 0 0 0 0 0 0 0 GICv3 195 Level ngd_slim_irq
11: 11 0 0 0 0 0 0 0 GICv3 196 Level sps
...
158: 578 104 0 176 0 0 0 0 GICv3 276 Level gpi_dma900000_gpii0
171: 343 0 0 297 0 0 0 0 GICv3 635 Level i2c_geni
172: 0 0 0 0 0 0 0 0 GICv3 637 Level i2c_geni
185: 966 26 0 0 0 0 0 0 GICv3 390 Level i2c_geni
...
401: 102 0 0 0 0 0 0 0 msmgpio 23 Edge goodix_ts
...
IPI6: 0 0 0 0 0 0 0 0 CPU wake-up interrupts
# touchpanel中断信息注释:
# 中断号401 ,在cpu0上发生102次中断, gpio为msmgpio 23, 边沿触发,中断name:goodix_ts
401: 102 0 0 0 0 0 0 0 msmgpio 23 Edge goodix_ts
cd /proc/irq/401
P875A02:/proc/irq/401 # ls -l
total 0
-r--r--r-- 1 root root 0 2021-07-16 07:14 affinity_hint
-r--r--r-- 1 root root 0 2021-07-16 07:14 effective_affinity
-r--r--r-- 1 root root 0 2021-07-16 07:14 effective_affinity_list
dr-xr-xr-x 2 root root 0 2021-07-16 07:14 goodix_ts
-r--r--r-- 1 root root 0 2021-07-16 07:14 node
-rw-r--r-- 1 root root 0 2021-07-16 07:14 smp_affinity
-rw-r--r-- 1 root root 0 2021-07-16 07:14 smp_affinity_list
-r--r--r-- 1 root root 0 2021-07-16 07:14 spurious
六:i2c-tools
i2c-tools是一套OpenSource,通过这个tools我們可以透过i2c与设备沟通;可以通过如下网站获取源码,然后通过toolchain编译出目标板工具;Android源码已经集成该工程,直接在手机里使用相关命令即可。
下载网址:https://i2c.wiki.kernel.org/index.php/I2C_Tools
# 列出所有的i2c bus
i2cdetect -l
# 列出此<bus>上所有设备
i2cdetect -y <bus>
# 读取<bus>上<device>设备<register>地址的值
i2cget -f -y <bus> <device> <register>
# 设置<bus>上<device>设备<register>地址的值为<value>, MODE is b for byte, w for 16-bit word, i for I2C block.
i2cset -f -y <bus> <device> <register> <value> <mode>
# dump 设备寄存器的值
i2cdump -f -y <bus> <device>
# 16bit地址读写,I2C-Tools 4.0增加了i2ctransfer命令;Android源码中暂无支持
# 读取0x1d设备,从地址0x0020开始16个字节数据
i2ctransfer -y -f 1 w2@0x1d 0x00 0x20 r16
示例:
# 查看通过/sys/bus/i2c/devices可以看到有哪些设备和bus注册;
# Note: 这个信息只能表示配置的设备已添加到对应的i2c bus,但是并不能说明真实的硬件设备确定存在,且能通信。
P875A02:/sys/bus/i2c/devices # ls
2-0034 3-0038 3-005d 4-0009 4-000d 4-0064 i2c-2 i2c-4 i2c-6
3-0001 3-0049 4-0008 4-000c 4-0042 5-0008 i2c-3 i2c-5
# 探测i2c bus4上面真实存在的设备,如下可看到0x07,0x08, 0x0c,0xd,0x42,0x64 这几个设备真实存在(UU标识符表示存在)
P875A02:/sys/bus/i2c/devices # i2cdetect -y 4
0 1 2 3 4 5 6 7 8 9 a b c d e f
00: -- -- -- -- -- UU UU -- -- UU UU -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40: -- -- UU -- -- -- -- -- -- -- -- -- -- -- -- --
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
60: -- -- -- -- UU -- -- -- -- -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- --
# 探测i2c bus3上面真实存在的设备,如下可看到只有0x5d设备真实存在,添加到/sys/bus/i2c/devices/的3-0038,3-0001,3-0049,3-0038等设备并不存在。
P875A02:/sys/bus/i2c/devices # i2cdetect -y 3
0 1 2 3 4 5 6 7 8 9 a b c d e f
00: -- -- -- -- -- -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: -- -- -- -- -- -- -- -- -- -- -- -- -- UU -- --
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- --
# 获取bus4 总线上0x42设备 0x04寄存器值
P875A02:/ # i2cget -f -y 4 0x42 0x04
0x98
# 设置bus4 总线上0x42设备 0x04寄存器值为0x90
P875A02:/ # i2cset -f -y 4 0x42 0x04 0x90 b
P875A02:/ # i2cget -f -y 4 0x42 0x04
0x90
# 获取bus4 总线上0x42设备的寄存器值
P875A02:/ # i2cdump -f -y 4 0x42
0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
00: 09 00 00 00 90 18 05 00 00 00 00 00 00 00 00 00 ?...???.........
10: 09 02 08 00 ff 16 00 01 00 00 ff ff 20 ff 00 07 ???.??.?..?? ?.?
20: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ????????????????
30: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ????????????????
40: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ????????????????
50: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ????????????????
60: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ????????????????
70: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ????????????????
80: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ????????????????
90: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ????????????????
a0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ????????????????
b0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ????????????????
c0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ????????????????
d0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ????????????????
e0: 00 00 00 00 00 00 00 00 00 00 00 0e f7 08 00 00 ...........???..
f0: 00 00 08 00 00 00 00 00 00 00 00 00 00 00 16 00 ..?...........?.
七:dts
在调试过程,经常遇到/sys/bus/<platform/i2c/spi>/devices/没有需要添加的设备信息;一般要检查设备是否有编译到添加的设备修改。
cd /sys/firmware/devicetree/base
路径下对应节点,查看是否有包含修改的信息;若没有,继续排查:
方式1:使用16进制方式查看,是否有需要的关键字
hecdump -C dtbo.img | grep xxx
hecdump -C vendor_boot.img | grep xxx
示例:
$ hexdump -C dtbo.img | grep preisp
00047950 70 72 65 69 73 70 40 36 30 00 00 00 00 00 00 03 |preisp@60.......|
00058340 70 72 65 69 73 70 00 70 72 65 69 73 70 5f 6e 6f |preisp.preisp_no|
00058350 74 69 66 79 00 70 72 65 69 73 70 5f 64 76 64 64 |tify.preisp_dvdd|
00058360 33 5f 33 00 70 72 65 69 73 70 5f 64 76 64 64 31 |3_3.preisp_dvdd1|
00058370 5f 38 00 70 72 65 69 73 70 5f 64 76 64 64 72 31 |_8.preisp_dvddr1|
00058380 5f 31 00 70 72 65 69 73 70 5f 64 76 64 64 72 30 |_1.preisp_dvddr0|
00058390 5f 36 00 70 72 65 69 73 70 5f 64 76 64 64 5f 63 |_6.preisp_dvdd_c|
000583a0 6f 72 65 30 5f 38 00 70 72 65 69 73 70 5f 6e 6e |ore0_8.preisp_nn|
00297c20 70 00 70 72 65 69 73 70 5f 6e 6f 74 69 66 79 00 |p.preisp_notify.|
00297c30 70 72 65 69 73 70 5f 64 76 64 64 33 5f 33 00 70 |preisp_dvdd3_3.p|
00297c80 38 00 70 72 65 69 73 70 5f 6e 6e 76 64 64 00 71 |8.preisp_nnvdd.q|
00465530 00 00 00 00 00 00 01 70 72 65 69 73 70 40 36 30 |.......preisp@60|
00465550 78 65 72 61 2c 70 72 65 69 73 70 00 00 00 00 00 |xera,preisp.....|
004760b0 70 00 70 72 65 69 73 70 5f 6e 6f 74 69 66 79 00 |p.preisp_notify.|
004760c0 70 72 65 69 73 70 5f 64 76 64 64 33 5f 33 00 70 |preisp_dvdd3_3.p|
00476110 38 00 70 72 65 69 73 70 5f 6e 6e 76 64 64 00 71 |8.preisp_nnvdd.q|
00798220 00 00 00 00 00 00 00 01 70 72 65 69 73 70 40 36 |........preisp@6|
00798240 61 78 65 72 61 2c 70 72 65 69 73 70 00 00 00 00 |axera,preisp....|
007a8c10 73 00 72 65 73 65 74 5f 70 72 65 69 73 70 00 70 |s.reset_preisp.p|
方式2:反编译dts
反编译后,直接文本打开反编译出的文件查看即可
# 先source,lunch Android编译环境,否则dtc,mkdtimg命令找不到路径
cd source/android/
source build/envsetup.sh
lunch lahaina-userdebug
# 反编译dtb.img
dtc -I dtb -O dts dtb.img -o dtsi.txt
# 反编译dtbo.img
mkdtimg dump dtbo.img -b dtbo
dtc -I dtb -O dts dtbo.00 -o dtsi.txt
#由于mkdtimg dump dtbo.img 会产生许多dtbo.xx的目标文件,批量反编译处理:
#!/bin/bash
for file in `ls dtbo.*`
do
echo $file
#echo ${file}_dtsi.txt
dtc -I dtb -O dts $file -o ${file}_dtsi.txt
done
示例:
$ ls
dtbo.0 dtbo.15_dtsi.txt dtbo.21_dtsi.txt dtbo.28_dtsi.txt dtbo.34_dtsi.txt dtbo.40_dtsi.txt dtbo.5
dtbo.0_dtsi.txt dtbo.16 dtbo.22 dtbo.29 dtbo.35 dtbo.41 dtbo.5_dtsi.txt
dtbo.1 dtbo.16_dtsi.txt dtbo.22_dtsi.txt dtbo.29_dtsi.txt dtbo.35_dtsi.txt dtbo.41_dtsi.txt dtbo.6
dtbo.10 dtbo.17 dtbo.23 dtbo.2_dtsi.txt dtbo.36 dtbo.42 dtbo.6_dtsi.txt
dtbo.10_dtsi.txt dtbo.17_dtsi.txt dtbo.23_dtsi.txt dtbo.3 dtbo.36_dtsi.txt dtbo.42_dtsi.txt dtbo.7
dtbo.11 dtbo.18 dtbo.24 dtbo.30 dtbo.37 dtbo.43 dtbo.7_dtsi.txt
dtbo.11_dtsi.txt dtbo.18_dtsi.txt dtbo.24_dtsi.txt dtbo.30_dtsi.txt dtbo.37_dtsi.txt dtbo.43_dtsi.txt dtbo.8
dtbo.12 dtbo.19 dtbo.25 dtbo.31 dtbo.38 dtbo.44 dtbo.8_dtsi.txt
八:kernel panic/Oops
1. 从log中提取calltrace
根据死机calltrace(串口log),确定PC指针信息,解析
pc : mmc_attach_sdio+0x30/0x180
mmc_attach_sdio:表示导致kernel panic的出错函数
0x30:表示出错语句在出错函数中的偏移位置
0x180: 表示mmc_attach_sdio函数的大小
2. 寻找与当前机器kernel版本一致的vmlinux(搜索vmlinux关键字"SMP PREEMPT",查看时间与/proc/version是否完全一样)
vmlinux路径:
Android R以前:out/target/product/lahaina/obj/KERNEL_OBJ
Android S:out目录下搜索vmlinux,可能收到多个,都是一样的,选一个用即可;
3. 解析出导致死机的代码所在行
# 先source,lunch Android编译环境,否则toolchain命令需要指定路径执行
# toolchainl路径:<AOSP>/prebuilts/gcc/linux-x86/aarch64/aarch64-linux-android-4.9/bin
cd source/android/
source build/envsetup.sh
lunch xxxx-userdebug
# 查找mmc_attach_sdio函数的起始地址
aarch64-linux-androidkernel-nm vmlinux | grep mmc_attach_sdio
ffffffc010e725e4 T mmc_attach_sdio
# 计算出错地址:
err_addr = 0xffffffc010e725e4 + 0x30 = 0xffffffc010e72614
# 解析出错地址对应的文件,行号
aarch64-linux-android-addr2line -e vmlinux ffffffc010e72614
/media/hdd_p/8350_r30/sm8350_aosp/kernel/msm-5.4/drivers/mmc/core/sdio.c:1112
# 反编译出错函数(--stop-address 需要大于出错地址,可估算大一点)
aarch64-linux-androidkernel-objdump -S --start-address=0xffffffc010e725e4 --stop-address=0xffffffc010e72618 vmlinux > tmp.txt
4. 根据出错行号代码,结合上下文进一步分析原因