2013年9月29日 星期日

Jtag Openocd Eclipse debug

OpenOCD debugging is the most efficient than KGDB.

1.
Seeedstudio Bus Blaster price is less than 40 US$ on Ebay. Very cheap.
bus blaster v3 or v3c or v4 or v4.1 connect to i.mx6dq jtag pings.(Vtg, Vcc disconnect)
Blaster      - I.Mx6dq
TRST         - TRSTn (Test access port reset)
TDI            - TDI
TMS          - TMS
TCK          - TCK
TDO          - TDO
TSRST      - nSRST (System reset)
GND         - GND

http://dangerousprototypes.com/docs/Bus_Blaster
http://www.mediafire.com/view/ozh1f11zx8s2g5s/BusBlaster_jtag.png#
http://www.mediafire.com/view/9tbesr2g5j1bp82/IMX6dq_jtag.png#

2. arm-eabi-gdb dependency lib
add-apt-repository ppa:fkrull/deadsnakes
apt-get update
apt-get install python2.6 python2.6-dev

3. openocd pre-install lib
apt-get update
apt-get install libftdi-dev
apt-get install libusb-1.0-0-dev
apt-get install texinfo
apt-get install automake autoconf libtool pkg-config

4.
http://sourceforge.net/projects/openocd/files/openocd/0.9.0
download file openocd-0.9.0.tar.gz
extract to
[~home]/openocd-0.9.0
or
open terminal window -> git clone git://git.code.sf.net/p/openocd/code

5.
//i.mx6 only have hardware breakpoint.
//Hit the soft breakpoint can not continue debug, bug fixed.
function gdb_breakpoint_watchpoint_packet of openocd-0.9.0/src/server/gdb_server.c
bp_type = BKPT_SOFT;
change to
bp_type = BKPT_HARD;

6. //auto switch AHB APB source
in function cortex_a_post_debug_entry(struct target *target)
after code
cortex_a->curr_mode = armv7a->arm.core_mode;
add new
armv7a->memory_ap = armv7a->armv7a_mmu.mmu_enabled; //0-AHB 1-APB

here explain how AHB and APB work
http://arttools.blogspot.tw/2009/09/debugging-on-cortex-a8-system.html

7. //APB force use slow path
gedit /root/openocd-0.9.0/src/target/cortex_a.c
//in function cortex_a_read_apb_ab_memory
if (size == 4 && (address % 4) == 0)
//change to
if( 0 )

//in function cortex_a_write_apb_ab_memory
if (size == 4 && (address % 4) == 0)
//change to
if( 0 )

8. //speed up openocd to debug (OPTION)
gedit /root/openocd-0.9.0/src/target/target.h
//in struct target
after
int32_t coreid;
add new
bool cp15_entry_switch; //by stone

gedit /root/openocd-0.9.0/src/server/gdb_server.c
//in gdb_new_connection(struct connection *connection)
after
command_set_output_handler(connection->cmd_ctx, gdb_output, connection);
add
gdb_service->target->cp15_entry_switch = true; //by stone, when new connect cp15 read

gedit /root/openocd-0.9.0/src/target/cortex_a.c
//in cortex_a_debug_entry(struct target *target)
if (armv7a->post_debug_entry) {
...
...
//change to
if (armv7a->post_debug_entry && target->cp15_entry_switch) {
    retval = armv7a->post_debug_entry(target);
    if (retval != ERROR_OK)
            return retval;
    target->cp15_entry_switch = false;
}

gedit /root/openocd-0.9.0/src/target/cortex_a.c
//in cortex_a_post_debug_entry(struct target *target)
after
armv7a->memory_ap = armv7a->armv7a_mmu.mmu_enabled; //0-AHB 1-APB
add new
LOG_INFO("memory bus type %d", armv7a->memory_ap);

9. Avoid gdb infinite request
gedit /root/openocd-0.9.0/src/server/gdb_server.c
//add
static int gdb_rmpacket_times = 0;

//in static int gdb_read_memory_packet
if ((retval != ERROR_OK) && !gdb_report_data_abort)
//change to
if ( (retval != ERROR_OK && !gdb_report_data_abort) || gdb_rmpacket_times >= 180 )

//in static int gdb_input_inner
if (packet_size > 0)
{
...
...
//add this section
if( packet[0] == 'm' )
    gdb_rmpacket_times++;
else
    gdb_rmpacket_times = 0;

/* if a packet handler returned an error, exit input loop */
if (retval != ERROR_OK)
    return retval;
}

10.
cd [~home]/openocd-0.9.0
./configure --prefix=/opt/openocd --enable-maintainer-mode --enable-ftdi
make && make install

//If build openocd 0.10.0
(a).
gedit all configure*.* and Makefile*.*
change keyword 1.14 change to 1.15 for automake

(b).
gedit ./src/flash/nor/jtagspi.c
~~~all status change
uint32_t status;
~~~change to
uint32_t status = 0;

(c).
sudo aclocal
sudo libtoolize --force
sudo automake --add-missing
sudo autoreconf

(d).
./configure --prefix=/opt/openocd --enable-maintainer-mode --enable-ftdi --enable-target64
make && make install

(e).
gedit /etc/environment
add this
/opt/openocd/bin

then reboot

///////////// Agent-proxy terminal, No minicom
1.
git clone git://git.kernel.org/pub/scm/utils/kernel/kgdb/agent-proxy.git
cd agent-proxy
make
~#./agent-proxy 4440^4441 0 /dev/ttyUSB0,115200

2.
open another terminal
~# telnet localhost 4440    //now connect to target console

////////////u-boot console debug
1. //Load code and boot-up
because add 2 events in our imx6d-1gb.cfg
$_TARGETNAME configure -event reset-assert
$_TARGETNAME configure -event reset-end

please compare mx6d1G_4x_mt41j128.cfg with imx6d-512mb-oocd-0.8.0.cfg
mx6d1G_4x_mt41j128.cfg at /root/project_board/free_imx/myandroid/bootable/bootloader/uboot-imx/board/freescale/imx/ddr
imx6d-512mb-oocd-0.8.0.cfg at http://www.voipac.com/downloads/imx/jtag

replace correct define on clock, ddr, cache, "set" address and "mww phys" write value in imx6d-512mb-oocd-0.8.0.cfg
save to /opt/openocd/share/openocd/scripts/target/imx6d-1gb.cfg

2.
gedit ~/myandroid/bootable/bootloader/uboot-imx/Kconfig
find [config CC_OPTIMIZE_FOR_SIZE]
default y
//to
default n

3. //u-boot
gedit /root/project_board/free_imx/myandroid/bootable/bootloader/uboot-imx/Makefile
modify
KBUILD_CFLAGS    += -O2
to
KBUILD_CFLAGS    += -O0 -g -fno-omit-frame-pointer -fno-optimize-sibling-calls

4. avoid call stack infinite
gedit /root/project_board/free_imx/myandroid/bootable/bootloader/uboot-imx/arch/arm/lib/crt0.S
in ENTRY(_main)
...
...
//sub    sp, sp, #GD_SIZE
to
subs    sp, sp, #GD_SIZE

Let me explain why use [subs]:
build gdb-7.10 source code first
./configure --target=arm-linux-androideabi
make

when target breakpoint at
//$home/myandroid/bootable/bootloader/uboot-imx/arch/arm/lib/crt0.S
sub        sp, sp, #GD_SIZE    /* allocate one GD above SP */
or
//$home/myandroid/kernel_imx/arch/arm/kernel/entry-armv.S
sub        sp, sp, #(S_FRAME_SIZE + \stack_hole - 4)

//attach debug process arm-linux-androideabi-gdb
//$home/gdb-7.10/gdb/mi/mi-cmd-stack.c
void mi_cmd_stack_info_depth (...)
{
...
for (i = 0, fi = get_current_frame ();
       fi && (i < frame_high || frame_high == -1);
       i++, fi = get_prev_frame (fi))   //--->here will always dead looping
    QUIT;
...
}

//trace into
//$home/gdb-7.10/gdb/arm-tdep.c
static CORE_ADDR arm_analyze_prologue(...)
{
...
...
 //ARM_SP_REGNUM = 13
 else if ((insn & 0xfff00000) == 0xe2400000    /* sub Rd, Rn, #n */
                    &&
                    pv_is_register (regs[bits (insn, 16, 19)], ARM_SP_REGNUM))
      {
          unsigned imm = insn & 0xff;
          unsigned rot = (insn & 0xf00) >> 7;
          int rd = bits (insn, 12, 15);
          imm = (imm >> rot) | (imm << (32 - rot));
          regs[rd] = pv_add_constant (regs[bits (insn, 16, 19)], -imm);
          continue;
      }
...
...
 else if ((insn & 0xfffff000) == 0xe24dd000)    /* sub sp, sp #n */
      {
            unsigned imm = insn & 0xff;
            unsigned rot = (insn & 0xf00) >> 7;
            imm = (imm >> rot) | (imm << (32 - rot));
            regs[ARM_SP_REGNUM] = pv_add_constant (regs[ARM_SP_REGNUM], -imm);
      }
...
...
}

5.
gedit /root/project_board/lollipop51/myandroid/bootable/bootloader/uboot-imx/arch/arm/lib/cache-cp15.c
static void cache_disable(uint32_t cache_bit)
{
...
if (cache_bit == (CR_C | CR_M))
    {
        flush_dcache_all();
        /* issue begin */
//mark here
/*
        set_cr(reg & ~CR_C);
        flush_dcache_all();
*/
    }
...
}

6. Change to usb upload
Hardware Switch Boot Mode1 to Boot Mode0

7. open new terminal
openocd -f /opt/openocd/share/openocd/scripts/target/imx6d-1gb.cfg

8. open new terminal
~#/root/project_board/free_imx/myandroid/prebuilts/gcc/linux-x86/arm/arm-eabi-4.6/bin/arm-eabi-gdb
(gdb)target remote localhost:3333
(gdb)monitor reset halt
(gdb)symbol-file /root/project_board/free_imx/out/matrix_io/uboot/u-boot  //must before load
(gdb)load /root/project_board/free_imx/out/matrix_io/uboot/u-boot
(gdb)break relocate_code
(gdb)continue
Breakpoint 1, relocate_code ()
    at /root/project_board/free_imx/myandroid/bootable/bootloader/uboot-imx/arch/arm/lib/relocate.S:25
        subs    r4, r0, r1        /* r0 <- relocation addr */

//////////relocate address uboot debug/////////
1.
//in u-boot start operation
Power key pressed
Normal Boot
Hit any key to stop autoboot:  0
=> bdinfo
arch_number = 0x00000F8C
boot_params = 0x10000100
DRAM bank   = 0x00000000
-> start    = 0x10000000
-> size     = 0x40000000
eth0name    = FEC
ethaddr     = (not set)
current eth = FEC
ip_addr     = <NULL>
baudrate    = 115200 bps
TLB addr    = 0x4FFF0000
relocaddr   = 0x4FF49000   ///////---> this value for add-symbol-file of arm-eabi-gdb
reloc off   = 0x3DF49000
irq_sp      = 0x4F546EE0
sp start    = 0x4F546ED0
FB base     = 0x00000000

2.
in u-boot start operation,  open new terminal type follows
~# openocd -f /opt/openocd/share/openocd/scripts/interface/ftdi/dp_busblaster.cfg -f /opt/openocd/share/openocd/scripts/target/imx6.cfg

3.
~#/root/project_board/free_imx/myandroid/prebuilts/gcc/linux-x86/arm/arm-eabi-4.6/bin/arm-eabi-gdb
(gdb)target remote localhost:3333
(gdb)add-symbol-file /root/project_board/free_imx/out/matrix_io/uboot/u-boot 0x4FF49000
(gdb)monitor reg
(gdb)cont (then press ctrl+c)
(gdb)bt
//////////////will show follows
#0  0x12000000 in ?? ()
#1  0x4ff704c8 in serial_getc ()
    at /root/project_board/free_imx/myandroid/bootable/bootloader/uboot-imx/drivers/serial/serial.c:413
#2  0x00000000 in ?? ()

4.
4ff704c8 - 3DF49000(reloc off) = 120274C8
/*check  /root/project_board/free_imx/out/matrix_io/uboot/u-boot.map
            .text.serial_getc
                0x00000000120274b8       0x14 drivers/serial/built-in.o
                0x00000000120274b8                serial_getc
             
                .text.serial_tstc
                0x00000000120274cc       0x14 drivers/serial/built-in.o
                0x00000000120274cc                serial_tstc             

confirm 120274b8  < [120274C8] < 120274cc the address is correct
openocd uboot debug is ok~~*/

////////////kernel console debug
1.
//default config
gedit /root/project_board/free_imx/myandroid/kernel_imx/arch/arm/configs/mx6dq_matrix_android_defconfig
//enableCONFIG_DEBUG_INFO=y
CONFIG_FTRACE=y
CONFIG_FUNCTION_TRACER=y

note:
CONFIG_FTRACE & CONFIG_FUNCTION_TRACER will enable CONFIG_FRAME_POINTER
[config FRAME_POINTER] in ~/myandroid/kernel_imx/arch/arm/Kconfig.debug 

2.
gedit /root/project_board/free_imx/myandroid/device/fsl/matrix_io/init.matrix_io.rc
on init
    #start watchdogd   -->mark here

#service watchdogd /sbin/watchdogd 10 20 5   -->mark here
#    class core
#    seclabel u:r:watchdogd:s0

3. //linux kernel
gedit /root/project_board/free_imx/myandroid/kernel_imx/Makefile
KBUILD_CFLAGS    += -O2
to
KBUILD_CFLAGS    += -O1 -g -fno-inline-functions-called-once -fno-omit-frame-pointer -U__OPTIMIZE__

__OPTIMIZE__ use in kernel_imx/include/linux/build_bug.h change define for BUILD_BUG_ON

if set -O0 or compile error, refer to
http://fatalfeel.blogspot.tw/2013/09/kgdb-eclipse-debug-kernel-on-imx6.html

4. debug linux drivers. (select any directory which you want to debug)
gedit /root/project_board/free_imx/myandroid/kernel_imx/drivers/Makefile
//first line add
KBUILD_CFLAGS    += -O0 -g

//rebuild

5. remove breakpoint and watchpoint reset action
gedit /root/project_board/free_imx/myandroid/kernel_imx/arch/arm/kernel/hw_breakpoint.c
//in functon reset_ctrl_regs(void *unused)
//mark this section
/*
for (i = 0; i < raw_num_brps; ++i) {
    write_wb_reg(ARM_BASE_BCR + i, 0UL);
    write_wb_reg(ARM_BASE_BVR + i, 0UL);
}
for (i = 0; i < core_num_wrps; ++i) {
    write_wb_reg(ARM_BASE_WCR + i, 0UL);
    write_wb_reg(ARM_BASE_WVR + i, 0UL);
}
*/

//in function static u8 get_max_wp_len(void)
//mark this section
/*
write_wb_reg(ARM_BASE_WVR, 0);
write_wb_reg(ARM_BASE_WCR, ctrl_reg);
*/

6. remove low power clock
arm clock need always enable for jtag have 2 ways, select one.
(a.)way
gedit /root/project_board/free_imx/myandroid/kernel_imx/arch/arm/mach-imx/pm-imx6.c
val |= 0x1 << BP_CLPCR_LPM;
val |= BM_CLPCR_ARM_CLK_DIS_ON_LPM;
to
/*val |= 0x1 << BP_CLPCR_LPM;
val |= BM_CLPCR_ARM_CLK_DIS_ON_LPM;*/

(b.)way
gedit /root/project_board/free_imx/myandroid/kernel_imx/arch/arm/configs/mx6dq_android_defconfig
CONFIG_CPU_IDLE=y
to
#CONFIG_CPU_IDLE=y

I select way (a.)

7.
gedit /root/project_board/free_imx/myandroid/kernel_imx/arch/arm/kernel/entry-armv.S
//find .macro    svc_entry, stack_hole=0
sub        sp, sp, #(S_FRAME_SIZE + \stack_hole - 4)
//change to
subs    sp, sp, #(S_FRAME_SIZE + \stack_hole - 4)

8. disable jtag alarm for Android 6.0
gedit /root/project_board/free_imx/myandroid/kernel_imx/drivers/crypto/caam/secvio.c
//find
static int snvs_secvio_probe(struct platform_device *pdev)

#if defined(CONFIG_JTAG_DEBUG)
    wr_reg32(&svpriv->svregs->hp.secvio_intcfg, HP_SECVIO_INTEN_SRC4 | HP_SECVIO_INTEN_SRC0);
#else
    wr_reg32(&svpriv->svregs->hp.secvio_intcfg, HP_SECVIO_INTEN_SRC4 | HP_SECVIO_INTEN_SRC2 | HP_SECVIO_INTEN_SRC1 | HP_SECVIO_INTEN_SRC0);
#endif

9. fixed for some device node can not stop on breakpoint
gedit /mnt/projects/marsh_mnt/myandroid/kernel_imx/drivers/base/devtmpfs.c
int __init devtmpfs_init(void)
{
...
...
/*kthread_run on myandroid/kernel_imx/include/linux/kthread.h*/
#if defined(CONFIG_JTAG_DEBUG)
    thread = kthread_create(devtmpfsd, &err, "kdevtmpfs");

    if (!IS_ERR(thread))
    {
        thread->wake_cpu = 0;
        wake_up_process(thread);
    }
#else
    thread = kthread_run(devtmpfsd, &err, "kdevtmpfs");
#endif
...
...
    printk(KERN_INFO "devtmpfs: initialized\n");
    return 0;
}

10. pass compile -O0 for Android 6.0
gedit /root/project_board/free_imx/myandroid/kernel_imx/kernel/seccomp.c
static inline void seccomp_sync_threads(void)
{
...
...
#if defined(CONFIG_JTAG_DEBUG)
        smp_mb(); //pass compiletime_assert_atomic_type on -O0
        ACCESS_ONCE(thread->seccomp.filter) =  caller->seccomp.filter;
#else
        smp_store_release(&thread->seccomp.filter, caller->seccomp.filter);
#endif
...
...
}

11.
enable [developer options]
Settings -> About Device -> Software info, tap on build number 7 times to unlock

enable [Stay awake] in developer options
(hint: screen will never sleep while charging)

12. kernel start operation at  [0.000000] Booting Linux on physical CPU 0x0
open new terminal type follows
~# /root/project_board/free_imx/myandroid/prebuilts/gcc/linux-x86/arm/arm-eabi-4.6/bin/arm-eabi-gdb
(gdb)target remote localhost:3333
(gdb)symbol-file /root/project_board/free_imx/out/matrix_io/kernel/vmlinux
(gdb)cont
(then press ctrl+c)

//show follows
Program received signal SIGINT, Interrupt.
0x8025c548 in kernel_map_pages (page=0x822bef44, numpages=1, enable=1)
    at /root/project_board/free_imx/myandroid/kernel_imx/mm/debug-pagealloc.c:99
            unpoison_pages(page, numpages);

////////////Openocd eclipse GUI
////////////u-boot GUI debug
1.install eclipse kepler
http://www.eclipse.org/downloads/packages/release/Kepler/SR2
Eclipse Standard 4.3.2 -> linux 64bits
install eclipse-standard-kepler-SR2-linux-gtk-x86_64.tar.gz
extract to /opt/eclipse
chmod 755 -R /opt/eclipse

gedit /opt/eclipse.ini
-XX:PermSize=64m
-XX:MaxPermSize=256m
-Xms128m
-Xmx4096m

Here is full install step:
http://fatalfeel.blogspot.tw/2013/09/eclipse-setting-for-ubuntu-imx6-android.html

2.
Help -> install new software...
work with: http://gnuarmeclipse.sourceforge.net/updates
//check
GNU ARM C/C++ OpenOCD Debugging

3.
right click project
Debug As -> Debug Configurations -> GDB Hardware Debugging
double click to create new name
c/c++ application: /root/project_board/free_imx/out/matrix_io/uboot/u-boot
click bottom line Select other... -> GDB(DSF) Hardware Debugging Launcher
check [disable auto build]

4.
click Debugger tab
GDB Command: /root/project_board/free_imx/myandroid/prebuilts/gcc/linux-x86/arm/arm-eabi-4.6/bin/arm-eabi-gdb
check [Use Remote Target]
Jtag device: GUN ARM OPENOCD
Host name or ip address:localhost
port number:3333

5.
click startup tab
uncheck the all items on startup page
add those lines under [Halt] Box
monitor reset halt
symbol-file /root/project_board/free_imx/out/matrix_io/uboot/u-boot //must before load
load /root/project_board/free_imx/out/matrix_io/uboot/u-boot

6. //Load code and boot-up
because add 2 events in our imx6d-1gb.cfg
$_TARGETNAME configure -event reset-assert
$_TARGETNAME configure -event reset-end

please compare mx6d1G_4x_mt41j128.cfg with imx6d-512mb-oocd-0.8.0.cfg
mx6d1G_4x_mt41j128.cfg at /root/project_board/free_imx/myandroid/bootable/bootloader/uboot-imx/board/freescale/imx/ddr
imx6d-512mb-oocd-0.8.0.cfg at http://www.voipac.com/downloads/imx/jtag

replace correct define on clock, ddr, cache, "set" address and "mww phys" write value in imx6d-512mb-oocd-0.8.0.cfg
save to /opt/openocd/share/openocd/scripts/target/imx6d-1gb.cfg

7. Change to usb upload
Hardware Switch Boot Mode1 to Boot Mode0

8. open new terminal
openocd -f /opt/openocd/share/openocd/scripts/target/imx6d-1gb.cfg

9.
click eclipse [Debug] button
//done

////////second debug, after u-boot relocate code address///////
1.
click startup tab
uncheck all the items on startup page
add this line under [Halt] Box
add-symbol-file /root/project_board/free_imx/out/matrix_io/uboot/u-boot 0x4FF04000
rember 0x4FF04000 is from u-boot start operation and input [bdinfo] will show you

2.
After u-boot relocate code address,  open new terminal type follows
~# openocd -f /opt/openocd/share/openocd/scripts/target/imx6d-1gb.cfg
or
~# openocd -f /opt/openocd/share/openocd/scripts/interface/ftdi/dp_busblaster.cfg -f /opt/openocd/share/openocd/scripts/target/imx6.cfg

3.
after into u-boot start operation click eclipse [Debug] button
//done

////////////Kernel GUI debug/////////
/////////////////////////////////////////
1.
right click project
Debug As -> Debug Configurations -> GDB Hardware Debugging
double click to create new name
C/C++ application: /root/project_board/free_imx/out/matrix_io/kernel/vmlinux
click bottom line Select other... -> GDB(DSF) Hardware Debugging Launcher
check [disable auto build]

2.
click startup tab
uncheck all items on startup page
two ways choice, I use way (a.)

(a.)//target remote localhost:3333 first then load symbol-file
add this line under [Halt] checkbox
symbol-file /root/project_board/free_imx/out/matrix_io/kernel/vmlinux

(b.) //load symbol-file first then target remote localhost:3333
check [Load symbols], Use project binary:

3.
After u-boot relocate code address, open new terminal type follows
~# openocd -f /opt/openocd/share/openocd/scripts/target/imx6d-1gb.cfg
or
~# openocd -f /opt/openocd/share/openocd/scripts/interface/ftdi/dp_busblaster.cfg -f /opt/openocd/share/openocd/scripts/target/imx6.cfg

4.
click eclipse debug
click debug continue

5.
in target console u-boot start operation
==> boot
then enter Starting kernel ...

6.
when Starting kernel operation at [0.000000] Booting Linux on physical CPU 0x0
click eclipse suspend button quickly

7.
set breakpoint
click continue
//done

///////////How debug module .ko
insmod /mytest/hellotest.ko
When cat /sys/module/hellotest/sections/.text = 0x00000000
Try one of these ways
1.
(a.)
gedit /root/project_board/free_imx/myandroid/kernel_imx/kernel/module.c
//in function module_sect_show
return sprintf(buf, "0x%pK\n", (void *)sattr->address);
//change to
return sprintf(buf, "0x%p\n", (void *)sattr->address);

(b.)
geidt ~/myandroid/device/fsl/matrix/etc/init.rc
write /proc/sys/kernel/kptr_restrict 2
//change to
write /proc/sys/kernel/kptr_restrict 0

I select (b.)

2.
root@matrix_io:/ # insmod /data/hellomod/hellotest.ko
[   76.104855] Hello, world
root@matrix_io:/ # cat /sys/module/hellotest/sections/.text
0x7f11c000  //-->get this addr

3.
in eclipse right click your project
Debug As -> Debug Configurations -> GDB Hardware Debugging
click [Startup tab]
uncheck the all items on startup page
add those lines under [Halt] box but do not check [Halt]
add-symbol-file /root/project_board/free_imx/out/matrix_io/uboot/u-boot 0x7f11c000
then click [Apply]

//////////////////////////////////////////////////////////////////////////////////////////////
///////////Hardware shared lib debugging
//////////////////////////////////////////////////////////////////////////////////////////////
1. Get target load address
grep gralloc_viv.imx6.so /proc/*/maps
ad920000-ad924000 r-xp 00000000 103:02 722       /system/lib/hw/gralloc_viv.imx6.so

2. Get shared lib .text address
/mnt/projects/lollipop_mnt/myandroid/prebuilts/gcc/linux-x86/arm/arm-eabi-4.6/bin/arm-eabi-readelf -S /mnt/projects/lollipop_mnt/out/matrix_io/android/target/product/matrix_io/system/lib/hw/gralloc_viv.imx6.so
Section Headers:
  [Nr] Name              Type            Addr     Off    Size   ES Flg Lk Inf Al
  [ 8] .text             PROGBITS        000013d8 0013d8 001988 00  AX  0   0  8

0xad920000 + 0x000013d8 = 0xad921d38

3. Set to arm-eabi-gdb
click Startup tab
uncheck the all items on startup page
add those lines under [Halt] box but do not check [Halt]
add-symbol-file /mnt/projects/lollipop_mnt/out/matrix_io/android/target/product/matrix_io/system/lib/hw/gralloc_viv.imx6.so 0xad9213d8
apply to debug

4. Set breakpoint in a function
/mnt/projects/lollipop_mnt/myandroid/prebuilts/gcc/linux-x86/arm/arm-eabi-4.6/bin/arm-eabi-readelf -s /mnt/projects/lollipop_mnt/out/matrix_io/android/target/product/matrix_io/system/lib/hw/gralloc_viv.imx6.so
28: 00001af1   456 FUNC    GLOBAL DEFAULT    8 _Z25gralloc_alloc_framebu

gralloc_alloc_frame = 0x00001af1 - 0x1 = 0x00001af0 (aligned 4 address in arm cortex)

set break point at target
0xad920000 + 0x00001af0 = 0xad921af0

//////////////////////////////////////////////////////////////////////////////////////////////
//Watchpoint patch
//////////////////////////////////////////////////////////////////////////////////////////////
1.
gedit /root/openocd-0.9.0/src/target/cortex_a.h
//berfore struct cortex_a_common
//add new
struct cortex_a_wrp
{
    int used;
    uint32_t value;
    uint32_t control;
    uint8_t WRPn;
};

//in struct cortex_a_common
//after struct cortex_a_brp *brp_list;
//add new
int wrp_num;
int wrp_num_available;
struct cortex_a_wrp* wrp_list;

2.
gedit /root/openocd-0.9.0/src/target/cortex_a.c
//after function cortex_a_remove_breakpoint
//add functions
static int cortex_a_set_watchpoint(struct target *target, struct watchpoint *watchpoint)
{
    int retval;
    int wrp_i = 0;
    uint32_t    control;
    uint8_t        access_mode;
    uint8_t        byte_addr_select = 0x0F;
    struct cortex_a_common*    cortex_a    = target_to_cortex_a(target);
    struct armv7a_common*        armv7a    = &cortex_a->armv7a_common;
    struct cortex_a_wrp*            wrp_list    = cortex_a->wrp_list;

    if (watchpoint->set)
    {
        LOG_WARNING("breakpoint already set");
        return ERROR_OK;
    }

    while (wrp_list[wrp_i].used && (wrp_i < cortex_a->wrp_num))
        wrp_i++;

    if (wrp_i >= cortex_a->wrp_num)
    {
        LOG_ERROR("ERROR Can not find free Watchpoint Register Pair");
        return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
    }

    watchpoint->set = wrp_i + 1;

    access_mode = watchpoint->rw+1;
    control = (byte_addr_select << 5) | (access_mode << 3) | (3 << 1) | 1;
    wrp_list[wrp_i].used = 1;
    wrp_list[wrp_i].value = (watchpoint->address & 0xFFFFFFFC);
    wrp_list[wrp_i].control = control;

    retval = cortex_a_dap_write_memap_register_u32(target,
                                                                                    armv7a->debug_base + CPUDBG_WVR_BASE + 4 * wrp_list[wrp_i].WRPn,
                                                                                    wrp_list[wrp_i].value);
    if (retval != ERROR_OK)
        return retval;

    retval = cortex_a_dap_write_memap_register_u32(target,
                                                                                    armv7a->debug_base + CPUDBG_WCR_BASE + 4 * wrp_list[wrp_i].WRPn,
                                                                                    wrp_list[wrp_i].control);

    if (retval != ERROR_OK)
        return retval;

    return ERROR_OK;
}

static int cortex_a_unset_watchpoint(struct target *target, struct watchpoint *watchpoint)
{
    int retval;
    int wrp_i;
    struct cortex_a_common *cortex_a = target_to_cortex_a(target);
    struct armv7a_common *armv7a = &cortex_a->armv7a_common;
    struct cortex_a_wrp *wrp_list = cortex_a->wrp_list;

    if (!watchpoint->set)
    {
        LOG_WARNING("watchpoint not set");
        return ERROR_OK;
    }

    wrp_i = watchpoint->set - 1;

    if ((wrp_i < 0) || (wrp_i >= cortex_a->wrp_num))
    {
        LOG_DEBUG("Invalid WRP number in watchpoint");
        return ERROR_OK;
    }

    LOG_DEBUG("rbp %i control 0x%0" PRIx32 " value 0x%0" PRIx32, wrp_i, wrp_list[wrp_i].control, wrp_list[wrp_i].value);

    wrp_list[wrp_i].used = 0;
    wrp_list[wrp_i].value = 0;
    wrp_list[wrp_i].control = 0;

    retval = cortex_a_dap_write_memap_register_u32(target,
                                                                                        armv7a->debug_base + CPUDBG_WCR_BASE + 4 * wrp_list[wrp_i].WRPn,
                                                                                        wrp_list[wrp_i].control);
    if (retval != ERROR_OK)
        return retval;

    retval = cortex_a_dap_write_memap_register_u32(target,
                                                                                        armv7a->debug_base + CPUDBG_WVR_BASE + 4 * wrp_list[wrp_i].WRPn,
                                                                                        wrp_list[wrp_i].value);
    if (retval != ERROR_OK)
        return retval;

    watchpoint->set = 0;

    return ERROR_OK;
}

static int cortex_a_add_watchpoint(struct target *target, struct watchpoint *watchpoint)
{
     struct cortex_a_common* cortex_a = target_to_cortex_a(target);

     if (cortex_a->wrp_num_available < 1)
     {
         LOG_INFO("no hardware breakpoint available");
         return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
     }

     //if (breakpoint->type == BKPT_HARD)
     cortex_a->wrp_num_available--;

     return cortex_a_set_watchpoint(target, watchpoint);
}

static int cortex_a_remove_watchpoint(struct target *target, struct watchpoint *watchpoint)
{
    struct cortex_a_common* cortex_a = target_to_cortex_a(target);

    if (watchpoint->set)
    {
        //if (breakpoint->type == BKPT_HARD)
        cortex_a_unset_watchpoint(target, watchpoint);

        cortex_a->wrp_num_available++;
    }

    return ERROR_OK;
}

3.
gedit /root/openocd-0.9.0/src/target/cortex_a.c
//in cortex_a_examine_first(struct target *target)
//after LOG_DEBUG("Configured %i hw breakpoints", cortex_a->brp_num);
//add
cortex_a->wrp_num = ((didr >> 28) & 0x0F) + 1;
cortex_a->wrp_num_available = cortex_a->wrp_num;
free(cortex_a->wrp_list);
cortex_a->wrp_list = calloc(cortex_a->wrp_num, sizeof(struct cortex_a_wrp));

for (i = 0; i < cortex_a->wrp_num; i++)
{
    cortex_a->wrp_list[i].used = 0;
    cortex_a->wrp_list[i].value = 0;
    cortex_a->wrp_list[i].control = 0;
    cortex_a->wrp_list[i].WRPn = i;
}
LOG_DEBUG("Configured %i hw watchpoints", cortex_a->wrp_num);

4.
gedit /root/openocd-0.9.0/src/target/cortex_a.c
//both struct target_type cortexa_target and struct target_type cortexr4_target
.add_watchpoint = NULL,
.remove_watchpoint=NULL,
//change to
.add_watchpoint = cortex_a_add_watchpoint,
.remove_watchpoint = cortex_a_remove_watchpoint,

5.
gedit /root/openocd-0.9.0/src/target/arm_dpm.c
//in arm_dpm_setup(struct arm_dpm *dpm)
target->type->add_watchpoint = dpm_add_watchpoint;
target->type->remove_watchpoint = dpm_remove_watchpoint;
//change to
if (!target->type->add_watchpoint)
{
    target->type->add_watchpoint = dpm_add_watchpoint;
    target->type->remove_watchpoint = dpm_remove_watchpoint;
}

//////////////////////////////////////////////////////////////////////////////////////////////
//Using watchpoint on eclipse
//////////////////////////////////////////////////////////////////////////////////////////////
In eclipse [Console] window select [GDB Hardware Debugging]  window
(arrch64 can not use monitor wp  because handle_wp_command use 32 bits set address)
(a)add watchpoint command:
monitor wp address sizeof(unit) r/w/a(read/write/access)
(b)remove watchpoint command:
monitor rwp address
example:
monitor wp 0x8144be4c 4 r
monitor rwp 0x8144be4c
https://picasaweb.google.com/106185541018774360364/IMx6#6245065388141165858
(c) Fit for Arm 32 and 64 bits:
open [Breakpoints] window
click inverted triangle icon [View Menu] -> [Add Watchpoint (C/C++)...]
Expression to watch: 0x8144be4c (fill address 32 or 64 bits)
Read: cheked
Write: cheked
Enabled: cheked

#After hit the watchpoint, you must remove it manually or debug can not continue.

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Ref. site:
a. bus blaster and i.mx6 setting
http://imx6dev.blogspot.tw/2014/07/inexpensive-jtag-on-imx6-solo-u-boot.html
http://wiki.wandboard.org/index.php/JTAG-BusBlaster

b. openocd console config
http://www.edlangley.co.uk/blog/2014/06/rescuing-bricked-secure-mode-i.mx6
http://wiki.voipac.com/xwiki/bin/view/imx6+rex/jtag_oocd
http://www.imx6rex.com/software/how-to-run-ddr3-calibration-on-imx6

c. openocd eclipse setting
https://www.tincantools.com/wiki/BeagleBone_Black_Eclipse_and_GDB
http://thehackerworkshop.com/?tag=eclipse

d. arm clock enable
https://community.freescale.com/thread/376786

e. watchpoint reference manual
https://developer.arm.com/docs/ddi0595/b/aarch64-system-registers/dbgwcrn_el1
http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0344k/Bcgjbgie.html
http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0438d/BCGGABBC.html

Demo:
1. https://www.youtube.com/watch?v=8K1qY3St06k
2. https://www.youtube.com/watch?v=2L1vr_LA8Nc 
3. https://picasaweb.google.com/106185541018774360364/IMx6#6241487014458388690
4. https://picasaweb.google.com/106185541018774360364/IMx6#6241103017491328690
5. https://picasaweb.google.com/106185541018774360364/IMx6#6240074819468163938
6. https://picasaweb.google.com/106185541018774360364/IMx6#6239524844608161106

My OpenOcd full patch:
https://github.com/fatalfeel/openocd_integrated
https://www.mediafire.com/file/7viduzzxmw9b4do/openocd-0.10.1_v03.tar.gz
http://www.mediafire.com/file/5zij1ul68ajrb59/openocd-0.10.0_v22.tar.gz
http://www.mediafire.com/file/p5ogkicf8nhg14i/openocd-0.9.0_v16.tar.gz

Android GDB aarch64 build script: OpenOcd need gdb send 64 bits address
gdb maybe need lzma debug format: (recommend lzma gdb)
http://www.mediafire.com/file/fi4mstilpruspkv/build_aarch64_gdb.sh
http://www.mediafire.com/file/a1xeyw0l3nvhrid/build_aarch64_lzma_gdb.sh
https://android.googlesource.com/platform/prebuilts/gcc/linux-x86/aarch64/aarch64-linux-android-4.9/+archive/5bf1af6cf88c2cc186191445a8086d4fd4bd4b28/bin.tar.gz (old version)

Docx files:
http://www.mediafire.com/file/ueixkx0xqj63p56/openocdv18.docx
http://www.mediafire.com/file/t4cv7b1d2z0b53g/openocdv17.docx
http://www.mediafire.com/file/3b5tbabxjj5a0a6/openocdv16.docx 

Jtag kernel patch
arm32 source of uboot and kernel for jtag
http://www.mediafire.com/file/rddsei4hsdcw8ad/myandroid.tar.gz
arm64 source of kernel for jtag
https://www.mediafire.com/file/ku1l1v9xsdi9p01/jtag_kernel_aarch64.tar.gz

Openocd plugin for eclipse install
https://github.com/eclipse-embed-cdt/eclipse-plugins/releases/tag/v2.12.1-201604190915

Eclipse Luna 64bits linux ADT + CDT + Openocd on Java8. Extract to /opt/eclipse_luna
http://www.mediafire.com/file/8fb3dsi88j5iru9/eclipse_luna_adt_cdt_openocd.tar.gz
 
Eclipse Kepler 64bits linux ADT + CDT + Openocd on Java6,7. Extract to /opt/eclipse_kepler
http://www.mediafire.com/file/7auvmwm2uw8avod/eclipse_adt_cdt_openocd.tar.gz

Eclipse Kepler 64bits linux ADT + CDT + Openocd on Java8. Extract to /opt/eclipse
http://www.mediafire.com/file/l0zh2uqlwmvsbjp/eclipse_kepler_java8_adt_cdt_openocd.tar.gz

21 則留言:

  1. Excellent article. Do you have dual or quad version ? How do you do multicore debug with openocd ?

    回覆刪除
  2. dual and quad are the same code~~~on imx6 i try on dual is ok

    回覆刪除
  3. support cortex a53 of armv8
    http://www.mediafire.com/file/bdddt53fsb81t3l/openocd-0.10.0_v5.tar.gz

    回覆刪除
  4. openocd update to
    Revision: 828ee07657914212f81152a768a8ec43bb73db03
    Author: Paul Fertser
    Date: 2018/1/13 下午 09:22:10
    server: bind to IPv4 localhost by default
    and
    update libjaylink to 2.0

    回覆刪除
  5. Great post man thanks for sharing this useful information as i was in serach for Xbox One Jailbreak download finally i found one original and working Xbox One Jailbreak download & Xbox One Jtag for free follow the link to read more.



    If you are looking for an Xbox 360 Jailbreak then your search is over now as we are giving you a chance to jailbreak your Xbox,Visit Xbox 360 Jailbreak download for free with Guide & Xbox 360 Jtag Download

    回覆刪除
  6. http://www.mediafire.com/file/rswyvns80epo8ab/openocd-0.10.0_v22.tar.gz
    Git version:
    Author: Paul Fertser 2016-11-04 18:58:05
    Committer: Tomas Vanek 2019-02-26 07:53:48

    回覆刪除
  7. openocd-0.10.1_v00.tar.gz

    code base from openocd git https://git.code.sf.net/p/openocd/code
    Author: Antonio Borneo 2019-06-25 22:01:38

    code base from libjylink git https://github.com/syntacore/libjaylink
    Author: Fredrik Ahlberg 2018-11-10 06:18:26

    Compile in ubuntu 16.04 x64 and Test ok in imx6 devboard
    Will test on imx8m in the future

    回覆刪除
  8. update new jimtcl in the version date 2019-11-20
    http://www.mediafire.com/file/uwenkc014kk8h3q/openocd-0.10.1_v03.tar.gz

    回覆刪除
  9. The Best Eclipse version is LUNA
    Mars need setting gtk2 in eclipse.ini
    After Mars,these are no Legacy setting for gdbserver

    回覆刪除
  10. Android GDB aarch64 build script: OpenOcd need gdb send 64 bits address
    (recommend)
    http://www.mediafire.com/file/fi4mstilpruspkv/build_aarch64_gdb.sh
    (old version)
    https://android.googlesource.com/platform/prebuilts/gcc/linux-x86/aarch64/aarch64-linux-android-4.9/+archive/5bf1af6cf88c2cc186191445a8086d4fd4bd4b28/bin.tar.gz

    回覆刪除
  11. aarch64 demo in eclipse LUNA
    http://www.mediafire.com/view/c2vpv991rfbplqp/2020-06-01%2018-14-49%20%E7%9A%84%E8%9E%A2%E5%B9%95%E6%93%B7%E5%9C%96.png#

    回覆刪除
  12. in arm or arm64 you need disable all CPU_IDLE
    or happend DAP transaction stalled (WAIT) - slowing down
    refer to my post:
    https://community.nxp.com/message/update-advanced-comment.jspa?id=1321770&draftID=902337

    回覆刪除
  13. aarch64 add watchpoint on 20/June/2020
    use eclipse ide set and hit the address

    回覆刪除
  14. modify for wifi debug in 2021
    kernel_imx_aarch64.tar.gz

    回覆刪除
  15. Thanks for the excellent post! I'm able to debug an i.MX8MN with OpenOCD 0.11.0 built with no patches, using board/nxp_mcimx8m-evk.cfg and by adding "cpuidle.off=1" to Linux boot args.

    回覆刪除
    回覆
    1. gedit $HOME/OK8MM-android/vendor/nxp-opensource/kernel_imx/arch/arm64/boot/dts/freescale/fsl-imx8mm.dtsi
      comment this section can skip idle too
      cpus { idle-states {...} }

      刪除
  16. update openocd base to 0.12.0+ 2022-09-27

    回覆刪除
  17. I add auto explore debug base cti tapid cfg
    https://github.com/fatalfeel/openocd_integrated/tree/master/tcl/test
    using ex:
    openocd -f /opt/openocd/share/openocd/scripts/test/explore_jtag.cfg
    openocd -f /opt/openocd/share/openocd/scripts/test/explore_swd.cfg

    回覆刪除
  18. openocd cfg -work-area-phys -work-area-size need refer to target dtsi for example

    rk3308.dtsi:
    sram: sram@fff80000 {
    compatible = "mmio-sram";
    reg = <0x0 0xfff80000 0x0 0x40000>;}

    rk3308.cfg:
    set _command "$_command -work-area-size 0x40000 -work-area-phys 0xfff80000 -work-area-backup 0"

    回覆刪除
  19. in Makefile when use -O1 -O2 -O3
    KBUILD_CFLAGS += -O1 -g -fno-inline-functions-called-once -fno-omit-frame-pointer -U__OPTIMIZE__
    can make step trace sequence correctly

    回覆刪除