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:
request system software addrefuses 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.- The package can’t be mounted directly. jfirmware ships in Juniper’s custom compressed-ISO container. Older JunOS shipped
/sbin/mount_isoto 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 == 65536are 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 ERASING → FLASHING → UPGRADED 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.