Project

General

Profile

SPI NOR Flash memory map

Added by Thomas Catalino about 6 years ago

(posted for a customer)

We are looking at using the SPI flash and/or NOR flash for storing our software on the L138 SOM. We are currently using uBoot and the exisiting boot code on the board so we do not want to overwrite these.

Could you provide a map of your use of NOR and NAND flash as initially occupied on a delivered board?

Also, could you provide the RAM address space used by uBoot? (Approximately).


Replies (6)

RE: SPI NOR Flash memory map - Added by Jonathan Cormier about 6 years ago

This appears to be what your looking for.
MityDSP-L138_Architecture

Also can be determined by looking at the uboot environment variables. The erase commands give the starting address and the max size expected for each image.

U-Boot > print
...
flashuboot=tftp 0xc0700000 mityomap/u-boot-ubl.bin; sf probe 0; sf erase 0x10000 0x80000; sf write 0xc0700000 0x10000 ${filesize}
flashkernel=tftp 0xc0700000 mityomap/uImage; sf probe 0; sf erase 0x100000 0x280000; sf write 0xc0700000 0x100000 ${filesize}
flashubl=tftp 0xc0700000 mityomap/UBL_SPI_MEM.ais; sf probe 0; sf erase 0 0x10000; sf write 0xc0700000 0 0x10000
flashrootfs=tftp 0xc2000000 mityomap/mityomap-base-mityomapl138.jffs2; nand erase 0 0x08000000; nand write.jffs2 0xc2000000 0 ${filesize}
...

RE: SPI NOR Flash memory map - Added by Mary Frantz about 6 years ago

This probably doesn't completely answer your question, but may be helpful. There is some "spare" memory on the SPI NOR flash.

On your target try:

root@mityomapl138:~# cat /proc/mtd
dev:    size   erasesize  name
mtd0: 08000000 00020000 "rootfs" 
mtd1: 08000000 00020000 "homefs" 
mtd2: 00010000 00010000 "ubl" 
mtd3: 00080000 00010000 "u-boot" 
mtd4: 00010000 00010000 "u-boot-env" 
mtd5: 00010000 00010000 "periph-config" 
mtd6: 00050000 00010000 "reserved" 
mtd7: 00300000 00010000 "kernel" 
mtd8: 00200000 00010000 "fpga" 
mtd9: 00200000 00010000 "spare" 

The "spare" section is an area you can read/write from linux programmatically. I don't know the starting address though.

Here's how to access from linux code:

#include <stdio.h>
#include <error.h>
#include <errno.h>

void FLASH_read(unsigned long off, void * pDest, unsigned int size)
{
    FILE *fd;

    fd = fopen("/dev/mtd9", "r");
    if (fd == NULL)
        error(0, errno,"FLASH_read() called fopen():");
    else
    {
        fseek(fd, off, SEEK_SET );            // move 'off' bytes from start
        fread(pDest, 1, size, fd );
        fclose(fd);

    }
} // end: FLASH_read()

void FLASH_write(unsigned long off, void * pSrc, unsigned int size)
{
    FILE *fd;

    fd = fopen("/dev/mtd9", "r+");
    if (fd == NULL)
        error(0, errno,"FLASH_write() called fopen():");
    else
    {
        fseek(fd, off, SEEK_SET );            // move 'off' bytes from start
        fwrite(pSrc, 1, size, fd );
        fclose(fd);
    }
} // end: FLASH_read()

RE: SPI NOR Flash memory map - Added by Fred Weiser about 6 years ago

Please allow me to chime in with a similar question... I have "reorganized" the upper part of the spi nor flash on my mityDspL138 module as I have a Linux kernel that is larger than the original allocation. I have modified the uboot environment variables to modify starting offset and size of the kernel and fpga locations, and the result seems to work fine; however, when I boot Linux and issue the "cat /proc/mtd" command shown earlier in this thread, the "kernel" area is still listed as the previous size. It seems I am missing something - how does the Linux kernel know where the spi nor flash partitions are? Is there a tool/procedure I should be using when reorganizing the spi nor flash to be sure everything is in synch? And is there a Linux command like "cat /proc/mtd" that shows starting offsets (or something in /sys/class/mtd perhaps)? --Thanks.

RE: SPI NOR Flash memory map - Added by Michael Williamson about 6 years ago

The SPI partitions are defaulted in the board-mityomapl138.c file in arch/arm/mach-davinci in the spi_flash_partitions[] structure. This is where the kernel is getting these values.

If you want the partitions to show up right in MTD, you'll need to modify this file, or it should be possible to override the default partitions table using the mtdparts kernel command line option if you have command line MTD partitions enabled (should be by default for MityDSP-L138 builds). We do this for the NAND quite often but I believe the NOR should also be supported. Something like:

bootargs mem=96M console=ttyS1,115200n8 ... mtdparts=nor:64k@0(ubl),512K@64k(u-boot), ....

I haven't tested this, if I get some time I will, but this might be enough of a hint?

-Mike

RE: SPI NOR Flash memory map - Added by Michael Williamson about 6 years ago

BTW:

It's not entirely clear to me if the write routine above will work properly. I don't know for sure, off-hand, if the driver is smart enough to do a FLASH erase prior to the write. And if it does, be aware that you will be erasing an entire sector not just the data you are interested in. But... the drivers may be OK there.

The MTD utility library (mtd-utils) might be a good option for managing the SPI interfaces.

-Mike

RE: SPI NOR Flash memory map - Added by Mary Frantz about 6 years ago

You are correct, Mike. The flash does have to be erased before writing. Here is a more fleshed out version of my code. It includes some checking for valid data before reading using a header, which others may not need but you get the idea...

unsigned int FLASH_read(unsigned int sector, void * pDest, unsigned int size)
{

    mtd_info_t mtd_info;
    int fd;
    unsigned int n = 0;
    FLASHINFO fInfo;
    unsigned char *pTemp;

    fd = open("/dev/mtd9", O_RDONLY);
    if (fd < 0)
        error(0, errno,"FLASH_read() called open():");
    else
    {
        ioctl(fd, MEMGETINFO, &mtd_info);
        lseek(fd, mtd_info.erasesize * sector , SEEK_SET );            // move to given sector
        read(fd, &fInfo, sizeof(fInfo));                            // get header

        if (fInfo.length == 0xFFFF)                                    // erased, don't read
            n = 0;
        else
        {
            n = (fInfo.length <= size) ? fInfo.length : size;        // use valid data up to size of destination buffer

            lseek(fd, (mtd_info.erasesize * sector) + sizeof(fInfo) , SEEK_SET );            // move past header

            // read flash
            // TODO: use permanent buffer rather than malloc?
            pTemp = (unsigned char *)malloc(n);
            if (pTemp == NULL)
                n = 0;
            else
            {
                read(fd, pTemp, n);                            // read into temporary buffer
                // Checksum
                if (fInfo.cs == checksum(pTemp, n))            // verify checksum
                    memcpy(pDest, pTemp, n);                // data ok, copy to destination
                else
                    n = 0;

                free(pTemp);

            }  // endelse: malloc
        } // endelse: erased
        close(fd);
    } // endelse: fd < 0

    return n;
} // end: FLASH_read()

void FLASH_store(unsigned int sector, void * pSrc, unsigned int size)
{

    mtd_info_t mtd_info;
    int fd;
    erase_info_t ei;
    FLASHINFO    fInfo;

    fd = open("/dev/mtd9", O_RDWR);
    if (fd < 0)
        error(0, errno,"FLASH_write() called open():");
    else
    {
        ioctl(fd, MEMGETINFO, &mtd_info);
        printf("MTD type: %u\n", mtd_info.type);
        printf("MTD total size : %u bytes\n", mtd_info.size);
        printf("MTD erase size : %u bytes\n", mtd_info.erasesize);

        // Erase sector
        ei.start = sector * mtd_info.erasesize;
        ei.length = mtd_info.erasesize;
        ioctl(fd, MEMUNLOCK, &ei);
        ioctl(fd, MEMERASE, &ei);

        // write header
        fInfo.length = size;
        fInfo.cs = checksum((unsigned char *)pSrc, size);
        lseek(fd, ei.start, SEEK_SET);        // move to start of sector
        write(fd, &fInfo, sizeof(fInfo));

        // write
        lseek(fd, ei.start + sizeof(fInfo), SEEK_SET);        // move to end of header
        write(fd, pSrc, size);

        // close
        close(fd);

    }
} // end: FLASH_store()

Mary

    (1-6/6)
    Add picture from clipboard (Maximum size: 500 MB)