9. SDK 系统调试工具介绍

开发过程中,我们将编译好的固件烧录到开发板之后需要进行开发调试,本文将介绍在开发调试中常用的工具。一般开发环境如下图所示,PC与开发板通过串口数据线USB数据线连接。通过串口数据线访问开发板控制终端,通过 USB 执行下载烧录,ADB等功能。

SDK预置静态编译的⼀些常⽤调试⼯具,具体如下:

device/rockchip/common/tools/
├── adbd
├── busybox
├── gdb
├── io
├── kmsgrab
├── modetest
├── perf-4.19
├── perf-4.4
├── perf-5.10
├── pmap
├── procrank
├── ps
├── slabtop
├── strace
├── top
├── update
├── vendor_storage
├── vmstat
└── watch

只要在 SDK ⽬录中 make menuconfig,选中相关配置。

| Symbol: RK_ROOTFS_PREBUILT_TOOLS [=y]
| Type  : bool
| Prompt: prebuilt tools
| Location:
|   -> Rootfs
|    -> Post rootfs installs
| Defined at Config.in.post-rootfs:263

保存配置,比如RK3588 EVB1具体修改如下:

device/rockchip/rk3588/rockchip_rk3588_evb1_lp4_v10_defconfig
@@ -1,4 +1,7 @@
RK_YOCTO_CFG="rockchip-rk3588-evb"
RK_WIFIBT_TTY="ttyS8"
+RK_ROOTFS_PREBUILT_TOOLS=y

9.1 ADB⼯具

可在Buildroot中打开以下宏进⾏编译获取:

BR2_PACKAGE_ANDROID_TOOLS=y
BR2_PACKAGE_ANDROID_TOOLS_STATIC=y

ADB⼯具使⽤具体可参考ADB官⽅指导⽂档

9.1.1 概述

  • 运行设备的shell(命令行)

  • 管理模拟器或设备的端口映射

  • 计算机和设备之间上传/下载文件

  • 将本地软件安装至Debian、Buildroot等Linux设备

  • ADB是一个“客户端-服务器端”程序,其中客户端主要是指PC,服务器端是Debian设备的实体机器或者虚拟机。根据PC连接Debian设备的方式不同,ADB可以分为两类:

    • 网络ADB:主机通过有线/无线网络(同一局域网)连接到STB设备

    • USB ADB:主机通过USB线连接到STB设备

9.1.2 USB adb使用说明

USB adb使用有以下限制:

  • 只支持USB OTG口

  • 不支持多个客户端同时使用

  • 只支持主机连接一个设备,不支持连接多个设备

连接步骤如下: 测试是否连接成功,运行“adb devices”命令,如果显示机器的序列号,表示连接成功。

9.2 Busybox工具

可在Buildroot中打开以下宏进行编译获取:

BR2_PACKAGE_BUSYBOX=y
BR2_PACKAGE_BUSYBOX_STATIC=y

Busybox类似Linux⼀个⼯具箱,它集成压缩了 Linux 的许多⼯具和命令。

###### Chapter-11./busybox

BusyBox v1.36.0 (2023-05-20 11:25:39 CST) multi-call binary.
BusyBox is copyrighted by many authors between 1998-2015.
Licensed under GPLv2. See source distribution for detailed copyright notices.

Usage: busybox [function [arguments]...]
    or: busybox --list[-full]
    or: busybox --show SCRIPT
    or: busybox --install [-s] [DIR]
    or: function [arguments]...

    BusyBox is a multi-call binary that combines many common Unix utilities into a single executable. Most people will create a link to busybox for each function they wish to use and BusyBox 
will act like whatever it was invoked as.

Currently defined functions:
    [, [, addgroup, adduser, ar, arch, arp, arping, ascii, ash, awk, base32, base64, basename, bc, blkid, bunzip2p, bzcat, cat, chattr, chgrp, chmod, chown, chroot, chrt, chw,cksum, clear, 
cmp, cp, cpio, crc32, crond, conntab, cut, date, dc, dd, deallocvt, delgroup, deluser, devmem, df, diff, dirname, dmesg, dnsd, dnsdomainname, dos2unix, du, dumpkmap, echo, egrep, eject, 
env, ether-wake, factor, fallocate, false, fbset, fdflush, fdisk, fdisk, fgrep, find, flock, fold, free, freeramdisk, fsck, fsfreeze, fstrim, fuser, getopt, getty, grep, groups, gunzip, 
gzip, halt, hdparm, head, hexdump, hexedit, hostid, hostname, hwclock, i2cdetect, i2cdump, i2cget, i2cset, i2ctransfer, id, ifconfig, ifdown, ifup, inetd, init, insmod, install, ip, 
ipaddr, ipcrm, ipcs, iplink, ipneigh, iproute, iprule, iptunnel, kill, killall, killall5, klogd, last, less, link, linux32, linux64, linuxrc, ln, loadfont, loadkmap, logger, login, 
logname, losetup, ls, lsattr, lsmode, lsof, lspci, lsscsi, lsusb, lzcat, lzma, lzopcat, makedevs, md5sum, mdev, mesg, microcom, mii, mkdir, mkdosfs, mkfs, mkfifo, mknod, mkpasswd, mkswap, 
mktemp, modprobe, more, mount, mountpoint, mt, mv, nameif, netstat, nice, nl, nohup, nproc, nprocs, nslookup, od, openvt, partprobe, passwd, paste, patch, pidof, ping, pipe_progress, 
pivot_root, pmap, poweroff, printenv, printf, ps, pwd, readlink, readprofile, realpath, reboot, renice, reset, resize, resume, rm, rmdir, rmmod, route, run-init, run-parts, runlevel, sed, 
sedreing, seq, setarch, setconsole, setfattr, setkeycodes, setlogcons, setpriv, setserial, setsid, sh, sha1sum, sha256sum, sha3sum, sha512sum, shred, sleep, sort, start-stop-daemon, 
strings, stty, su, sulogin, svok, swapoff, swapon, switch_root, sync, sysctl, syslogd, tail, tar, taskset, tc, tee, telnet, test, tftp, time, timeout, top, touch, tr, traceroute, tree, 
true, truncate, ts, tsort, tty, ubrename, udhcpc, uevent, umount, uname, uniq, unix2dos, unlink, unlzma, unzip, unxz, unzip, uptime, usleep, uudecode, uuencode, vconfig, vi, vlock, w, 
watch, watchdog, wc, wget, which, who, whoami, xargs, xxd, xz, xzcat, yes, zcat

9.3 GDB⼯具

可在Buildroot中打开以下宏进⾏编译获取:

BR2_PACKAGE_GDB=y
BR2_PACKAGE_GDB_STATIC=y
BR2_PACKAGE_GDB_DEBUGGER=y

Linux常⽤调试⼯具gdb,是⼀个功能强⼤的程序调试器。具体使⽤参考GDB

使⽤gdb -p调试进程,复现崩溃后通过bt查询调⽤栈,以及具体的代码,然后通过加log等⽅式调试。定位到具体代码后⾃⾏对⽐最新官⽅模块相应代码,或在官⽅模块issue系统咨询:

其他⽤法: gdb \--args

root@rk3588-buildroot:/## gdb --args ./waylandTest
GNU gdb (GDB) 11.2
...
(gdb) r
    Starting program: /waylandTest
warning: Loadable section "" outside of ELF segments
    in /lib/libmali.so.1
....

(gdb) bt f
##0 0x0000007ff66988dc in get_next_argument () from /lib/libwayland-client.so.0
No symbol table info available.
##1 0x0000007ff6698f68 in wl_argument_from_va_list ()
    from /lib/libwayland-client.so.0
No symbol table info available.
##2 0x0000007ff6696f00 in wl_proxy_marshal () from /lib/libwayland-client.so.0
No symbol table info available.
##3 0x0000007ff0109d18 in ?? () from /lib/libmali.so.1
No symbol table info available.
##4 0x000000000052bd20 in ?? ()
No symbol table info available.

由于Buildroot打包去掉符号表。可以通过更新buildroot编译的⽣成更新⽅便调试。⽐如替换\~/buildroot/output/rockchip\_rk3588/build/wayland-1.22.0/wayland-1.22.0.tar ⾄于怎么查看库对应的Buildroot包可以通过output/rockchip\_rk3588/build/packages-file- list.txt查看。

file test/usr/lib/libwayland-client.so.0.22.0
test/usr/lib/libwayland-client.so.0.22.0: ELF 64-bit LSB shared object, ARM
aarch64, version 1 (SYSV), dynamically linked, not stripped ==》not stripped 表明有符号表

⼀般buildroot打包都会被 stripped

target/usr/lib$ file libwayland-client.so.0.22.0
libwayland-client.so.0.22.0: ELF 64-bit LSB shared object, ARM aarch64, version 1
(SYSV), dynamically linked, stripped

9.4 IO⼯具

可在Buildroot中打开以下宏进⾏编译获取:

BR2_PACKAGE_RKTOOLKIT=y
BR2_PACKAGE_RKTOOLKIT_STATIC=y

⼀个可通过/dev/mem进⾏内存访问,都对芯⽚寄存器进⾏读写操作。

9.5 kmsgrab⼯具

在SDK⼯程中, 可进⾏如下进⾏编译获取。

For building kmsgrab:
1/ ./build.sh shell
2/ source ./buildroot/output/$RK_BUILDROOT_CFG/host/environment-setup
3/ $CC $RK_DATA_DIR/kmsgrab.c $(pkg-config --cflags --libs libdrm) -static -o
kmsgrab

捕获与指定CRTC或屏幕相关联的KMS扫描输出帧缓冲区,作为可以传递给其他硬件功能的DRM对象。

9.6 modetest⼯具

modetest是libdrm源码⾃带的调试⼯具, 可以对drm进⾏⼀些基础的调试。 modetest帮助信息:

(shell)## modetest -h
usage: modetest [-cDdefMPpsCvw]
Query options:
    -c list connectors
    -e list encoders
    -f list framebuffers
    -p list CRTCs and planes (pipes)

Test options:
    -P <crtc_id>:<w>x<h>[+<x>+<y>][*<scale>][@<format>] set a plane
    -s <connector_id>[,<connector_id>][@<crtc_id>]:<mode>[-<vrefresh>][@<format>]

    set a mode
    -C test hw cursor
    -v test vsynced page flipping
    -w <obj_id>:<prop_name>:<value> set property

Generic options:
    -d drop master after mode set
    -M module use the given driver
    -D device use the given device
Default is to dump all info.

9.7 perf工具

可在Buildroot中打开以下宏进行编译获取:

For building perf:
1/ Build dynamic version firstly
2/ Enable BR2_PACKAGE_LINUX_TOOLS_PERF_STATIC
3/ Run: make linux-tools-reconfigure

perf是一款Linux性能分析工具。

9.8 pmap工具

查看进程用了多少内存,Pmap提供了进程的内存映射,pmap命令用于显示一个或多个进程的内存状态。其报告进程的地址空间和内存状态信息。

## pmap PID

9.9 procrank工具

可在Buildroot中打开以下宏进行编译获取:

BR2_PACKAGE_PROCRANK_LINUX=y
BR2_PACKAGE_PROCRANK_LINUX_STATIC=y

使用procrank分析内存利用及分析源代码。procrank是一个统计内存使用的工具,包括VSS,PSS,PSS和USS的详细参数。作为内存常用的一个分析工具。

比如Buildroot用procrank分析内存使用情况:


  PID    Vss       Rss      Pss         Uss         cmdline

------ --------- -------- -------- -- -------- -- ---------------------------------------

  690    452188K   37124K   24503K      15496K      /usr/bin/weston
  853    62012K    32468K   17955K      7496K       /usr/libexec/weston-desktop-shell
  850    46376K    16612K   8517K       4444K       /usr/libexec/weston-keyboard
  701    221584K   6104K    4208K       3596K       /usr/bin/pulseaudio
  778    84068K    5584K    2868K       1792K       /usr/libexec/pulse/gsettings-helper
  641    4784K     3500K    1667K       1224K       /usr/libexec/bluetooth/bluetoothd
  686    72824K    2836K    1645K       1468K       /usr/sbin/ntpd
  917    3620K     3116K    1493K       1188K       -/bin/sh
  435    13928K    2356K    1493K       1444K       /sbin/udevd
  883    234456K   2396K    1175K       1024K       /usr/bin/adbd
  487    10784K    1068K    1064K       1060K       /usr/sbin/irqbalance
  882    3752K     1904K    893K        648K        /bin/sh
  632    3488K     1712K    594K        348K        /bin/sh
  515    2492K     1488K    514K        392K        dbus-daemon
  669    2504K     1712K    503K        376K        dhcpcd: \[manager\] \[ip4\] \[ip6\]
  910    2464K     1372K    497K        448K        /usr/sbin/dnsmasq
  919    760K      472K     472K        472K        brcm\_patchram\_plus1
  698    2324K     1096K    390K        356K        /usr/sbin/dropbear
  408    2876K     1704K    367K        148K        /sbin/syslogd
  670    2536K     1912K    352K        104K        dhcpcd: \[privileged proxy\]
  412    2876K     1712K    350K        136K        /sbin/klogd
  1244   2044K     1248K    341K        292K        procrank
  1      2876K     1552K    321K        124K        init
  1216   2536K     1416K    272K        96K         dhcpcd: \[BPF ARP\] eth0 172.16.15.72
  671    2172K     1148K    202K        64K         dhcpcd: \[network proxy\]
  672    2172K     1084K    186K        64K         dhcpcd: \[control proxy\]
  915    1896K     452K     151K        136K        input-event-daemon
                            73007K      44436K      TOTAL

cache回收可以这么操作:


+------------------------------+---------+-------+-------------------+-----------+
| > root\@rk3399-buildroot:/\## | free -h | free  | shared buff/cache | available |
| >                            |         |       |                   |           |
| > total                      | used    |       |                   |           |
+==============================+=========+=======+===================+===========+
| > Mem: 3.7Gi                 | 131Mi   | 3.5Gi | 49Mi 153Mi        | 3.5Gi     |
+------------------------------+---------+-------+-------------------+-----------+
| > Swap: 0B                   | 0B      | 0B    |                   |           |
+------------------------------+---------+-------+-------------------+-----------+

9.10 ps工具

Linux ps(英文全拼:process status)命令用于显示当前进程的状态,类似于windows的任务管理器。

ps的参数非常多,在此仅列出几个常用的参数并大略介绍含义:

  • -A 列出所有的进程

  • -w 显示加宽可以显示较多的资讯

  • -au 显示较详细的资讯

  • -aux 显示所有包含其他使用者的进程

au(x) 输出格式:
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND

USER:行程拥有者
PID:pid
%CPU:占用的 CPU 使用率
%MEM:占用的记忆体使用率
VSZ:占用的虚拟记忆体大小
RSS:占用的记忆体大小
TTY:终端的次要装置号码(minor device number of tty)
STAT:该行程的状态:
D:无法中断的休眠状态(通常 IO 的进程)
R:正在执行中
S:静止状态
T:暂停执行
Z:不存在但暂时无法消除
W:没有足够的记忆体分页可分配
<:高优先序的行程
N:低优先序的行程
L:有记忆体分页分配并锁在记忆体内
START:行程开始时间
TIME:执行的时间
COMMAND:所执行的指令

9.11 slabtop工具

实时显示内核slab缓冲信息。

每隔十秒钟刷新显示slab缓冲区信息:

slabtop -d 10

9.12 strace工具

strace是一个可用于诊断、调试的Linux用户空间跟踪器。

测试时候新开一个终端执行: strace -ttTf -e ioctl -p 这里过滤ioctl抓log

9.13 top工具

top命令是linux下常用的性能分析工具,能够实时的显示系统中各个进程的资源占用情况,常用于服务端性能分析。

9.14 update工具

进入recovery程序更新并格式化,然后重启进入正常系统。

9.15 vendor_storage工具

对Vendor分区进行读写操作。

root@rk3588-buildroot:/armhf##./vendor_storage --help
vendor storage tool - Revision: 2.0
./vendor_storage [-r/w <vendor_id> -t <pr_type> -i <input>] [-R]
-r Read specify vendor_id
-R Read common vendor_id
-w Write specify vendor_id
-t print type
-i input string
<vendor_id> There are 16 types
        "VENDOR_SN_ID"
        "VENDOR_WIFI_MAC_ID"
        "VENDOR_LAN_MAC_ID"
        "VENDOR_BT_MAC_ID"
        "VENDOR_HDCP_14_HDMI_ID"
        "VENDOR_HDCP_14_DP_ID"
        "VENDOR_HDCP_2x_ID"
        "VENDOR_DRM_KEY_ID"
        "VENDOR_PLAYREADY_Cert_ID"
        "VENDOR_ATTENTION_KEY_ID"
        "VENDOR_PLAYREADY_ROOT_KEY_0_ID"
        "VENDOR_PLAYREADY_ROOT_KEY_1_ID"
        "VENDOR_SENSOR_CALIBRATION_ID"
        "VENDOR_RESERVE_ID_14"
        "VENDOR_IMEI_ID"
        "VENDOR_CUSTOM_ID"
        And custom can define other id like
        VENDOR_CUSTOM_ID_1A (define ID = 26)
<pr_type> In write case, used with -i <input>
        There are 3 types
        "hex": <input> must be hex form like 0123
        "string": <input> must be ASCII string
        "file": <input> must be file
        Note: If use "file" and -i with read, it means save storage to file
Examples:
./vendor_storage -w VENDOR_CUSTOM_ID_1A -t file -i /userdata/test.bin
        write userdata/test.bin to storage
        Or -t string -i test_storage
        write string "test_storage" to storage
        ID = 26
./vendor_storage -r VENDOR_CUSTOM_ID_1A -t file -i /userdata/read.bin
        read storage(ID=26) to userdata/read.bin
        Or -t string
        print storage(ID=26) with ASCII string

9.16 vmstat工具

vmstat命令会报告有关内核线程、虚拟内存、磁盘、管理程序页面、陷阱和处理器活动的统计信息。

9.17 watch工具

watch可以帮助监测一个命令的运行结果。

Chapter-11 watch
Usage:
watch [options] command
Options:
    -b, --beep beep if command has a non-zero exit
    -c, --color interpret ANSI color and style sequences
    -d, --differences[=<permanent>] highlight changes between updates
    -e, --errexit exit if command has a non-zero exit
    -g, --chgexit exit when output from command changes
    -n, --interval <secs> seconds to wait between updates
    -p, --precise attempt run command in precise intervals
    -t, --no-title turn off header
    -w, --no-wrap turn off line wrapping
    -x, --exec pass command to exec instead of "sh -c"
    -h, --help display this help and exit
    -v, --version output version information and exit

9.18 weston调试方式

root@rk3288-buildroot:## WAYLAND_DEBUG=1 weston --debug

Weston相关参数如下:

root@rk3288-buildroot:## weston --help
Usage: weston [OPTIONS]

This is weston version 12.0.1, the Wayland reference compositor.
Weston supports multiple backends, and depending on which backend is in use
different options will be accepted.

Core options:

    --version Print weston version
    -B, --backend=BACKEND Backend module, one of drm
--renderer=NAME Renderer to use, one of auto Automatic selection of one of the below renderers
                                    gl OpenGL ES
                                    noop No-op renderer for testing only
                                    pixman Pixman software renderer

--shell=NAME Shell to load, defaults to desktop
-S,                             --socket=NAME Name of socket to listen on
-i, --idle-time=SECS            Idle time in seconds
--modules                       Load the comma-separated list of modules
--log=FILE                      Log to the given file
-c, --config=FILE               Config file to load, defaults to weston.ini
--no-config                     Do not read weston.ini
--wait-for-debugger Raise SIGSTOP on start-up
--debug                         Enable debug extension
-l, --logger-scopes=SCOPE
                                Specify log scopes to subscribe to.
                                Can specify multiple scopes, each followed by comma
-f, --flight-rec-scopes=SCOPE
                                Specify log scopes to subscribe to.
                                Can specify multiple scopes, each followed by comma
-w, --warm-up                   Hold display for the first app
-h, --help                      This help message
Options for drm:

--seat=SEAT                     The seat that weston should run on, instead of the seat
defined in XDG_SEAT
--drm-device=CARD               The DRM device to use, e.g. "card0".
--use-pixman                    Use the pixman (CPU) renderer (deprecated alias for --
renderer=pixman)
--current-mode                  Prefer current KMS mode over EDID preferred mode
--continue-without-input        Allow the compositor to start without input devices

9.19 fiq

1、打开CONFIG_DEBUG_SPINLOCK

2、irqchip.gicv3_pseudo_nmi=1 linux下/proc/sysrq-trigger详解

diff --git a/arch/arm64/boot/dts/rockchip/rk3588-linux.dtsi
b/arch/arm64/boot/dts/rockchip/rk3588-linux.dtsi
index 12b815850b57..7cda66903ed6 100644
--- a/arch/arm64/boot/dts/rockchip/rk3588-linux.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3588-linux.dtsi
@ -12,7 +12,7 @
};
chosen: chosen {
-                  bootargs = "earlycon=uart8250,mmio32,0xfeb50000 console=ttyFIQ0
irqchip.gicv3_pseudo_nmi=0 root=PARTUUID=614e0000-0000 rw rootwait";
+                  bootargs = "earlycon=uart8250,mmio32,0xfeb50000 console=ttyFIQ0
irqchip.gicv3_pseudo_nmi=1 root=PARTUUID=614e0000-0000 rw rootwait";
};

3、Kernel hacking --> Debug Oops, Lockups and Hangs --> (0) panic timeout 这个要配成0

请打上上面3个修改,复现死机,输入fiq,进入debugger模式,输入pcsr,确认是哪个cpu死锁了,用cpu x命令切到该cpu,输入bt查看cpu的调用栈。

9.20 linux下/proc/sysrq-trigger详解

如果系统出现挂起的情况或在诊断一些和内核相关,比较怪异,比较难重现的问题的时候,使用SysRq键是个比较好的方式。

怎么打开和关闭SysRq组合键?默认SysRq组合键是关闭的。

打开功能:

echo 1 > /proc/sys/kernel/sysrq

关闭功能:

echo 0 > /proc/sys/kernel/sysrq

sysrq功能被打开后,有几种sysrq事件能被触发,echo "m" > /proc/sysrq-trigger

- m - 导出关于内存分配的信息,
- t - 导出线程状态信息,

- p - 导出当前CPU寄存器信息和标志位的信息,
- c - 故意让系统崩溃(在使用netdump或diskdump的时候有用),
- s - 即时同步所有挂载的文件系统,
- u - 即时重新挂载所有的文件系统为只读,
- b - 即时重新启动系统,
- o - 即时关机(如果机器设置并支持此项功能)。

9.21 generate_logs自动抓取logs

运行generate_logs可以抓取系统相关log信息

buildroot## generate_logs
Log files zipped to /tmp/log-110223-090017.tar.gz

log信息都会⾃动获取到/info⽬录下, 主要log信息如下:


log信息都会自动获取到/info目录下,主要log信息如下:

- clk_summary
- cmdline
- config-5.10
- cpuinfo
- device-tree
- df.txt
- diskstats
- dma_buf
- dmesg.txt
- dri
- fstab
- gpio
- interrupts
- iomem
- kallsyms
- log
- lsof.txt
- manifest.xml
- meminfo
- modetest.txt
- os-release
- partitions
- pinctrl
- plane_58.raw
- plane_58.txt
- ps.txt
- rk_dmabuf
- rockchip_config
- slabinfo
- softirqs
- sysrq.txt
- System.map-5.10

- timestamp.txt
- top.txt
- version
- wakeup_sources
- wifibt-info.txt
...