EJTAG: аттракцион для хакеров-2


EJTAG: Black Swift: EJTAG EJTAG — . , EJTAG . EJTAG, - openocd GDB.

, — AR9344 ( U-boot) — EJTAG ?
AR9344 , Black Swift Pro AR9331, . , , AR9344 .
:
Black Swift Pro, openocd EJTAG .
, , , , .
:
  • — openocd — openocd. ;
  • — openocd + GDB — GDB, openocd GDB EJTAG.

.
, Black Swift: EJTAG.


1: openocd


EJTAG , openocd ( ), . . , openocd «» . openocd telnet-.
, telnet- TCP- 4444. TCP- telnet_port (. ).
Black Swift openocd.
black-swift-trace.cfg openocd, openocd telnet- 4455:
 source [find interface/ftdi/tumpa.cfg]
 
 adapter_khz 6000
 
 source [find black-swift.cfg]
 
 telnet_port 4455
 
 init
 halt

openocd 0.9.0 root :
 # openocd -f black-swift-trace.cfg
 Open On-Chip Debugger 0.9.0 (2015-05-28-17:08)
 Licensed under GNU GPL v2
 For bug reports, read
         http://openocd.org/doc/doxygen/bugs.html
 none separate
 adapter speed: 6000 kHz
 Info : auto-selecting first available session transport "jtag". To override use 'transport select <transport>'.
 Error: no device found
 Error: unable to open ftdi device with vid 0403, pid 8a98, description '*' and serial '*'
 Info : clock speed 6000 kHz
 Info : JTAG tap: ar9331.cpu tap/device found: 0x00000001 (mfg: 0x000, part: 0x0000, ver: 0x0)
 target state: halted
 target halted in MIPS32 mode due to debug-request, pc: 0xbfc00000
 target state: halted
 target halted in MIPS32 mode due to single-step, pc: 0xbfc00404

telnet- openocd telnet:
 $ telnet localhost 4455
 Trying ::1...
 Trying 127.0.0.1...
 Connected to localhost.
 Escape character is '^]'.
 Open On-Chip Debugger
 >

openocd help.
step:
 step [address]
           ,  
         (PC).    address, 
             address.

:
 > step 0xbfc00400
 target state: halted
 target halted in MIPS32 mode due to single-step, pc: 0xbfc00404
 > step
 target state: halted
 target halted in MIPS32 mode due to single-step, pc: 0xbfc00408
 > step
 target state: halted
 target halted in MIPS32 mode due to single-step, pc: 0xbfc0040c

openocd:
 reg [(register_number|register_name) [(value|'force')]]
            .
        reg        .
          'force',  
           (  
       ).
 
 mwb ['phys'] address value [count]
          address ,     value.
          phys,   address —  ,
          — .
          count    address  
           count,    
         value.
 
 mwh ['phys'] address value [count]
         mwb,     16- .
 
 mww ['phys'] address value [count]
         mwb,     32- .
 
 mdb ['phys'] address [count]
               address.
          phys,   address —  ,
          — .
          count        
          address  count .
 
 mdh ['phys'] address [count]
         mdb,     16- .
 
 mdw ['phys'] address [count]
         mdb,     32- .

, , ( ) openocd 0.9.0 MIPS, ARM .
openocd . , GDB.

2: openocd + GDB


openocd + GDB : GDB, , , openocd GDB.
GDB MIPS EJTAG , openocd:
  • , GDB MIPS;
  • ; , C-, GDB C- , ;
  • openocd GDB GDB Remote Serial Protocol; qemu , , — GDB;
  • , GDB TAB.

, GDB , openocd , GDB EJTAG.
, GDB , openocd, MIPS openocd :
  • sdbbp, , openocd sdbbp , sdbbp , . software breakpoint. , .
  • . . , hardware breakpoint, .

GDB Remote Serial Protocol hardware breakpoint software breakpoint (. z z0 ), GDB , , . openocd gdb_breakpoint_override, .
GDB openocd GDB-, TCP- 3333. TCP- gdb_port.
GDB- openocd, MIPS, GDB MIPS. , openocd GDB x86/amd64 Debian Linux, mips-linux-gnu-gdb Sourcery CodeBench. , , , Sourcery CodeBench mips-2015.05-18, 2015 , .
openocd + GDB . openocd:
 # openocd -f run-u-boot_mod-trace.cfg \
 > -c "gdb_breakpoint_override hard" -c "step 0xbfc00400"

openocd :
  • hardware breakpoints, , GDB ( 0xbfc0xxxx , software breakpoints );
  • 0xbfc00400, .

GDB:
 $ /opt/mips-2015.05/bin/mips-linux-gnu-gdb
 GNU gdb (Sourcery CodeBench Lite 2015.05-18) 7.7.50.20140217-cvs
 Copyright (C) 2014 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=i686-pc-linux-gnu --target=mips-linux-gnu".
 Type "show configuration" for configuration details.
 For bug reporting instructions, please see:
 <https://sourcery.mentor.com/GNUToolchain/>.
 Find the GDB manual and other documentation resources online at:
 <http://www.gnu.org/software/gdb/documentation/>.
 For help, type "help".
 Type "apropos word" to search for commands related to "word".
 (gdb)

GDB , , , GDB- openocd:
 (gdb) set architecture mips:isa32r2
 The target architecture is assumed to be mips:isa32r2
 (gdb) set endian big
 The target is assumed to be big endian
 (gdb) set disassemble-next-line on
 (gdb) target remote :3333
 Remote debugging using :3333
 0xbfc00404 in ?? ()
 => 0xbfc00404:  40 80 08 00     mtc0    zero,c0_random

GDB stepi. GDB (can't find the start of the function), .
 (gdb) stepi
 warning: GDB can't find the start of the function at 0xbfc00408.
 
     GDB is unable to find the start of the function at 0xbfc00408
 and thus can't determine the size of that function's stack frame.
 This means that GDB may be unable to access that stack frame, or
 the frames below it.
     This problem is most likely caused by an invalid program counter or
 stack pointer.
     However, if you think GDB should simply search farther back
 from 0xbfc00408 for code which looks like the beginning of a
 function, you can increase the range of the search using the `set
 heuristic-fence-post' command.
 0xbfc00408 in ?? ()
 => 0xbfc00408:  40 80 10 00     mtc0    zero,c0_entrylo0
 (gdb) stepi
 warning: GDB can't find the start of the function at 0xbfc0040c.
 0xbfc0040c in ?? ()
 => 0xbfc0040c:  40 80 18 00     mtc0    zero,c0_entrylo1
 (gdb) stepi
 warning: GDB can't find the start of the function at 0xbfc00410.
 0xbfc00410 in ?? ()
 => 0xbfc00410:  40 80 20 00     mtc0    zero,c0_context
 (gdb)

32- 0xbfc00408:
 (gdb) p /x *0xbfc00408
 $1 = 0x40801000

info registers:
 (gdb) info registers
           zero       at       v0       v1       a0       a1       a2       a3
  R0   00000000 37c688e2 22b15a00 28252198 0c12d319 4193c014 84e49102 06193640
             t0       t1       t2       t3       t4       t5       t6       t7
  R8   00000002 9f003bc0 92061301 1201c163 31d004a0 92944911 ac031248 b806001c
             s0       s1       s2       s3       s4       s5       s6       s7
  R16  8bc81985 402da011 c94d2454 88d5a554 81808e0d cc445151 4401a826 50020402
             t8       t9       k0       k1       gp       sp       s8       ra
  R24  01c06b30 01000000 10000004 fffffffe 9f003bc0 54854eab 329d626b bfc004b4
         status       lo       hi badvaddr    cause       pc
       00400004 00244309 b9ca872c ed6a1f00 60808350 bfc00410
           fcsr      fir
       00000000 00000000

GDB — ; GDB GDB.

AR9331


, GDB : U-boot Black Swift, , . , Black Swift openocd U-boot. Black Swift.
openocd ( , ):
 # openocd -f run-u-boot_mod-trace.cfg \
 > -c "gdb_breakpoint_override hard" -c "step 0xbfc00400"

GDB bs-u-boot-trace-gdb.conf:
 set architecture mips:isa32r2
 set endian big
 set disassemble-next-line on
 
 target remote :3333
 
 set pagination off
 
 set logging file bs_gdb.log
 set logging on
 
 while $pc != (void (*)()) 0x9f002ab0
         stepi
         info registers
 end
 
 detach
 
 quit

GDB bs_gdb.log, pagination ( ), . PC ( ) 0x9f002ab0 GDB openocd . GDB bs_gdb.log .
GDB :
 $ /opt/mips-2015.05/bin/mips-linux-gnu-gdb -x bs-u-boot-trace-gdb.conf

: bs-u-boot-trace-gdb.conf, , , u-boot_mod AR9331 , . openocd GDB, openocd GDB .

bs_gdb.log sw (store word, 32- ). AR9331 32-, , store .
- sw
 => 0xbfc004ec: ad f9 00 00 sw  t9,0(t7)

, bs_gdb.log , sw. , sw bs_gdb.log . parse_gdb_output.pl:
 #!/usr/bin/perl -w
 
 my %r;
 
 foreach $i (qw(zero at v0 v1 a0 a1 a2 a3 t0 t1 t2 t3 t4 t5 t6 t7
        s0 s1 s2 s3 s4 s5 s6 s7 t8 t9 k0 k1 gp sp s8 ra)) {
    $r{$i} = "none";
 }
 
 sub parse_reg($)
 {
    $_ = $_[0];
    if (/^ R/) {
        my @fields = split m'\s+';
        my $f = 2;
        my @rgs;
 
        @rgs = qw(zero at v0 v1 a0 a1 a2 a3) if (/^ R0/);
        @rgs = qw(t0 t1 t2 t3 t4 t5 t6 t7) if (/^ R8/);
        @rgs = qw(s0 s1 s2 s3 s4 s5 s6 s7) if (/^ R1/);
        @rgs = qw(t8 t9 k0 k1 gp sp s8 ra) if (/^ R2/);
 
        foreach $i (@rgs) {
            $r{$i} = $fields[$f];
            $f = $f + 1;
        }
    }
 }
 
 while (<>) {
    if (/^=>([^s]*)\tsw\t([^,]*),(\d+)\(([^)]*)\)/) {
        my $rs = $2;
        my $offset = $3;
        my $rd = $4;
 
        parse_reg(<>);
        parse_reg(<>);
        parse_reg(<>);
        parse_reg(<>);
 
        print("$1    sw $rs={0x$r{$rs}}, $offset($rd={0x$r{$rd}})\n");
    }
 }


parse_gdb_output.pl :
 $ grep "^=\|^ R" bs_gdb.log | ./parse_gdb_output.pl

parse_gdb_output.pl ( '<<< PLL' '<<< DDR' ):
 ...
  0x9f002700:   ad cf 00 00    sw t7={0x00dbd860}, 0(t6={0xb8116248})
  0x9f00271c:   ad f9 00 00    sw t9={0x000fffff}, 0(t7={0xb800009c})
  0x9f0027a0:   ad f9 00 00    sw t9={0x00018004}, 0(t7={0xb8050008}) <<< PLL
  0x9f0027dc:   ad f9 00 00    sw t9={0x00000352}, 0(t7={0xb8050004}) <<<
  0x9f002840:   ad f9 00 00    sw t9={0x40818000}, 0(t7={0xb8050000}) <<<
  0x9f002898:   ad f9 00 00    sw t9={0x001003e8}, 0(t7={0xb8050010}) <<<
  0x9f0028f4:   ad f9 00 00    sw t9={0x00818000}, 0(t7={0xb8050000}) <<<
  0x9f002970:   ad cf 00 00    sw t7={0x00800000}, 0(t6={0xb8116248})
 ...
  0x9f002994:   ad cf 00 00    sw t7={0x40800700}, 0(t6={0xb8116248})
  0x9f002a54:   ad f9 00 00    sw t9={0x00008000}, 0(t7={0xb8050008})
  0x9f00309c:   af 38 00 00    sw t8={0x7fbc8cd0}, 0(t9={0xb8000000}) <<< DDR
  0x9f0030b0:   af 38 00 00    sw t8={0x9dd0e6a8}, 0(t9={0xb8000004}) <<<
  0x9f0030dc:   af 38 00 00    sw t8={0x00000a59}, 0(t9={0xb800008c}) <<<
  0x9f0030ec:   af 38 00 00    sw t8={0x00000008}, 0(t9={0xb8000010}) <<<
 ...

(PLL) DDR , , .


JTAG openocd GDB , AR9331, , , , openocd GDB.

Source: https://habr.com/ru/post/fr383505/


All Articles