Meraki MS220-series FOSS firmware

Notice: Page may contain affiliate links for which we may earn a small commission through services like Amazon Affiliates or Skimlinks.

hmartin

Active Member
Sep 20, 2017
316
243
43
37
I am looking for people who are willing to test a FOSS firmware for the Meraki MS220 (MS22, MS42, MS320) series switches.

Background:

The current state of the firmware:
  • Modified RedBoot bootloader
  • Kernel 3.18.123 compiled from Meraki GPL source (see switch-11-22-ms220 GitHub repository above)
  • buildroot-based userspace
  • Loads all the kernel modules needed to manage the ASIC
  • Network connectivity to the management CPU is broken because Click is not correctly configured to pass traffic to userspace
    • I would really appreciate help debugging this!
  • Switch will DHCP after booting and start an SSH server
If you have this hardware and are interested in participating in development of a FOSS firmware that you can use to locally manage the switch without a license, please reply or send me a DM and I'll pass along the GDoc with installation instructions and the current build from master.

Note: This firmware is not yet functional for using your switch as a switch. But I hope to be at that point soon™
Update 2020-07-22: we have reached the point of soon™

Warning: Installing the firmware requires physical access and an SPI flashing tool. You will void any remaining warranty.
 
Last edited:

hmartin

Active Member
Sep 20, 2017
316
243
43
37
Update:
By first running switch_brain, and then overwriting the default traffic rules with “allow all” I was able to SSH to the management CPU:

Code:
/ # echo "allow all" > /click/nat/common_switch_nat/from_smc_filter/config

/ # echo "allow all" > /click/nat/common_switch_nat/from_mgmt_filter/config

/ # tail /tmp/messages | grep dropbear

Jan  1 00:15:49 buildroot authpriv.info dropbear[680]: Child connection from 10.10.10.1:39248

Jan  1 00:15:50 buildroot authpriv.notice dropbear[680]: Password auth succeeded for 'root' from 10.10.10.1:39248

/ # w

USER            TTY             IDLE    TIME             HOST

root            pts/0           00:00   Jan  1 00:15:50  10.10.10.1
I think it is now very clear that the “only” thing blocking full access to the management CPU is the Click configuration. My hope is to build the configuration from the switch_brain strace output and package that into an initscript.

Blog post
Installation instructions
 
  • Like
Reactions: Seenc

hmartin

Active Member
Sep 20, 2017
316
243
43
37
I have resolved the issue with network connectivity to the management CPU. PoE is non-functional as this requires some additional work, however L2 switching features are working.

I have also tested the firmware on the Meraki MS42, and all 48 GigE ports plus the 4 SFP+ ports are working.

If you have an MS22, MS42, MS220-8/24/48, or MS320-24/48 switch and are interested in beta testing the firmware, please send me a PM.

Code:
LinuxLoader built Nov 12 2002 18:01:50
init_pll ok
init_spi ok
init_memctl ok
wait_memctl ok
Training DRAM ok
init_irq ok
init_dram_uncached ok
init_icache ok
init_dcache ok
enable_caches ok
init_board ok
Low level initialization complete, exiting boot mode
[    0.000000] Linux version 3.18.123-meraki-elemental (hmartin@alp) (gcc version 5.4.0 (GCC) ) #10 Sat Jul 18 17:06:37 UTC 2020
[    0.000000] CPU0 revision is: 02019654 (MIPS 24KEc)
[    0.000000] Determined physical RAM map:
[    0.000000]  memory: 00477000 @ 00100000 (usable)
[    0.000000]  memory: 00049000 @ 00577000 (usable after init)
[    0.000000] User-defined physical RAM map:
[    0.000000]  memory: 07ff0000 @ 00000000 (usable)
[    0.000000] Initmem setup node 0 [mem 0x00000000-0x07feffff]
[    0.000000] Reserving 0MB of memory at 0MB for crashkernel
[    0.000000] Kernel command line: console=ttyS0,115200 mtdparts=m25p80:0x40000(redboot),0x2c0000(kernel),0x800000(squashfs),0x500000(overlay) root=/dev/mtdblock3
 ubi.mtd=gen_nand.0 mem=134152192
[    0.000000] PID hash table entries: 512 (order: -1, 2048 bytes)
[    0.000000] Dentry cache hash table entries: 16384 (order: 4, 65536 bytes)
[    0.000000] Inode-cache hash table entries: 8192 (order: 3, 32768 bytes)
[    0.000000] Writing ErrCtl register=80000810
[    0.000000] Readback ErrCtl register=80000810
[    0.000000] Cache parity protection enabled
[    0.000000] SLUB: HWalign=32, Order=0-3, MinObjects=0, CPUs=1, Nodes=1
[    0.000000] NR_IRQS:66
[    0.000000] sched_clock: 32 bits at 1kHz, resolution 1000000ns, wraps every 2147483648000000ns
[    0.001000] Calibrating delay loop... 275.45 BogoMIPS (lpj=137728)
[    0.010000] pid_max: default: 32768 minimum: 301
[    0.010000] Mount-cache hash table entries: 1024 (order: 0, 4096 bytes)
[    0.010000] Mountpoint-cache hash table entries: 1024 (order: 0, 4096 bytes)
[    0.012000] ftrace: allocating 11994 entries in 24 pages
[    0.039000] Performance counters: mips/24K PMU enabled, 2 32-bit counters available to each CPU, irq -1 (share with timer interrupt)
[    0.045000] devtmpfs: initialized
[    0.051000] NET: Registered protocol family 16
[    0.112000] Switched to clocksource MIPS
[    0.139000] NET: Registered protocol family 2
[    0.141000] TCP established hash table entries: 1024 (order: 0, 4096 bytes)
[    0.141000] TCP bind hash table entries: 1024 (order: 0, 4096 bytes)
[    0.141000] TCP: Hash tables configured (established 1024 bind 1024)
[    0.142000] TCP: reno registered
[    0.142000] UDP hash table entries: 256 (order: 0, 4096 bytes)
[    0.142000] UDP-Lite hash table entries: 256 (order: 0, 4096 bytes)
[    0.142000] NET: Registered protocol family 1
[    0.147000] VCORE-III Watchdog Timer enabled (30 seconds).  Prev boot was not caused by WDT reset.
[    0.149000] futex hash table entries: 256 (order: -1, 3072 bytes)
[    0.178000] squashfs: version 4.0 (2009/01/31) Phillip Lougher
[    0.178000] jffs2: version 2.2. (NAND) © 2001-2006 Red Hat, Inc.
[    0.180000] msgmni has been set to 241
[    0.209000] io scheduler noop registered
[    0.209000] io scheduler deadline registered (default)
[    0.211000] Serial: 8250/16550 driver, 1 ports, IRQ sharing disabled
[    0.212000] console [ttyS0] disabled
[    0.213000] serial8250.0: ttyS0 at MMIO 0x70100000 (irq = 14, base_baud = 13020833) is a 16550A
[    0.512000] console [ttyS0] enabled
[    0.521000] nand: device found, Manufacturer ID: 0x2c, Chip ID: 0xf1
[    0.527000] nand: Micron MT29F1G08ABADAWP
[    0.531000] nand: 128MiB, SLC, page size: 2048, OOB size: 64
[    0.543000] Scanning device for bad blocks
[    0.659000] m25p80 spi0.1: found mx25l12805d, expected m25p80
[    0.665000] m25p80 spi0.1: mx25l12805d (16384 Kbytes)
[    0.670000] 4 cmdlinepart partitions found on MTD device m25p80
[    0.676000] Creating 4 MTD partitions on "m25p80":
[    0.681000] 0x000000000000-0x000000040000 : "redboot"
[    0.694000] 0x000000040000-0x000000300000 : "kernel"
[    0.706000] 0x000000300000-0x000000b00000 : "squashfs"
[    0.715000] 0x000000b00000-0x000001000000 : "overlay"
[    0.726000] tun: Universal TUN/TAP device driver, 1.6
[    0.731000] tun: (C) 1999-2004 Max Krasnyansky <maxk@qualcomm.com>
[    0.741000] i2c /dev entries driver
[    0.747000] TCP: cubic registered
[    0.750000] Initializing XFRM netlink socket
[    0.757000] NET: Registered protocol family 10
[    0.765000] NET: Registered protocol family 17
[    0.770000] NET: Registered protocol family 15
[    0.775000] 8021q: 802.1Q VLAN Support v1.8
[    0.779000] Meraki MS220-8 board detected
[    0.788000] i2c-gpio i2c-gpio.1: using pins 6 (SDA) and 5 (SCL)
[    0.802000] UBI: attaching mtd0 to ubi0
[    1.602000] UBI: scanning is finished
[    1.638000] UBI: attached mtd0 (name "gen_nand.0", size 128 MiB) to ubi0
[    1.645000] UBI: PEB size: 131072 bytes (128 KiB), LEB size: 129024 bytes
[    1.652000] UBI: min./max. I/O unit sizes: 2048/2048, sub-page size 512
[    1.659000] UBI: VID header offset: 512 (aligned 512), data offset: 2048
[    1.665000] UBI: good PEBs: 1024, bad PEBs: 0, corrupted PEBs: 0
[    1.671000] UBI: user volume: 12, internal volumes: 1, max. volumes count: 128
[    1.679000] UBI: max/mean erase counter: 1957/1118, WL threshold: 4096, image sequence number: 1276936678
[    1.688000] UBI: available PEBs: 462, total reserved PEBs: 562, PEBs reserved for bad PEB handling: 20
[    1.698000] UBI: background thread "ubi_bgt0d" started, PID 247
[    1.783000] devtmpfs: mounted
[    1.816000] VFS: Mounted root (squashfs filesystem) readonly on device 31:3.
[    1.860000] devtmpfs: mounted
[    1.868000] Freeing unused kernel memory: 292K
[    5.715000] devpts: called with bogus options
Starting syslogd: OK
Starting klogd: OK
Running sysctl: OK
[    8.631000] random: nonblocking pool is initialized
[   28.679000] jffs2: Cowardly refusing to erase blocks on filesystem with no valid JFFS2 nodes
[   28.688000] jffs2: empty_blocks 0, bad_blocks 0, c->nr_blocks 80
mount: mounting /dev/mtdblock4 on /overlay failed: Input/output error
First boot, formatting /overlay
0+3 records in
0+3 records out
board-config is /dev/mtd5
[   61.126000] vtss_core: module license '(c) Vitesse Semiconductor Inc.' taints kernel.
[   61.134000] Disabling lock debugging due to kernel taint
[   61.757000] switch: 'Meraki MS220-8' board detected
Loaded 'luton26/vtss_core.ko board_desc=MERAKI_BOARD_MS220_8'
Loaded 'proclikefs.ko'
[   75.841000] click: starting router thread pid 407 (87a81700)
Loaded 'merakiclick.ko'
Loaded 'elts_meraki.ko'
Loaded 'luton26/vc_click.ko'
[  111.091000] chatter: from_sw0 :: FromVitesse: initializing fdma
Switch port count: 10
net.ipv4.ip_local_reserved_ports = 50000-50127
sh: Size: unknown operand
Waiting for IP address...
Waiting for IP address...
Waiting for IP address...
Waiting for IP address...
Waiting for IP address...
Waiting for IP address...
Waiting for IP address...
Using IP address: 192.168.0.21
Saving random seed: SKIP (read-only file system detected)
Starting network: OK
Starting dhcpcd...
/var/db/dhcpcd/duid: Read-only file system
DUID 00:03:00:01:88:15:44:27:29:79
arping: IAID 44:27:29:79
sw0_pcap: IAID 02:03:04:05
arping: soliciting a DHCP lease
sw0_pcap: soliciting a DHCP lease
sw0_pcap: soliciting an IPv6 router
arping: soliciting an IPv6 router
arping: probing for an IPv4LL address
sw0_pcap: probing for an IPv4LL address
sw0_pcap: using IPv4LL address 169.254.83.119
sw0_pcap: adding route to 169.254.0.0/16
sw0_pcap: adding default route
forked to background, child pid 644
No persistent location to store SSH host keys. New keys will be
generated at each boot. Are you sure this is what you want to do?
Starting dropbear sshd: OK

/ #
 
Last edited:

hmartin

Active Member
Sep 20, 2017
316
243
43
37
I have had a few people contact me about testing the firmware, and I want to thank you all for the feedback!

Someone asked me about next steps, so I wanted to start a discussion on what I consider the next steps for firmware development:
  1. Centralized switch configuration
  2. Web UI
  3. PoE daemon
  4. Adding support for the vcoreiii ASICs in upstream Linux

Centralized switch configuration
Currently, the switch boots to a default configuration of VLAN 1 untagged on every port. While this is useful for the initial configuration, it has the potential to expose devices to incorrect VLANs and is generally not a configuration that people are likely to want on a switch in their home network.

Centralizing the layer 2 configuration of the switch and applying this configuration on boot would allow people to configure the switch to their individual needs starting from the second boot (or first, if you generate the JFFS2 filesystem yourself before flashing).

While maybe not very "unix-like" I was thinking of a single JSON configuration file that configures each port, so that backing up and restoring the configuration is simple. The advantage of using a JSON file (in my opinion) is that when/if a web UI is written, the only requirement is a simple HTTP server (like uhttpd) which supports GET/POST and the web UI can then operate entirely on the JSON configuration on the client side.


Web UI
There's no web UI. I don't do modern front-end development. If someone else with experience in frontend development is willing to write a web UI, that'd be awesome.


PoE daemon
PoE auto configuration is done in this init script. While this works for the simple case of "plug and play" PoE, it doesn't allow you to query the PoE power budget, or disable PoE on a port (e.g. to power cycle an unresponsive PoE device). I've done some initial work on reverse engineering the libpoecore that Meraki uses, but if we want to have PoE control, either a user-space or kernel module needs to be written to interface with the PD690xx.


Mainline support
u-boot has basic support for the VSC7425, including networking support. The ultimate stretch goal would be upstream support in the kernel for the Vitesse ASICs used in Meraki switches, as this would allow newer kernels and support for other operating systems like OpenWrt on the hardware.

 
  • Like
Reactions: Seenc and legopc

hmartin

Active Member
Sep 20, 2017
316
243
43
37
I've had a number of people contact me to say that they tried to flash their switch but the SPI flash wasn't detected by their programmer.

I can't really offer remote debugging of this scenario. I use the ch341a_spi programmers you can find on AliExpress or eBay for a few dollars. I also solder wires directly to the SOIC16 because chip clips, while convenient, tend to be flaky.

I've had many people provide private feedback that they were able to flash the firmware. For those of you still having difficulty, please review the wiring in the installation instructions and/or consider purchasing an SOIC16 socket and some blank W25Q256 chips to practice. It'll only cost you a few dollars extra and you'll confirm that the programmer and installation instructions work.

If you're still having issues, please post in this thread, with photos of your entire setup (programmer, wiring, and SOIC16 visible) and I or someone else will assist you. The most likely cause of failure is a poor/incomplete connection to the SOIC16 or incorrect wiring.

Anyone with a larger switch (-24 or -48LP/FP) please let me know if PoE works or not. I have a report of an MS220-48LP that doesn't have functional PoE despite following the same initialization steps as Meraki's daemon.

pd690xx has been updated to operate on 24/48 port switches. I'll have a build with the new version available soon. It may not be perfect as I haven't had anyone with an MS320 available to test it.
 
  • Like
Reactions: Seenc

hmartin

Active Member
Sep 20, 2017
316
243
43
37
@lewru: my apologies, I didn't see your reply until now. I've started a discussion with you and dannlori about flashing the MS320.
 

lewru

New Member
Oct 29, 2020
2
0
1
Was able to successfully flash chip, and verify upload, but when the switch boots, I dont get an IP address, nor do the lights show up on the front. Here are the serial logs. (did I miss a step after flashing the chip, I thought it was just flash chip, find IP address, and ssh in).
LinuxLoader built Nov 12 2020 18:01:50
init_pll ok
init_spi ok
init_memctl ok
wait_memctl ok
Training DRAM ok
init_irq ok
init_dram_uncached ok
init_icache ok
init_dcache ok
enable_caches ok
init_pi ok
init_board ok
Low level initialization complete, exiting boot mode
[ 0.000000] Linux version 3.18.123-meraki-elemental (hmartin@alp) (gcc version 5.4.0 (GCC) ) #10 Sat Jul 18 17:06:37 UTC 2020
[ 0.000000] CPU0 revision is: 01019654 (MIPS 24KEc)
[ 0.000000] Determined physical RAM map:
[ 0.000000] memory: 00477000 @ 00100000 (usable)
[ 0.000000] memory: 00049000 @ 00577000 (usable after init)
[ 0.000000] User-defined physical RAM map:
[ 0.000000] memory: 07ff0000 @ 00000000 (usable)
[ 0.000000] Initmem setup node 0 [mem 0x00000000-0x07feffff]
[ 0.000000] Reserving 0MB of memory at 0MB for crashkernel
[ 0.000000] Kernel command line: console=ttyS0,115200 mtdparts=m25p80:0x40000(redboot),0x2c0000(kernel),0x800000(squashfs),0x500000(overlay) root=/dev/mtdblock3 ubi.mtd=gen_nand.0 mem=134152192
[ 0.000000] PID hash table entries: 512 (order: -1, 2048 bytes)
[ 0.000000] Dentry cache hash table entries: 16384 (order: 4, 65536 bytes)
[ 0.000000] Inode-cache hash table entries: 8192 (order: 3, 32768 bytes)
[ 0.000000] Writing ErrCtl register=80001200
[ 0.000000] Readback ErrCtl register=80001200
[ 0.000000] Cache parity protection enabled
[ 0.000000] SLUB: HWalign=32, Order=0-3, MinObjects=0, CPUs=1, Nodes=1
[ 0.000000] NR_IRQS:66
[ 0.000000] sched_clock: 32 bits at 1kHz, resolution 1000000ns, wraps every 2147483648000000ns
[ 0.002000] VCore-III slave device ID 7460 found
[ 0.002000] Calibrating delay loop... 275.45 BogoMIPS (lpj=137728)
[ 0.011000] pid_max: default: 32768 minimum: 301
[ 0.011000] Mount-cache hash table entries: 1024 (order: 0, 4096 bytes)
[ 0.011000] Mountpoint-cache hash table entries: 1024 (order: 0, 4096 bytes)
[ 0.013000] ftrace: allocating 11994 entries in 24 pages
[ 0.041000] Performance counters: mips/24K PMU enabled, 2 32-bit counters available to each CPU, irq -1 (share with timer interrupt)
[ 0.048000] devtmpfs: initialized
[ 0.055000] NET: Registered protocol family 16
[ 0.094000] Switched to clocksource MIPS
[ 0.124000] NET: Registered protocol family 2
[ 0.127000] TCP established hash table entries: 1024 (order: 0, 4096 bytes)
[ 0.128000] TCP bind hash table entries: 1024 (order: 0, 4096 bytes)
[ 0.128000] TCP: Hash tables configured (established 1024 bind 1024)
[ 0.128000] TCP: reno registered
[ 0.128000] UDP hash table entries: 256 (order: 0, 4096 bytes)
[ 0.128000] UDP-Lite hash table entries: 256 (order: 0, 4096 bytes)
[ 0.129000] NET: Registered protocol family 1
[ 0.133000] VCORE-III Watchdog Timer enabled (30 seconds). Prev boot was not caused by WDT reset.
[ 0.158000] futex hash table entries: 256 (order: -1, 3072 bytes)
[ 0.195000] squashfs: version 4.0 (2009/01/31) Phillip Lougher
[ 0.195000] jffs2: version 2.2. (NAND) © 2001-2006 Red Hat, Inc.
[ 0.198000] msgmni has been set to 241
[ 0.226000] io scheduler noop registered
[ 0.226000] io scheduler deadline registered (default)
[ 0.228000] Serial: 8250/16550 driver, 1 ports, IRQ sharing disabled
[ 0.230000] console [ttyS0] disabled
[ 0.231000] serial8250.0: ttyS0 at MMIO 0x70100000 (irq = 14, base_baud = 13020833) is a 16550A
[ 0.612000] console [ttyS0] enabled
[ 0.622000] nand: device found, Manufacturer ID: 0x2c, Chip ID: 0xf1
[ 0.628000] nand: Micron MT29F1G08ABADAWP
[ 0.633000] nand: 128MiB, SLC, page size: 2048, OOB size: 64
[ 0.644000] Scanning device for bad blocks
[ 0.762000] m25p80 spi0.1: found mx25l12805d, expected m25p80
[ 0.768000] m25p80 spi0.1: mx25l12805d (16384 Kbytes)
[ 0.773000] 4 cmdlinepart partitions found on MTD device m25p80
[ 0.779000] Creating 4 MTD partitions on "m25p80":
[ 0.784000] 0x000000000000-0x000000040000 : "redboot"
[ 0.805000] 0x000000040000-0x000000300000 : "kernel"
[ 0.816000] 0x000000300000-0x000000b00000 : "squashfs"
[ 0.831000] 0x000000b00000-0x000001000000 : "overlay"
[ 0.841000] tun: Universal TUN/TAP device driver, 1.6
[ 0.847000] tun: (C) 1999-2004 Max Krasnyansky <maxk@qualcomm.com>
[ 0.858000] i2c /dev entries driver
[ 0.865000] TCP: cubic registered
[ 0.869000] Initializing XFRM netlink socket
[ 0.876000] NET: Registered protocol family 10
[ 0.885000] NET: Registered protocol family 17
[ 0.890000] NET: Registered protocol family 15
[ 0.895000] 8021q: 802.1Q VLAN Support v1.8
[ 0.905000] i2c-gpio i2c-gpio.1: using pins 15 (SDA) and 14 (SCL)
[ 0.912000] at24 1-0051: 1024 byte 24c08 EEPROM, writable, 8 bytes/write
[ 0.921000] meraki-config meraki-config: Meraki config device loaded
[ 1.057000] i2c-gpio i2c-gpio.2: using pins 708 (SDA) and 709 (SCL)
[ 1.112000] i2c-gpio i2c-gpio.3: using pins 714 (SDA) and 715 (SCL)
[ 1.170000] i2c-gpio i2c-gpio.4: using pins 720 (SDA) and 721 (SCL)
[ 1.227000] i2c-gpio i2c-gpio.5: using pins 726 (SDA) and 727 (SCL)
[ 1.244000] tmp401 6-004c: Detected TI TMP411 chip
[ 1.254000] i2c-gpio i2c-gpio.6: using pins 47 (SDA) and 46 (SCL)
[ 1.272000] i2c-gpio i2c-gpio.7: using pins 51 (SDA) and 50 (SCL)
[ 1.288000] i2c-gpio i2c-gpio.8: using pins 53 (SDA) and 52 (SCL)
[ 1.296000] at24 2-0050: 256 byte 24c02 EEPROM, read-only, 0 bytes/write
[ 1.304000] at24 3-0050: 256 byte 24c02 EEPROM, read-only, 0 bytes/write
[ 1.311000] at24 4-0050: 256 byte 24c02 EEPROM, read-only, 0 bytes/write
[ 1.318000] at24 5-0050: 256 byte 24c02 EEPROM, read-only, 0 bytes/write
[ 1.331000] pca953x 6-0022: interrupt support not compiled in
[ 1.348000] UBI: attaching mtd0 to ubi0
[ 2.162000] UBI: scanning is finished
[ 2.206000] UBI: attached mtd0 (name "gen_nand.0", size 128 MiB) to ubi0
[ 2.213000] UBI: PEB size: 131072 bytes (128 KiB), LEB size: 129024 bytes
[ 2.220000] UBI: min./max. I/O unit sizes: 2048/2048, sub-page size 512
[ 2.227000] UBI: VID header offset: 512 (aligned 512), data offset: 2048
[ 2.234000] UBI: good PEBs: 1024, bad PEBs: 0, corrupted PEBs: 0
[ 2.240000] UBI: user volume: 12, internal volumes: 1, max. volumes count: 128
[ 2.247000] UBI: max/mean erase counter: 3873/2473, WL threshold: 4096, image sequence number: 1097212687
[ 2.257000] UBI: available PEBs: 462, total reserved PEBs: 562, PEBs reserved for bad PEB handling: 20
[ 2.267000] UBI: background thread "ubi_bgt0d" started, PID 299
[ 2.386000] devtmpfs: mounted
[ 2.430000] VFS: Mounted root (squashfs filesystem) readonly on device 31:3.
[ 2.469000] devtmpfs: mounted
[ 2.478000] Freeing unused kernel memory: 292K
[ 6.467000] devpts: called with bogus options
Starting syslogd: OK
Starting klogd: OK
Running sysctl: OK
[ 8.718000] random: nonblocking pool is initialized
/overlay is already mounted
board-config is /dev/mtd5
insmod: ERROR: could not load module /lib/modules//vtss_core.ko: No such file or directory
Loaded 'proclikefs.ko'
[ 28.435000] click: starting router thread pid 470 (87b9c900)
Loaded 'merakiclick.ko'
[ 65.112000] elts_meraki: module license 'unspecified' taints kernel.
[ 65.118000] Disabling lock debugging due to kernel taint
Loaded 'elts_meraki.ko'
insmod: ERROR: could not load module /lib/modules//vc_click.ko: No such file or directory
[ 68.188000] unsatisfied requirement 'vc_click'
[ 68.194000] click-config/switch/io-real/vitesse.click:26: unknown element class 'ToVitesse'
[ 68.203000] click-config/switch/io-real/vitesse.click:31: unknown element class 'FromVitesse'
[ 68.213000] click-config/switch/io-real/vitesse.click:59: unknown element class 'VitesseController'
[ 68.614000] click-config/switch.template:74: While configuring 'switch_intf_table :: SwitchIntfTable':
[ 68.623000] SWITCH_HARDWARE: element type mismatch, expected SwitchHardwareIntf
[ 68.634000] click-config/switch.template:1045: While configuring 'switch_port_table :: SwitchPortTable':
[ 68.644000] SWITCH_HARDWARE_INTERFACE: element type mismatch, expected SwitchHardwareIntf
[ 68.668000] click-config/switch.template:58: While configuring 'l3_update_hardware :: UpdateHardwareTable':
[ 68.678000] SWITCH_HARDWARE_INTERFACE: element type mismatch, expected SwitchHardwareIntf
[ 68.696000] click-config/switch.template:383: While configuring 'switch_rpc_server :: SwitchRPCServer':
[ 68.706000] HW_INTF: element type mismatch, expected SwitchHardwareIntf
[ 68.716000] click-config/switch.template:566: While configuring 'CheckStackMaster@187 :: CheckStackMaster':
[ 68.726000] HW_INTF: element type mismatch, expected SwitchHardwareIntf
[ 68.735000] click-config/switch.template:602: While configuring 'CheckStackMaster@235 :: CheckStackMaster':
[ 68.745000] HW_INTF: element type mismatch, expected SwitchHardwareIntf
[ 68.753000] click-config/switch.template:633: While configuring 'switch_mrt :: MulticastRoutingTable':
[ 68.763000] SWITCH_HARDWARE_INTERFACE: element type mismatch, expected SwitchHardwareIntf
[ 68.774000] click-config/switch.template:655: While configuring 'ospf_hello_inspector :: OspfHelloInspector':
[ 68.784000] SWITCH_HARDWARE_INTERFACE: element type mismatch, expected SwitchHardwareIntf
[ 68.817000] click-config/switch.template:875: While configuring 'msstp_encap_inst :: MSSTPEncap':
[ 68.826000] HW_INTF: element type mismatch, expected SwitchHardwareIntf
[ 68.838000] click-config/switch.template:930: While configuring 'IntraStackResolver@527 :: IntraStackResolver':
[ 68.848000] HW_INTF: element type mismatch, expected SwitchHardwareIntf
[ 68.860000] click-config/switch.template:1072: While configuring 'igmp_table :: IGMPSnoopTable':
[ 68.869000] SWITCH_HARDWARE_INTERFACE: element type mismatch, expected SwitchHardwareIntf
[ 68.878000] click-config/switch.template:1093: While configuring 'mld_table :: MLDSnoopTable':
[ 68.887000] SWITCH_HARDWARE_INTERFACE: element type mismatch, expected SwitchHardwareIntf
[ 68.898000] click-config/switch.template:1125: While configuring 'msstp_decap :: MSSTPDecap':
[ 68.907000] HW_INTF: element type mismatch, expected SwitchHardwareIntf
[ 68.920000] click-config/switch.template:1187: While configuring 'CheckStackMaster@664 :: CheckStackMaster':
[ 68.930000] HW_INTF: element type mismatch, expected SwitchHardwareIntf
[ 68.937000] click-config/switch.template:1189: While configuring 'CheckStackMaster@669 :: CheckStackMaster':
[ 68.947000] HW_INTF: element type mismatch, expected SwitchHardwareIntf
[ 68.955000] click-config/switch.template:1199: While configuring 'CheckStackMaster@680 :: CheckStackMaster':
[ 68.965000] HW_INTF: element type mismatch, expected SwitchHardwareIntf
[ 68.973000] click-config/switch.template:1212: While configuring 'CheckStackMaster@693 :: CheckStackMaster':
[ 68.983000] HW_INTF: element type mismatch, expected SwitchHardwareIntf
[ 68.992000] click-config/switch.template:1238: While configuring 'CheckStackMaster@726 :: CheckStackMaster':
[ 69.002000] HW_INTF: element type mismatch, expected SwitchHardwareIntf
[ 69.014000] click-config/switch.template:1307: While configuring 'stp_check_master :: CheckStackMaster':
[ 69.024000] HW_INTF: element type mismatch, expected SwitchHardwareIntf
[ 69.031000] click-config/switch.template:1320: While configuring 'lacp_check_master :: CheckStackMaster':
[ 69.041000] HW_INTF: element type mismatch, expected SwitchHardwareIntf
[ 69.050000] click-config/switch.template:1409: While configuring 'udld :: UDLD':
[ 69.058000] HW_INTF: element type mismatch, expected SwitchHardwareIntf
[ 69.067000] click-config/switch.template:1459: While configuring 'CheckStackMaster@861 :: CheckStackMaster':
[ 69.077000] HW_INTF: element type mismatch, expected SwitchHardwareIntf
[ 69.166000] Router could not be initialized!
Default port count: 10
net.ipv4.ip_local_reserved_ports = 50000-50127
vc_click isn't loaded; aborting!
/etc/init.d/S11leds: line 8: can't create /click/sw0_ctrl/power_led_orange: nonexistent directory
/etc/init.d/S11leds: line 9: can't create /click/sw0_ctrl/power_led_green: nonexistent directory
Generating dropbear ECDSA host key
Generating 521 bit ecdsa key, this may take a while...
Public key portion is:
ecdsa-sha2-nistp521 AAAAE2VjZHNhLXNoYTItbmlzdHA1MjEAAAAIbmlzdHA1MjEAAACFBAFNxGJYZLVaBWMYi5vRjYArtacG8O4bmhaEi8fJag3o6WlVDUjEm85AP6AuMJOU6AAHx2Y0hzENRBLT2Bzav+HCtAC5fZonIWbLxrBPVY+kRLflQkoICN5maZA3sWznSebN6iXXbP0Tr0lnFLJ6qmoT91+nw962rsA7F8N2r7QVvNa1vw== root@m881544122673
Fingerprint: sha1!! 6b:a5:fc:c6:4b:7b:78:38:2e:a2:d2:50:6c:c2:d2:db:16:7d:76:de
Saving random seed: SKIP (read-only file system detected)
Starting network: OK
Starting chrony: Could not open configuration file /etc/chrony.conf : No such file or directory
FAIL
Starting dropbear sshd: OK
Starting lighttpd: OK

/ # LinuxLoader built Nov 12 2020 18:01:50
init_pll ok
init_spi ok
init_memctl ok
wait_memctl ok
Training DRAM ok
init_irq ok
init_dram_uncached ok
init_icache ok
init_dcache ok
enable_caches ok
init_pi ok
init_board ok
Low level initialization complete, exiting boot mode
[ 0.000000] Linux version 3.18.123-meraki-elemental (hmartin@alp) (gcc version 5.4.0 (GCC) ) #10 Sat Jul 18 17:06:37 UTC 2020
[ 0.000000] CPU0 revision is: 01019654 (MIPS 24KEc)
[ 0.000000] Determined physical RAM map:
[ 0.000000] memory: 00477000 @ 00100000 (usable)
[ 0.000000] memory: 00049000 @ 00577000 (usable after init)
[ 0.000000] User-defined physical RAM map:
[ 0.000000] memory: 07ff0000 @ 00000000 (usable)
[ 0.000000] Initmem setup node 0 [mem 0x00000000-0x07feffff]
[ 0.000000] Reserving 0MB of memory at 0MB for crashkernel
[ 0.000000] Kernel command line: console=ttyS0,115200 mtdparts=m25p80:0x40000(redboot),0x2c0000(kernel),0x800000(squashfs),0x500000(overlay) root=/dev/mtdblock3 ubi.mtd=gen_nand.0 mem=134152192
[ 0.000000] PID hash table entries: 512 (order: -1, 2048 bytes)
[ 0.000000] Dentry cache hash table entries: 16384 (order: 4, 65536 bytes)
[ 0.000000] Inode-cache hash table entries: 8192 (order: 3, 32768 bytes)
[ 0.000000] Writing ErrCtl register=80001200
[ 0.000000] Readback ErrCtl register=80001200
[ 0.000000] Cache parity protection enabled
[ 0.000000] SLUB: HWalign=32, Order=0-3, MinObjects=0, CPUs=1, Nodes=1
[ 0.000000] NR_IRQS:66
[ 0.000000] sched_clock: 32 bits at 1kHz, resolution 1000000ns, wraps every 2147483648000000ns
[ 0.002000] VCore-III slave device ID 7460 found
[ 0.002000] Calibrating delay loop... 275.45 BogoMIPS (lpj=137728)
[ 0.011000] pid_max: default: 32768 minimum: 301
[ 0.011000] Mount-cache hash table entries: 1024 (order: 0, 4096 bytes)
[ 0.011000] Mountpoint-cache hash table entries: 1024 (order: 0, 4096 bytes)
[ 0.013000] ftrace: allocating 11994 entries in 24 pages
[ 0.041000] Performance counters: mips/24K PMU enabled, 2 32-bit counters available to each CPU, irq -1 (share with timer interrupt)
[ 0.048000] devtmpfs: initialized
[ 0.055000] NET: Registered protocol family 16
[ 0.094000] Switched to clocksource MIPS
[ 0.124000] NET: Registered protocol family 2
[ 0.127000] TCP established hash table entries: 1024 (order: 0, 4096 bytes)
[ 0.128000] TCP bind hash table entries: 1024 (order: 0, 4096 bytes)
[ 0.128000] TCP: Hash tables configured (established 1024 bind 1024)
[ 0.128000] TCP: reno registered
[ 0.128000] UDP hash table entries: 256 (order: 0, 4096 bytes)
[ 0.128000] UDP-Lite hash table entries: 256 (order: 0, 4096 bytes)
[ 0.129000] NET: Registered protocol family 1
[ 0.133000] VCORE-III Watchdog Timer enabled (30 seconds). Prev boot was not caused by WDT reset.
[ 0.158000] futex hash table entries: 256 (order: -1, 3072 bytes)
[ 0.196000] squashfs: version 4.0 (2009/01/31) Phillip Lougher
[ 0.196000] jffs2: version 2.2. (NAND) © 2001-2006 Red Hat, Inc.
[ 0.199000] msgmni has been set to 241
[ 0.226000] io scheduler noop registered
[ 0.226000] io scheduler deadline registered (default)
[ 0.228000] Serial: 8250/16550 driver, 1 ports, IRQ sharing disabled
[ 0.231000] console [ttyS0] disabled
[ 0.231000] serial8250.0: ttyS0 at MMIO 0x70100000 (irq = 14, base_baud = 13020833) is a 16550A
[ 0.611000] console [ttyS0] enabled
[ 0.621000] nand: device found, Manufacturer ID: 0x2c, Chip ID: 0xf1
[ 0.627000] nand: Micron MT29F1G08ABADAWP
[ 0.632000] nand: 128MiB, SLC, page size: 2048, OOB size: 64
[ 0.643000] Scanning device for bad blocks
[ 0.761000] m25p80 spi0.1: found mx25l12805d, expected m25p80
[ 0.767000] m25p80 spi0.1: mx25l12805d (16384 Kbytes)
[ 0.772000] 4 cmdlinepart partitions found on MTD device m25p80
[ 0.778000] Creating 4 MTD partitions on "m25p80":
[ 0.783000] 0x000000000000-0x000000040000 : "redboot"
[ 0.804000] 0x000000040000-0x000000300000 : "kernel"
[ 0.814000] 0x000000300000-0x000000b00000 : "squashfs"
[ 0.830000] 0x000000b00000-0x000001000000 : "overlay"
[ 0.840000] tun: Universal TUN/TAP device driver, 1.6
[ 0.845000] tun: (C) 1999-2004 Max Krasnyansky <maxk@qualcomm.com>
[ 0.857000] i2c /dev entries driver
[ 0.864000] TCP: cubic registered
[ 0.868000] Initializing XFRM netlink socket
[ 0.875000] NET: Registered protocol family 10
[ 0.884000] NET: Registered protocol family 17
[ 0.889000] NET: Registered protocol family 15
[ 0.894000] 8021q: 802.1Q VLAN Support v1.8
[ 0.904000] i2c-gpio i2c-gpio.1: using pins 15 (SDA) and 14 (SCL)
[ 0.911000] at24 1-0051: 1024 byte 24c08 EEPROM, writable, 8 bytes/write
[ 0.922000] meraki-config meraki-config: Meraki config device loaded
[ 1.056000] i2c-gpio i2c-gpio.2: using pins 708 (SDA) and 709 (SCL)
[ 1.111000] i2c-gpio i2c-gpio.3: using pins 714 (SDA) and 715 (SCL)
[ 1.168000] i2c-gpio i2c-gpio.4: using pins 720 (SDA) and 721 (SCL)
[ 1.226000] i2c-gpio i2c-gpio.5: using pins 726 (SDA) and 727 (SCL)
[ 1.243000] tmp401 6-004c: Detected TI TMP411 chip
[ 1.253000] i2c-gpio i2c-gpio.6: using pins 47 (SDA) and 46 (SCL)
[ 1.271000] i2c-gpio i2c-gpio.7: using pins 51 (SDA) and 50 (SCL)
[ 1.287000] i2c-gpio i2c-gpio.8: using pins 53 (SDA) and 52 (SCL)
[ 1.295000] at24 2-0050: 256 byte 24c02 EEPROM, read-only, 0 bytes/write
[ 1.303000] at24 3-0050: 256 byte 24c02 EEPROM, read-only, 0 bytes/write
[ 1.310000] at24 4-0050: 256 byte 24c02 EEPROM, read-only, 0 bytes/write
[ 1.317000] at24 5-0050: 256 byte 24c02 EEPROM, read-only, 0 bytes/write
[ 1.330000] pca953x 6-0022: interrupt support not compiled in
[ 1.347000] UBI: attaching mtd0 to ubi0
[ 2.160000] UBI: scanning is finished
[ 2.203000] UBI: attached mtd0 (name "gen_nand.0", size 128 MiB) to ubi0
[ 2.210000] UBI: PEB size: 131072 bytes (128 KiB), LEB size: 129024 bytes
[ 2.217000] UBI: min./max. I/O unit sizes: 2048/2048, sub-page size 512
[ 2.224000] UBI: VID header offset: 512 (aligned 512), data offset: 2048
[ 2.230000] UBI: good PEBs: 1024, bad PEBs: 0, corrupted PEBs: 0
[ 2.237000] UBI: user volume: 12, internal volumes: 1, max. volumes count: 128
[ 2.244000] UBI: max/mean erase counter: 3873/2473, WL threshold: 4096, image sequence number: 1097212687
[ 2.254000] UBI: available PEBs: 462, total reserved PEBs: 562, PEBs reserved for bad PEB handling: 20
[ 2.264000] UBI: background thread "ubi_bgt0d" started, PID 298
[ 2.386000] devtmpfs: mounted
[ 2.431000] VFS: Mounted root (squashfs filesystem) readonly on device 31:3.
[ 2.469000] devtmpfs: mounted
[ 2.478000] Freeing unused kernel memory: 292K
[ 6.468000] devpts: called with bogus options
Starting syslogd: OK
Starting klogd: OK
Running sysctl: OK
/overlay is already mounted
[ 8.814000] random: nonblocking pool is initialized
insmod: ERROR: could not load module /lib/modules//vtss_core.ko: No such file or directory
Loaded 'proclikefs.ko'
Loaded 'merakiclick.ko'
[ 15.041000] click: starting router thread pid 461 (87ba3900)
[ 26.180000] elts_meraki: module license 'unspecified' taints kernel.
[ 26.187000] Disabling lock debugging due to kernel taint
Loaded 'elts_meraki.ko'
insmod: ERROR: could not load module /lib/modules//vc_click.ko: No such file or directory
[ 28.481000] unsatisfied requirement 'vc_click'
[ 28.487000] click-config/switch/io-real/vitesse.click:26: unknown element class 'ToVitesse'
[ 28.496000] click-config/switch/io-real/vitesse.click:31: unknown element class 'FromVitesse'
[ 28.506000] click-config/switch/io-real/vitesse.click:59: unknown element class 'VitesseController'
[ 28.834000] click-config/switch.template:74: While configuring 'switch_intf_table :: SwitchIntfTable':
[ 28.844000] SWITCH_HARDWARE: element type mismatch, expected SwitchHardwareIntf
[ 28.855000] click-config/switch.template:1045: While configuring 'switch_port_table :: SwitchPortTable':
[ 28.865000] SWITCH_HARDWARE_INTERFACE: element type mismatch, expected SwitchHardwareIntf
[ 28.897000] click-config/switch.template:58: While configuring 'l3_update_hardware :: UpdateHardwareTable':
[ 28.907000] SWITCH_HARDWARE_INTERFACE: element type mismatch, expected SwitchHardwareIntf
[ 28.925000] click-config/switch.template:383: While configuring 'switch_rpc_server :: SwitchRPCServer':
[ 28.935000] HW_INTF: element type mismatch, expected SwitchHardwareIntf
[ 28.945000] click-config/switch.template:566: While configuring 'CheckStackMaster@187 :: CheckStackMaster':
[ 28.955000] HW_INTF: element type mismatch, expected SwitchHardwareIntf
[ 28.964000] click-config/switch.template:602: While configuring 'CheckStackMaster@235 :: CheckStackMaster':
[ 28.974000] HW_INTF: element type mismatch, expected SwitchHardwareIntf
[ 28.982000] click-config/switch.template:633: While configuring 'switch_mrt :: MulticastRoutingTable':
[ 28.992000] SWITCH_HARDWARE_INTERFACE: element type mismatch, expected SwitchHardwareIntf
[ 29.003000] click-config/switch.template:655: While configuring 'ospf_hello_inspector :: OspfHelloInspector':
[ 29.013000] SWITCH_HARDWARE_INTERFACE: element type mismatch, expected SwitchHardwareIntf
[ 29.045000] click-config/switch.template:875: While configuring 'msstp_encap_inst :: MSSTPEncap':
[ 29.055000] HW_INTF: element type mismatch, expected SwitchHardwareIntf
[ 29.066000] click-config/switch.template:930: While configuring 'IntraStackResolver@527 :: IntraStackResolver':
[ 29.077000] HW_INTF: element type mismatch, expected SwitchHardwareIntf
[ 29.088000] click-config/switch.template:1072: While configuring 'igmp_table :: IGMPSnoopTable':
[ 29.097000] SWITCH_HARDWARE_INTERFACE: element type mismatch, expected SwitchHardwareIntf
[ 29.107000] click-config/switch.template:1093: While configuring 'mld_table :: MLDSnoopTable':
[ 29.116000] SWITCH_HARDWARE_INTERFACE: element type mismatch, expected SwitchHardwareIntf
[ 29.127000] click-config/switch.template:1125: While configuring 'msstp_decap :: MSSTPDecap':
[ 29.136000] HW_INTF: element type mismatch, expected SwitchHardwareIntf
[ 29.148000] click-config/switch.template:1187: While configuring 'CheckStackMaster@664 :: CheckStackMaster':
[ 29.159000] HW_INTF: element type mismatch, expected SwitchHardwareIntf
[ 29.166000] click-config/switch.template:1189: While configuring 'CheckStackMaster@669 :: CheckStackMaster':
[ 29.176000] HW_INTF: element type mismatch, expected SwitchHardwareIntf
[ 29.183000] click-config/switch.template:1199: While configuring 'CheckStackMaster@680 :: CheckStackMaster':
[ 29.193000] HW_INTF: element type mismatch, expected SwitchHardwareIntf
[ 29.201000] click-config/switch.template:1212: While configuring 'CheckStackMaster@693 :: CheckStackMaster':
[ 29.211000] HW_INTF: element type mismatch, expected SwitchHardwareIntf
[ 29.220000] click-config/switch.template:1238: While configuring 'CheckStackMaster@726 :: CheckStackMaster':
[ 29.230000] HW_INTF: element type mismatch, expected SwitchHardwareIntf
[ 29.242000] click-config/switch.template:1307: While configuring 'stp_check_master :: CheckStackMaster':
[ 29.252000] HW_INTF: element type mismatch, expected SwitchHardwareIntf
[ 29.260000] click-config/switch.template:1320: While configuring 'lacp_check_master :: CheckStackMaster':
[ 29.269000] HW_INTF: element type mismatch, expected SwitchHardwareIntf
[ 29.278000] click-config/switch.template:1409: While configuring 'udld :: UDLD':
[ 29.286000] HW_INTF: element type mismatch, expected SwitchHardwareIntf
[ 29.296000] click-config/switch.template:1459: While configuring 'CheckStackMaster@861 :: CheckStackMaster':
[ 29.306000] HW_INTF: element type mismatch, expected SwitchHardwareIntf
[ 29.394000] Router could not be initialized!
Default port count: 10
net.ipv4.ip_local_reserved_ports = 50000-50127
vc_click isn't loaded; aborting!
/etc/init.d/S11leds: line 8: can't create /click/sw0_ctrl/power_led_orange: nonexistent directory
/etc/init.d/S11leds: line 9: can't create /click/sw0_ctrl/power_led_green: nonexistent directory
Saving random seed: SKIP (read-only file system detected)
Starting network: OK
Starting chrony: Could not open configuration file /etc/chrony.conf : No such file or directory
FAIL
Starting dropbear sshd: OK
Starting lighttpd: OK

/ #
 

hmartin

Active Member
Sep 20, 2017
316
243
43
37
@lewru Board detection is not working for your MS320 and thus it is not loading the correct kernel modules. I sent you a PM with some commands to run, and then I'll fix the init script responsible for loading kernel modules and you should have networking.

Edit: Sigh, I fixed this already in October and forgot to update the link to the latest build in the installation instructions. It's been fixed, please reflash.
 
Last edited:

hmartin

Active Member
Sep 20, 2017
316
243
43
37
@networkdawg: The pinout of that chip clip is not visible on the Amazon page, but they're routing way more than 8 wires from the chip clip to the 2.54mm pins.

Here's one review:
Confusing to wire, the cable is done in a slightly non-standard way, but if you can figure it out, it works as you would expect it to.
Did you check the pinout from the chip clip to the header? It needs to be correct for a SOIC8 to be used with the ch341a_spi.

Here is the table from the installation GDoc to help you with the conversion between SOIC8 (used by the ch341a_spi) and SOIC16:
DescriptionSOIC16 PinSOIC8 Pin
GND104
/CS71
CLK166
DO82
DI155
VCC (3.3V)28

Only 8 pins are used in the ch341a_spi and only from the 25XX side:
ch341a_spi_25XX_pin1.jpg

Note pin 1 is marked with a red dot.
 
Last edited:
  • Like
Reactions: Seenc

Forums

New Member
Jul 9, 2020
2
0
1
Most SOIC16 clips are failing people due to horrible fit, wrong preconfigured pinouts, non-dupont standard exposed pin clips, or all of the above. Is there a more straightforward way that does NOT involve soldering? Do the square/surround style clamps work? Do any adapter boards fit 1:1 with the chips on board spacing to hot glue directly overhead, etc? Most people are going to buy the generic ch341a + extras kit from amazon or ebay with a few adapters and the soic8 clip. A non-direct nor end-to-end method is going to deflate available meraki stock as dust collectors. Would it be easier and cheaper just to buy the chip(2x) itself, flash it off-board, and put a hair dryer or hg to the existing chip?
 
Last edited:

hmartin

Active Member
Sep 20, 2017
316
243
43
37
Is there a more straightforward way that does NOT involve soldering?
No.

Do any adapter boards fit 1:1 with the chips on board spacing to hot glue directly overhead, etc?
Even console mod chips require some minimal soldering.

Would it be easier and cheaper just to buy the chip(2x) itself, flash it off-board, and put a hair dryer or hg to the existing chip?
Hair driers do not get hot enough to melt solder (to the relief of everyone who prefers their hair not melted to their scalp). Heat guns are extremely imprecise tools and you are very likely to permanently damage other components on the PCB while attempting to replace the SOIC16.

Quality soldering irons are not expensive, buy a Pinecil or a SH72.

A non-direct nor end-to-end method is going to deflate available meraki stock as dust collectors.
I am genuinely sorry this is so difficult for people who do not routinely work with hardware and have the equipment. The words I would use to describe Meraki's business practice of intentionally creating e-waste through hardware licensing are not fit to print.

I am working to provide FOSS firmware for these devices, so that they can see a second life after EoL/license expiry. Unfortunately, it is beyond my control how difficult it is to flash the firmware. I can provide a full dump of the Meraki firmware for you (or anyone else) to find a remote code execution, because that would make life easier for everyone.

Until then, flashing must be done via hardware means and soldering is the most reliable way to accomplish that.
 
  • Like
Reactions: mathiastro