硬件平台: 全志R40 + JLinkV9
软件工具: sunxi-tools, JLinkExe, JLinkGdbServer, arm-linux-gnueabihf-gcc, arm-linux-gnueabihf-gdb
程序源码:
2021.01-rc1-14752-gcdeb7b8f98-dirty
Linux OrangePi_One 5.11.0-40525-g77cdf1d653ba-dirty
一. 使用sunxi-tools构建可从ram启动的系统
使用sunxi-tools将编译后的引导, 内核, dtb, 根文件系统通过usb下载至内存中, 等待u-boot启动之后, 按任意按键进入u-boot控制台, 之后输入bootz命令可以启动linux系统. 免去烧写镜像的过程. 使用的uInitrd可以从https://whycan.com/files/members/2542/uInitrd_20210223-1517.zip中下载.
#!/bin/bash
BOARD=r40
UBOOT=~/debug/port/github-os/u-boot-${BOARD}
LINUX=~/debug/port/github-os/linux-${BOARD}/arch/arm/boot
DTS=${LINUX}/dts/sun8i-r40-bananapi-m2-ultra.dtb
sunxi-fel -p uboot ${UBOOT}/u-boot-sunxi-with-spl.bin write 0x42000000 ${LINUX}/zImage write 0x43000000 ${DTS} write 0x43300000 ./ramdisk/uInitrd
echo "Input this command in u-boot shell to boot linux kernel:"
echo "bootz 42000000 43300000 43000000"
$ sudo ./start_r40_live.sh
[sudo] password for qianfan:
100% [================================================] 4688 kB, 352.0 kB/s
100% [================================================] 24 kB, 343.7 kB/s
100% [================================================] 5044 kB, 349.3 kB/s
Input this command in u-boot shell to boot linux kernel:
bootz 42000000 43300000 43000000
(测试发现, R40使用sunxi-fel下载镜像速度比H3慢很多. H3可以达到接近1M的速度)
二: 使用tf卡转接板从MMC0(PF0-PF5)接口上引出JTAG并连接至JLink. 按下RPI M2U的boot按键进入fel模式. 使用JLinkExe程序测试硬件连接.
正常的话可以读取到芯片的信息.
Type "connect" to establish a target connection, '?' for help
J-Link>connect
Please specify device / core. <Default>: CORTEX-A7
Type '?' for selection dialog
Device>
Please specify target interface:
J) JTAG (Default)
S) SWD
T) cJTAG
TIF>
Device position in JTAG chain (IRPre,DRPre) <Default>: -1,-1 => Auto-detect
JTAGConf>
Specify target interface speed [kHz]. <Default>: 4000 kHz
Speed>
Device "CORTEX-A7" selected.
Connecting to target via JTAG
TotalIRLen = 4, IRPrint = 0x01
JTAG chain detection found 1 devices:
#0 Id: 0x5BA00477, IRLen: 04, CoreSight JTAG-DP
DPv0 detected
Scanning AP map to find all available APs
AP[2]: Stopped AP scan as end of AP map has been reached
AP[0]: AHB-AP (IDR: 0x64770001)
AP[1]: APB-AP (IDR: 0x44770002)
Iterating through AP map to find APB-AP to use
AP[0]: Skipped. Not an APB-AP
AP[1]: APB-AP found
ROMTbl[0][0]: CompAddr: 80001000 CID: 00000000, PID: 00000000 ???
ROMTbl[0][1]: CompAddr: 80100000 CID: B105100D, PID: 000BB4A7 ROM Table
ROMTbl[1][0]: CompAddr: 80110000 CID: B105900D, PID: 005BBC07 Cortex-A7
Found Cortex-A7 r0p5
6 code breakpoints, 4 data breakpoints
Debug architecture ARMv7.1
Data endian: little
Main ID register: 0x410FC075
I-Cache L1: 32 KB, 512 Sets, 32 Bytes/Line, 2-Way
D-Cache L1: 32 KB, 128 Sets, 64 Bytes/Line, 4-Way
Unified-Cache L2: 512 KB, 1024 Sets, 64 Bytes/Line, 8-Way
System control register:
Instruction endian: little
Level-1 instruction cache disabled
Level-1 data cache disabled
MMU disabled
Branch prediction enabled
Memory zones:
Zone: Default Description: Default access mode
Zone: AHB-AP (AP0) Description: DMA like acc. in AP0 addr. space
Zone: APB-AP (AP1) Description: DMA like acc. in AP1 addr. space
Cortex-A7 identified.
J-Link>
三: 修改代码保留JTAG功能
u-boot及内核启动之后, 会配置MMC0的引脚, 复用为MMC功能. 需要禁用相关代码以保证JTAG功能呢可用.
u-boot:
禁用CONFIG_MMC和CONFIG_CMD_MMC
linux: 在dts中禁用mmc0
diff --git a/arch/arm/boot/dts/sun8i-r40-bananapi-m2-ultra.dts b/arch/arm/boot/dts/sun8i-r40-bananapi-m2-ultra.dts
index a7aa8112433a..68ffa2e48658 100644
--- a/arch/arm/boot/dts/sun8i-r40-bananapi-m2-ultra.dts
+++ b/arch/arm/boot/dts/sun8i-r40-bananapi-m2-ultra.dts
@@ -175,21 +175,21 @@
#include "axp22x.dtsi"
&ir0 {
status = "okay";
};
&mmc0 {
vmmc-supply = <®_dcdc1>;
bus-width = <4>;
cd-gpios = <&pio 7 13 GPIO_ACTIVE_LOW>; /* PH13 */
- status = "okay";
+ status = "disabled";
};
&mmc1 {
pinctrl-names = "default";
pinctrl-0 = <&mmc1_pg_pins>;
vmmc-supply = <®_dldo2>;
vqmmc-supply = <®_dldo1>;
mmc-pwrseq = <&wifi_pwrseq>;
bus-width = <4>;
non-removable;
四: 配置linux内核以增加调试信息
在menuconfig中勾上这些选项:
CONFIG_DEBUG_INFO=y
CONFIG_GDB_SCRIPTS=y
CONFIG_DEBUG_KERNEL=y
CONFIG_DEBUG_VM=y
五: 启动系统并停留在u-boot控制台中.
(不要输入bootz命令, 仅停留在控制台中, 等待JLink连接. 参考步骤一)
六: 在u-boot停留在控制台中时, 使用JLinkGdbServer连接芯片
➜ ~ JLinkGDBServer -device CORTEX-A7 -if jtag -speed 2000
SEGGER J-Link GDB Server V6.92 Command Line Version
JLinkARM.dll V6.92 (DLL compiled Dec 18 2020 14:10:53)
Command line: -device CORTEX-A7 -if jtag -speed 2000
-----GDB Server start settings-----
GDBInit file: none
GDB Server Listening port: 2331
SWO raw output listening port: 2332
Terminal I/O port: 2333
Accept remote connection: yes
Generate logfile: off
Verify download: off
Init regs on start: off
Silent mode: off
Single run mode: off
Target connection timeout: 0 ms
------J-Link related settings------
J-Link Host interface: USB
J-Link script: none
J-Link settings file: none
------Target related settings------
Target device: CORTEX-A7
Target interface: JTAG
Target interface speed: 2000kHz
Target endian: little
Connecting to J-Link...
J-Link is connected.
Firmware: J-Link V9 compiled Dec 13 2019 11:14:50
Hardware: V9.30
S/N: 36310083
Feature(s): RDI, GDB, FlashDL, FlashBP, JFlash
Checking target voltage...
Target voltage: 3.31 V
Listening on TCP/IP port 2331
Connecting to target...
J-Link found 1 JTAG device, Total IRLen = 4
JTAG ID: 0x5BA00477 (Cortex-A7)
Connected to target
Waiting for GDB connection...
七: 启动arm gdb, 并连接到JLinkGdbServer的端口2331
➜ linux git:(sun8i-r40-usb-otg) ✗ arm-linux-gnueabihf-gdb vmlinux
GNU gdb (Linaro_GDB-2019.12) 8.3.1.20191204-git
Copyright (C) 2019 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Type "show copying" and "show warranty" for details.
This GDB was configured as "--host=x86_64-unknown-linux-gnu --target=arm-linux-gnueabihf".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
连接成功之后, 使用target命令连接远程端口, 并在start_kernel上面打上断点. 此时CPU已经halt. 需要使用continue命令继续运行u-boot.
(gdb) tar extended-remote :2331
Remote debugging using :2331
0xbffa4740 in ?? ()
(gdb) b start_kernel
Breakpoint 1 at 0xc0b0093c: file init/main.c, line 850.
(gdb) c
Continuing.
八: 启动linux内核.
在u-boot控制台中输入bootz 42000000 43300000 43000000命令以启动内核. 启动之后gdb停在start_kernel函数中, 之后可以单步调试.
Breakpoint 1, start_kernel () at init/main.c:850
850 {
(gdb) n
854 set_task_stack_end_magic(&init_task);
(gdb)
850 {
(gdb)
854 set_task_stack_end_magic(&init_task);
(gdb)
855 smp_setup_processor_id();
(gdb)
858 cgroup_init_early();
(gdb)
860 local_irq_disable();
(gdb)
九: 部分函数设置断点无法进入
使用该方法调试内核时, 发现只能停在start_kernel中, 在驱动中打断点无法进入. 经过探索, 发现是多核引起的. 在menuconfig中关掉CONFIG_SMP并重新编译内核, 该问题得到解决.
例如: 在gpiolib_seq_show函数中打上断点.
(gdb) b gpiolib_seq_show
Breakpoint 2 at 0xc03ca5f8: file drivers/gpio/gpiolib.c, line 4321.
(gdb) c
Continuing.
在linux控制台中触发:
mount -t debugfs none /sys/kernel/debug
cat /sys/kernel/debug/gpio
断点被gdb捕捉到, 可进行单步调试:
(gdb) i b
Num Type Disp Enb Address What
1 breakpoint keep y 0xc0b0093c in start_kernel at init/main.c:850
breakpoint already hit 1 time
2 breakpoint keep y 0xc03ca5f8 in gpiolib_seq_show at drivers/gpio/gpiolib.c:4321
(gdb) c
Continuing.
Breakpoint 2, gpiolib_seq_show (s=0xc1bd3000, v=0xc1835800) at drivers/gpio/gpiolib.c:4321
4321 {
(gdb) n
4323 struct gpio_chip *gc = gdev->chip;
(gdb)
4321 {
(gdb)
4326 if (!gc) {
(gdb)
4334 gdev->base, gdev->base + gdev->ngpio - 1);
(gdb)
4332 seq_printf(s, "%s%s: GPIOs %d-%d", (char *)s->private,
(gdb)
4334 gdev->base, gdev->base + gdev->ngpio - 1);
(gdb)
4332 seq_printf(s, "%s%s: GPIOs %d-%d", (char *)s->private,
(gdb) p s
$1 = (struct seq_file *) 0xc1bd3000
(gdb) n
4334 gdev->base, gdev->base + gdev->ngpio - 1);
(gdb)
4332 seq_printf(s, "%s%s: GPIOs %d-%d", (char *)s->private,
(gdb)
4335 parent = gc->parent;
(gdb) bt
#0 gpiolib_seq_show (s=0xc1bd3000, v=0xc1835800) at drivers/gpio/gpiolib.c:4335
#1 0xc02217fc in seq_read_iter (iocb=0xc1bf3e88, iocb@entry=0xc1bf3e80, iter=0xc0c043bc <totalreserve_pages>,
iter@entry=0xc1bf3e68) at fs/seq_file.c:227
#2 0xc0221ce0 in seq_read (file=file@entry=0xc1bfe840,
buf=buf@entry=0xbee4ec58 <error: Cannot access memory at address 0xbee4ec58>, size=size@entry=4096,
ppos=ppos@entry=0xc1bf3f78) at fs/seq_file.c:159
#3 0xc03383b4 in full_proxy_read (filp=filp@entry=0xc1bfe840,
buf=buf@entry=0xbee4ec58 <error: Cannot access memory at address 0xbee4ec58>, size=size@entry=4096,
ppos=ppos@entry=0xc1bf3f78) at fs/debugfs/file.c:229
#4 0xc01fcf60 in vfs_read (file=0xc1bfe840, buf=0xbee4ec58 <error: Cannot access memory at address 0xbee4ec58>,
count=<optimized out>, pos=0xc1bf3f78) at fs/read_write.c:494
#5 0xc01fd5d4 in ksys_read (fd=<optimized out>, buf=0xbee4ec58 <error: Cannot access memory at address 0xbee4ec58>,
count=4096) at fs/read_write.c:634
#6 0xc0100060 in cpu_v7_reset () at arch/arm/mm/proc-v7.S:64
Backtrace stopped: previous frame identical to this frame (corrupt stack?)
(gdb)
最近编辑记录 qianfan (2021-02-23 15:20:01)
离线