- Как примонтировать /dev/mtdblock SPI flash память в линуксе?
- How to read/write from an Flash connected through SPI in an embedded Linux (ARM)?
- SPI flash support in embedded Linux box
- SPI Flash: hardware overview
- What are needed to enable SPI flash access from Linux ?
- Enable SPI controller in device tree.
- Access from user space
Как примонтировать /dev/mtdblock SPI flash память в линуксе?
Всем привет! Как в линуксе примонтировать SPI флеш память? Есть железка, в которой такая память напаяна, хотелось бы с системы в неё иметь доступ.
если там залита какая то линуксовая фс — берешь и монтируешь, только очевидно в ro. пардон, можно и в rw, но mtdblock не умеет в wear leveling.
vvviperrr ★★★★★ ( 20.04.22 21:54:01 MSK )
Последнее исправление: vvviperrr 20.04.22 21:54:44 MSK (всего исправлений: 1)
а как он в OpenWRT умеет на ходу перезаписыватт?
нихера не понял. если ты пытался спросить, как правильно работать с rw флешем в линуксе через mtd драйвер — mtd-utils (обрати внимание на устройства /dev/mtd2). можно и mtdblock, но говорю, он не поддерживает wear leveling, флешка быстрее сдохнет. а еще можно ubi поверх mtd накатить, там уже rw без проблем.
в опенврт обычно squashfs на mtd + где то лежит оверлей, мб и в ubi, я хз. а мб через mtd-utils. mount надо хотя бы посмотреть чтоб понять.
vvviperrr ★★★★★ ( 20.04.22 22:03:35 MSK )
Последнее исправление: vvviperrr 20.04.22 22:05:48 MSK (всего исправлений: 3)
Врядли сдохнет флешка, не буду я так часто перезаписывать. Хотелось бы туда ядро положить.
Монтируются не устройства, а ФС.
Для ядра главное, чтобы SPI мог прочитать uboot, а не linux.
Для хранения образа ядра ФС не нужна, просто dd (возможно со смещением).
У uboot-а есть свои способы упаковки в один образ: ядра, dts и firmware.
На SPI обычно хранят загрузчик (загрузчик должен иметь поддержку загрузки со SPI), а не ядро.
Ну да, не так сформулировал. Обратиться мне от системы к SPI надо.
а как он в OpenWRT умеет на ходу перезаписыватт?
/dev/root on /rom type squashfs (ro,relatime) /dev/mtdblock4 on /overlay type jffs2 (rw,noatime) overlayfs:/overlay on / type overlay (rw,noatime,lowerdir=/,upperdir=/overlay/upper,workdir=/overlay/work)
осталось разобраться, как заставить систему видеть /dev/mtdblock
А у тебя их нет вообще в /dev, что ли?
How to read/write from an Flash connected through SPI in an embedded Linux (ARM)?
I am using Yocto and meta-atmel to build an embedded Linux(4.4.19). On my board is an Flash which is connected through SPI. I tried several ways to write on it. But they all failed. How to read/write data into it? Some info: Flashtype 4Mbit:
s25fl164k (http://www.farnell.com/datasheets/1756778.pdf) Included through Device Tree:
spi1: spi@f8008000 < cs-gpios = ; status = "okay"; m25p80@0 < compatible = "spansion,s25fl164k"; spi-max-frequency = ; reg = ; >; >;
[ 2.630000] Creating 8 MTD partitions on "atmel_nand": [ 2.640000] 0x000000000000-0x000000040000 : "bootstrap" [ 2.640000] 0x000000040000-0x0000000c0000 : "uboot" [ 2.650000] 0x0000000c0000-0x000000100000 : "env" [ 2.660000] 0x000000100000-0x000000140000 : "env_redundant" [ 2.660000] 0x000000140000-0x000000180000 : "spare" [ 2.670000] 0x000000180000-0x000000200000 : "dtb" [ 2.670000] 0x000000200000-0x000000800000 : "kernel" [ 2.680000] 0x000000800000-0x000010000000 : "rootfs" [ 2.690000] atmel_spi f0004000.spi: version: 0x213 [ 2.690000] atmel_spi f0004000.spi: DMA TX channel not available, SPI unable to use DMA [ 2.700000] atmel_spi f0004000.spi: Atmel SPI Controller using PIO only [ 2.700000] atmel_spi f0004000.spi: Atmel SPI Controller at 0xf0004000 (irq 25) [ 2.710000] m25p80 spi32766.0: at25df321a (4096 Kbytes)
fdisk print (look at mtdblock8 ):
root@sama5d3xek:~# fdisk -l Disk /dev/ram0: 8 MiB, 8388608 bytes, 16384 sectors Units: sectors of 1 * 512 = 512 bytes Sector size (logical/physical): 512 bytes / 4096 bytes I/O size (minimum/optimal): 4096 bytes / 4096 bytes Disk /dev/ram1: 8 MiB, 8388608 bytes, 16384 sectors Units: sectors of 1 * 512 = 512 bytes Sector size (logical/physical): 512 bytes / 4096 bytes I/O size (minimum/optimal): 4096 bytes / 4096 bytes Disk /dev/ram2: 8 MiB, 8388608 bytes, 16384 sectors Units: sectors of 1 * 512 = 512 bytes Sector size (logical/physical): 512 bytes / 4096 bytes I/O size (minimum/optimal): 4096 bytes / 4096 bytes Disk /dev/ram3: 8 MiB, 8388608 bytes, 16384 sectors Units: sectors of 1 * 512 = 512 bytes Sector size (logical/physical): 512 bytes / 4096 bytes I/O size (minimum/optimal): 4096 bytes / 4096 bytes Disk /dev/mtdblock0: 256 KiB, 262144 bytes, 512 sectors Units: sectors of 1 * 512 = 512 bytes Sector size (logical/physical): 512 bytes / 512 bytes I/O size (minimum/optimal): 512 bytes / 512 bytes Disk /dev/mtdblock1: 512 KiB, 524288 bytes, 1024 sectors Units: sectors of 1 * 512 = 512 bytes Sector size (logical/physical): 512 bytes / 512 bytes I/O size (minimum/optimal): 512 bytes / 512 bytes Disk /dev/mtdblock2: 256 KiB, 262144 bytes, 512 sectors Units: sectors of 1 * 512 = 512 bytes Sector size (logical/physical): 512 bytes / 512 bytes I/O size (minimum/optimal): 512 bytes / 512 bytes Disk /dev/mtdblock3: 256 KiB, 262144 bytes, 512 sectors Units: sectors of 1 * 512 = 512 bytes Sector size (logical/physical): 512 bytes / 512 bytes I/O size (minimum/optimal): 512 bytes / 512 bytes Disk /dev/mtdblock4: 256 KiB, 262144 bytes, 512 sectors Units: sectors of 1 * 512 = 512 bytes Sector size (logical/physical): 512 bytes / 512 bytes I/O size (minimum/optimal): 512 bytes / 512 bytes Disk /dev/mtdblock5: 512 KiB, 524288 bytes, 1024 sectors Units: sectors of 1 * 512 = 512 bytes Sector size (logical/physical): 512 bytes / 512 bytes I/O size (minimum/optimal): 512 bytes / 512 bytes Disk /dev/mtdblock6: 6 MiB, 6291456 bytes, 12288 sectors Units: sectors of 1 * 512 = 512 bytes Sector size (logical/physical): 512 bytes / 512 bytes I/O size (minimum/optimal): 512 bytes / 512 bytes Disk /dev/mtdblock7: 248 MiB, 260046848 bytes, 507904 sectors Units: sectors of 1 * 512 = 512 bytes Sector size (logical/physical): 512 bytes / 512 bytes I/O size (minimum/optimal): 512 bytes / 512 bytes Disk /dev/mtdblock8: 4 MiB, 4194304 bytes, 8192 sectors Units: sectors of 1 * 512 = 512 bytes Sector size (logical/physical): 512 bytes / 512 bytes I/O size (minimum/optimal): 512 bytes / 512 bytes Disk /dev/mmcblk0: 7.4 GiB, 7985954816 bytes, 15597568 sectors Units: sectors of 1 * 512 = 512 bytes Sector size (logical/physical): 512 bytes / 512 bytes I/O size (minimum/optimal): 512 bytes / 512 bytes Disklabel type: dos Disk identifier: 0x00000000 Device Boot Start End Sectors Size Id Type /dev/mmcblk0p1 8192 15597567 15589376 7.4G b W95 FAT32
cat /dev/mtdblock8 echo "hello" > /dev/mtdblock8 cat /dev/mtdblock8
I don’t get any results/errors.
mkdir /tmp/abc mount -t jffs2 /dev/mtdblock8 /tmp/abc mount: /dev/mtdblock8: can't read superblock
I like to do a demo. Let’s say write «hello Linux» on position 12345 at the SPI flash.
SPI flash support in embedded Linux box
Serial Peripheral Interface (SPI) flash memory is often used in an embedded Linux box to hold bootloader. During very initial board bringup, SPI flash memory needs to be programmed properly using device like Dediprog, otherwise the box won’t boot. After the box is up running linux, often there is need to access SPI flash, e.g. upgrade new version of bootloader from linux. I will share what needs to be done for that.
SPI Flash: hardware overview
There are many flash memory devices in the market, often people see USB flash memory, SD card. Those flash memory are parallel flash, eithe NOR or NAND flash. With parell access, the throughput is a lot higher. SPI flash is accessed in a serial way, so it is much slower.
SPI devices communicate in full duplex mode using a master-slave architecture with a single master. The master device originates the frame for reading and writing. Multiple slave devices are supported through selection with individual slave select (SS) lines.
SCK: Serial Clock MOSI: Master Output Slave Input MISO: Master Input Slave Output SS: Slave Select
SPI Master often is provided by SoC, SPI flash device serves as SPI slave.
What are needed to enable SPI flash access from Linux ?
There are three areas to do in order to enable SPI flash access from Linux user space.
Enable SPI controller in device tree.
In my case, Marvell ARMADA 7040 SoC has SPI controller provided, I need do the following:
Access from user space
With the changes in DTS and kernel, after linux boots, the below will be observed in kernel space:
bash# dmesg . [ 4.110288] m25p80 spi2.0: n25q128a13 (16384 Kbytes) [ 4.115301] 3 ofpart partitions found on MTD device spi2.0 [ 4.120815] Creating 3 MTD partitions on "spi2.0": [ 4.125632] 0x000000000000-0x000000200000 : "boot" [ 4.130895] 0x000000200000-0x000000f00000 : "Filesystem" [ 4.136619] 0x000000f00000-0x000001000000 : "boot_2nd" .
From the user space, the first thing can be seen is the mtd device files:
bash# ls -l /dev/mtd* crw------- 1 root root 90, 0 Feb 6 08:14 /dev/mtd0 crw------- 1 root root 90, 1 Feb 6 08:14 /dev/mtd0ro crw------- 1 root root 90, 2 Feb 6 08:14 /dev/mtd1 crw------- 1 root root 90, 3 Feb 6 08:14 /dev/mtd1ro crw------- 1 root root 90, 4 Feb 6 08:14 /dev/mtd2 crw------- 1 root root 90, 5 Feb 6 08:14 /dev/mtd2ro brw------- 1 root disk 31, 0 Feb 6 08:14 /dev/mtdblock0 brw------- 1 root disk 31, 1 Feb 6 08:14 /dev/mtdblock1 brw------- 1 root disk 31, 2 Feb 6 08:14 /dev/mtdblock2
/dev/mtdblock0 is for “boot” (first bootloader) partition; /dev/mtdblock1 is for “FileSystem” partition; /dev/mtdblock2 is for “boot_2nd” partition.
what can we do now? Life is easy with all these infrastructure in place.
- To program a new version bootloader, simply: dd if=new-bootloader.bin of=/dev/mtdblock0
- If we want to use partition as file system, simply:
- mkdir /mnt/spi
- mkfs.jffs2 /dev/mtdblock1
- mount -t jfss2 /dev/mtdblock1 /mnt/spi
- http://free-electrons.com/blog/managing-flash-storage-with-linux/
- http://slideplayer.com/slide/10452504/