Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Select an option

  • Save maurice-w/faeb60bf8201ce70391873bcb9059bc2 to your computer and use it in GitHub Desktop.

Select an option

Save maurice-w/faeb60bf8201ce70391873bcb9059bc2 to your computer and use it in GitHub Desktop.
Zyxel PMG3000-D20B firmware image files

Zyxel PMG3000-D20B firmware image files

The firmware of this GPON ONT SFP module can be updated using the web interface (Management | Update Software):

image

The web interface only accepts image files with a special header. These can be created by adding the header to a flash dump.

Firmware collection

.img unmodified mtd2 / mtd3 flash dump
.upf with header (can be installed using the web interface)

V1.00 is based on OpenWrt 12.09. Deutsche Telekom (Germany) seems to stick with this branch.

V1.00(ABVJ.0)b3s (2020-12-23)

V1.00(ABVJ.0)b3v (2021-05-08)

V1.00(ABVJ.1)b1e (2023-07-26) (no ssh)

V1.00(ABVJ.1)b1i (2026-02-06) (no ssh, known compatibility issues)

V2.50 is based on OpenWrt 14.07. Wind Tre (Italy) upgraded to this branch at the end of 2022.

V2.50(ABVJ.1)b1d (2023-04-21)

V2.50(ABVJ.1)b1f (2023-07-14)

Both branches are maintained separately, so a 1.00 image can have a later build date than a 2.50 image.

Please leave a comment if you have any other flash dumps.

Creating image files

Create flash dump of mtd2 or mtd3 (Image A / Image B):

dd if=/dev/mtd2 of=/tmp/mtd2

Download flash dump from SFP (e. g. using TFTP).

Download header file and add it to flash dump:

cat header mtd2 > firmware.upf

Copy software version string from flash dump to header:

dd if=firmware.upf of=firmware.upf bs=1 skip=632 seek=124 count=32 conv=notrunc

Get CRC32 of firmware.upf:

v=$(cat firmware.upf | gzip | tail -c 8 | head -c 4 | hexdump -e '1/4 "%08x"')

Convert CRC32 to binary and write it to header:

echo -e -n "\x${v:0:2}\x${v:2:2}\x${v:4:2}\x${v:6:2}" | dd of=firmware.upf bs=1 seek=104 conv=notrunc
View raw

(Sorry about that, but we can’t show files that are this big right now.)

View raw

(Sorry about that, but we can’t show files that are this big right now.)

View raw

(Sorry about that, but we can’t show files that are this big right now.)

View raw

(Sorry about that, but we can’t show files that are this big right now.)

View raw

(Sorry about that, but we can’t show files that are this big right now.)

View raw

(Sorry about that, but we can’t show files that are this big right now.)

@AyrtonRicardo
Copy link
Copy Markdown

Firmware links are down, anybody has a mirror?

@maurice-w
Copy link
Copy Markdown
Author

@AyrtonRicardo The links were never down, just a bit... special. But since you're the third person asking for assistance with the download, I've decided to change the way the binaries are embedded in the gist. Should be easier now.

@AyrtonRicardo
Copy link
Copy Markdown

Thank you very much for maintaining this open. I took the file from one of your comments, I honestly appreciate the dedication.

@github-tomster
Copy link
Copy Markdown

github-tomster commented Apr 21, 2026

@maurice-w
xvzf/zyxel-gpon-sfp#41
ssh not available on V1.00(ABVJ.1)b1i 😿

@maurice-w
Copy link
Copy Markdown
Author

@github-tomster
You mean V1.00(ABVJ.1)b1i doesn't have ssh? That's not surprising, given that they already removed it in V1.00(ABVJ.1)b1e.
If you want to provide an image of V1.00(ABVJ.1)b1i, you can install a version with ssh to the other partition, boot it and then create an image of the inactive partition. You always have access to both partitions (mtd2 / mtd3) from ssh.
Thanks!

@github-tomster
Copy link
Copy Markdown

@maurice-w
indeed no ssh available [i edited my comment].
so i guess it is not possible for me to
provide a dump. just the info about that new version.

@maurice-w
Copy link
Copy Markdown
Author

@github-tomster
The module has two firmware partitions, an active and an inactive one. Performing an upgrade / downgrade writes the new image to the inactive partition and then makes it active. So there are always two images installed and you can dump both of them, no matter which one is currently active.

Example:
V1.00(ABVJ.1)b1i is in mtd2 (Image A) and currently active. You then downgrade to V1.00(ABVJ.0)b3v using the web interface, which will write the image to mtd3 (Image B). After the reboot, mtd3 (Image B) is active and V1.00(ABVJ.0)b3v is running. But V1.00(ABVJ.1)b1i is still in mtd2 and can be dumped.
Of course it can be the other way around (V1.00(ABVJ.1)b1i in mtd3 and V1.00(ABVJ.0)b3v in mtd2), this you'll have to check.

omci
show me classid 7

@github-tomster
Copy link
Copy Markdown

@maurice-w
if it works i can provide the dump next week. 🤞

@github-tomster
Copy link
Copy Markdown

@maurice-w
let us know if this is the right data:
https://nowtransfer.de/ac7846389c90

@maurice-w
Copy link
Copy Markdown
Author

@github-tomster
Looks good, thanks a lot! I added it to the collection. Didn't test it yet though. I'm a bit worried I might lock myself out.

@maurice-w
Copy link
Copy Markdown
Author

@github-tomster
I updated my module and it works fine in a MikroTik hEX S (first generation).

@github-tomster
Copy link
Copy Markdown

@maurice-w
happy to see it was useful 🥳

you wrote you are using the 2.50 branch. so can you confirm these
have ssh and can be cross-flashed with the 1.00 ❓

@maurice-w
Copy link
Copy Markdown
Author

I was using V2.50(ABVJ.1)b1f, yes. This has SSH and worked just fine (Deutsche Telekom infrastructure / ISP Telefonica o2). Switching between V1.00 and V2.50 images works just like any other update.

I've now switched to V1.00(ABVJ.1)b1i and will probably keep using this. Works fine for me and I don't really need SSH (although it would be nice of course).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment