Installing jfirmware PIC firmware on a 64-bit JunOS SRX320 from an unsupported 32-bit package

A working recipe for getting a jfirmware PIC update installed on a Juniper SRX320 running 64-bit JunOS 24.4+ when the only available jfirmware package is from an older 32-bit release (24.2).

Do this at your own risk. The official upgrade path doesn’t work for this combination, and what’s below is a workaround — useful, but unsupported.

Why the obvious paths fail

Two things stand in the way:

  1. request system software add refuses to install. JunOS treats the 24.2 jfirmware package as an OS downgrade against a 24.4 base and bails out, even though only the PIC firmware is involved.
  2. The package can’t be mounted directly. jfirmware ships in Juniper’s custom compressed-ISO container. Older JunOS shipped /sbin/mount_iso to handle it; 64-bit JunOS 24.4 doesn’t. You have to decompress to a raw ISO9660 image first.

The recipe below side-steps both: decompress on a workstation, copy the resulting ISO to the SRX, attach it with mdconfig, mount as cd9660, and symlink the firmware into place so request system firmware upgrade pic finds it.

The compressed-ISO format

For the curious — it’s a block-compressed container:

  • A header of big-endian u32 (offset, size) pairs.
  • Entry 0 holds (data_start_offset, uncompressed_size).
  • Entries 1..N are the compressed 64 KB blocks.
  • Blocks with size == 65536 are stored uncompressed (the compressor declined them).
  • A metadata trailer like fstype=iso9660, compressed, ... sits after the last block.

The Python snippet in step 2 walks the table, decompresses each block with raw deflate, and concatenates the result into a plain ISO9660 image.

Preparation (on a workstation, not the SRX)

1. Extract the inner firmware image from the signed package

tar -xzf jfirmware-srxsme-24.2R1.17-signed.tgz jfirmware-srxsme-24.2R1.6.tgz
tar -xzf jfirmware-srxsme-24.2R1.6.tgz packages/jfirmware-srxsme-24.2R1.6

2. Decompress the Juniper compressed ISO to a plain ISO9660 image

python3 -c "
import struct, zlib

with open('packages/jfirmware-srxsme-24.2R1.6', 'rb') as fin:
    fin.seek(0)
    n_blocks, uncompressed_size = struct.unpack('>II', fin.read(8))
    blocks = [struct.unpack('>II', fin.read(8)) for _ in range(n_blocks)]

    with open('jfirmware-srxsme-24.2R1.6.iso', 'wb') as fout:
        for offset, size in blocks:
            fin.seek(offset)
            data = fin.read(size)
            if size == 65536:
                fout.write(data)
            else:
                fout.write(zlib.decompress(data, -15))
"

3. Copy the ISO to the SRX

The output is around 478 MB. SCP it into a writable path on the SRX — for example /var/home/nprice/.

On the SRX (as root)

4. Attach the ISO as a memory disk

root@% mdconfig -a -t vnode -f /var/home/nprice/jfirmware-srxsme-24.2R1.6.iso

Note the device name returned (e.g. md47). The remaining steps assume md47; substitute whatever you got.

5. Mount the ISO

root@% mkdir -p /packages/mnt/jfirmware-srxsme-24.2R1.6
root@% mount -t cd9660 /dev/md47 /packages/mnt/jfirmware-srxsme-24.2R1.6

6. Create the package symlink

root@% ln -s /packages/mnt/jfirmware-srxsme-24.2R1.6/ /packages/mnt/jfirmware-srxsme

7. Create firmware symlinks so JunOS can find the files

root@% mkdir -p /usr/share/pfe/firmware
root@% ln -s /packages/mnt/jfirmware-srxsme/usr/share/pfe/firmware/* /usr/share/pfe/firmware/

8. Enter the CLI and confirm new firmware is visible

root@% cli
root> show system firmware

If the Available version column is populated, you’re good to upgrade. If not, re-check steps 6 and 7 — the symlinks must resolve to real files.

9. Run the upgrade

Adjust the slot numbers to match your device (the SRX320 has FPCs in slots 1 and 2):

root> request system firmware upgrade pic fpc-slot 1
root> request system firmware upgrade pic fpc-slot 2

Confirm with yes when prompted.

10. Watch the upgrade progress

root> show system firmware

Status moves through ERASINGFLASHINGUPGRADED SUCCESSFULLY. Don’t reboot the FPC until you see the success state.

11. Restart the FPCs to load the new firmware

root> restart fpc 1
root> restart fpc 2

Wait for them to come back up before declaring victory.

Clean up (optional)

root> exit
root@% rm /usr/share/pfe/firmware
root@% rm /packages/mnt/jfirmware-srxsme
root@% umount /packages/mnt/jfirmware-srxsme-24.2R1.6
root@% mdconfig -d -u 47

The mount point under /packages/mnt/jfirmware-srxsme-24.2R1.6 can stay or be removed; nothing else references it once the symlinks are gone.