Posts: 70
Joined: Sat Sep 29, 2018 11:27 am

SPI Serial FLASH --> File system

Sun Jun 16, 2019 10:15 pm

Hi there,

I have an ISSI IS25LP128F SPI 128Mbit FLASH chip attached to SPI bus 0 on nCS0 (GPIO8 pin 24 nCS_FLASH) This shows up as /dev/spidev0.0 on the Pi

I would like to put a file system on this device allowing me to leave the SD card mounted RO (except for the all important security updates).

I realise that I will need to use a file system that will handle wear levelling for me - JFFS should do the trick. But before I can mount the file system I will need (I think) the MTD layer to take /dev/spi0.0 and present it as /dev/mtd0

Does anyone have a simple, worked through example of how to setup an MTD node on the Pi?

-- 8< --

I can access this using the flashroom tool

Code: Select all

RPi$ flashrom -p linux_spi:dev=/dev/spidev0.0,spispeed=60000

flashrom v1.1-rc1-14-gee13d0c on Linux 4.19.42-v7+ (armv7l)
flashrom is free software, get the source code at https://flashrom.org

Using clock_gettime for delay loops (clk_id: 1, resolution: 1ns).
Found ISSI flash chip "IS25LP128" (16384 kB, SPI) on linux_spi.
No operations were specified.
So clearly the hardware is correctly connected and working correctly :-)

Many thanks

Posts: 70
Joined: Sat Sep 29, 2018 11:27 am

Re: SPI Serial FLASH --> File system

Sun Sep 15, 2019 11:13 am

So it has been 3 months since I asked this question, and no reply.

I have been digging for an answer and it appears that the MTD drivers are a bit 'special' and unlikely to work correctly out of the box ( the code being flaky enough that patches to make one FLASH IC work break others - according to Kylikki; one of the original devs). Kylikki also suggested that I should be able to get working a very basic driver (with no DMA support). However at the same weekend it was suggested to me (thanks iDunno) that instead I should write a user space Daemon to cache the FLASH as a RAMDisk. This is what I ended up doing.

if you are interested then what follows is a description of how my userspace daemon works (I will make the code available over the next few days and update this thread)


Code: Select all

Because I only need a small amount of persistent storage (just for configuration files) 2MByte is plenty of space (still bigger than a floppy disk!), this means that I can also implement a simple ring buffer in my 8MByte FLASH, thus providing wear leavening (and cleanly handling bad blocks) as well as roll back in the event of a corrupted write due to power fail/software crash DURING the write process.

S.1.  Copy FLASH (using flashromm utility) to a 22MB RAMDisk  (using / creating mount points along the way as required)
S.2.  Parse the FLASH image (on the RAMDisk)  looking for a valid header, and payload matching the checksum in the header (I have divided the FLASH into 8, 2MByte 'SuperBlocks - aligned on FLASH Erase / Block boundaries)
S.3.  Copy the payload from valid Superblock with the highest sequance number in it's headder to a file (superblock_payload.img) in the 22MB RAMDisk  
S3.1. If no valid payload is found create a blank file the size of the payload.
S3.2. Format the payload file as FAT12 (really simple non journalling lightweigh file system)
S.4.  Mount that file as a loopback device (as /mnt/persistant)  
S.5.  Create 'ionotify' events for any changes to the loopback partition
S.6. Enter sleep loop pending events

On ionotify event
I.1.  Create (or restart if already running) a countdown timer  (Ensures that clusters of changes are treated as one)

On Timer Elapsed Event 
T.1. Disable Timer event triggers - timer can still elapse but we don't get new events until after we re-enable the timer trigger.
T.2. Make a copy of the loopback file (super_blocy_payload.img --> newpayload.img)  Note use dd and ensure that the block size is the same as the size of the payload file.  (the copy then happens in one time slice of dd)
T.3. copy the new payload file into the payload of the superblock space of the next superblock in the copy image of the FLASH
T.4. create header in the new superblock (increment sequence number, checksum for payload, etc)
T.5 use flashrom to write FLASH image back to FLASH and verify (note you can configure flashrom to only erase & write the superblock you have changed, not erase and write the entire FLASH)
T5.1 if flashrom fails copy into the next superblock and re-try (handles bad block)
T6. Re-enable timer events

On Exit
E.1. Make a copy of the loopback file (super_blocy_payload.img --> newpayload.img) 
E.2. Compare newpayload.img with the current superblock in the FLASH image.
E.2.1. If different trigger Timer Elapsed Event and wait for it to complete
E.3.  unmount loopback file / remove RAMDisks etc.

Return to “Interfacing (DSI, CSI, I2C, etc.)”