Glasgow Interface Explorer

The Glasgow Interface Explorer is self-described as a tool for exploring digital interfaces, aimed at embedded developers, reverse engineers, digital archivists, electronics hobbyists, and everyone else who wants to communicate to a wide selection of digital devices with high reliability and minimum hassle.

The device is capable of communicating with standard protocols including UART, SPI, and I2C, as well as reading and writing memory chips, programming microcontrollers, and much, much more. The Glasgow stands out amongst other hardware hacking tools because it uses reconfigurable logic, via an iCE40 FPGA, to communicate with devices - you can program the Glasgow on the fly to adapt to custom or obsolete interfaces.

It’s a seriously cool piece of hardware which you can pre-order on crowdsupply.


SPI Flash Memory

SPI is a synchronous serial communication interface. It’s used for communicating between a single controller (in this case a Glasgow) and one or more peripheral devices (the SPI flash chip). It’s a full-duplex interface meaning it supports bilateral communication between the controller and peripheral via the two data lines.

Flash memory is a non-volatile memory storage medium for embedded devices. You’ll find it storing device firmware, program data, so on.

We’re going to look at a winbond W25Q64JV. It’s a 64Mb chip released in ~2015 that costs about a dollar fifty. Why this chip? Because I found it in a janky IoT camera in box of fractally-janky IoT devices destined to emit blue smoke.

┌──┴─┐                    ┌─┴──┐
│CS# │ 1 ██             8 │VCC │
└──┬─┘                    └─┬──┘
┌──┴─┐                    ┌─┴──┐
│CIPO│ 2                7 │HOLD│
└──┬─┘      W25Q64JV      └─┬──┘
┌──┴─┐                    ┌─┴──┐
│WP# │ 3                6 │SCK │
└──┬─┘                    └─┬──┘
┌──┴─┐                    ┌─┴──┐
│GND │ 4                5 │COPI│
└──┬─┘                    └─┬──┘

The W25Q64JV pin assignments are displayed above. You can identify pin 1 because it’s next to the little notch or circular impression on the top of the chip.

I’m using a SOIC 8-pin test clip to connect to the W25Q64JV chip. Make sure the red line on the ribbon is placed over line 1 on the chip!

To read memory from this chip we’ll need to connect each line from it to the Glasgow.

If you’re following along on your own device, make sure that it’s not powered when connecting to the Glasgow. Since we’ll provide power from the Glasgow directly to the SPI chip via the VCC line a secondary power source from the IoT device may damage the chip or other components in the device.

Connecting the Glasgow

Look at Port A on the image below. It’s the upper 20-pin IDC connector. You’ll see 8 IO lines numbered 0 to 7 (coloured in orange). We’ll assign SPI lines to each of these I/O lines at run-time via command line arguments.

What exactly are we connecting? There are 4 important SPI lines you should to know:

CS: Chip Select

The controller uses this line to tell a peripheral that that data is being sent.

SCK: Serial Clock

The clock line is used to set the data transmission rate.

COPI: Controller Out, Peripheral In

The COPI line carries data from the controller to the peripheral.

CIPO: Controller In, Peripheral Out

The CIPO line carries data from the peripheral to the controller.

In addition to these 4 SPI lines, we’ll also need to power the chip via the VCC line, ground the chip via a GND line, and connect the WP# line (used for write protect input), and finally the HOLD line (used for Hold or Reset input).


Image below shows how I’ve connected my chip to the Glasgow. You can connect your IO lines in any order but make sure that your chip is grounded and powered using the VIOA and GND lines on the Glasgow.

│                              PORT A                           │
│ ┌────┐┌────┐┌────┐┌────┐┌────┐┌────┐┌────┐┌────┐┌────┐ ┌────┐ │
│ │VCC ││GND ││    ││    ││    ││    ││    ││    ││    │ │    │ │
│ └────┘└────┘└────┘└────┘└────┘└────┘└────┘└────┘└────┘ └────┘ │
│ ┌────┐┌────┐┌────┐┌────┐┌────┐┌────┐┌────┐┌────┐┌────┐ ┌────┐ │
│ │    ││CS# ││CIPO││COPI││SCK ││WP# ││HOLD││    ││    │ │    │ │
│ └────┘└────┘└────┘└────┘└────┘└────┘└────┘└────┘└────┘ └────┘ │
│   V     0     1     2     3     4     5     6     7      N    │


Glasgow CLI organizes core capabilities into applets. Each applet exposes functions such as reading or writing memory, determining JTAG pinout, and so on.

We’ll use the memory-25x applet because we’re working with a 25x chip. The memory-25x applet operations are listed below.

$ glasgow run memory-25x -h


positional arguments:
    identify                identify memory using REMS and RDID commands
    read                    read memory using READ command
    fast-read               read memory using FAST READ command
    program-page            program memory page using PAGE PROGRAM command
    program                 program a memory region using PAGE PROGRAM command
    erase-sector            erase memory using SECTOR ERASE command
    erase-block             erase memory using BLOCK ERASE command
    erase-chip              erase memory using CHIP ERASE command
    erase-program           modify a memory region using SECTOR ERASE and PAGE PROGRAM commands
    protect                 query and set block protection using READ/WRITE STATUS REGISTER commands
    verify                  read memory using READ command and verify contents


Let’s examine the chip info to check it’s JEDEC ID and ensure the chip is actually a W25Q64JV. To do so we’ll use the identify operation in the memory-25x applet which will return the JEDEC ID and some other basic info about the chip.

Assign SPI lines to the Glasgow using the --pin-* positional arguments which should match the previous diagram if you’re following along. Use the -V positional argument to set the voltage for the chip. We’ll use 3.3V which we’ve already learned from the W25Q64JV datasheet.

$ glasgow run memory-25x -V 3.3 --pin-cs 0 --pin-cipo 1 --pin-copi 2 --pin-sck 3 \
--pin-wp 4 --pin-hold 5 identify

I: g.device.hardware: building bitstream ID 7d418322d63a0291d83cefa19b3b57c4
I: g.cli: running handler for applet 'memory-25x'
I: g.applet.memory.25x: port(s) A, B voltage set to 3.3 V
I: g.applet.memory.25x: JEDEC manufacturer 0xef (NEXCOM) device 0x16 (8-bit ID)
I: g.applet.memory.25x: JEDEC manufacturer 0xef (NEXCOM) device 0x4017 (16-bit ID)
I: g.applet.memory.25x: device has valid SFDP 1.5 (JESD216A) descriptor
I: g.applet.memory.25x:   SFDP table #0: JEDEC, Flash Parameter Table 1.5 (JESD216A)
I: g.applet.memory.25x:     density (Mebibits)     : 64
I: g.applet.memory.25x:     density (Mebibytes)    : 8
I: g.applet.memory.25x:     address byte count     : 3
I: g.applet.memory.25x:     write granularity      : 64 byte(s)
I: g.applet.memory.25x:     sector sizes           : 4096, 32768, 65536
I: g.applet.memory.25x:     sector size 4096       : erase opcode 0x20
I: g.applet.memory.25x:     sector size 32768      : erase opcode 0x52
I: g.applet.memory.25x:     sector size 65536      : erase opcode 0xd8
I: g.applet.memory.25x:     double transfer rate   : yes
I: g.applet.memory.25x:     fast read modes        : (1-1-2), (1-1-4), (1-2-2), (1-4-4), (4-4-4)
I: g.applet.memory.25x:     fast read mode (1-1-2) : opcode 0x3b, 8 wait states, 0 mode bits
I: g.applet.memory.25x:     fast read mode (1-1-4) : opcode 0x6b, 8 wait states, 0 mode bits
I: g.applet.memory.25x:     fast read mode (1-2-2) : opcode 0xbb, 2 wait states, 2 mode bits
I: g.applet.memory.25x:     fast read mode (1-4-4) : opcode 0xeb, 4 wait states, 2 mode bits
I: g.applet.memory.25x:     fast read mode (4-4-4) : opcode 0xeb, 0 wait states, 2 mode bits

Once we have this info we can use the datasheet to confirm that the JEDEC ID 0xEF is Winbond and the device ID 0x4017 is W25Q64JV-IQ/JQ.

Reading Flash Memory

We’ll read the chip using the fast-read operation, specifying an output filename using the -f positional arg, a start offset of 0, and the number of bytes to read, and then give it a few minutes to cook.

$ glasgow run memory-25x -V 3.3 --pin-cs 0 --pin-cipo 1 --pin-copi 2 --pin-sck 3 \
--pin-wp 4 --pin-hold 5 fast-read 0 8388608 -f firmware.bin 

I: g.device.hardware: device already has bitstream ID 7d418322d63a0291d83cefa19b3b57c4
I: g.cli: running handler for applet 'memory-25x'
I: g.applet.memory.25x: port(s) A, B voltage set to 3.3 V

Then we’ll unblob the resulting binary file.

$ unblob firmware.bin

2023-07-13 02:06.20 [info     ] Start processing file          file=firmware.bin pid=34067
2023-07-13 02:06.20 [warning  ] Found unknown Chunks           chunks=[0x0-0x346f4, 0x21ec3a-0x220000, 0x530000-0x540000] pid=34071
2023-07-13 02:06.20 [info     ] Extracting unknown chunk       chunk=0x0-0x346f4 path=firmware.bin_extract/0-214772.unknown pid=34071


Open the extracted squashfs filesystem.

$ cd firmware.bin_extract/2228224-5439488.squashfs_v4_le_extract
$ ls

bin  dev  etc  gm  home  init  lib  mnt  npc  opt  patch  proc  rom  root  sbin  share  squashfs_init  sys  tmp  usr  var

And poke around…

$ cat etc/issue

Welcome to \n (\m-\s-\r@\l/\b)
Grain Media ARM Linux 3.3

Copyright (C) 2005 Faraday Corp. <>
Released under GNU GPL