Flashing a Meraki Mini

Flashing the Meraki Mini with NetBSD

NOTE: This process will clobber the load of Linux on this unit. I have not been able to successfully save the original image, but that was probably largely due to my own pilot error -- it turns out that Linux uses the entire flash memory.

First, you must have an image compiled. Redboot prefers to load srecords, and the default kernel builds an srecord file.

% ./build.sh -m evbmips-eb kernel=MERAKI

We're going to use HTTP to load the files. I just put the resulting netbsd.srec file into the root htdocs on my server. You could probably put it somewhere else too.

% cp sys/arch/evbmips/compile/obj/MERAKI/netbsd.srec \
                /var/apache/htdocs

Next we need to connect to the Mini via a serial line. I set up a line called "usb" in /etc/remote, so that I can tip in like this:

% tip -115200 usb
connected

However you connect, its 115200 8N1. Once you power up the unit, you'll see something like this:

        Ethernet eth0: MAC address 00:18:0a:01:06:d1
        IP: 192.168.84.1/255.255.255.0, Gateway: 0.0.0.0
        Default server: 192.168.84.9

        RedBoot(tm) bootstrap and debug environment [ROMRAM]
        Release, version V1.04 - built 12:24:00, Apr 17 2006

        Copyright (C) 2000, 2001, 2002, 2003, 2004 Red Hat, Inc.

        Board: Meraki Mini 
        RAM: 0x80000000-0x82000000, [0x8003d110-0x80fe1000] available
        FLASH: 0xa8000000 - 0xa87e0000, 128 blocks of 0x00010000 bytes each.
        == Executing boot script in 2.000 seconds - enter ^C to abort

Quickly press Control-C to interrupt the boot. Run "fconfig" to update the configuration data flash.

        RedBoot> fconfig

Now it will prompt you for all the flash parameters. You might want to record the old parameters in case you want to restore them. I didn't bother.

The following is what I entered, I have the Mini configured as 192.168.251.93 and I have a HTTP server providing the srecord image on 192.168.251.21. It is possible that BOOTP could be used too, but I've not tested it. Redboot isn't particularly robust.

        Run script at boot: false
        Use BOOTP for network configuration: false
        Gateway IP address: 192.168.251.1
        Local IP address: 192.168.251.93
        Local IP address mask: 255.255.255.0
        Default server IP address: 192.168.251.21
        Console baud rate: 115200
        GDB connection port: 9000
        Force console for special debug messages: false
        Network debug at boot time: false
        Update RedBoot non-volatile configuration - continue (y/n)? y
        ... Erase from 0xa87d0000-0xa87e0000: .
        ... Program from 0x80ff0000-0x81000000 at 0xa87d0000: .

Next we reset the board, so the new parameters will take effect.

        RedBoot> reset

Wait a short bit (~2 secs or less) for the unit to reboot. It will not autoboot this time, instead going right to the prom property.

        Ethernet eth0: MAC address 00:18:0a:01:06:d1
        IP: 192.168.251.93/255.255.255.0, Gateway: 192.168.251.1
        Default server: 192.168.251.21

        RedBoot(tm) bootstrap and debug environment [ROMRAM]
        Release, version V1.04 - built 12:24:00, Apr 17 2006

        Copyright (C) 2000, 2001, 2002, 2003, 2004 Red Hat, Inc.

        Board: Meraki Mini 
        RAM: 0x80000000-0x82000000, [0x8003d110-0x80fe1000] available
        FLASH: 0xa8000000 - 0xa87e0000, 128 blocks of 0x00010000 bytes each.
        RedBoot> 

Now we load our netbsd.srec file. The following assumes the path to it on your HTTP server is /netbsd.srec. Adjust accordingly if you need to.

        RedBoot> load -m http /netbsd.srec
        Entry point: 0x80041000, address range: 0x80041000-0x80202350

At this point, if you just type "go", the NetBSD kernel you loaded will boot. This is the safest way to run NetBSD on the Meraki, becuase it never disrupts flash.

                        ===========
                        | WARNING |
                        ===========

        Proceeding from this point will erase the flash on your unit,
        and might leave it unusable.  Proceed at your own risk.

If you're still here, you must want to write NetBSD to flash. It is instructive to look at what is already in flash:

        RedBoot> fis list
        Name              FLASH addr  Mem addr    Length      Entry point
        RedBoot           0xA8000000  0xA8000000  0x00030000  0x00000000
        stage2            0xA8030000  0x80100000  0x00020000  0x80100000
        FIS directory     0xA87D0000  0xA87D0000  0x0000F000  0x00000000
        RedBoot config    0xA87DF000  0xA87DF000  0x00001000  0x00000000

Note that the flash starts at 0xA8000000. Allocation is done in flash sector sizes of 64K at a time. (I.e. except for the RedBoot config, all flash addresses should end in 0000 when displayed in hex.)

Unfortunately, the Linux code doesn't properly allocate everything in RedBoot. It turns out that stage2 is the Linux bootloader. There is a JFFS2 image located at 0xa8050000 thru 0xa8150000. The Linux kernel is located at 0xa8150000 through 0xa8490000. I mistakenly believed the data between 0xa849000 and 0xa87d0000 to be free. But I was wrong. Pretty much the whole flash is used.

I have not tested this theory, but it should be possible to read the flash data that we are going to overwrite, and save it in a file. Then in theory we could restore it. I only had the one unit, and I neglected to perform this step. Doh!

Anyway our kernels are always under 2MB, so we allocate based on that. (If you put an mfs in your kernel, it will be bigger, and you might need to change some parameters appropriately. I recommend leaving the first 320K of flash alone. You _must_ leave the first 192K alone, because it is used by RedBoot, and the 128K after that is useful if you ever want to restore Linux. I'm not sure if the Meraki Linux code drop includes the source for this bit.)

Recall our kernel load from above (if you do it again, its harmless):

        RedBoot> load -m http /netbsd.srec
        Entry point: 0x80041000, address range: 0x80041000-0x80202350

So, lets write it to flash. The fis create command below should all be typed on one line, but to facilitate display, I've broken it up and used a backslash "\" to indicate that the data should continue unbroken. Don't type the backslash.

The results look like this (it will take a while to do this, maybe a couple of minutes, the SPI flash is not fast):

        RedBoot> fis create -b 0x80041000 -l 0x200000 -f 0xa8490000 \
                -e 0x80041000 -r 0x80041000 netbsd
        ... Erase from 0xa8490000-0xa8690000: ................................
        ... Program from 0x80041000-0x80241000 at 0xa8490000: ................................
        ... Erase from 0xa87d0000-0xa87e0000: .
        ... Program from 0x80ff0000-0x81000000 at 0xa87d0000: .
        RedBoot> 

Notice that it did two erases/programs. That's because we also updated the RedBoot directory in upper flash. In case you were wondering:
  -b indicates the source address to copy from
  -l indicates the image length (2 MB)
  -f indicates the destination flash address
  -e indicates the entry address when the image is loaded
  -r indicates the image load address when the image is loaded
  netbsd is the image name (you could name it something else!)

If you change the flash destination address and length, you can store a larger kernel. I recommend never starting your flash address lower than 0xa8150000 and you must not let the image extend beyond 0xa87d0000.

Here's the image listing in flash:

        RedBoot> fis list
        Name              FLASH addr  Mem addr    Length      Entry point
        RedBoot           0xA8000000  0xA8000000  0x00030000  0x00000000
        stage2            0xA8030000  0x80100000  0x00020000  0x80100000
        netbsd            0xA8490000  0x80041000  0x00200000  0x80041000
        FIS directory     0xA87D0000  0xA87D0000  0x0000F000  0x00000000
        RedBoot config    0xA87DF000  0xA87DF000  0x00001000  0x00000000

Lets reset and make sure that we can use it.

        RedBoot> reset
        Ethernet eth0: MAC address 00:18:0a:01:06:d1
        IP: 192.168.251.93/255.255.255.0, Gateway: 192.168.251.1
        Default server: 192.168.251.21

        RedBoot(tm) bootstrap and debug environment [ROMRAM]
        Release, version V1.04 - built 12:24:00, Apr 17 2006

        Copyright (C) 2000, 2001, 2002, 2003, 2004 Red Hat, Inc.

        Board: Meraki Mini 
        RAM: 0x80000000-0x82000000, [0x8003d110-0x80fe1000] available
        FLASH: 0xa8000000 - 0xa87e0000, 128 blocks of 0x00010000 bytes each.
        RedBoot> 

Now lets try loading the NetBSD image from flash:

RedBoot> fis load netbsd

It will take a few seconds to load the image from flash. Now lets boot!

RedBoot> go


[ netbsd boots... dmesg begins...
MIPS32/64 params: cpu arch: 32
...

That's it. After this, the rest is just normal NetBSD. If you want to set this up automatically, you can setup an automatic boot script using fconfig. The commands you want to setup in the script are just:

fis load netbsd
go

Enjoy.

candlerb
Submitted by candlerb on Tue, 2007-01-09 04:29.

There is a more detailed analysis of the Meraki Mini's flash layout at http://wiki.openwrt.org/OpenWrtDocs/Hardware/Meraki/Mini

In particular:
* 0xa8050000 to 0xa8150000 is indeed JFFS2 (the Mini mounts it on /storage)
* 0xa8150000 to 0xa8490000 is the kernel
* 0xa8490000 to 0xa87d0000 is an identical copy of the kernel

These partitions don't appear in the FIS map, because Meraki have hardcoded their locations into the stage2 bootloader and the kernel itself.

The kernel includes a ramdisk image which forms the root filesystem.

The two copies are there so that the Mini is not "bricked" if you happen to unplug the power while a flash upgrade is taking place. The stage2 boot loader checks the CRC on image 1, and if it is bad, boots from image 2 instead. It also has an LZMA decompressor.

The source code for the stage2 boot loader *is* included in the Meraki source release at http://www.meraki.net/linux/openwrt-meraki.tar.gz in subdirectory openwrt-meraki/base/stage2/

The OpenWrt page linked above also gives instructions on backing up and restoring the firmware, and also how to get a RedBoot> prompt without a serial cable.

As for running NetBSD, I'd like to give it a try. The above instructions don't say what to do about a root filesystem, apart from a mention that it's possible to use mfs. Did you use an NFS root? Does NetBSD have any usable support for JFFS2? The only postings I can find on the web suggest not.

Regards, Brian.