Repository navigation
problems with Winbond W25Q256JV as QSPI flash #28
Description
Activity
Maybe someone has the same W25Q256JV, bought it from the same shop, and can confirm or not confirm the problems I'm seeing?
Same Libresdr from hamgeek here. Working mainly with sd card for now. Next step of https://github.com/F5OEO/tezuka_fw is able to boot from flash (did'nt try it).
As SPI flash should be blank right now, how to test the issue of 3bytes adressing from linux booted from sd? Maybe dd on mtdblock ?The first indication would be the kernel message that I see on
dmesgwhere it says "failed to read ear reg". If you also have this then my guess is that you will have the same issues.Using dd on the mtdblock device should be one way to test, yes! Just mind the partitioning that is described in the device tree (or in
/proc/mtd). Up to the 16 MiB boundary (somewhere in mtdblock3) all should be OK, and writing beyond that would probably overwrite parts of the first 16 MiB.
edit: better useflashcpon/dev/mtdXOr maybe you want to test booting from SPI. Is the MSD Daemon thing working with tezuka_fw? This feature where you connect a PC to the "OTG" USB port and a mass storage device appears on your PC? Then you could just copy a "boot.frm" to it, unmount the USB device, and it should automatically do the flashing and reboot.
Otherwise you could copy "boot.bin" and "u-boot-env.bin" (from the "build" folder, or extracted from "boot.frm"!) to your SD card, boot, mount the SD card, and do manually what
update.shwould do in the background:
edit: better useflashcpon/dev/mtdXdd if=/opt/boot.bin of=/dev/mtdblock0 bs=64k && dd if=/opt/u-boot-env.bin of=/dev/mtdblock1 bs=64kNow you should get the U-Boot console when you reboot without the SD card. And when you reboot to SD and flash the firmware image (copy firmware.frm to the MSD or dd the FIT image (.itb file) to mtdblock3) it may or may not be broken again :D
See the document about the flash.
I have build the https://github.com/F5OEO/tezuka_fw firmware as well running from SD card ok but updating the flash via copying the boot.frm and pluto.frm did not work, The flash must be erased first to write again!
Hope this give some additional info
Johan PA3GSBHi Johan, thanks for sharing your findings!
If I interpret your document correctly then your solution was not fitting the QSPI contents into the lower 16 MiB of the chip, but changing something about how the software talks to the chip? In your document you write "The third and last step is modifying the linux driver or updating the linux image".
Do you also get
spi-nor spi1.0: failed to read ear regin your Linux kernel log?I tried again, following the correct commands from your document with
flashcp <file> /dev/mtdXinstead ofdd if=<file> of=/dev/mtdblockX.Doing this with a build of the hz12opensource firmware fails:
# uname -a Linux libre 5.15.0-175882-ge14e351533f9-dirty #1 SMP PREEMPT Wed Jan 8 17:33:33 CET 2025 armv7l GNU/Linux # flashcp -v libre.fit /dev/mtd3 Erasing blocks: 248/248 (100%) Writing data: 15818k/15818k (100%) Verifying data: 10k/15818k (0%)File does not seem to match flash data. First mismatch at 0x00000000-0x00002800 # mtd_debug read /dev/mtd0 0x0 0x100000 /tmp/boot.readback.bin Copied 1048576 bytes from address 0x00000000 in flash to /tmp/boot.readback.bin # cmp boot.bin /tmp/boot.readback.bin boot.bin /tmp/boot.readback.bin differ: char 1, line 1But when I boot tezuka_fw instead then it works and I can boot from QSPI:
# uname -a Linux libresdr 6.1.0 #1 SMP PREEMPT Thu Jan 16 17:54:03 UTC 2025 armv7l GNU/Linux # flashcp -v libre.fit /dev/mtd3 Erasing blocks: 248/248 (100%) Writing data: 15818k/15818k (100%) Verifying data: 15818k/15818k (100%) # mtd_debug read /dev/mtd0 0x0 0x100000 /tmp/boot.readback.bin Copied 1048576 bytes from address 0x00000000 in flash to /tmp/boot.readback.bin # cmp boot.bin /tmp/boot.readback.bin cmp: EOF on boot.binAll my previous attempts were with the hz12opensource firmware, so I guess tezuka's kernel fixed it for me.
Using dd on the mtdblock device should be one way to test, yes! Just mind the partitioning that is described in the device tree (or in
/proc/mtd). Up to the 16 MiB boundary (somewhere in mtdblock3) all should be OK, and writing beyond that would probably overwrite parts of the first 16 MiB.[..]
Otherwise you could copy "BOOT.bin" and "u-boot-env.bin" to your SD card, boot, mount the SD card, and do manually what
update.shwould do in the background:dd if=/opt/boot.bin of=/dev/mtdblock0 bs=64k && dd if=/opt/u-boot-env.bin of=/dev/mtdblock1 bs=64kThis was wrong, sorry, just using
ddon the block device does not erase the flash cells first, likeflashcpdoes.Also BOOT.bin (for the SD card) doesn't have the same content as boot.frm (for the QSPI partitions 0 and 1).
boot.frm has only the FSBL and U-Boot + the default uEnv.
BOOT.bin also includes the FPGA bitstream.
Or something like that. I hope I didn't confuse anyone.Indeed using a new linux version does do the right writing to the flash. Indeed with the version 5 linux version the addressing above the 16MB is not working.
In the .gitmodules i changed the linux kernel link:
path = linux
url = https://github.com/maia-sdr/linux.git
branch = maia-sdrWhich is the same as tezuka_fw is using.
Hope this helps.
Reacted by Michael Büchler- added a commit that references this issue
on Oct 9, 2026
This month I received a ZynqSDR/LibreSDR from aliexpress seller "HamGeek Store". It came with some minor differences from the zynqsdr_rev5.pdf that I found here (this was helpful, thanks!!).
Actually the only real difference I can see is that the AD7291 ADC for voltage monitoring is not populated, plus some related silkscreen changes:
This seems to close the circle..
I built the firmware from this repo, put it on an SD card, and this works. Now I'm trying to solve the various problems, and I'm not sure where to put my findings. Let me start with the QSPI flash.
The W25Q256JV seems like a wrong choice: it is not officially supported by AMD/Xilinx and Vivado cannot program it over JTAG.
With this repo the device tree for U-Boot has a
compatiblestatement for then25q256atype of SPI memory; alsomicron,m25p80is listed, not sure how it works. But I guess other LibreSDRs are shipped with non-Winbond SPI flash?When U-Boot is flashed to the QSPI with this device tree (as part of
boot.dfuorboot.frm), U-Boot will fail to load (no output on /dev/ttyUSB2). When thecompatiblestatement of theqspinode in 'u-boot-xlnx/arch/arm/dts/zynq-libre-sdr.dts' is changed tow25q256(see here), U-Boot works.But now when I also flash the libre.frm, it is dead again. I think this is because it writes above the first 16 MiB of the chip, where 3 byte addressing is no longer enough and 4 bytes per address are needed. This mode is not supported by the Zynq-7000 SPI controller, so the SPI memory has to be put into a 3 byte addressing mode where the controller writes the 4th address byte into a dedicated "Extended Address Register". Some context here. The Linux kernel driver (spi-nor) handles this, but it runs into a problem (from dmesg):
It can be used, but I suspect that the 3 byte addressing with the EAR is broken here, and when Linux writes to addresses >16MiB, it actually starts at 0 again, overwriting the boot code.
I should do a full write and readback to confirm this, or do a low-level analysis with SPI transactions, but I'm okay with just using the SD card instead.. maybe someone else will run into this and won't waste too much time.
speculation: