Installing LEDE-Project on a Cisco Meraki MR24

RussellSenior purchased 9 of these total so far, 8 of them in a batch. The following is a description of how to get a LEDE Project image on them as of 2016-09-18, using Russell's method. The instructions here are mostly derived from here, but adapted and refined a little bit.

Description

The Meraki MR24 is a dual-band, single-ethernet router using a PPC cpu and two ath9k radios with 3x3 MIMO channels. It is intended for wall mounting and has a steel backing plate.

Instructions

  1. To open an MR24, first remove 6 screws from around the circumference of the plastic case. The screws are T-6 torx head screws, pretty small, don't lose them ;-). It is a little tricky to free the plastic covers, there are three catches on each long edge and two on each short edge. Starting near the ethernet connector on the long edge with a guitar pick or something similar eventually worked for me.
  2. Once the plastic is removed, you need to remove 4 phillips head screws holding the circuit board to the steel backing plate. Once freed, you will want to rest the board with the antenna down, but suspended in a way that the delicate antenna bits are not bent.
  3. So that the devices do not succeed in phoning home to Meraki World Headquarters, it is recommended to not connect ethernet to the device until you have managed to stop the device at a u-boot prompt.
  4. With the antenna down, and the ethernet jack facing you, the serial console (3.3V TTL) 4 pin header is located at J2 on the right edge about 2/3 of the way to the back, also labelled UART. Only the three closest pins should be connected (from nearest: BLACK (GND), GREEN (board's RX, cable's TX), WHITE (board's TX, cable's RX), NC. Do NOT connect the red wire (it is the 5V USB supply voltage, the NC pin will probably have 3.3V supplied by the board. Again DO NOT connect the red wire from the serial cable.
  5. Configure your serial console software. Russell uses GNU Screen from linux. Plug in your USB-serial 3.3V TTL console cable to your computer, and check "dmesg | tail" to see how the usb-serial device enumerated itself. If it's the only one, it will probably be ttyUSB0. In that case, you can start a console session with: screen /dev/ttyUSB0 115200. It is nice to keep a record of your doings, so turn on logging with: C-a H (if this is your only screen window, your log file will appear in screenlog.0.
  6. Attach a 12V power supply to the barrel jack or investigate PoE (Russell hasn't yet, it's believed to be standard IEEE 802.3at or whatever the modern gigabit compatible version is, but CHECK FIRST). Watch the device begin to boot.
  7. To stop at a u-boot prompt, start pressing the space bar very early. It only pauses for 1 second, but it will recognize a space hit a bit early. You should see something like this:
    U-Boot 2010.06-00036-g4e1a276 Meraki MR24 (May 11 2012 - 16:57:49)
    
    CPU:   AMCC PowerPC  UNKNOWN (PVR=12c41c82) at 800 MHz (PLB=200 OPB=100 EBC=100)
           Bootstrap Option H - Boot ROM Location I2C (Addr 0x52), booting from NAND
           32 kB I-Cache 32 kB D-Cache
    Board: MR24 - Meraki MR24 Cloud Managed Access Point
    ============================
    BoardID: 0 0
    POE-PWR_DET Status: 0
    ADAPTER_DET Status: 1
    Reset Button Status: 1
    ============================
    SDR0_PERCLK=0x40000300
    I2C:   ready
    DRAM:  128 MiB
    I2C write: failed 4
    NAND:  32 MiB
    Configure Max Payload 256B 
    PCIE0: successfully set as root-complex
            03  00  168c  0030  0280  ff
            02  02  111d  8039  0604  00
            04  00  168c  0030  0280  ff
            02  03  111d  8039  0604  00
            01  00  111d  8039  0604  00
    I2C read: failed 4
    I2C write: failed 4
    I2C read: failed 4
    I2C read: failed 4
    I2C write: failed 4
    Net:   ppc_4xx_eth0
    RESET is un-pushed
    
    Set serverpath and run meraki_netboot to netboot
    
    Hit any key to stop autoboot:  0 
  8. For your own reference, type the commands:
    help
    and
    printenv
    If you mess anything up, you can probably restore things by re-entering some of the u-boot environment variables.
  9. You will need two images, an initramfs image and a squashfs-sysupgrade image. You can either obtain these from Russell or perhaps the LEDE Project snapshots, or you can build them yourself. The initramfs image needs to be relatively small in order to fit within some size constraints. It is also used as a recovery image, so something small and simple is preferred. Russell built his vanilla images with the following starting LEDE .config file.
    CONFIG_TARGET_apm821xx=y
    CONFIG_TARGET_apm821xx_nand=y
    CONFIG_TARGET_apm821xx_nand_DEVICE_mr24=y
    CONFIG_DEVEL=y
    CONFIG_BUILD_LOG=y
    CONFIG_PACKAGE_ip=y
    CONFIG_PACKAGE_iwinfo=y
    CONFIG_PACKAGE_libiwinfo=y

    Also, you can obtain a files overlay to go with it (recommended) here. The tarball should be unpacked from the LEDE build tree at $TOPDIR, so that you get files like $TOPDIR/files/etc/uci-defaults/ptp.defaults. Once unpacked, you can look at the files and modify them as desired. For more details on how to build LEDE, see the appropriate documentation or ask Russell lots of questions.

  10. You will need a TFTP server to provide the initramfs image to the device. Russell uses the hpa-tftpd package on a Debian/Ubuntu box. Put your initramfs image, which is named "lede-apm821xx-nand-mr24-initramfs-kernel.bin" in the TFTP servers directory.
  11. From the u-boot prompt, do a test boot of the initramfs image. First, plug in the ethernet cable in such a way that the TFTP server will be reachable. Then apply the following temporary changes to the u-boot environment (they won't be saved until you give u-boot the command: "saveenv"). Substitute IP addresses that make sense for you. The "ipaddr" variable is for the MR24, "serverip" is for your TFTP server.
    setenv ipaddr 192.168.80.49
    setenv serverip 192.168.80.7
    setenv meraki_bootfile lede-apm821xx-nand-mr24-initramfs-kernel.bin
    You can do another printenv to make sure they were set properly. Now try booting your initramfs image like so:
    setenv netloadmethod tftpboot; setenv bootargs console=ttyS0,${baudrate} rootfstype=squashfs mtdoops.mtddev=oops; run meraki_load_net meraki_checkpart meraki_bootlinux
    or the whole thing as two lines:
    setenv ipaddr 192.168.80.49; setenv serverip 192.168.80.7; setenv meraki_bootfile lede-apm821xx-nand-mr24-initramfs-kernel.bin; setenv netloadmethod tftpboot; setenv bootargs console=ttyS0,${baudrate} rootfstype=squashfs mtdoops.mtddev=oops
    run meraki_load_net meraki_checkpart meraki_bootlinux
    You should see something like this:
    Waiting for PHY auto negotiation to complete.... done
    ENET Speed is 1000 Mbps - FULL duplex connection (EMAC0)
    Using ppc_4xx_eth0 device
    TFTP from server 192.168.80.7; our IP address is 192.168.80.49
    Filename 'lede-apm821xx-nand-mr24-initramfs-kernel.bin'.
    Load address: 0xc00000
    Loading: #################################################################
             #################################################################
             #################################################################
             #################################################################
             #################################################################
             ###
    done
    Bytes transferred = 4806656 (495800 hex)
    ## Booting kernel from Legacy Image at 00c10000 ...
       Image Name:   POWERPC LEDE Linux-4.4.21
       Created:      2016-09-17  19:43:29 UTC
       Image Type:   PowerPC Linux Kernel Image (lzma compressed)
       Data Size:    1555506 Bytes = 1.5 MiB
       Load Address: 00000000
       Entry Point:  00000000
       Verifying Checksum ... OK
    ## Loading init Ramdisk from Legacy Image at 00e00000 ...
       Image Name:   DEVICE_mr24 rootfs
       Created:      2016-09-17  19:43:29 UTC
       Image Type:   PowerPC Linux RAMDisk Image (gzip compressed)
       Data Size:    2675791 Bytes = 2.6 MiB
       Load Address: 00000000
       Entry Point:  00000000
       Verifying Checksum ... OK
    ## Flattened Device Tree blob at 00c00400
       Booting using the fdt blob at 0xc00400
       Uncompressing Kernel Image ... OK
       Loading Ramdisk to 078e1000, end 07b6e44f ... OK
    [    0.000000] Using PowerPC 44x Platform machine description
    [    0.000000] Linux version 4.4.21 (openwrt@hawg) (gcc version 5.4.0 (LEDE GCC 5.4.0 r1491+1) ) #0 Sat Sep 17 19:43:29 2016
    [    0.000000] Found initrd at 0xc78e1000:0xc7b6e44f
    [    0.000000] bootconsole [udbg0] enabled
    setup_arch: initmem
    arch: exit
    [    0.000000] Zone ranges:
    [    0.000000]   DMA      [mem 0x0000000000000000-0x0000000007ffffff]
    [    0.000000]   Normal   empty
    [    0.000000] Movable zone start for each node
    [    0.000000] Early memory node ranges
    [    0.000000]   node   0: [mem 0x0000000000000000-0x0000000007ffffff]
    [    0.000000] Initmem setup node 0 [mem 0x0000000000000000-0x0000000007ffffff]
    [    0.000000] MMU: Allocated 1088 bytes of context maps for 255 contexts
    [    0.000000] Built 1 zonelists in Zone order, mobility grouping on.  Total pages: 32512
    [    0.000000] Kernel command line: console=ttyS0,115200 rootfstype=squashfs mtdoops.mtddev=oops
    [    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] Sorting __ex_table...
    [    0.000000] Memory: 122512K/131072K available (3256K kernel code, 152K rwdata, 876K rodata, 176K init, 209K bss, 8560K reserved, 0K cma-reserved)
    [...]
  12. Press enter to get a shell prompt, then grab some images and write them off to a persistent storage somewhere to preserve the original state, should you ever want to compare or restore.
    for i in 0 1 2 ; do dd if=/dev/mtdblock$i of=/tmp/mtdblock$i.img ; done
    scp /tmp/mtdblock*.img <myusername>@<myhost>:<mypath>/mr24/stock01/
    rm /tmp/mtdblocks*.img
    ubinfo -a > /tmp/ubinfo.txt
    for i in 0 1 2 3 ; do dd if=/dev/ubi0_$i of=/tmp/ubi0_$i.img ; done
    scp /tmp/ubi* <myusername>@<myhost>:<mypath>/mr24/stock01/
  13. Now reboot to a u-boot prompt again (you might want to disconnect ethernet until you are sure you have a u-boot prompt). You may want to do a power cycle too, in order to clear the previous setenv's you have done. Make sure you've got your initramfs and squashfs-sysupgrade images ready. At the u-boot prompt, you are going to create some new environment variables and to repoint the regular boot command at the lede version:
    setenv lede_loadaddr c00000
    setenv lede_loadaddr_kernel c10000
    setenv lede_loadaddr_ramdisk e00000
    setenv lede_loadaddr_fdt c00400
    setenv lede_ubi ubi part ubi
    setenv lede_checkpart meraki checkpart \${lede_loadaddr}
    setenv lede_bootlinux bootm \${lede_loadaddr_kernel} \${lede_loadaddr_ramdisk} \${lede_loadaddr_fdt}
    setenv lede_load1 ubi read \${lede_loadaddr} kernel
    setenv lede_load2 ubi read \${lede_loadaddr} recovery
    setenv lede_bootkernel bootm \${lede_loadaddr_kernel} - \${lede_loadaddr_fdt}
    setenv lede_bootargs setenv bootargs console=ttyS0,\${baudrate} rootfstype=squashfs mtdoops.mtddev=oops
    setenv lede_boot run lede_ubi lede_bootargs\; run lede_load1 lede_checkpart lede_bootkernel\; run lede_load2 lede_checkpart lede_bootlinux
    setenv bootcmd run lede_boot
    setenv ipaddr 192.168.80.49
    setenv serverip 192.168.80.7
    setenv lede_bootfile lede-apm821xx-nand-mr24-initramfs-kernel.bin
    setenv tftpboot_lede run lede_bootargs\; tftpboot \${lede_loadaddr} \${serverpath}\${lede_bootfile}\; run lede_checkpart lede_bootlinux
    saveenv
    or, in fewer lines:
    setenv lede_loadaddr c00000; setenv lede_loadaddr_kernel c10000; setenv lede_loadaddr_ramdisk e00000; setenv lede_loadaddr_fdt c00400; setenv lede_ubi ubi part ubi
    setenv lede_checkpart meraki checkpart \${lede_loadaddr}; setenv lede_bootlinux bootm \${lede_loadaddr_kernel} \${lede_loadaddr_ramdisk} \${lede_loadaddr_fdt}
    setenv lede_load1 ubi read \${lede_loadaddr} kernel; setenv lede_load2 ubi read \${lede_loadaddr} recovery; setenv lede_bootkernel bootm \${lede_loadaddr_kernel} - \${lede_loadaddr_fdt}
    setenv lede_bootargs setenv bootargs console=ttyS0,\${baudrate} rootfstype=squashfs mtdoops.mtddev=oops; 
    setenv lede_boot run lede_ubi lede_bootargs\; run lede_load1 lede_checkpart lede_bootkernel\; run lede_load2 lede_checkpart lede_bootlinux; setenv bootcmd run lede_boot
    setenv ipaddr 192.168.80.49; setenv serverip 192.168.80.7; setenv lede_bootfile lede-apm821xx-nand-mr24-initramfs-kernel.bin; 
    setenv tftpboot_lede run lede_bootargs\; tftpboot \${lede_loadaddr} \${serverpath}\${lede_bootfile}\; run lede_checkpart lede_bootlinux
    saveenv
    Up to now, you have not changed anything on flash, but the change in "bootcmd" means you won't boot the meraki firmware anymore. We are about to change things substantially, so hold tight.
  14. Boot into the initramfs again:
    run tftpboot_lede
  15. At the lede shell prompt, carefully do the following:
    ubinfo /dev/ubi0 -N board-config
    Check to make sure that the Volume ID for board-config is 2. If so, first make a copy of the board-config partition to a file in /tmp/, then remove all the ubi volumes, then create a new one and write the board-config image back:
    dd if=/dev/ubi0_2 of=/tmp/board-config.img
    ubirmvol /dev/ubi0 -N part1
    ubirmvol /dev/ubi0 -N part2
    ubirmvol /dev/ubi0 -N storage
    ubirmvol /dev/ubi0 -N board-config
    ubimkvol /dev/ubi0 -s 24KiB -N board-config
    ubiupdatevol /dev/ubi0_0 /tmp/board-config.img
  16. Copy an initramfs image and the sysupgrade image to the MR24's /tmp/ directory (using scp, either pushing or pulling), e.g., from your build machine:
    scp bin/targets/apm821xx/nand/lede-apm821xx-nand-mr24-initramfs-kernel.bin root@<mr24-ipaddr>:/tmp/
    scp bin/targets/apm821xx/nand/lede-apm821xx-nand-mr24-squashfs-sysupgrade.tar root@<mr24-ipaddr>:/tmp/

    Note that the squashfs-sysupgrade image does not need to be the same vanilla build as the initramfs, and can be a full FooCab build. You can use the vanilla version as a proof of concept, and then sysupgrade from that to arbitrary other sysupgrade images. Obviously, this doesn't replace the "recovery" image, flashed in the next step, but that's okay.

  17. On the MR24, check the size of the initramfs image, then if less than 5MB, you can create a recovery ubi partition:
    ls -alh /tmp/lede-apm821xx-nand-mr24-initramfs-kernel.bin
    ubimkvol /dev/ubi0 -s 5MiB -N recovery
    ubiupdatevol /dev/ubi0_1 /tmp/lede-apm821xx-nand-mr24-initramfs-kernel.bin
  18. Now do a sysupgrade from the initramfs, using the squashfs image:
    sysupgrade -v -n /tmp/lede-apm821xx-nand-mr24-squashfs-sysupgrade.tar
    When it is done, it will reboot and hopefully boot back to a familiar looking LEDE boot, this time from flash. You might want to reboot a few times to make sure things went okay.

Tada! You may have succeeded!

Recovery

  1. In order to exploit the recovery partition, from u-boot, run the following command:
    run lede_bootargs lede_ubi; ubi read ${lede_loadaddr} recovery; run lede_checkpart lede_bootlinux
  2. Ideally, this is triggered from powering on with the reset button held (which spawns factory_boot). To set this up, at the u-boot prompt:
    setenv factory_boot run lede_bootargs lede_ubi\; ubi read \${lede_loadaddr} recovery\; run lede_checkpart lede_bootlinux
    saveenv


[CategoryHardware] [CategoryVendor]