Skip to content

Instantly share code, notes, and snippets.

@maurice-w
Last active December 8, 2025 21:13
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)

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
@Emmegi2001
Copy link

cd /tmp (....ok)
dd if=/dev/mtd2 of=mtd2 (....ok)

tftp -v 10.10.1.2 -m binary -c put mdt2 (....not ok: invalid option -v )

@maurice-w
Copy link
Author

@Emmegi2001 Oh sorry, I seem to recall that the module uses busybox. The tftp command is a little different there.
tftp -l mtd2 -p 10.10.1.2 should work.

@Emmegi2001
Copy link

mtd2
ok, done!
So... I have another pmg3000-d20b but the mtd0, mtd2, mtd3, mtd4 and mtd5 partitions have been erased. How can I restore them via UART?

@maurice-w
Copy link
Author

@Emmegi2001 Thanks a lot for the image, but this is V1.00(ABVJ.0)b3s. The active firmware is most likely image B. Could you please try again with mtd3?

cd /tmp
dd if=/dev/mtd3 of=mtd3
tftp -l mtd3 -p 10.10.1.2

Without mtd0, I don't think the SFP can be unbricked via UART. mtd0 contains the bootloader, so it won't even boot and there's just nothing which answers on the UART.

@Emmegi2001
Copy link

Emmegi2001 commented Aug 16, 2025

mtd2
mtd3
screenshot Done (take two)

@maurice-w
Copy link
Author

@Emmegi2001 These are identical, both are V1.00(ABVJ.0)b3s. But according to the screenshot, mtd3 is indeed V2.50(ABVJ.1)b1f.
There probably was a mix-up at some point. Could you try again?

@Emmegi2001
Copy link

ok, no problem.

mtd2
mtd3

Done. (Take three)

@maurice-w
Copy link
Author

@Emmegi2001 Thanks a lot! I tested the image on my SFP module and added it to the gist.

@Emmegi2001
Copy link

Emmegi2001 commented Aug 17, 2025

Great! ;-)

@binlex-ar
Copy link

ok, no problem.

mtd2 mtd3

Done. (Take three)

Hello, could you please resend the mtd2/mtd3 V2.50(ABVJ.1)b1f versions? The links here are inactive. Thank you!

@maurice-w
Copy link
Author

@binlex-ar The links in the gist are working fine. As explained: Download link, change extension to .zip and extract.

@binlex-ar
Copy link

@maurice-w Sorry, I'm an idiot, it's all good!

@bentau
Copy link

bentau commented Sep 4, 2025

@maurice-w Thanks for providing those firmwares! Did you notice any difference with ipv6 support in these firmware versions?

@maurice-w
Copy link
Author

Hey @bentau, IPv6 works fine in all of them, >99% of my traffic is IPv6. GPON shouldn't really care about layer 3, it handles Ethernet frames regardless of their contents.

My ISP does use PPPoE though, so any potential bugs regarding plain IPv6-over-Ethernet would have gone unnoticed.

Or do you mean the management (web interface / ssh)? Unfortunately, that's IPv4-only in all versions.

@bentau
Copy link

bentau commented Sep 4, 2025

I noticed that this GPON module does not work with my provider with IPv6. I don't get any IPv6 IP with it. v4 just works.
However, the one that I bought from fs.com actually does work with IPv6 (same router and provider).

Also, https://hack-gpon.org/ont-zyxel-pmg3000-d20b/ says that someone also had problems with IPv6.

@maurice-w
Copy link
Author

@bentau Do you use PPPoE or plain IP over Ethernet?

A different SFP working with the same router and ISP might indeed indicate an issue with the Zyxel SFP. Have you tried all firmware versions?

@bentau
Copy link

bentau commented Sep 4, 2025

@maurice-w I think I use plain IP over Ethernet. At least I didn't have to configure PPPoE on my mikrotik router

I haven't tested the firmware versions yet. Since I have a working module, getting the Zyxel to work is low priority now.

@maurice-w
Copy link
Author

@bentau That makes sense. Since my module doesn't ever see "naked" IPv6 packets (everything is encapsulated in PPPoE), I wouldn't notice potential bugs with that.

@AyrtonRicardo
Copy link

Firmware links are down, anybody has a mirror?

@maurice-w
Copy link
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

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

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