首页 [Beaglebone] Linux 3.8添加SPi Flash及文件系统支持
文章
取消

[Beaglebone] Linux 3.8添加SPi Flash及文件系统支持

####Spi Flash芯片

由于制作JFSS2文件系统镜像、初始化需要芯片的详细sector size(page size)、erase size,因此需要详细的芯片类型和数据手册。我使用的SPI Flash芯片是“25Q128A 13E40”,是Micron的N25Q128A13ESE40E。几个重要参数需要弄清楚:

Erase capability – Subsector erase 4KB uniform granularity blocks – Sector erase 64KB uniform granularity blocks – Full-chip erase

Memory Management 简而言之是25664KB=25616*4096 bytes的结构。

  • erase size: 64KB
  • sector size: 64kb
  • subsector size: 4096b

The memory is organized as 256 (64KB) main sectors that are further divided into 16 subsectors each (4096 subsectors in total). The memory can be erased one 4KB subsector at a time, 64KB sectors at a time, or as a whole.

####F2FS

linux 3.8内核上默认支持F2FS文件系统,这个新兴的文件系统在Linux 3.8中首次加入其稳定版代码支持,但是使用mkf2fs格式话时发现:

# mkfs.f2fs -l userroot /dev/mtdblock0

        F2FS-tools: mkfs.f2fs Ver: 1.4.1 (2015-03-04)

Info: Label = userroot
Info: sector size = 512
Info: total sectors = 32768 (in 512 bytes)
Error: Min volume size supported is 104857600

F2FS文件系统不支持100M以下的设备。

####JFFS2简介 JFFS2 provides a filesystem directly on the flash, rather than emulating a block device. For more information, see the (JFFS2 PDF)[http://linux-mtd.infradead.org/~dwmw2/jffs2.pdf].

####让内核支持选定的SPI Flash

  1. 添加kernel对jffs2的支持
Symbol: JFFS2_FS [=y]     
│ Type  : tristate     
│ Prompt: Journalling Flash File System v2 (JFFS2) support
│   Defined at fs/jffs2/Kconfig:1                         
│   Depends on: MISC_FILESYSTEMS [=y] && MTD [=y]         
│   Location:                                             
│     -> File systems                                     
│       -> Miscellaneous filesystems (MISC_FILESYSTEMS [=y])
│   Selects: CRC32 [=y]
  1. 添加mtd层flash驱动
Symbol: MTD_M25P80 [=y]
│ Type  : tristate  
│ Prompt: Support most SPI Flash chips (AT26DF, M25P, W25X, ...)
│   Defined at drivers/mtd/devices/Kconfig:82                   
│   Depends on: MTD [=y] && HAS_IOMEM [=y] && SPI_MASTER [=y] && EXPERIMENTAL [=y]
│   Location:                                                                     
│     -> Device Drivers                                                           
│       -> Memory Technology Device (MTD) support (MTD [=y])                      
│         -> Self-contained MTD device drivers                                    
  1. 添加SPI0 Flash到Device Tree
    设备树不再赘述。SPI设备的cape可参考BB-BONE-SPI0-00A0.dts
/dts-v1/;
/plugin/;

/* SPI1 */
/* D1 output and D0 input */

/ {
    compatible = "ti,beaglebone", "ti,beaglebone-black";

    part-number = "BB-BONE-SPI0";
    version = "00A0";

    fragment@0 {
        target = <&am33xx_pinmux>;
        __overlay__ {
            spi0_pins_s0: spi0_pins_s0 {
                pinctrl-single,pins = <
                    0x150 0x30 /* P9_22 = spi0_sclk, INPUT_PULLUP | MODE0 */
                    0x154 0x30 /* P9_21 = spi0_d0, INPUT_PULLUP | MODE0 */
                    0x158 0x10 /* P9_18 = spi0_d1, OUTPUT_PULLUP | MODE0 */
                    0x15c 0x10 /* P9_17 = spi0_cs0, OUTPUT_PULLUP | MODE0 */
                >;
            };
        }; 
    };

    fragment@1 {
        target = <&spi0>;
        __overlay__ {
            #address-cells = <1>;
            #size-cells = <0>;

            status = "okay";
            pinctrl-names = "default";
            pinctrl-0 = <&spi0_pins_s0>;

            spidev@0 {
                spi-max-frequency = <100000000>;
                reg = <0>;
                compatible = "n25q128a13";
                linux,modalias = "m25p80", "n25q128a13";
                #address-cells = <1>;
                #size-cells = <1>;
                /*parition@uroot{
                    label = "spi-flash0";
                    reg = <0x0 0x1000000>;
                };*/
            };
        };
    };
};

####buildroot & busybox & kernel加入mtd支持

首先加入mtd基本工具和flash_erase的支持,叫交叉编译出flash_erase工具用于格式化,mkfs.ubifs、mkfs.jffs2用于制作镜像。


Symbol: BR2_PACKAGE_MTD [=y]
  │ Type  : boolean        
  │ Prompt: mtd, jffs2 and ubi/ubifs tools
  │   Location:                           
  │     -> Target packages                
  │       -> Filesystem and flash utilities

Symbol: BR2_PACKAGE_MTD_FLASH_ERASE [=y]
  │
  │ Type  : boolean
  │ Prompt: flash_erase
  │   Location:        
  │     -> Target packages
  │       -> Filesystem and flash utilities
  │         -> mtd, jffs2 and ubi/ubifs tools (BR2_PACKAGE_MTD [=y]) 
  │   Defined at package/mtd/Config.in:21                            
  │   Depends on: BR2_PACKAGE_MTD [=y]

Symbol: BR2_PACKAGE_MTD_MKFSJFFS2 [=y]
  │ Type  : boolean                  
  │ Prompt: mkfs.jffs2               
  │   Location:                      
  │     -> Target packages           
  │       -> Filesystem and flash utilities
  │         -> mtd, jffs2 and ubi/ubifs tools (BR2_PACKAGE_MTD [=y])
  │   Defined at package/mtd/Config.in:54                           
  │   Depends on: BR2_PACKAGE_MTD [=y]                              
  │   Selects: BR2_PACKAGE_ZLIB [=y] && BR2_PACKAGE_LZO [=y]        

####制作JFFS2镜像 可以在Host机器上制作镜像,但一定得弄清楚上面提到的flash的几个特性,否则会出现I cannot mount JFFS2 and see "Magic bitmask 0x1985 not found" messages的常见错误。

参考: (http://www.linux-mtd.infradead.org/faq/jffs2.html)[http://www.linux-mtd.infradead.org/faq/jffs2.html]

I cannot mount JFFS2 and see “Magic bitmask 0x1985 not found” messages If you cannot mount your JFFS2 file system and you see many messages like jffs2_scan_eraseblock(): Magic bitmask 0x1985 not found at 0x00000024: 0x2b10 instead …

Further such events for this erase block will not be printed

this means that the data on your flash device is not a valid JFFS2 file system. There is no single solution for this problem, but we will try to provide you some ideas how to fix this.

The first question you should try to answer is “why the data on my flash device is incorrect so that JFFS2 rejects to deal with it?”. There are may be a plenty of reasons, e.g.:

you flash driver is severely buggy so it reads trash instead of valid data; you flashed some trash instead of a valid JFFS2 image; you did not manage to flash JFFS2 image correctly so that you ended up with garbage on your flash, although the original image was perfectly fine; you forgot to erase your flash before flashing it, etc.

Anyways, JFFS2 wouldn’t complain if it was able to find correct data. As it does complain, there is something wrong with the data it reads.

One common mistake is to use /dev/mtdX or /dev/mtdblockX devices to flash JFFS2 images on NAND flashes. E.g. cp jffs2_fs.img /dev/mtd2

This is incorrect because when dealing with NAND flashes one has to skip bad eraseblocks and write only in NAND page size chunks. Please, use the nandwrite utility instead.

Also please, do not forget to erase your flash before flashing the image. You may use the flash_eraseall utility for this. And it makes sense to make sure the erase functionality actually works by reading the erased MTD device back and checking that only 0xFF bytes were read.

You may try to check if your flash driver works correctly and if you flashed the file system image correctly by means of reading the flash back after you have flashed your image, and compare the read image with the original one. Please, use the nandread utility to read from NAND flashes.

You can also do the following experiment to make sure JFFS2 works well. Erase your MTD device and mount it to JFFS2. You will end up with an empty file system. Copy some files to the JFFS2 file system and unmount it. Then mount it again and see if it mounts without problems. If it does, this is most probably not a JFFS2 bug.

  1. 制作镜像
    /usr/sbin/mkfs.jffs2 -n -r ./spiflash_128BBits -e 0x10000 -s 0x10000 -l -p 0x1000000 -o flash0.0x10000_0x10000.img -v 此处page size为64kb,erase size为4k也是flash支持的最小度量的erase单位。

  2. 格式化flash
    # flash_erase -j /dev/mtd0 0 256 此处按照256块(每块64k)进行格式化

  3. 拷贝到目标并dd到flash并挂载目标flash

1
2
3
4
5
6
7
8
9
# dd if= ./flash0.   of=/dev/mtdblock0
flash0.0x10000_0x10000.img  flash0.jffs2.img
flash0.0x1000_0x10000.img
# dd if=./flash0.0x1000_0x10000.img    of=/dev/mtdblock0
16+0 records in
16+0 records out
# mount -t jffs2 /dev/mtdblock0  /mnt/mtd0/
[  362.309070] jffs2: notice: (198) jffs2_build_xattr_subsystem: complete building xattr subsystem, 0 of xdatum (0 unchecked, 0 orphan) and 0 of xref (0 dead, 0 orphan) found.
# 

至此,flash设备成功挂载到用户空间的文件系统中去了。

参考

  • http://processors.wiki.ti.com/index.php/MTD_Utilities
  • http://processors.wiki.ti.com/index.php/JFFS2_kernel_configuration
  • http://www.linux-mtd.infradead.org/doc
本文由作者按照 CC BY 4.0 进行授权