Welcome! Log In Create A New Profile


Thecus N2350 Installation Instruction

Posted by bodhi 
Thecus N2350 Installation Instruction
October 25, 2019 10:23PM
Thecus N2350 Installation


Enable SSH for the box either through serial console login to stock OS (with credential root/admin). There is an extra step needed to enable SSH inside stock OS, please post question if you want to do that. Or you can login the box's web page in your local network (see instruction in the manual that comes with the retail box) and use Control Panel to enable SSH. If you have serial console then it is not necessary to enable SSH.


I would strongly recommend that users have connected serial console to have a better control, and also to test UART booting to ensure that this rescue mechanism is working before instalation. Once UART booting is tested to be working on your box, it is almost impossible to brick it. See NOTE1 at the end of this post for a demonstration on UART booting for this box.


1. Create the USB rootfs using Debian-5.2.9-mvebu-tld-1-rootfs-bodhi.tar.bz2 following the instruction from Linux Kernel 5.2.9 MVEBU package and Debian armhf rootfs..

Note: Create uImage with DTB appended in the rootfs (Step 3 in the instruction) should look like below with armada-385-thecus-n2350.dtb as the N2350 DTB file name.

cd /media/sdb1/boot
cp -a zImage-5.2.9-mvebu-tld-1 zImage.fdt 
cat dts/armada-385-thecus-n2350.dtb  >> zImage.fdt
mkimage -A arm -O linux -T kernel -C none -a 0x00008000 -e 0x00008000 -n Linux-5.2.9-mvebu-tld-1 -d zImage.fdt uImage

After the rootfs was created, continue with Step 2 below to prepare the rootfs further while the USB is still mounted.

2. Prepare the Debian USB rootfs

2.b. Adjust u-boot envs configuration in USB rootfs

echo "/dev/mtd2 0x00000 0x10000 0x10000" > /media/sdb1/etc/fw_env.config

2.c. Download the new u-boot thecus-n2350-Marvell-2015_T1.0p18-tld-4 uboot tarball to rootfs /boot/uboot folder.


Download at Dropbox

mkdir -p  /media/sdb1/boot/uboot
cd /media/sdb1/boot/uboot
tar xf thecus-n2350-Marvell-2015_T1.0p18-tld-4-bodhi.tar
Make sure the files are listed as followed
ls -lart

-rwxr-xr-x 1 root root 8.6K May  1  2018 send-stop-pattern.c
-rwxr-xr-x 1 root root 8.6K May  1  2018 send-stop-pattern
-rwxr-xr-x 1 root root  530 May  1  2018 download-serial.sh
-rw-r--r-- 1 root root 939K Nov 12  2018 u-boot-a38x-2015T1_p18_Thecus-tld-4-spi-uart.bin
-rw-r--r-- 1 root root 940K Nov 12  2018 u-boot-a38x-2015T1_p18_Thecus-tld-4-spi.bin
-rw-r--r-- 1 root root 1.9M Nov 15  2018 thecus-n2350-Marvell-2015_T1.0p18-tld-4-bodhi.tar

2.d. Download envs setup script to rootfs

(The script thecus-n2350-boot-script-tld-5.sh is attached to this post at the end).

Download it to the rootfs /media/sdb1/boot/uboot folder and make sure the file looks like below
ls -l thecus-n2350-boot-script-tld-5.sh

-rwxr-xr-x 1 root root 2.6K Oct 24 18:34 thecus-n2350-boot-script-tld-5.sh

2.e. Sync and umount the USB rootfs.

umount /media/sdb1

3. UART booting

I would strongly recommend that you try UART booting first to make sure there is a rescue mechanism in case something goes wrong (typos, power outage,...). However, it is not a requirement for the installation. Please see NOTE1 at the end of Installation Instruction for a demonstration of UART booting for this box.

Proceed to the step 4 after you've tried UART booting, or would like to do this in the future when it is more convenient.

4. Perform installation in stock OS.

4.a. Power on, log into stock OS through SSH (or serial console if prefered). Plug in the USB rootfs (use USB port next to Ethernet port).

And mount the USB rootfs
mkdir /tmp/sdw1
mount -o noatime /dev/sdw1 /tmp/sdw1/
cd /tmp/sdw1/boot/uboot/

4.b. Verify that the MTDs are ready for installation. And back up mtd1 and mtd2, and the envs.

cat /proc/mtd
Expected output:
dev:    size   erasesize  name
mtd0: 20000000 00020000 "ubifs"
mtd1: 00400000 00010000 "U-Boot-img"
mtd2: 00300000 00010000 "U-Boot-env"
mtd3: 058c3000 0001f000 "boot"
mtd4: 008d7000 0001f000 "etc"
mtd5: 16fc3000 0001f000 "rom"
mtd6: 01477000 0001f000 "version"

Backup the mtds:
mkdir -p /tmp/sdw1/boot/uboot/mtds
cd /tmp/sdw1/boot/uboot/mtds
dd if=/dev/mtd1 of=thecus_n2350.mtd1 bs=4096k conv=sync
dd if=/dev/mtd2 of=thecus_n2350.mtd2 bs=3072k conv=sync

List them to verify that the back up mtd1 and mtd2 sizes are 4M and 3M
ls -latrh

Save current stock envs
fw_printenv > stock_envs.txt

4.c. Flash new u-boot to SPI mtd1

cd /tmp/sdw1/boot/uboot/
flashcp -v u-boot-a38x-2015T1_p18_Thecus-tld-4-spi.bin /dev/mtd1
Expected output:
Erasing blocks: 15/15 (100%)
Writing data: 939k/0k (100%)
Verifying data: 939k/0k (100%)

4.d. Setup envs for booting new Debian rootfs on USB.

cd /tmp/sdw1/boot/uboot/
Expected output:
boot_config=setenv devices "usb scsi"; setenv bootdev usb; setenv device 0:1; setenv disks "0 1 2 3 4 5 6 7";
scan_disk=echo running scan_disk ...; scan_done=0; setenv scan_usb "usb start";  setenv scan_scsi "scsi reset"; for dev in $devices; do if test $scan_done -eq 0; then echo Scan device $dev; run scan_$dev; for disknum in $disks; do if test $scan_done -eq 0; then echo device $dev $disknum:1; if ext2load $dev $disknum:1 $load_image_addr /boot/zImage 1; then scan_done=1; echo Found bootable drive on $dev $disknum; setenv device $disknum:1; setenv bootdev $dev; fi; fi; done; fi; done
kernel_config=setenv load_dtb_addr 0x1000000; setenv load_initrd_addr 0x3000000; setenv load_image_addr 0x02000000; setenv dtb_file /boot/dts/armada-385-thecus-n2350.dtb
load_image=load_image=echo loading uImage ...; ext2load $bootdev $device $load_image_addr /boot/uImage
load_dtb=echo loading DTB $dtb_file ...; ext2load $bootdev $device $load_dtb_addr $dtb_file
load_initrd=echo loading uInitrd ...; ext2load $bootdev $device $load_initrd_addr /boot/uInitrd
set_bootargs=setenv bootargs "console=ttyS0,115200 root=LABEL=rootfs rootdelay=10 mtdparts=armada-nand:-(ubifs);spi1.0:0x00400000(uboot),0x00010000@0x00100000(uboot_env),0x00010000@0x00300000(uboot_scr) earlyprintk=serial"
set_bootargs_stock=setenv bootargs "root=/dev/ram0 rw max_loop=210 console=ttyS0,115200 init=sbin/init rootdelay=3 ubi.mtd=0 mtdparts=armada-nand:-(ubifs);spi_flash:0x00400000(uboot),0x00010000@0x00100000(uboot_env)"
bootcmd_exec=echo Booting from $bootdev $device …; setenv fdt_skip_update yes; setenv initrd_high 0xffffffff; if run load_image; then if run load_initrd; then bootm $load_image_addr $load_initrd_addr; else bootm $load_image_addr; fi; fi
bootcmd_custom=run boot_config; run kernel_config; run scan_disk; run set_bootargs; run bootcmd_exec
bootcmd=echo Booting Debian ...; run bootcmd_custom; echo Booting stock ...; run set_bootargs_stock; usb reset; if fatload usb 0:1 0x2000000 rescue_fw/rescue_fw.img;then imi 0x2000000;source 0x2000000; fi; ubi part ubifs;ubifsmount boot;ubifsload 0x2000000 boot/bzImage;ubifsload 0x3000000 boot/ramdisk;bootm 0x2000000 0x3000000

And save the modified envs:
fw_printenv > new_envs.txt

4.e. Sync and Reboot

At this point the installation is done, so reboot the box and let it boot automatically.

4.f. Login into Debian

The root user credential is root/root.

After reboot, ff you have serial console then watch the serial console logging, the Debian prompt will appear when the box finishes booting. .

If you don't have serial console then wait for a few minutes and log in through SSH using the host name, or find the dynamic IP that the router has assigned to this box (using scanning app such as Linux nmap or IOS Fing).

ssh root@debian.local

5. End of Instruction.


1. To prepare for UART booting, use 2 SSH terminals. First one for running the download script, and the 2nd terminal for running a regular serial console which should be started immediately when "transfer complete" to interupt u-boot (the default countdown is only 3 seconds so there is not enough time to interupt u-boot if you wait too long).

2. The files necessary to run UART booting are in the new u-boot tarball thecus-n2350-Marvell-2015_T1.0p18-tld-4-bodhi.tar. Please see Step 2.c in the Installation Instruction steps.

3. Power down the N2350. Connect serial console on an ARM Linux box.

Assuming you have downloaded and extracted the u-boot tarball to /tmp folder of the ARM Linux host that has the serial module converter connected.
cd /tmp
./download-serial.sh /dev/ttyUSB0  u-boot-a38x-2015T1_p18_Thecus-tld-4-spi-uart.bin
Expected output
Now reset or power cycle your Armada 38x board and then press enter

At this point, power up the N2350.

When the download-serial script has successful made a handshake with the N2350, it will show that it got the NACK (0x15) character.
Out of sleep
Got something 21
Got NACK (0x15) character
The board should be in serial downloader now. Sending the binary file 
Sending /media/rootfs/boot/uboot/u-boot-a38x-2015T1_p18_Thecus-tld-4-spi-uart.bin, 7506 blocks: Give your local XMODEM receive command now.
Bytes Sent: 960896   BPS:10018

Transfer complete


- If you see "Got something xx" a few times, but got no NACK, then just Control-C to abort and then recall the download-serial command and try again. There is no need to wait. Do this a few times until you get a NACK.
- If you see "Got something -1", then it is all out of sync. Power off the N2350 and try again from the beginning.

4. Immediately after "Transfer Complete" was shown, run your regular serial console on the 2nd terminal
picocom --b 115200 --f n --p n --d 8 /dev/ttyUSB0

and press Enter right away. U-boot will show a countdown that was interrupted:
Terminal ready

5. At the Marvell>> prompt, Verify the new uboot is running

Expected output
U-Boot 2013.01 (Nov 12 2018 - 20:56:19) Marvell version: 2015_T1.0p18-tld-4
arm-linux-gnueabi-gcc (Linaro GCC 4.9-2017.01) 4.9.4
GNU ld (Linaro_Binutils-2017.01) Linaro 2014_11-3-git

If the u-boot banner above show that you are running my tld-4 build version then UART booting has been successful. Congrats! you now have an unbrickable N2350 box.

Forum Wiki
bodhi's corner

Edited 4 time(s). Last edit at 10/26/2019 03:48AM by bodhi.
open | download - thecus-n2350-boot-script-tld-5.sh (2.5 KB)

Your Email:


Spam prevention:
Please, enter the code that you see below in the input field. This is for blocking bots that try to post this form automatically. If the code is hard to read, then just try to guess it right. If you enter the wrong code, a new image is created and you get another chance to enter it right.