Need help with a bricked LinkSYS E8450

My Linksys E8450 is bricked. I'm not sure what I need to do and any help will be greatly appreciated. I was loading OpenWRT and flashed the wrong package. Now there are no lights on or flashing and no ethernet connection. I connected a serial cable with screen and tried to load files, but I'm not not sure what it needs now.

Just a precaution: I don't own this device.

That early boot log with "BL2: Failed to load image id 3" sounds like major trouble. It is much too early in the boot process that anything from the full OpenWrt recovery etc. would be in play.

You likely need deeper knowledge from @daniel

But as you have serial access, the situation is likely not hopeless.

The closest similar thing that I found, is the discussion from a few months ago, starting here:
(that discussion is about bad blocks affecting fip, but closely related to broken bl2 and/or fip images)

Compared to that discussion, your log ends before the "BL31 starts" line, which might mean that your boot process fails already before the full u-boot have even started...
(...so you might just have parts of the ARM trusted firmware loader to play with)

Yes, this looks like the fip image containing U-Boot and TF-A BL31 has been overwritten. That really shouldn't happen by chance as the fip MTD partition is read-only under Linux.
Hence it is crucial for us to know what you did exactly before that happened -- most likely you are dealing with a semi-broken flash chip, unless you deliberately removed the read-only attribute from the fip partition and wrote something there.

To rescue the device at this point you will need to setup JTAG with OpenOCD and load U-Boot to RAM using that. Then you need to re-write the bootchain, the easiest way is to re-run the installer loaded via TFTP.

1 Like

I tried to flash the preloader and I think it was this one at https://downloads.openwrt.org/releases/openwrt-22.03.2-mediatek-mt7622-linksys_e8450-ubi-preloader.bin
I might have chosen the wrong file. Actually I think I shouldn't have flashed any file. I have several older routers and I plan to play with the older ones next time.

I bought another E8450 and I'm including a screen snaphost of the OpenWRT status page.

I've ordered a JTAG from DIYGadget.

BLACK FLASH USB+ UNIVERSAL MEMORY PROGRAMMER WITH INTEGRATED USB TO COM(TTL) AND TWO PORT USB 2.0 HUB

I did not remove the read-only attribute.

Thank you all for the help.
Robert Mitchell

So as you didn't remove the read-only attribute I understand you were flashing this file via TFTP using the U-Boot menu. Correct? If so, you should have also flashed the BL31+U-Boot (FIP) image at this point. Anyway. Both is very dangerous (hence the red background) and should never be needed once the device is running U-Boot 202x.xx.

This is a flash adapter, not JTAG. It will not help you in this situation, or at least it is very difficult as you would have to write the flash out-of-band area in such a way that it looks correct to MediaTek's hardware ECC/BCH engine. Better to write using JTAG, as then you are using that very same ECC/BCH engine for writing, so it will all be fine.

This part can help here:
https://www.diygadget.com/tiao-usb-multi-protocol-adapter-lite-jtag-spi-i2c-serial?search=JTAG&category_id=0

1 Like

I also tried to flash uboot with tftp.

What was the motivation or reason for updating bl2 and U-Boot? I'm thinking that maybe it's needed to make a bigger warning message and also clarify that there is no advantage what-so-ever of updating the bootchain once it is working...

Now, to rescue the device with JTAG:

Maybe forum user @vasilii can give you a hand if needed, they went through the procedure most recently...

1 Like
openocd -f tumpa-lite.cfg -f mt7622.cfg 
Open On-Chip Debugger 0.12.0-rc3
Licensed under GNU GPL v2
For bug reports, read
	http://openocd.org/doc/doxygen/bugs.html
adapter speed: 500 kHz

Info : Listening on port 6666 for tcl connections
Info : Listening on port 4444 for telnet connections
Info : clock speed 500 kHz
Info : JTAG tap: mt7622.cpu tap/device found: 0x4ba00477 (mfg: 0x23b (ARM Ltd), part: 0xba00, ver: 0x4)
Info : mt7622.cpu0: hardware has 6 breakpoints, 4 watchpoints
Info : starting gdb server for mt7622.cpu0 on 3333
Info : Listening on port 3333 for gdb connections
^Cshutdown command invoked

I got jtag working and found this as well. Is this what I need to load uboot? I'm not sure what to use to move uboot.bin from my pc to the router. I'm still looking.

Chapter 5: OpenOCD Project Setup 18

proc ramboot { } {
# Reset, running the target’s "reset-init" scripts
# to initialize clocks and the DDR RAM controller.
# Leave the CPU halted.
reset init
# Load CONFIG_SKIP_LOWLEVEL_INIT version into DDR RAM.
load_image u-boot.bin 0x20000000
# Start running.
resume 0x20000000
}


proc newboot { } {
# Reset, leaving the CPU halted. The "reset-init" event
# proc gives faster access to the CPU and to NOR flash;
# "reset halt" would be slower.
reset init

# Write standard version of U-Boot into the first two
# sectors of NOR flash ... the standard version should
# do the same lowlevel init as "reset-init".
flash protect 0 0 1 off
flash erase_sector 0 0 1
flash write_bank 0 u-boot.bin 0x0
flash protect 0 0 1 on
# Reboot from scratch using that new boot loader.
reset run
}

No the steps above will not work on MT7622 devices, we don't support flash read/write in OpenOCD. You have to load U-Boot to RAM, as described here:

I get this at set cp and the variable is not set.

type or paste > set cp [aarch64 mrc 15 0 1 0 0]
mt7622.cpu0: not 32-bit arm target
code here

Searching I find this:
In AArch64, system configuration is controlled through system registers, and accessed using MSR and MRS instructions.

replacing mrc with mrs I get this output:

> set cp [aarch64 mrs 15 0 1 0 0]
aarch64
  aarch64 cache_info
  aarch64 dbginit
  aarch64 disassemble address [count]
  aarch64 maskisr ['on'|'off']
  aarch64 mcr cpnum op1 CRn CRm op2 value
  aarch64 mrc cpnum op1 CRn CRm op2
  aarch64 smp [on|off]
  aarch64 smp_gdb
  mt7622.cpu0 aarch64
    mt7622.cpu0 aarch64 cache_info
    mt7622.cpu0 aarch64 dbginit
    mt7622.cpu0 aarch64 disassemble address [count]
    mt7622.cpu0 aarch64 maskisr ['on'|'off']
    mt7622.cpu0 aarch64 mcr cpnum op1 CRn CRm op2 value
    mt7622.cpu0 aarch64 mrc cpnum op1 CRn CRm op2
    mt7622.cpu0 aarch64 smp [on|off]
    mt7622.cpu0 aarch64 smp_gdb
  mt7622.cpu1 aarch64
    mt7622.cpu1 aarch64 cache_info
    mt7622.cpu1 aarch64 dbginit
    mt7622.cpu1 aarch64 disassemble address [count]
    mt7622.cpu1 aarch64 maskisr ['on'|'off']
    mt7622.cpu1 aarch64 mcr cpnum op1 CRn CRm op2 value
    mt7622.cpu1 aarch64 mrc cpnum op1 CRn CRm op2
    mt7622.cpu1 aarch64 smp [on|off]
    mt7622.cpu1 aarch64 smp_gdb
type or paste code here

Does the mrs do what you expect?

the next step is:
From the output of halt command:
Do I execute "halt"?

BTW, I'm being extremely careful here.

You have to build OpenOCD from source and also apply this patch.

I've downloaded openocd rc3 3 times and patch the file.

patch src/target/armv8_dpm.c 0001-armv8-do-not-read-ESR_EL3-in-AArch32-state.patch
./configure  --enable-ftdi
make
sudo make install

I look at the armv8_dpm.c and it contains the 4 lines in the patch.

I still get > set cp [aarch64 mrc 15 0 1 0 0]
mt7622.cpu0: not 32-bit arm target

At this point I'm going to go watch football

What is the best way to debug this?

should be

git clone https://repo.or.cz/openocd.git
cd openocd
curl https://raw.githubusercontent.com/mtk-openwrt/openocd-scripts/main/patch/0001-armv8-do-not-read-ESR_EL3-in-AArch32-state.patch | git am

For reference, this is my openocd.cfg used to re-flash this device:

adapter speed 10000
transport select jtag
ftdi_tdo_sample_edge falling

adapter srst delay 750
jtag_ntrst_assert_width 100
jtag_ntrst_delay 50

reset_config trst_and_srst separate srst_gates_jtag srst_open_drain

if { [info exists CHIPNAME] } {
        set _CHIPNAME $CHIPNAME
} else {
        set _CHIPNAME mt7622
}

if { [info exists DAP_TAPID] } {
        set _DAP_TAPID $DAP_TAPID
} else {
        set _DAP_TAPID 0x4ba00477
}

jtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0x0f -expected-id $_DAP_TAPID
dap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu
target create $_CHIPNAME.ahb mem_ap -dap $_CHIPNAME.dap -ap-num 0 -dbgbase 0x80070000

# declare the 2 main application cores
set _TARGETNAME $_CHIPNAME.core
set _smp_command ""

set $_TARGETNAME.base(0) 0x80810000
set $_TARGETNAME.base(1) 0x80910000

set $_TARGETNAME.cti(0) 0x80820000
set $_TARGETNAME.cti(1) 0x80920000

set _cores 2

proc mmu_off {} {
        set cp [aarch64 mrc 15 0 1 0 0]
        set cp [expr ($cp & ~1)]
        aarch64 mcr 15 0 1 0 0 $cp
}

proc mmu_on {} {
        set cp [aarch64 mrc 15 0 1 0 0]
        set cp [expr ($cp | 1)]
        aatch64 mcr 15 0 1 0 0 $cp
}

proc mt7622_reset {} {
        #
        # halt target
        #
        poll
        sleep 2
        halt
        wait_halt
        #
        # disable wdt
        #
        mww 0x10212000 0x22000000
        mmu_off
        mt7622.core0 configure -work-area-phys 0x101000 -work-area-size 8096

        # switch to AArch64 mode
        reg cpsr 0x1d3
        load_image /usr/src/mtk-openocd-scripts/mt7622/switch_mode_32_64.bin 0x100000 bin
        load_image /usr/src/mtk-openocd-scripts/mt7622/aarch64_stall.bin 0x100100 bin
        reg pc 0x100000
        resume
}

proc mt7622_ddrinit {} {
        # initialize DDR with for 1 chip
        load_image /usr/src/mtk-openocd-scripts/mt7622/bl2-1c.bin 0x201000 bin
        # initialize DDR with for 2 chip
        #load_image /usr/src/mtk-openocd-scripts/mt7622/bl2-2c.bin 0x201000 bin
        reg pc 0x201000
        resume
}

proc mt7622_uboot {} {
        # load U-Boot and ATF
        load_image /usr/src/mtk-openocd-scripts/mt7622/fip-snand-no-bmt.bin 0x40020000 bin
        mww 0x100200 1
        resume
}

for { set _core 0 } { $_core < $_cores } { incr _core 1 } {

    cti create cti$_core -dap $_CHIPNAME.dap -baseaddr [set $_TARGETNAME.cti($_core)] -ap-num 1

    set _command "target create ${_TARGETNAME}$_core aarch64 \
                         -dap $_CHIPNAME.dap -coreid $_core -cti cti$_core \
                         -dbgbase [set $_TARGETNAME.base($_core)]"

    if { $_core != 0 } {
        set _smp_command "$_smp_command ${_TARGETNAME}$_core"
        set _command "$_command -defer-examine"
    } else {
        # uncomment to use hardware threads pseudo rtos
        set _command "$_command -rtos linux"
        set _command "$_command -work-area-size 0x40000 -work-area-phys 0xfff80000 \
                                -work-area-backup 0"
        set _smp_command "target smp ${_TARGETNAME}$_core"
    }

    eval $_command
}

eval $_smp_command

targets ${_TARGETNAME}0

I'm still stuck on "not 32-bit arm target"

Is there any reason this could happen with a properly patched and compiled openocd installation?

I'm using adapter driver ftdi for a tumpa-lite with chip FT232FL with tumpa-lite.cfg. Now I'm trying to find commands that do the same functions as

ntrst_assert_width 100

Let me know if I'm heading in the wrong direction, please.

BTW, Thank you for helping.

Make sure the pinout of the adapter is configured correctly to match your actual connection to nTRST and nSRST signals. In tumpa-lite.cfg you see the commands for assigning the pins, so make sure they are either really exactly the same or modify your configuration accordingly.

Edit: I've also been using FTDI chip, but using FT2232HL breakout board and some pull-up/pull-down resistors added.

Well, I have another error:

Open On-Chip Debugger
> halt
Failed to read pauth_dmask register

> mww 0x10212000 0x22000000
> mt7622.cpu0 configure -work-area-phys 0x101000 -work-area-size 8096
8096
> set cp [aarch64 mrc 15 0 1 0 0]                               
12912696
> set cp [expr ($cp & ~1)]
wrong # args: should be "expr expression"
>