Enabling SPI-NOR Flash on Raspberry Pi 5 with Device Tree Modification

Enabling SPI-NOR Flash on Raspberry Pi 5 with Device Tree Modification

Introduction

In this article, we document the process of enabling and verifying an SPI-NOR flash device on a Raspberry Pi 5. We go through modifying the device tree, rebuilding it, and validating the SPI-NOR detection using Linux commands. This guide provides detailed explanations of the commands used and how conclusions were drawn from the outputs.

Modifying the Device Tree

To enable SPI-NOR flash, we need to modify the Device Tree Source (DTS) file to include the correct configuration. The relevant modifications involve defining the SPI controller node and specifying the SPI-NOR flash as a child device.

The modified device tree entry might look like this:

&spi10 {
    status = "okay";
    flash@0 {
       // compatible = "spidev"; 
        compatible = "jedec,spi-nor";
        reg = <0>;
        spi-max-frequency = <50000000>;
    };
};
        

This change ensures that the SPI controller is enabled and that the SPI-NOR flash is properly recognized as a JEDEC-compatible NOR device.

Rebuilding the Device Tree

After modifying the DTS file, we need to recompile it into a Device Tree Blob (DTB). The standard way to rebuild the device tree on Raspberry Pi is by running:

make -j$(nproc) ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- dtbs
        

This command:

  • Uses make to build the device tree blobs.
  • Uses -j$(nproc) to compile using all available processor cores for faster execution.
  • Specifies the architecture (ARCH=arm64) since Raspberry Pi 5 runs a 64-bit ARM processor.
  • Uses CROSS_COMPILE=aarch64-linux-gnu- to ensure correct cross-compilation for the target system.

Once built, the new DTB file should be copied to the boot partition:

sudo cp arch/arm64/boot/dts/broadcom/*.dtb /boot/firmware/
        

Finally, reboot the system for the changes to take effect:

sudo reboot
        

Verifying SPI-NOR Flash Detection

Once the system is boot up, we check if the SPI-NOR flash is detected correctly.

Checking Kernel Modules

lsmod | grep nor        

Output:

spi_nor               114688  0
mtd                    98304  3 spi_nor,ofpart        

Interpretation:

spi_nor Module

  • The spi_nor module is loaded, indicating that the kernel has recognized and enabled support for SPI-NOR flash devices.
  • The size (114688 bytes) refers to the memory footprint of the module.
  • The 0 at the end means that no other modules currently depend on spi_nor.

mtd Module

  • The mtd (Memory Technology Device) module is also loaded, which is necessary for interfacing with flash memory.
  • The size is 98304 bytes.
  • The 3 indicates that three other modules are using mtd: spi_nor and ofpart (Open Firmware partition parser).

Since the spi_nor and mtd modules are loaded, this confirms that the kernel has successfully recognized the SPI-NOR flash memory. To further verify detection and operation, checking /proc/mtd and dmesg logs is essential.

Inspecting Kernel Log

dmesg | grep spi
        

Relevant output:

[    9.719773] spi-nor spi10.0: s25fl016k (2048 Kbytes)
        

This log confirms that the SPI-NOR flash (S25FL016K) has been detected and initialized.

Checking MTD (Memory Technology Device) Partitions

cat /proc/mtd        

Output:

dev:    size   erasesize  name
mtd0: 00200000 00001000 "spi10.0"        

Interpretation:

  • mtd0: The first MTD (Memory Technology Device) partition detected.
  • 00200000: The total size of the SPI-NOR flash, which is 2MB.
  • 00001000: The erase block size, which is 4KB.
  • "spi10.0": The label assigned to this flash memory, which matches the SPI-NOR flash detected in dmesg.

This confirms that the flash memory is correctly registered as an MTD device and can be accessed for read, write, and erase operations.

Installing MTD Utilities

To interact with the SPI NOR flash, install the MTD utilities:

sudo apt update
sudo apt install mtd-utils        

Interacting with the SPI NOR Flash

Once the device is set up, you can read, write, and erase it using MTD utilities.

Checking Flash Information

mtd_debug info /dev/mtd0        

This provides details about the flash memory.

Reading Flash Data

To dump the flash contents into a file:

sudo dd if=/dev/mtd0 of=flash_backup.bin        

Or using mtd_debug:

sudo mtd_debug read /dev/mtd0 0 0x200000 flash_backup.bin        

Erasing Flash

To erase the entire SPI NOR flash:

sudo flash_erase /dev/mtd0 0 0        

?? Warning: This permanently erases all data!

Writing to Flash

To write a new firmware binary:

sudo mtd_debug write /dev/mtd0 0 0x200000 new_firmware.bin        

Ensure the file size does not exceed the flash size.

?? The Underlying Logic of Device Tree Change

     flash@0 {
       // compatible = "spidev"; 
        compatible = "jedec,spi-nor";        

This is a change in the Device Tree configuration, switching from configuring a spidev device to configuring an spi - nor flash device. Here are the impacts:

Device driver matching

  • Original configuration: The original spidev@0 configuration uses compatible = "spidev". spidev is a general - purpose SPI device driver framework, mainly providing a simple SPI device access interface. It isn't targeted at the specific functions of a particular SPI device, such as reading and writing for storage devices.
  • New configuration: The new flash@0 uses compatible = "jedec,spi - nor". This compatible property makes the kernel attempt to match the spi_nor driver, which is specifically designed to manage SPI NOR flash devices compliant with the JEDEC standard. In other words, after the change, the kernel will manage and operate the device in a way more suitable for the characteristics of SPI NOR flash.

Impact on the /dev directory

$ ls /dev/spi*
/dev/spidev10.0         

Original configuration: After loading the spidev driver, device nodes like /dev/spidev1.0 are usually generated in the /dev directory. This node can be used for general data transmission operations via the SPI interface, but it can't be directly used for operations like mounting a file system on the flash device or reading and writing data from/to it.

$ ls spi*
ls: cannot access 'spi*': No such file or directory
$ ls mtd*
mtd0  mtd0ro        

  • New configuration: When the new spi - nor device tree configuration is successfully matched and the corresponding driver is loaded, MTD (Memory Technology Device) - related device nodes may be generated in the /dev directory, such as /dev/mtd0, /dev/mtdblock0, etc. /dev/mtd0 can be used to directly access the flash device, and /dev/mtdblock0 can be used to mount a file system, enabling operations like data storage and reading on the flash. This is a completely different way of device operation compared to the previous spidev configuration.

Function implementation

  • Original configuration: It mainly provides basic data transmission functions for SPI devices and can't perform specific operations on the flash device, such as erasing and programming.
  • New configuration: It enables the full management of SPI NOR flash devices using the spi_nor driver, including device initialization, reading the device ID, erasing flash blocks, writing data, etc. This provides support for applications based on flash devices, such as storing file systems and firmware.

Conclusion

Through device tree modification, recompilation, and validation steps, we successfully enabled an SPI-NOR flash device on the Raspberry Pi 5. By analyzing kernel logs, module status, and MTD partitions, we confirmed that the flash memory is properly recognized and accessible in Linux. These steps provide a solid foundation for using SPI-NOR flash for firmware storage, boot configurations, or data logging applications.

Appendix:

In the Linux operating system, the /proc file system is a virtual file system that provides an interface to access information about running processes and kernel - related data. Here's why /proc/mtd exists and how the path organization in /proc generally works:

Why /proc/mtd exists

  • MTD device information access: The /proc/mtd file is used to expose information about Memory Technology Device (MTD) partitions in the system. MTD devices are commonly used for various types of flash memory, such as SPI - NOR flash, NAND flash, etc. The kernel maintains internal data structures about these MTD partitions, and /proc/mtd serves as a simple way for userspace programs (including shell commands like cat) to access details like partition size, erase size, and partition names. This helps in understanding the layout and characteristics of the flash - based storage in the system, which is crucial for tasks like mounting file systems on MTD partitions, flashing firmware, etc.

Rule of path organization in /proc

  • Process - related paths: For each running process in the system, a directory is created under /proc with the process ID (PID) as the directory name. For example, if a process has a PID of 1234, there will be a /proc/1234 directory. Inside this directory, there are many files and sub - directories that provide information specific to that process. For instance, /proc/1234/cmdline contains the command line arguments used to start the process, and /proc/1234/maps shows the memory maps of the process.
  • Kernel - wide information paths: There are also many files and directories under /proc that provide system - wide or kernel - related information, not specific to a single process. These often represent different subsystems or features in the kernel. For example:/proc/cpuinfo provides information about the CPU(s) in the system, like the model name, CPU frequency, etc./proc/meminfo gives details about the system's memory usage, including total memory, free memory, buffer and cache sizes./proc/devices lists all the device drivers that are currently registered in the kernel and the major device numbers associated with them.

In general, the naming convention in /proc is designed to be intuitive, with the path components often directly related to the type of information being exposed. The file system is used as a convenient way to export important system - level and process - level data to user - space for monitoring, debugging, and configuration purposes.


Artyom Sabadyr

Embedded Software Engineer | C/C++ | C# | Linux Kernel | Yocto

2 周

SPI flash is useful for storing some configs or serial numbers. This way you can ensure that data will survive full device reflash.

回复

要查看或添加评论,请登录

David Zhu的更多文章

社区洞察

其他会员也浏览了