[SOLVED] Jlink on raspberry pi 4 (aarch64) failed to read memory

This site uses cookies. By continuing to browse this site, you are agreeing to our Cookie Policy.

  • [SOLVED] Jlink on raspberry pi 4 (aarch64) failed to read memory

    Hi,

    I'd like to use JLink to debug the Linux kernel on Raspberry Pi 4B, which is based on the Cortex-A72 architecture.
    I have discovered that debugging works fine when the system runs in ARM32 mode, but it fails when using the AARCH64 (ARM64) environment.
    I checked the following points:
    • AArch64/ARM32 environment (ARM32 is okay but not AArch64)
    • Kernel randomization disabled
    • Trying to read 64-bit registers


    In the AARCH64 environment, it is unable to set breakpoints from GDB, and memory accesses are also failing, as shown in the example below.
    (But I could read 64-bit registers, though.)

    I'd like to ask about:
    1. Is there anything that I am missing to config in JLink (like 32-bit/64-bit mode.. or something else?)
    2. Methods to check MMU mappings. Are there any functions supported by JLink solution to check the mapping table?
      (Reading physical address 0x082DC210 to read virtual address 0xffffffc0082dc210,4 seems strange. I'd like to look into this.)
    3. I found there are JLink scripts to setup the environment. Should I try or write it up to attach the board for the 64-bit environment?


    JLink log:

    Source Code

    1. 01-000008B0-00-00010027-0007: $E01#a6
    2. 00-000008B0-00-00010032-000D: $qSymbol::#5b
    3. 01-000008B0-00-00010032-0006: $OK#9a
    4. 02-00000000-00-00011035-0028: T6B24 012:453.837 JLINK_GetHWStatus(...)
    5. 02-00000000-00-00011036-0025: T6B24 012:454.838 - 1.006ms returns 0
    6. 02-00000000-00-00013241-0028: T6B24 014:660.227 JLINK_GetHWStatus(...)
    7. 02-00000000-00-00013241-0025: T6B24 014:660.976 - 0.752ms returns 0
    8. 00-000008B0-00-00014457-0017: $mffffffc0082dc218,4#c0
    9. 02-00000000-00-00014457-003B: T94A0 015:876.763 JLINK_ReadMem(0x082DC218, 0x4 Bytes, ...)
    10. 02-00000000-00-00014457-0035: T94A0 015:876.792 CPU_ReadMem(4 bytes @ 0x082DC218)
    11. 02-00000000-00-00014490-001A: T94A0 015:909.126 failed
    12. 02-00000000-00-00014490-0026: T94A0 015:909.174 - 32.412ms returns 1
    13. 03-00000000-00-00014490-0034: WARNING: Failed to read memory @ address 0x082DC218
    14. 01-000008B0-00-00014490-0007: $E01#a6
    15. 00-000008B0-00-00014490-0017: $mffffffc0082dc210,4#b8
    16. 02-00000000-00-00014490-003B: T94A0 015:909.738 JLINK_ReadMem(0x082DC210, 0x4 Bytes, ...)
    17. 02-00000000-00-00014490-0035: T94A0 015:909.760 CPU_ReadMem(4 bytes @ 0x082DC210)
    18. 02-00000000-00-00014523-001A: T94A0 015:942.603 failed
    19. 02-00000000-00-00014523-0026: T94A0 015:942.683 - 32.946ms returns 1
    20. 03-00000000-00-00014523-0034: WARNING: Failed to read memory @ address 0x082DC210
    Display All

    GDB logs:

    Source Code

    1. cpu_do_idle () at arch/arm64/kernel/idle.c:32
    2. 32 arm_cpuidle_restore_irq_context(&context);
    3. (gdb) print $pc
    4. $2 = (void (*)()) 0xffffffc008b814cc <cpu_do_idle+12>
    5. (gdb) print *0xffffffc008b814cc
    6. Cannot access memory at address 0xffffffc008b814cc
    7. (gdb) print 0xffffffc008b814cc
    8. $3 = 18446743798977926348
    9. (gdb) print *0xffffffc008b814cc
    10. Cannot access memory at address 0xffffffc008b814cc
    11. (gdb) print cpu_do_idle
    12. Cannot access memory at address 0xffffffc008b814c0
    13. (gdb) print *cpu_do_idle
    14. Cannot access memory at address 0xffffffc008b814c0
    15. (gdb) l
    16. 27 arm_cpuidle_save_irq_context(&context);
    17. 28
    18. 29 dsb(sy);
    19. 30 wfi();
    20. 31
    21. 32 arm_cpuidle_restore_irq_context(&context);
    22. 33 }
    23. 34
    24. 35 /*
    25. 36 * This is our default idle handler.
    26. (gdb) n
    27. Cannot access memory at address 0xffffffc008b814cc
    28. (
    Display All

    The post was edited 2 times, last by Sukbeom Kim ().

  • I will wrap up this thread by adding a comment by myself.

    I've noticed that the software breakpoint is not working with JLink in aarch64 environment but the hardware breakpoint works well.

    I tried to write up a JLink script but there is less information about writing scripts for multiple cores. So, I decided to use openocd which has better examples and supports about this.

    This might not be the right place to wrap up with the openocd script, but I will share the script here for someone who wants to debug Linux kernel with JLink + rpi4 (aarch64).

    Source Code

    1. adapter driver jlink
    2. set _CHIPNAME bcm2711
    3. set _DAP_TAPID 0x4ba00477
    4. adapter speed 1000
    5. transport select jtag
    6. reset_config trst_and_srst
    7. telnet_port 4444
    8. # create tap
    9. jtag newtap auto0 tap -irlen 4 -expected-id $_DAP_TAPID
    10. # create dap
    11. dap create auto0.dap -chain-position auto0.tap
    12. set DBGBASE {0x80410000 0x80510000 0x80610000 0x80710000}
    13. set CTIBASE {0x80420000 0x80520000 0x80620000 0x80720000}
    14. set _cores 4
    15. set _TARGETNAME $_CHIPNAME.a72
    16. set _CTINAME $_CHIPNAME.cti
    17. set _smp_command ""
    18. for {set _core 0} {$_core < $_cores} { incr _core} {
    19. cti create $_CTINAME.$_core -dap auto0.dap -ap-num 0 -baseaddr [lindex $CTIBASE $_core]
    20. target create ${_TARGETNAME}.$_core aarch64 \
    21. -dap auto0.dap -dbgbase [lindex $DBGBASE $_core] \
    22. -coreid $_core -cti $_CTINAME.$_core
    23. $_TARGETNAME.$_core configure -event gdb-attach { halt }
    24. }
    Display All

    I can make breakpoints with `hbreak` not `break` in gdb after running the openocd script:

    Source Code

    1. sukbeom@LAPTOP-R4FQS2C5:~/workspace/linux-rpi-64$ /usr/bin/openocd -f rpi4.cfg
    2. Open On-Chip Debugger 0.11.0
    3. Licensed under GNU GPL v2
    4. For bug reports, read
    5. http://openocd.org/doc/doxygen/bugs.html
    6. Info : Listening on port 6666 for tcl connections
    7. Info : Listening on port 4444 for telnet connections
    8. Info : J-Link V11 compiled May 8 2023 13:12:36
    9. Info : Hardware version: 11.00
    10. Info : VTarget = 3.348 V
    11. Info : clock speed 1000 kHz
    12. Info : JTAG tap: auto0.tap tap/device found: 0x4ba00477 (mfg: 0x23b (ARM Ltd), part: 0xba00, ver: 0x4)
    13. Info : bcm2711.a72.0: hardware has 6 breakpoints, 4 watchpoints
    14. Info : bcm2711.a72.1: hardware has 6 breakpoints, 4 watchpoints
    15. Info : bcm2711.a72.2: hardware has 6 breakpoints, 4 watchpoints
    16. Info : bcm2711.a72.3: hardware has 6 breakpoints, 4 watchpoints
    17. Info : starting gdb server for bcm2711.a72.0 on 3333
    18. Info : Listening on port 3333 for gdb connections
    19. Info : starting gdb server for bcm2711.a72.1 on 3334
    20. Info : Listening on port 3334 for gdb connections
    21. Info : starting gdb server for bcm2711.a72.2 on 3335
    22. Info : Listening on port 3335 for gdb connections
    23. Info : starting gdb server for bcm2711.a72.3 on 3336
    24. Info : Listening on port 3336 for gdb connections
    Display All

    You have to open alll gdb ports (3333 ~ 3336) to debug each core before starting the debug, but it is working well as I expected:

    Source Code

    1. $x27 : 0x0000000000400cc0 → 0x0000000000000000 → 0x0000000000000000 → [loop detected]
    2. $x28 : 0x0000000000000001 → 0x0000000000000000 → 0x0000000000000000 → [loop detected]
    3. $x29 : 0xffffffc00a2dbbc0
    4. $x30 : 0xffffffc00834525c → <seq_read_iter+444> mov w28, w0
    5. $sp : 0xffffffc00a2dbbc0
    6. $pc : 0xffffffc0082dc218 → <memblock_debug_show+8> paciasp
    7. $cpsr: [negative zero carry overflow interrupt endian fast t32 m[4]]
    8. $fpsr: 0x0000000000000000 → 0x0000000000000000 → [loop detected]
    9. $fpcr: 0x0000000000000000 → 0x0000000000000000 → [loop detected]
    10. ──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── stack ────
    11. [!] Unmapped address: '0xffffffc00a2dbbc0'
    12. ────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── code:arm64: ────
    13. 0xffffffc0082dc20c nop
    14. 0xffffffc0082dc210 <memblock_debug_show+0> mov x9, x30
    15. 0xffffffc0082dc214 <memblock_debug_show+4> nop
    16. → 0xffffffc0082dc218 <memblock_debug_show+8> paciasp
    17. 0xffffffc0082dc21c <memblock_debug_show+12> stp x29, x30, [sp, #-80]!
    18. 0xffffffc0082dc220 <memblock_debug_show+16> mrs x1, sp_el0
    19. 0xffffffc0082dc224 <memblock_debug_show+20> mov x29, sp
    20. 0xffffffc0082dc228 <memblock_debug_show+24> stp x23, x24, [sp, #48]
    21. 0xffffffc0082dc22c <memblock_debug_show+28> mov x23, x0
    22. ──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── source:mm/memblock.c+2141 ────
    23. 2136 }
    24. 2137
    25. 2138 #if defined(CONFIG_DEBUG_FS) && defined(CONFIG_ARCH_KEEP_MEMBLOCK)
    26. 2139
    27. 2140 static int memblock_debug_show(struct seq_file *m, void *private)
    28. → 2141 {
    29. 2142 struct memblock_type *type = m->private;
    30. 2143 struct memblock_region *reg;
    31. 2144 int i;
    32. 2145 phys_addr_t end;
    33. 2146
    34. ────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── threads ────
    35. [#0] Id 1, stopped 0xffffffc0082dc218 in memblock_debug_show (), reason: BREAKPOINT
    36. ──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── trace ────
    37. [#0] 0xffffffc0082dc218 → memblock_debug_show(m=0xffffff8041a94168, private=0x1)
    38. [#1] 0xffffffc00834525c → seq_read_iter(iocb=0xffffffc00a2dbc98, iter=0xffffffc00a2dbc70)
    39. [#2] 0xffffffc0083455dc → seq_read(file=0xffffff804765c200, buf=<optimized out>, size=0x20000, ppos=0xffffffc00a2dbde0)
    40. [#3] 0xffffffc00851a608 → full_proxy_read(filp=0xffffff804765c200, buf=0x7fae14d000 "", size=0x20000, ppos=0xffffffc00a2dbde0)
    41. [#4] 0xffffffc00830f708 → vfs_read(file=0xffffff804765c200, buf=0x7fae14d000 "", count=0x20000, pos=0xffffffc00a2dbde0)
    42. [#5] 0xffffffc0083100c0 → ksys_read(fd=<optimized out>, buf=0x7fae14d000 "", count=0x20000)
    43. [#6] 0xffffffc008310174 → __do_sys_read(count=<optimized out>, buf=<optimized out>, fd=<optimized out>)
    44. [#7] 0xffffffc008310174 → __se_sys_read(count=<optimized out>, buf=<optimized out>, fd=<optimized out>)
    45. [
    Display All