WRT1900ACS Boot


I am investigating the WRT1900ACS boot process. There is nothing I found out, I think, that the OpenWRT team doesn’t already know, but I thought it might be helpful to post boot text, for others wanting to reference it.

To view the bootloader output, you must remove the blue cover, and use the pins in the white connector on the right for UART serial access. More instructions are here:


I used minicom set to 8N1 at highest speed, with a USB TTL serial cable showing up as /dev/ttyUSB0.

Original GPL sources are available here:


Here is default boot up text:

BootROM - 1.73
Booting from NAND flash

General initialization - Version: 1.0.0
Detected Device ID 6820
High speed PHY - Version: 2.0

Init RD NAS topology Serdes Lane 3 is USB3
Serdes Lane 4 is SGMII
board SerDes lanes topology details:
 | Lane #  | Speed |  Type       |
 |   0    |  06   |  SATA0  |
 |   1    |  05   |  PCIe0  |
 |   2    |  06   |  SATA1  |
 |   3    |  05   |  USB3 HOST1 |
 |   4    |  05   |  PCIe1  |
 |   5    |  00   |  SGMII2 |
:** Link is Gen1, check the EP capability 
PCIe, Idx 0: Link upgraded to Gen2 based on client cpabilities 
:** Link is Gen1, check the EP capability 
PCIe, Idx 1: remains Gen1
High speed PHY - Ended Successfully
DDR3 Training Sequence - Ver TIP-1.26.0
mvSysEnvGetTopologyUpdateInfo: TWSI Read failed
DDR3 Training Sequence - Switching XBAR Window to FastPath Window 
DDR3 Training Sequence - Ended Successfully
Not detected suspend to RAM indication
BootROM: Image checksum verification PASSED

 __   __                      _ _
|  \/  | __ _ _ ____   _____| | |
| |\/| |/ _` | '__\ \ / / _ \ | |
| |  | | (_| | |   \ V /  __/ | |
|_|  |_|\__,_|_|    \_/ \___|_|_|
         _   _     ____              _
        | | | |   | __ )  ___   ___ | |_ 
        | | | |___|  _ \ / _ \ / _ \| __| 
        | |_| |___| |_) | (_) | (_) | |_ 
         \___/    |____/ \___/ \___/ \__| 
 ** LOADER **

U-Boot 2013.01 (Mar 27 2015 - 16:50:46) Marvell version: 2014_T3.0p6

Boot version : v1.0.13

Board: RD-NAS-88F6820-DDR3
SoC:   MV88F6820 Rev A0
       running 2 CPUs
CPU:   ARM Cortex A9 MPCore (Rev 1) LE
       CPU 0
       CPU    @ 1600 [MHz]
       L2     @ 800 [MHz]
       TClock @ 200 [MHz]
       DDR    @ 800 [MHz]
       DDR 32 Bit Width, FastPath Memory Access, DLB Enabled, ECC Disabled
DRAM:  512 MiB

Map:   Code:            0x1fea9000:0x1ff7632c
       BSS:         0x1ffef6b4
       Stack:           0x1f9a8f20
       Heap:            0x1f9a9000:0x1fea9000
raise: Signal # 8 caught
U-ENV offset == 0x200000
raise: Signal # 8 caught
U-ENV offset == 0x200000
       U-Boot Environment:  0x00200000:0x00220000 (NAND)

NAND:  128 MiB
MMC:   mv_sdh: 0
DEVINFO offset == 0x900000
U-ENV offset == 0x200000
U-ENV offset == 0x200000
S-ENV offset == 0x240000

#### auto_recovery ####
[u_env] get auto_recovery == yes
[u_env] get auto_recovery == yes
[u_env] get boot_part == 1
[u_env] get boot_part_ready == 3
auto_recovery enabled:1, boot_part:1, boot_part_ready:3 

S-ENV offset == 0x240000
[boot_count_read] block:0x240000, size:128KB, records:64 
[boot_count_read_record] boot_count:0, next_record:28

[boot_count_write] erase:0, auto_recovery->block_offset:0x240000 offset=0x24E000

Updating boot_count ... 
[boot_count_write] offset:0x24E000 , length:2048

PCI-e 0 (IF 0 - bus 0) Root Complex Interface, Detected Link X1, GEN 2.0
PCI-e 1 (IF 1 - bus 1) Root Complex Interface, Detected Link X1, GEN 1.1
USB2.0 0: Host Mode
USB3.0 1: Host Mode
USB3.0 0: Host Mode
Board configuration detected:
mvEthE6171SwitchBasicInit init 
|  port  | Interface | PHY address  |
| egiga0 |   RGMII   |     0x01     |
| egiga1 |   SGMII   |     0x00     |
egiga0 [PRIME], egiga1
auto_recovery_check changes bootcmd: run nandboot 
Hit any key to stop autoboot:  3  2  1  0 

NAND read: device 0 offset 0xa00000, size 0x600000
 6291456 bytes read: OK
## Booting kernel from Legacy Image at 02000000 ...
   Image Name:   Linksys WRT1900ACS Router
   Created:      2018-03-29  13:05:04 UTC
   Image Type:   ARM Linux Kernel Image (uncompressed)
   Data Size:    4229843 Bytes = 4 MiB
   Load Address: 00008000
   Entry Point:  00008000
   Verifying Checksum ... OK
   Loading Kernel Image ... OK

Starting kernel ...

Uncompressing Linux... done, booting the kernel.
Booting Linux on physical CPU 0x0
Linux version 3.10.39 (root@build-vm) (gcc version 4.6.4 (Linaro GCC branch-4.6.4. Marvell GCC Dev 201310-2126.3d181f66 64K MAXPAGESIZE ALIGN) ) #1 SMP Thu Mar 29 06:04:48 PDT 2018
CPU: ARMv7 Processor [414fc091] revision 1 (ARMv7), cr=10c53c7d
CPU: PIPT / VIPT nonaliasing data cache, VIPT aliasing instruction cache
Machine: Marvell Armada 380/381/382/385/388 (Device Tree), model: Marvell Armada 385 Development Board

Et cetera.

Now, if you “hit any key to stop autoboot” you can enter the bootloader shell:

Marvell>> help
?       - alias for 'help'
Creset  - Creset    - Run 'reset' or boot command in a loop, while counting.

SatR    - Sample At Reset sub-system
active_units- print active units on board
base    - print or set address offset
bdinfo  - print Board Info structure
boot    - boot default, i.e., run 'bootcmd'
boot_menu- command allows to select boot script from boot device
    example: boot_menu
bootd   - boot default, i.e., run 'bootcmd'
bootelf - Boot from an ELF image in memory
bootm   - boot application image from memory
bootp   - boot image via network using BOOTP/TFTP protocol
bootvx  - Boot vxWorks from an ELF image
bootz   - boot Linux zImage image from memory
bubt    - bubt  - Burn an image on the Boot Nand Flash.

chpart  - change active partition
cmp     - memory compare
coninfo - print console devices and information
cp      - memory copy
crc32   - checksum calculation
date    - get/set/reset date & time
ddrPhyRead- ddrPhyRead - Read DDR PHY register

ddrPhyWrite- ddrPhyWrite - Write DDR PHY register

devinfo - devinfo handling commands
dhcp    - boot image via network using DHCP/TFTP protocol
diskboot- diskboot- boot from IDE device

dma     - dma   - Perform DMA using the XOR engine

echo    - echo args to console
editenv - edit environment variable
eeprom  - EEPROM sub-system
env     - environment handling commands
exit    - exit script
ext2load- load binary file from a Ext2 filesystem
ext2ls  - list files in a directory (default /)
ext4load- load binary file from a Ext4 filesystem
ext4ls  - list files in a directory (default /)
ext4write- create a file in the root directory
false   - do nothing, unsuccessfully
fatinfo - print information about filesystem
fatload - load binary file from a dos filesystem
fatls   - list files in a directory (default /)
fdt     - flattened device tree utility commands
fsinfo  - print information about filesystems
fsload  - load binary file from a filesystem image
go      - start application at address 'addr'
help    - print command description/usage
i2c     - I2C sub-system
ide     - ide     - IDE sub-system

iminfo  - print header information for application image
imxtract- extract a part of a multi-image
ir      - ir    - reading and changing MV internal register values.

itest   - return true/false on integer compare
loadb   - load binary file over serial line (kermit mode)
loads   - load S-Record file over serial line
loadx   - load binary file over serial line (xmodem mode)
loady   - load binary file over serial line (ymodem mode)
loop    - infinite loop on address range
ls      - list files in a directory (default /)
map     - map   - Display address decode windows

md      - memory display
me      - me    - PCIe master enable

mfg     - mfg   - Diagnostic tools for MFG

mm      - memory modify (auto-incrementing address)
mmc     - MMC sub system
mmcinfo - display MMC info
mp      - mp    - map PCIe BAR

mtdparts- define flash/nand partitions
mtest   - simple RAM read/write test
mw      - memory write (fill)
nand    - NAND sub-system
nboot   - boot from NAND device
nfs     - boot image via network using NFS protocol
nm      - memory modify (constant address)
pci     - list and access PCI Configuration Space
pciePhyRead- phyRead    - Read PCI-E Phy register

pciePhyWrite- pciePhyWrite  - Write PCI-E Phy register

phyRead - phyRead   - Read Phy register

phyWrite- phyWrite  - Write Phy register

ping    - send ICMP ECHO_REQUEST to network host
printenv- print environment variables
pxe     - commands to get and boot from pxe files
rcvr    - rcvr  - Start recovery process (with TFTP server)

reset   - Perform RESET of the CPU
resetenv- resetenv  - Erase environment sector to reset all variables to default.

run     - run commands in an environment variable
saveenv - save environment variables to persistent storage
scsi    - SCSI sub-system
scsiboot- boot from SCSI device
se      - se    - PCIe Slave enable

senv    - senv handling commands
setdevinfo- set devinfo variables
setenv  - set environment variables
setsenv - set senv variables
sg      - sg    - scanning the PHYs status

showvar - print local hushshell variables
sleep   - delay execution for some time
source  - run script from memory
sp      - scan and detect all devices on PCI-e interface
stage_boot- command to load script/image from different devices
    example: stage_boot hd_img pxe
switchCountersRead- switchCntPrint  - Read switch port counters.

switchPhyRegRead- - Read switch register

switchPhyRegWrite- - Write switch register

switchRegRead- switchRegRead    - Read switch register

switchRegWrite- switchRegWrite  - Write switch register

sys_restore- sys_restore    - Search for install script on USB DOK and start installation of linux kernel and rootfs.

sysboot - command to get and boot from syslinux files
temp    - temp  - Display the device temperature.

tempCmd0- tempCmd - This command allocated for monitor extinction

tempCmd1- tempCmd - This command allocated for monitor extinction

tempCmd2- tempCmd - This command allocated for monitor extinction

tempCmd3- tempCmd - This command allocated for monitor extinction

test    - minimal test like /bin/sh
tftpboot- boot image via network using TFTP protocol
training- training  - prints the results of the DDR3 Training.

true    - do nothing, successfully
ts_report- ts_report    - report touch screen coordinate

ts_test - ts_test   - test touch screen

ubi     - ubi commands
ubifsload- load file from an UBIFS filesystem
ubifsls - list files in a directory
ubifsmount- mount UBIFS volume
ubifsumount- unmount UBIFS volume
usb     - USB sub-system
usbboot - boot from USB device
version - print monitor, compiler and linker version
whoAmI  - - reading CPU ID

Marvell>> active_units
Active: cpu0, cpu1, pex0, pex1, egiga0, egiga1, usb0, usb1, nand, i2c0
Marvell>> base
Base Address: 0x00000000
Marvell>> bdinfo
arch_number = 0x00000210
boot_params = 0x00000100
DRAM bank   = 0x00000000
-> start    = 0x00000000
-> size     = 0x20000000
DRAM bank   = 0x00000001
-> start    = 0x00000000
-> size     = 0x00000000
ethaddr     = C0:56:27:C7:56:57
ip_addr     =
baudrate    = 115200 bps
TLB addr    = 0x1FFF0000
relocaddr   = 0x1FEA9000
reloc off   = 0x1FEA9000
irq_sp      = 0x1F9A8F30
sp start    = 0x1F9A8F20
FB base     = 0x00000000
Marvell>> coninfo
List of available devices:
serial   80000003 SIO stdin stdout stderr 
Marvell>> devinfo
devinfo - devinfo handling commands

devinfo get [name] - gets the value of the specified variable
devinfo set [name=value] - sets the value of the specified variable
devinfo unset [name] - deletes the specified variable
devinfo update [args...] - update devinfo from the specified file
devinfo commit - commit variables to flash
devinfo erase - erase all devinfo
devinfo show - shows all variables

Marvell>> devinfo show
manufacturer=Linksys, LLC
modelDescription=Simultaneous Dual-Band Wireless-AC Gigabit Router

Devinfo size: 695/131068 bytes
Marvell>> fatino fo
usage: fatinfo  [<dev[:part]>]
Marvell>> fsinfo
### filesystem type is JFFS2
Scanning JFFS2 FS:    done.
Compression: NONE
    frag count: 0
    compressed sum: 0
    uncompressed sum: 0
Compression: ZERO
    frag count: 0
    compressed sum: 0
    uncompressed sum: 0
Compression: RTIME
    frag count: 0
    compressed sum: 0
    uncompressed sum: 0
Compression: RUBINMIPS
    frag count: 0
    compressed sum: 0
    uncompressed sum: 0
Compression: COPY
    frag count: 0
    compressed sum: 0
    uncompressed sum: 0
Compression: DYNRUBIN
    frag count: 0
    compressed sum: 0
    uncompressed sum: 0
Compression: ZLIB
    frag count: 0
    compressed sum: 0
    uncompressed sum: 0
Marvell>> ls
Scanning JFFS2 FS:    done.
Marvell>> md
md - memory display

md [.b, .w, .l] address [# of objects]
Marvell>> mmcin     printevn  nv
altnandboot=setenv bootargs console=ttyS0,115200 root=/dev/mtdblock7 ro rootdelay=1 rootfstype=jffs2 earlyprintk $mtdparts;nand read $defaultLoadAddr $altKernAddr $altKernSize; bootm $defaultLoadAddr
boot_order=hd_scr usb_scr mmc_scr hd_img usb_img mmc_img pxe net_img net_scr
bootargs_dflt=$console $nandEcc $mtdparts $bootargs_root nfsroot=$serverip:$rootpath ip=$ipaddr:$serverip$bootargs_end $mvNetConfig video=dovefb:lcd0:$lcd0_params clcd.lcd0_enable=$lcd0_enable clcd.lcd_panel=$lcd_panel
bootargs_root=root=/dev/nfs rw
bootcmd=run nandboot
bootcmd_auto=stage_boot $boot_order
bootcmd_fdt=tftpboot 0x2000000 $image_name;tftpboot $fdtaddr $fdtfile;setenv bootargs $console $nandEcc $mtdparts $bootargs_root nfsroot=$serverip:$rootpath ip=$ipaddr:$serverip$bootargs_end $mvNetConfig video=dovefb:lcd0:$lcd0_params clcd.lcd0_enable=$lcd0_enable clcd.lcd_panel=$lcd_panel; bootz 0x2000000 - $fdtaddr;
bootcmd_fdt_boot=tftpboot 0x2000000 $image_name; setenv bootargs $console $nandEcc $mtdparts $bootargs_root nfsroot=$serverip:$rootpath ip=$ipaddr:$serverip$bootargs_end $mvNetConfig video=dovefb:lcd0:$lcd0_params clcd.lcd0_enable=$lcd0_enable clcd.lcd_panel=$lcd_panel; bootz 0x2000000 - $fdtaddr;
bootcmd_fdt_edit=tftpboot $fdtaddr $fdtfile; fdt addr $fdtaddr; setenv bootcmd $bootcmd_fdt_boot
bootcmd_lgcy=tftpboot 0x2000000 $image_name; setenv bootargs $bootargs_dflt; bootm 0x2000000; 
flash_alt_image=tftpboot $defaultLoadAddr $firmwareName && nand erase $altKernAddr $altFwSize && nand write $defaultLoadAddr $altKernAddr $filesize
flash_pri_image=tftpboot $defaultLoadAddr $firmwareName && nand erase $priKernAddr $priFwSize && nand write $defaultLoadAddr $priKernAddr $filesize
nandboot=setenv bootargs console=ttyS0,115200 root=/dev/mtdblock5 ro rootdelay=1 rootfstype=jffs2 earlyprintk $mtdparts;nand read $defaultLoadAddr $priKernAddr $priKernSize; bootm $defaultLoadAddr
standalone=fsload 0x2000000 $image_name;setenv bootargs $console $nandEcc $mtdparts root=/dev/mtdblock0 rw ip=$ipaddr:$serverip$bootargs_end; bootm 0x2000000;
update_both_images=tftpboot $defaultLoadAddr $firmwareName && nand erase $priKernAddr $priFwSize && nand erase $altKernAddr $altFwSize && nand write $defaultLoadAddr $priKernAddr $filesize && nand write $defaultLoadAddr $altKernAddr $filesize

Environment size: 4325/131068 bytes
Marvell>> ubi
ubi - ubi commands

ubi part [part] [offset]
 - Show or set current partition (with optional VID header offset)
ubi info [l[ayout]] - Display volume and ubi layout information
ubi create[vol] volume [size] [type] - create volume name with size
ubi write[vol] address volume size - Write volume from address with size
ubi read[vol] address volume [size] - Read volume to address with size
ubi remove[vol] volume - Remove volume
 volume: character name
 size: specified in bytes
 type: s[tatic] or d[ynamic] (default=dynamic)
Marvell>> version

U-Boot 2013.01 (Mar 27 2015 - 16:50:46) Marvell version: 2014_T3.0p6

Boot version : v1.0.13
arm-marvell-linux-gnueabi-gcc (Linaro GCC branch-4.6.4. Marvell GCC release 201308-2123.0cc69bb4 64K MAXPAGESIZE ALIGN) 4.6.4
GNU ld (Linaro GCC branch-4.6.4. Marvell GCC release 201308-2123.0cc69bb4 64K MAXPAGESIZE ALIGN)
Marvell>> whoAmI
cpu #: 0Marvell>>

LibreCMC, Signals, Modulation

Studying Wi-Fi is rather fascinating because it is involves radio signals, signal modulation, and digital communication, which are all also interesting subjects. LibreCMC router firmware gives you a nice display containing much useful and interesting signal and modulation info for each associated station. Here is the whole page:

Screenshot from 2018-11-15 10-27-01

Here is the zoom in on the associated stations:


The second station is more interesting, so for educational purposes we explain each part:

  • wlan0 – the wireless interface receiving the signal from the associated station
  • ASI Downstairs – the name of the wireless network it is associated with
  • 50:3E:AA:B4:9D:C9 – MAC address of the associated host
  • 2001:470:b:469:c6a – The IPv6 address of the associated host
  • -40 / -95 dBm – the signal to noise ratio. Signal is the level of useful signal being received (more precisely, dBm, which is the voltage level as a logarithmic comparison to the millivolt), and noise is the level of background signal being received (e.g., thermal noise, interference from other stations, and such like). We need the SNR to be as high as possible. In other words, the greater the difference in the signal value to the noise value, the more clear the communications are and ultimately the more data we are going to be able to move. Since we are dealing in negative values, we must remember that -40 is higher than -95. Since we are dealing with dBm values (already a ratio) we can simply take a difference to get an SNR of 35, which is a very good value.
  • 144.4 Mbit/s – our maximum data transfer rate, i.e., max number of bits the current modulation mode will let us move per second. This would more logically be placed at the end.
  • 20 Mhz – our bandwidth, i.e., the amount of frequency space we have decided to use for our communications
  • MCS 15 – This is a abbreviated way of referring to the modulation being used, by referring to a row in the Modulation and Coding Index table:

Screenshot from 2018-11-15 10-26-34

Modulation refers to the scheme you use for changing your signal (more precisely, your carrier signal) to store information in it. You need to somehow change your signal in real time, to represent the ones and zeros you are trying to transmit across the air. There are quite a few ways to do this. In amplitude modulation, you raise and lower the strength of your signal slightly. In phase modulation, you modify the timing of your signal (rotating the phase).

MCS 15 refers to (somewhat confusingly) 3 modulation schemes, evidently 64-QAM 5/6 in this case. QAM refers to Quadrature Amplitude Modulation. Read the Wikipedia page for the full (and interesting) details, but basically it is a combination of amplitude modulation and phase modulation, using two signals that have been merged into one. The 64 part means the modulation scheme can communicate one of 64 different codes with its allowed combinations of amplitude and phase. The higher this number, the more data you can stuff into one modulation of your transmission, which is for the most part a very good thing. (Errors are, however, more likely when transmitting with denser codes.)

The 5/6 part, if I remember correctly is referring to the error correction. You use up some of your data bits for error correction. In this case, five of your six bit are meaningful data while one bit is for error correction.

You router is going to try to use the fastest (i.e., most dense) modulation scheme that it can, but if your SNR becomes too low, the faster modulation schemes will break down, and it will how to “shift down” to a slower modulation. This is why you (ideally) want your AP and your station radios to be using good high gain antennas, and to be kept close together, so SNR is kept high.

  • Short GI – lets us know that we are using a short guard interval value (400 ns) rather than the longer 800 ns value. Guard interval is how long we wait in between sending our codes. Ideally you want the guard interval to be as small as possible, so you have more time for sending data. However, owing to the complexities of radio communication, it is difficult to keep the timing synchronized. With a short guard interval, signals are more likely to overlap each other, causing errors in the code stream.

The first line we read is the values for the receive channel, the next line is the values for the transmit channel.