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 draws about 7.4 watts, 0.156 amps, at 48V PoE. The MR24 is intended for wall mounting and has a steel backing plate.
Instructions for factory_boot install
This method exploits the Meraki MR24 out-of-the-box uboot environment variables to enable a TFTP boot into a bootstrap OpenWrt image, from which the uboot environment can be modified, and the ubi volumes updated over an ssh session without the need to open the case, thus substantially speeding up the operation. This method requires a tailored TFTP server (I used a Buffalo WZR600DHP with atftpd installed), along with some customized blobs (three required: an kernel-initramfs.bin, a device tree dtb, and an initramfs blob which isn't actually used but needs to be present to satisfy u-boot). The bootstrap image is configured with sufficient ssh credentials to reach a machine on the network to save copies of the original flash, but otherwise trimmed down to just ethernet and enough tools to manipulated the u-boot environment and the ubi volumes. It also requires a modified device tree to allow the u-boot environment partitions to be written to.
The second version of MR24 firmware is a recovery kernel-initramfs.bin to be written to a recovery ubi volume.
A third version of the MR24 firmware is a regular OpenWrt build that boots from flash normally (i.e. without the reset button held). The second and third firmware images can be stored on the same machine that hosts the flash backups, so that the same ssh credentials can be used to fetch the images.
Setting up the TFTP server
Preparing the bootstrap firmware
Preparing the recovery firmware
Preparing the OpenWrt firmware
Installation steps
- Attach an ethernet cable from the TFTP server to the MR24 to be installed.
- With a straightened paper clip or similar device, press and hold the reset button.
- Plug in 12V power to the MR24 and continue holding the reset button for approximately 8-10 seconds.
- The MR24 should fetch the kernel, dtb and initramfs from the TFTP server and boot. If doing this for the first time, it is wise to disassemble the device and attach a serial console to enable intervention at the u-boot console, if needed. However, note that with the default u-boot environment, the serial console will not function after the tftp'd kernel boots.
- Examine the DHCP leases on the network where the MR24 was plugged in. The MR24 uses a preconfigured ipaddr while in u-boot and tftp'ing, but the booted operating system will used DHCP to request a lease. The DHCP leases will indicate which address it was allocated.
- Ssh to the indicated address:
# ssh root@${ipaddr}
No password is required at this stage. - Save backups of the flash using the backup-mtd script:
# backup-mtd
The script is as follows:macaddr=$(cat /sys/class/net/eth0/address | tr -d ':') user=grabber dest=192.168.80.181 ssh ${user}@${dest} mkdir mr24/$macaddr fw_printenv | sed 's/=/ /' > /tmp/ubootenv.txt scp /tmp/ubootenv.txt ${user}@${dest}:mr24/$macaddr/ for i in 0 1 2 3 4 ; do dd if=/dev/mtdblock$i of=/tmp/mtdblock$i.img bs=16k conv=noerror scp /tmp/mtdblock$i.img ${user}@${dest}:mr24/$macaddr/ rm /tmp/mtdblock$i.img done ubinfo -a > /tmp/ubinfo.txt scp /tmp/ubinfo.txt ${user}@${dest}:mr24/$macaddr/ for i in 0 1 2 3 ; do dd if=/dev/ubi0_$i of=/tmp/ubi0_$i.img bs=15872 scp /tmp/ubi0_$i.img ${user}@${dest}:mr24/$macaddr/ rm /tmp/ubi0_$i.img done
Check to make sure the results make sense. This is your only chance to preserve the original configuration, you may need this later down the road to reconstruct state. It is a REALLY GOOD IDEA to keep these copies and to make sure they are complete.
The u-boot environment partitions may be empty. If they are empty, u-boot is programmed to use a baked-in version. When a new variable is written from u-boot, the baked-in version, as modified by the new variable, is written into one of the two partitions along with a serial number that indicates the current active version. However, when trying to set the environment from OpenWrt, this baked-in version isn't normally available. An extracted version has been packaged with the bootstrap firmware to allow the meraki original environment to be combined with the openwrt-needed changes, like so:
cat /etc/meraki.ubootenv /etc/openwrt.ubootenv > /tmp/combined.ubootenv
Note that the order in significant, as openwrt.ubootenv overrides some variables. Look at combined.ubootenv to ensure it makes sense. Do not apply the prepared u-boot environment yet, because it refers to an object that is not yet in place. Once the new environment is applied, you will not be able to repeat the factory tftp procedure without a serial console.- Examine the ubi, it will look something like this:
# ubinfo -a UBI version: 1 Count of UBI devices: 1 UBI control device major/minor: 10:59 Present UBI devices: ubi0 ubi0 Volumes count: 4 Logical eraseblock size: 15872 bytes, 15.5 KiB Total amount of logical eraseblocks: 1952 (30982144 bytes, 29.5 MiB) Amount of available logical eraseblocks: 243 (3856896 bytes, 3.6 MiB) Maximum count of volumes 92 Count of bad physical eraseblocks: 0 Count of reserved physical eraseblocks: 40 Current maximum erase counter value: 2976 Minimum input/output unit size: 512 bytes Character device major/minor: 251:0 Present volumes: 0, 1, 2, 3 Volume ID: 0 (on ubi0) Type: dynamic Alignment: 1 Size: 567 LEBs (8999424 bytes, 8.5 MiB) State: OK Name: part1 Character device major/minor: 251:1 ----------------------------------- Volume ID: 1 (on ubi0) Type: dynamic Alignment: 1 Size: 567 LEBs (8999424 bytes, 8.5 MiB) State: OK Name: part2 Character device major/minor: 251:2 ----------------------------------- Volume ID: 2 (on ubi0) Type: dynamic Alignment: 1 Size: 2 LEBs (31744 bytes, 31.0 KiB) State: OK Name: board-config Character device major/minor: 251:3 ----------------------------------- Volume ID: 3 (on ubi0) Type: dynamic Alignment: 1 Size: 529 LEBs (8396288 bytes, 8.0 MiB) State: OK Name: storage Character device major/minor: 251:4
- Fetch the stage 2 and stage 3 images:
# scp ${user}@${dest}:mr24/images/\* /tmp/ openwrt-apm821xx-nand-meraki_mr24-initramfs-k 100% 4125KB 4.0MB/s 00:00 openwrt-apm821xx-nand-meraki_mr24-squashfs-sy 100% 8421KB 4.1MB/s 00:02
- Remove the meraki ubi volumes:
# ubirmvol /dev/ubi0 -N part1 # ubirmvol /dev/ubi0 -N part2 # ubirmvol /dev/ubi0 -N storage
and check the ubinfo -a:# ubinfo -a UBI version: 1 Count of UBI devices: 1 UBI control device major/minor: 10:59 Present UBI devices: ubi0 ubi0 Volumes count: 1 Logical eraseblock size: 15872 bytes, 15.5 KiB Total amount of logical eraseblocks: 1952 (30982144 bytes, 29.5 MiB) Amount of available logical eraseblocks: 1906 (30252032 bytes, 28.8 MiB) Maximum count of volumes 92 Count of bad physical eraseblocks: 0 Count of reserved physical eraseblocks: 40 Current maximum erase counter value: 2976 Minimum input/output unit size: 512 bytes Character device major/minor: 251:0 Present volumes: 2 Volume ID: 2 (on ubi0) Type: dynamic Alignment: 1 Size: 2 LEBs (31744 bytes, 31.0 KiB) State: OK Name: board-config Character device major/minor: 251:3
- Check the size of the recovery firmware:
wc -c /tmp/openwrt-apm821xx-nand-meraki_mr24-initramfs-kernel.bin 4223584 /tmp/openwrt-apm821xx-nand-meraki_mr24-initramfs-kernel.bin
- Create a ubi volume for the recovery firmware (it might be wise to allocate some slack space to allow future replacement with a potentially larger image, but I haven't here):
# ubimkvol /dev/ubi0 -s 4223584 -N recovery Volume ID 0, size 267 LEBs (4237824 bytes, 4.0 MiB), LEB size 15872 bytes (15.5 KiB), dynamic, name "recovery", alignment 1
- Noting the Volume ID, write the recovery firmware into the recovery volume:
# ubiupdatevol /dev/ubi0_0 /tmp/openwrt-apm821xx-nand-meraki_mr24-initramfs-kernel.bin
- Check the state of the u-boot environment:
# fw_printenv Warning: Bad CRC, using default environment bootcmd=bootp; setenv bootargs root=/dev/nfs nfsroot=${serverip}:${rootpath} ip=${ipaddr}:${serverip}:${gatewayip}:${netmask}:${hostname}::off; bootm bootdelay=5 baudrate=115200
If you see the "Bad CRC", then use the combined.ubootenv you prepared earlier, to write a full u-boot environment:# fw_setenv -s /tmp/combined.ubootenv Warning: Bad CRC, using default environment
and then check the result:# fw_printenv bootdelay=1 baudrate=115200 preboot=echo;echo Set serverpath and run meraki_netboot to netboot;echo nload=${netloadmethod} 600000 ${serverpath}u-boot-nand.bin nupdate=nand erase 0 0x00170000 ;nand write 600000 0 0x00100000 nupd=run nload nupdate kernel_addr=fc000000 fdt_addr=fc1e0000 ramdisk_addr=fc200000 pciconfighost=1 pcie_mode=RP:RP netdev=eth0 netloadmethod=dhcp ethact=ppc_4xx_eth0 ethaddr=00:01:73:01:23:41 boardtype=pcie mtd_addr_r=0x4000000 kernel_size=0x400000 fdt_size=0x25000 meraki_bootargs=setenv bootargs root=/dev/ram console=ttyS0,${baudrate} ubi.mtd=ubi MERAKI_BOARD=mr24 mtdoops.mtddev=oops ${extra_bootargs} meraki_bootfile=mr24.bin meraki_bootlinux=bootm ${meraki_loadaddr_kernel} ${meraki_loadaddr_ramdisk} ${meraki_loadaddr_fdt} meraki_boot=run meraki_ubi meraki_bootargs ; run meraki_load1 meraki_checkpart meraki_bootlinux; run meraki_load2 meraki_bootlinux meraki_checkpart=meraki checkpart ${meraki_loadaddr} meraki_netboot=run meraki_load_net meraki_bootargs meraki_bootlinux meraki_loadaddr=c00000 meraki_loadaddr_kernel=c10000 meraki_loadaddr_fdt=c00400 meraki_loadaddr_ramdisk=e00000 meraki_load1=ubi read ${meraki_loadaddr} part1 meraki_load2=ubi read ${meraki_loadaddr} part2 meraki_load_net=${netloadmethod} ${meraki_loadaddr} ${serverpath}${meraki_bootfile} meraki_ubi=ubi part ubi meraki_ubifile=mr24-ubi.bin meraki_ubi_loadfile=${netloadmethod} 600000 ${serverpath}${meraki_ubifile} meraki_ubi_update_nand=nand erase 0x00180000 0x01e80000 ; nand write 600000 0x00180000 ${filesize} meraki_ubi_update=run meraki_ubi_loadfile meraki_ubi_update_nand meraki_update_part1=run meraki_ubi meraki_load_net meraki_write1 meraki_update_part2=run meraki_ubi meraki_load_net meraki_write2 meraki_write1=ubi write ${meraki_loadaddr} part1 ${filesize} meraki_write2=ubi write ${meraki_loadaddr} part2 ${filesize} mtdids=nand0=nand0 mtdparts=mtdparts=nand0:0x00170000@0(firmware),0x00010000@0x00170000(panic),0x01e80000@0x00180000(ubi) ipaddr=192.168.1.1 serverip=192.168.1.101 gatewayip=192.168.1.1 netmask=255.255.255.0 factory_cmdline=setenv bootargs root=/dev/ram ramdisk_size=${factory_ramdisk_size} rw ip=${ipaddr}:${serverip}:${gatewayip}:${netmask}:${hostname}:${netdev}:off panic=1 console=ttyS1,${baudrate} factory_ramdisk_file=uRamdisk factory_bootfile=uImage factory_fdt_file=bluestone.dtb factory_kernel_addr_r=0x600000 factory_fdt_addr_r=0xa00000 factory_mtd_addr_r=0x4000000 factory_ramdisk_size=0x200000 ver=U-Boot 2010.06-00036-g4e1a276 Meraki MR24 (May 11 2012 - 16:57:49) openwrt_load=ubi read ${meraki_loadaddr} kernel openwrt_recovery=ubi read ${meraki_loadaddr} recovery;bootm ${meraki_loadaddr} openwrt_bootkernel=bootm ${meraki_loadaddr_kernel} - ${meraki_loadaddr_fdt} openwrt_bootargs=setenv bootargs console=ttyS0,${baudrate} rootfstype=squashfs mtdoops.mtddev=oops openwrt_boot=run meraki_ubi openwrt_bootargs;run openwrt_load meraki_checkpart openwrt_bootkernel;run openwrt_recovery openwrt_bootfile=openwrt-apm821xx-nand-meraki_mr24-initramfs-kernel.bin openwrt_tftp=tftpboot ${meraki_loadaddr} ${openwrt_bootfile};run openwrt_bootargs;bootm ${fileaddr} bootcmd=run openwrt_boot factory_boot_orig=tftp ${factory_kernel_addr_r} ${factory_bootfile};tftp ${factory_fdt_addr_r} ${factory_fdt_file};tftp ${factory_mtd_addr_r} ${factory_ramdisk_file};run factory_cmdline;bootm ${factory_kernel_addr_r} ${factory_mtd_addr_r} ${factory_fdt_addr_r} factory_boot=run meraki_ubi;run openwrt_bootargs;run openwrt_recovery
Use sysupgrade to install the normal OpenWrt firmware:
# sysupgrade -v -n /tmp/openwrt-apm821xx-nand-meraki_mr24-squashfs-sysupgrade.bin
- The MR24 will install the firmware and reboot. Look for dhcp leases again and try ssh'ing into the device to confirm success. Try a "factory_boot" with the reset button pressed at power-on to confirm the recovery firmware works as well.
- If something went wrong and you can't get access to the device, you will need to open the device to get access to the u-boot prompt. Recovery should be possible from there, though that is left as an exercise for the reader. Hopefully, enough artifacts have been collected to recover. If the u-boot environment is lost or hopelessly mangled, you might be able to erase the blocks where the u-boot environment usually lives to recover (note the address ranges, from dmesg):
[ 1.493402] nand: device found, Manufacturer ID: 0xad, Chip ID: 0x75 [ 1.602330] 0x000000000000-0x000000150000 : "u-boot" [ 1.603070] 0x000000150000-0x000000160000 : "u-boot-env" [ 1.603622] 0x000000160000-0x000000170000 : "u-boot-env-redundant" [ 1.604132] 0x000000170000-0x000000180000 : "oops" [ 1.604680] 0x000000180000-0x000002000000 : "ubi"
DO NOT ERASE THE WRONG THINGS.
Instructions for serial console install
WARNING: Currently broken due to a change in the initramfs image construction ... see the OpenWrt wiki page for Meraki MR24 for updated instructions ... will come back and fix this later
- 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.
- 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.
- 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.
- 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.
- 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.
- 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.
- 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
- For your own reference, type the commands:
help
andprintenv
If you mess anything up, you can probably restore things by re-entering some of the u-boot environment variables. - 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_meraki_mr24=y CONFIG_DEVEL=y CONFIG_BUILD_LOG=y # CONFIG_PACKAGE_kmod-lib-crc-ccitt is not set # CONFIG_PACKAGE_kmod-ppp is not set # CONFIG_PACKAGE_ppp is not set
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.
- 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.
- 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 openwrt-apm821xx-nand-meraki_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 openwrt-apm821xx-nand-meraki_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 'openwrt-apm821xx-nand-meraki_mr24-initramfs-kernel.bin'. Load address: 0xc00000 Loading: ################################################################# ################################################################# ################################################################# ################################################################# ####################################################### done Bytes transferred = 4613120 (466400 hex) ## Booting kernel from Legacy Image at 00c10000 ... Image Name: POWERPC OpenWrt Linux-4.14.20 Created: 2018-02-22 22:40:16 UTC Image Type: PowerPC Linux Kernel Image (lzma compressed) Data Size: 1751563 Bytes = 1.7 MiB Load Address: 00000000 Entry Point: 00000000 Verifying Checksum ... OK ## Loading init Ramdisk from Legacy Image at 00e00000 ... Image Name: DEVICE_meraki_mr24 rootfs Created: 2018-02-22 22:40:16 UTC Image Type: PowerPC Linux RAMDisk Image (gzip compressed) Data Size: 2484765 Bytes = 2.4 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 07910000, end 07b6ea1d ... OK [ 0.000000] Linux version 4.14.20 (openwrt@hawg) (gcc version 5.5.0 (OpenWrt GCC 5.5.0 r6156-6873cf4f63)) #0 Thu Feb 22 22:40:16 2018 [ 0.000000] Found initrd at 0xc7910000:0xc7b6ea1d [ 0.000000] Using PowerPC 44x Platform machine description [ 0.000000] bootconsole [udbg0] enabled [ 0.000000] ----------------------------------------------------- [ 0.000000] phys_mem_size = 0x8000000 [ 0.000000] dcache_bsize = 0x20 [ 0.000000] icache_bsize = 0x20 [ 0.000000] cpu_features = 0x0000000010100040 [ 0.000000] possible = 0x0000000030100040 [ 0.000000] always = 0x0000000000100000 [ 0.000000] cpu_user_features = 0x8c008000 0x00000000 [ 0.000000] mmu_features = 0x00000008 [ 0.000000] ----------------------------------------------------- [ 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, 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] Memory: 122080K/131072K available (3708K kernel code, 192K rwdata, 976K rodata, 176K init, 234K bss, 8992K reserved, 0K cma-reserved) [...]
- 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/mtdblock*.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/
- 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 openwrt-apm821xx-nand-meraki_mr24-initramfs-kernel.bin setenv tftpboot_lede run lede_bootargs\; tftpboot \${lede_loadaddr} \${serverpath}\${lede_bootfile}\; run lede_checkpart lede_bootlinux setenv factory_boot run lede_bootargs lede_ubi\; ubi read \${lede_loadaddr} recovery\; 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 openwrt-apm821xx-nand-meraki_mr24-initramfs-kernel.bin; setenv tftpboot_lede run lede_bootargs\; tftpboot \${lede_loadaddr} \${serverpath}\${lede_bootfile}\; run lede_checkpart lede_bootlinux setenv factory_boot run lede_bootargs lede_ubi\; ubi read \${lede_loadaddr} recovery\; 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. - Boot into the initramfs again:
run tftpboot_lede
- 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
- 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/openwrt-apm821xx-nand-meraki_mr24-initramfs-kernel.bin root@<mr24-ipaddr>:/tmp/ scp bin/targets/apm821xx/nand/openwrt-apm821xx-nand-meraki_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.
- 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/openwrt-apm821xx-nand-meraki_mr24-initramfs-kernel.bin ubimkvol /dev/ubi0 -s 5MiB -N recovery ubiupdatevol /dev/ubi0_1 /tmp/openwrt-apm821xx-nand-meraki_mr24-initramfs-kernel.bin
- Now do a sysupgrade from the initramfs, using the squashfs image:
sysupgrade -v -n /tmp/openwrt-apm821xx-nand-meraki_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
- 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
- Or, just hold the reset button for a few seconds while powering on