Category Archives: Networking

Meraki MS210/MS225 hardware overview

The Meraki MS210 and MS225 series switches offer 24 or 48 ports of Gigabit Ethernet, four SFP/SFP+ uplink ports, a dedicated remote management port, and stacking capabilities via QSFP.

Meraki MS210-24 and MS210-48


Here is a quick summary of the MS210/MS225/MS250 specs:

  • Broadcom Broadcom BCM56160 “Hurricane3” ASIC
  • Broadcom BCM82756 10G PHY
  • Broadcom BCM59121 PSE controller (PoE models only)
  • 16MB of SPI flash (MX25L12805D)
  • 1024MB DDR4 RAM (soldered)
  • 256MB of NAND (MT29F2G08ABAEAWP)
MS225-48LP internal PCB

MS225-48LP switch internals with PoE midplane removed


The Meraki codename for the MS210, MS225, and MS250 series is “brumby” and all brumby switches run the same firmware release (switch-arm). The MS250 is essentially the MS225 with hot-swap power supplies (similar to the MS220/MS320).

Keen readers may be wondering why the MS210 series has only SFP ports while the MS225 has SFP+ ports, given they are identical hardware and run the same switch-arm firmware. The answer is market segmentation; Meraki decided to artificially limit the speed of the MS210 SFP ports to 1G, even though the MS210 hardware is capable of 10G via SFP+. Early in the boot process switch_brain checks the switch model, and if it identifies as the MS210 series the SFP port speed is limited to 1000M.

The stock Meraki boot process uses u-boot on SPI to load a “bootkernel” (also from SPI), which then initializes NAND and using kexec boots the main firmware. The firmware layout follows the standard Meraki practice of having A/B firmware images: bootkernel1, bootkernel2, part.safe, part.old.


If you wish to flash your MS210/MS225, you will need to remove or socket the SOIC8 SPI flash (U18). This is because the ASIC is powered by the same +3.3V voltage rail as the SPI flash, and will attempt to boot when you attach your flashing device, which interferes with your ability to read/write the contents of flash. I prefer the Wieson G6179-10 SOIC8 socket (available from Adafruit). People outside the US will probably find it easier to desolder the flash and use a SOIC8 socket with prototype wires, as the G6179-10 is difficult to obtain for a reasonable price.

MS225 with SPI flash socket installed

Unlike the MS120, the MS210/MS225 do not implement secure boot, so all that is needed to develop on the platform is to recompile and flash u-boot from the Meraki GPL release and then interrupt the boot process and provide your own firmware build (e.g. via TFTP).

The UART header is J31 on both the 24 and 48 port models and follows the standard Meraki UART pinout (1: VCC/3.3V, 2: Tx, 3: Rx, 4: GND) at 115200 baud.


The Broadcom SDK for the BCM56160 series implements the packet engine in userspace, using the linux_kernel_bde and linux_user_bde kernel modules to interface with the ASIC. In the Meraki firmware, the packet engine is a component of the userspace click daemon, which loads the bcm_click shared object during click router initialisation.

There are no public datasheets available for any of the Broadcom chips used in the MS210/225. While you can find information on OpenBCM, as far as I can tell the API provided by OpenBCM (via the kernel modules) which is used to implement the packet engine has no public documentation. If anyone has more information, please get in touch 😀


Model Meraki Board Part number
MS210-24 (P) BRUMBY_24 600-58015 (P: 600-58025)
MS210-48 (LP/FP) BRUMBY_48 600-58035 (LP: 600-58045, FP: 600-58055)
MS225-24 (P) BRUMBY_24 600-58010 (P: 600-58020)
MS225-48 (LP/FP) BRUMBY_48 600-58030 (LP: 600-58040, FP: 600-58000)
MS250-24 (P) BRUMBY_24 600-58050 (P: 600-58060)
MS250-48 (LP/FP) BRUMBY_48 600-58070 (LP: 600-58080, FP: 600-58090)

Riverbed SteelHead CX 255

The Riverbed SteelHead are a series of bandwidth optimization appliances that can typically be found for a reasonable price on eBay. Today we are looking at the Riverbed CX 255 (36€ from eBay.de), a small unit with 3 Ethernet interfaces.
Riverbed SteelHead CX 255

Powering the CX 255 is an Intel Celeron 725C (1C2T) soldered to the NAMB-3250MB motherboard, along with with 2GB of DDR3-1333 unbuffered ECC. You will not win any benchmarks with this CPU.

NAMB-3250MB motherboard (Rev. A102-1; 19A2325001-01) inside the CX 255

The CX 255 consumes 20W idle, and is powered by an external 12V 7A power supply (5.5×2.5mm, center positive).

Running powertop --auto-tune sadly does nothing to the reduce power consumption. It appears to the primary reason for this is the high power consumption of the DH89xxCC chipset used

DH89xxCC chipset features and TDP (PDF)

The console port uses the Cisco rollover cable pinout, and operates at 115200n8. The two 40mm PWM fans run at around 5000RPM, and while not they do not scream as some 1U servers do, they are clearly audible from several meters away.


OpenWrt x86-64 running on the CX 255

00:00.0 Host bridge: Intel Corporation 2nd Generation Core Processor Family DRAM Controller (rev 09)
00:01.0 PCI bridge: Intel Corporation Xeon E3-1200/2nd Generation Core Processor Family PCI Express Root Port (rev 09)
00:1c.0 PCI bridge: Intel Corporation DH89xxCC PCI Express Root Port #1 (rev 08)
00:1d.0 USB controller: Intel Corporation DH89xxCC USB2 Enhanced Host Controller #1 (rev 08)
00:1f.0 ISA bridge: Intel Corporation DH89xxCC LPC Controller (rev 08)
00:1f.2 SATA controller: Intel Corporation DH89xxCC 4 Port SATA AHCI Controller (rev 08)
00:1f.3 SMBus: Intel Corporation DH89xxCC SMBus Controller (rev 08)
00:1f.6 Signal processing controller: Intel Corporation DH89xxCC Thermal Subsystem (rev 08)
00:1f.7 System peripheral: Intel Corporation DH89xxCC Watchdog Timer (rev 08)
01:00.0 Co-processor: Intel Corporation DH89XXCC Series QAT (rev 21)
01:00.1 Ethernet controller: Intel Corporation DH8900CC Series Gigabit Network Connection (rev 21)
01:00.2 Ethernet controller: Intel Corporation DH8900CC Series Gigabit Network Connection (rev 21)
02:00.0 Ethernet controller: Intel Corporation I210 Gigabit Network Connection (rev 03)

There are also the CX 570 and CX 770, which appear quite similar from the exterior. The CX 570 and CX 770 have three additional Ethernet interfaces and better CPUs. According to this document (PDF) the CX 570 has an Intel Pentium B925C while the CX 770 has an Intel Xeon E3-1125C v2.

From the lspci output on the CX 255 and the board layout, I assume that the CX 570/770 has an additional I210 controller and the remaining 2 Ethernet PHYs from the DH8900CC populated. I anticipate that the idle power consumption is similar to that of the CX 255.


Here is the lspci output from the CX 770:

00:00.0 Host bridge: Intel Corporation 3rd Gen Core processor DRAM Controller (rev 09)
00:01.0 PCI bridge: Intel Corporation Xeon E3-1200 v2/3rd Gen Core processor PCI Express Root Port (rev 09)
00:1c.0 PCI bridge: Intel Corporation DH89xxCC PCI Express Root Port #1 (rev 08)
00:1c.1 PCI bridge: Intel Corporation DH89xxCC PCI Express Root Port #2 (rev 08)
00:1d.0 USB controller: Intel Corporation DH89xxCC USB2 Enhanced Host Controller #1 (rev 08)
00:1f.0 ISA bridge: Intel Corporation DH89xxCC LPC Controller (rev 08)
00:1f.2 SATA controller: Intel Corporation DH89xxCC 4 Port SATA AHCI Controller (rev 08)
00:1f.3 SMBus: Intel Corporation DH89xxCC SMBus Controller (rev 08)
00:1f.6 Signal processing controller: Intel Corporation DH89xxCC Thermal Subsystem (rev 08)
00:1f.7 System peripheral: Intel Corporation DH89xxCC Watchdog Timer (rev 08)
01:00.0 Co-processor: Intel Corporation DH89XXCC Series QAT (rev 21)
01:00.1 Ethernet controller: Intel Corporation DH8900CC Series Gigabit Network Connection (rev 21)
01:00.2 Ethernet controller: Intel Corporation DH8900CC Series Gigabit Network Connection (rev 21)
01:00.3 Ethernet controller: Intel Corporation DH8900CC Series Gigabit Network Connection (rev 21)
01:00.4 Ethernet controller: Intel Corporation DH8900CC Series Gigabit Network Connection (rev 21)
02:00.0 Ethernet controller: Intel Corporation I210 Gigabit Network Connection (rev 03)
03:00.0 Ethernet controller: Intel Corporation I210 Gigabit Network Connection (rev 03)

The CX 770 also includes minimal lights out management (Aspeed AST1050 BMC), which can be configured to share the PRI ethernet interface. The BMC only provides remote power control and sensor readings, there is no support for KVM or serial console redirection.

Meraki MX80: buildroot firmware

Ten years ago, before ARM was in everything, many embedded systems that did not justify using an x86 used PowerPC (or MIPS). This leads us to today’s subject: the Meraki MX80, an “enterprise security appliance.”

Meraki MX80 marketing image

Meraki MX80

The MX80 is End-of-Life (EOL) and can be purchased quite inexpensively on eBay.

The MX-series differs from other Meraki networking products of the 2010-era that we have previously covered (the MS220) in that it is PowerPC based (APM86290) with 2GB of RAM and 1GB of NAND flash. The factory bootlog of the device can be found in this GitHub gist.


MX80 PCB with uart header highlighted

MX80 UART header

Removing the cover allows you to connect to the UART header J3 (57600n8), with the pinout:

  1. VCC (don’t connect)
  2. Rx
  3. Tx
  4. GND

Ground (pin 4) is closest to the Ethernet ports.

Obtaining a root shell is very easy as u-boot has a 1 second boot delay and accepts input on UART. The default meraki_boot target sets the bootargs from meraki_bootargs which appends extra_bootargs, so just override rdinit with /bin/sh to prevent the Meraki OS from booting.

setenv extra_bootargs rdinit=/bin/sh
run meraki_boot

Once the MX80 has booted, bring up eth0 (port label Internet on the MX80):

$ mount -t proc proc /proc
$ mount -t sysfs sysfs /sys
$ ifconfig lo up
$ ifconfig eth0 up
$ udhcpc eth0

Once you have functional networking, you can dump the contents of NAND to a remote host for further analysis:

$ cat /proc/mtd
dev:    size   erasesize  name
mtd0: 00100000 00020000 "firmware"
mtd1: 00100000 00020000 "environment"
mtd2: 00040000 00020000 "oops-old"
mtd3: 3fdc0000 00020000 "ubi"
mtd4: 40000000 00020000 "all"
mtd5: 0201d800 0001f800 "part1"
mtd6: 0201d800 0001f800 "part2"
mtd7: 0001f800 0001f800 "board-config"
mtd8: 2001f000 0001f800 "storage"
$ dd if=/dev/mtdblock4 bs=1M | gzip -c | nc -l -p 5000

Running binwalk on “part1” shows us the structure of Meraki’s firmware:

$ binwalk part1.bin

DECIMAL       HEXADECIMAL     DESCRIPTION
--------------------------------------------------------------------------------
1024          0x400           device tree image (dtb)
16384         0x4000          device tree image (dtb)
131072        0x20000         uImage header, header size: 64 bytes, header CRC: 0xD84034B5, created: 2020-05-29 01:15:36, image size: 2447726 bytes, Data Address: 0x0, Entry Point: 0x0, data CRC: 0xCE3A4A5E, OS: Linux, CPU: PowerPC, image type: OS Kernel Image, compression type: gzip, image name: "Linux-3.4.113"
131136        0x20040         gzip compressed data, maximum compression, from Unix, last modified: 1970-01-01 00:00:00 (null date)
4194304       0x400000        uImage header, header size: 64 bytes, header CRC: 0xDA83B155, created: 2020-05-29 01:16:17, image size: 16719915 bytes, Data Address: 0x0, Entry Point: 0x0, data CRC: 0x2381914F, OS: Linux, CPU: PowerPC, image type: RAMDisk Image, compression type: lzma, image name: "Simple Ramdisk Image"
4194368       0x400040        LZMA compressed data, properties: 0x5D, dictionary size: 67108864 bytes, uncompressed size: -1 bytes

There is a device tree image at offset 0x400 which seems to be for the MX60 (codename bluestone). There is a second device tree image at offset 0x4000 for the MX80 (codename fullerene).

It is not as simple as creating a binary image with the DTB at offset 0x4000, the kernel at 0x200000, and initrd at 0x40000 because Meraki have modified u-boot to have a custom command meraki which reads a header, verifies the contents of the ubi partition part1 or part2 with SHA1, and then sets environment variables from addresses defined in the header.

The layout of the header is as follows:

Header field Data type (value)
SHA1_MAGIC uint32 (0x8e73ed8a)
HEADER_LEN int32
DATA_LEN int32
SHA1SUM char[20]
MERAKI_EXTRA_MAGIC uint32 (0xa1f0beef)
MERAKI_EXTRA_LEN uint16 (0x0006)
MERAKI_EXTRA_TYPE uint16 (0x0001)
IMAGE_OFFSET uint32 (0x20000)
RAMDISK_OFFSET uint32 (0x400000)
FDT_OFFSETS array uint32 (0x400 or 0x4000)

The FDT used to boot depends on the value of meraki_part_fdt_index in u-boot. For the MX80, the index of the FDT offset is 1, meaning the FDT located at 0x4000 is used to boot. The presence of two FDTs suggests that Meraki are using the same firmware for both the MX60 and MX80. Despite the MX80 being a dual core CPU only one CPU core is usable, there is no SMP support in the kernel provided by Meraki.


To simplify booting, I have written a post-image.sh script which generates the appropriate header and assembles a bootable firmware image as part of the buildroot build process. You can find instructions on how to build the firmware in the meraki-builder GitHub repository.

The 3.4 kernel provided by Meraki doesn’t have any of the features required by OpenWrt (e.g. overlayfs) and buildroot doesn’t have a package manager. If you just want something to boot and run SSH on, then the buildroot image fulfills that need. You will most probably want to customize buildroot to include the packages and configuration that suits your needs. Upstream support in OpenWrt is still a long way away, as the APM86290 does not have support in the mainline kernel.