2013-03-11 94 views
9

MTDブロックデバイスを使用してNANDフラッシュメモリに書き込もうとしていますが、すべてを理解できません。mtdブロックデバイスに書き込む

Iはhere

  • mtdblockNを読み取るように読み取り専用ブロックデバイスN
  • mtdNある読み出し/書き込みチャーデバイスN
  • mtdNro
読み取り専用チャーデバイスNであります

しかし、Cで単純なwriteを使ってバイトをパーティションに直接書きたいと思います。それは動作します(私は最初に書き込みたいセクタを消去しなければならないと私は少し読んでいます)。

どのデバイスを使用し、このデバイスに書き込むのですか?ようにするに

+0

ないこのことができますが、あなたは、ここで提供されている例を見ているかどうかわから:[リンク](http://www.linuxforu.com/2012/01/working-with-mtd-devices/)、セクション「アプリケーションからのMTDへのアクセス」 – Habi

+0

ええ私はそれを見ました;-)私は現在それを試しています – marmottus

+0

MTDデバイスは生のフラッシュへのアクセスを提供します。ファイルの作成、編集、削除などをしたい場合。これは、ファイルシステム(あなたの場合はyaffs2)上で行う必要があります。 MTDデバイスを介してフラッシュにアクセスしても、このようなレイヤは提供されません。 – Rerito

答えて

12

読書とメモリ技術のデバイスへ/からの書き込みは、あなたが書く前に(ブロック消去)のセクターを消去する必要があることを除いて、本当にIOの他のタイプよりすべてが異なっていない

コードを書かなくても、mtd-utils(たとえば、flash_erasenanddumpnandwriteなど)を使用するだけで簡単に使えます。

#include <stdio.h> 
#include <fcntl.h> 
#include <sys/ioctl.h> 
#include <mtd/mtd-user.h> 

int main() 
{ 
    mtd_info_t mtd_info;   // the MTD structure 
    erase_info_t ei;    // the erase block structure 
    int i; 

    unsigned char data[20] = { 0xDE, 0xAD, 0xBE, 0xEF, // our data to write 
           0xDE, 0xAD, 0xBE, 0xEF, 
           0xDE, 0xAD, 0xBE, 0xEF, 
           0xDE, 0xAD, 0xBE, 0xEF, 
           0xDE, 0xAD, 0xBE, 0xEF}; 
    unsigned char read_buf[20] = {0x00};    // empty array for reading 

    int fd = open("/dev/mtd0", O_RDWR); // open the mtd device for reading and 
             // writing. Note you want mtd0 not mtdblock0 
             // also you probably need to open permissions 
             // to the dev (sudo chmod 777 /dev/mtd0) 

    ioctl(fd, MEMGETINFO, &mtd_info); // get the device info 

    // dump it for a sanity check, should match what's in /proc/mtd 
    printf("MTD Type: %x\nMTD total size: %x bytes\nMTD erase size: %x bytes\n", 
     mtd_info.type, mtd_info.size, mtd_info.erasesize); 

    ei.length = mtd_info.erasesize; //set the erase block size 
    for(ei.start = 0; ei.start < mtd_info.size; ei.start += ei.length) 
    { 
     ioctl(fd, MEMUNLOCK, &ei); 
     // printf("Eraseing Block %#x\n", ei.start); // show the blocks erasing 
                // warning, this prints a lot! 
     ioctl(fd, MEMERASE, &ei); 
    }  

    lseek(fd, 0, SEEK_SET);    // go to the first block 
    read(fd, read_buf, sizeof(read_buf)); // read 20 bytes 

    // sanity check, should be all 0xFF if erase worked 
    for(i = 0; i<20; i++) 
     printf("buf[%d] = 0x%02x\n", i, (unsigned int)read_buf[i]); 

    lseek(fd, 0, SEEK_SET);  // go back to first block's start 
    write(fd, data, sizeof(data)); // write our message 

    lseek(fd, 0, SEEK_SET);    // go back to first block's start 
    read(fd, read_buf, sizeof(read_buf));// read the data 

    // sanity check, now you see the message we wrote!  
    for(i = 0; i<20; i++) 
     printf("buf[%d] = 0x%02x\n", i, (unsigned int)read_buf[i]); 


    close(fd); 
    return 0; 
} 

このことについての素晴らしい事は、あなたができるためである:あなたが実用的にそれを行うにはしたくない場合は

はしかし、ここで私はそこにすべての詳細を入れて、すべてのコメントを読んでください例ですあなたが他のデバイスから行うように標準utilsを使用すると、write()open()、およびread()が何を期待しているのかを簡単に理解することができます。例えば

write()を使用しているときは、それが意味するかもしれませんEINVALの値を得た場合:

FDを書くには適していないオブジェクトを参照しています。またはファイルがO_DIRECTフラグで開かれ、bufで指定されたアドレス、countで指定された値、または現在のファイルオフセットが適切に整列されていない。

+0

これはHabiのリンクに従って行われました。しかし、私は書き込みサイズを次のセクタに揃えなければなりません。それ以外の場合、私はカーネル警告を受け取ります:-) – marmottus

+0

そして別の質問:この場合、不良ブロックはどのように処理されますか?あなたは健全性チェックを行いますが、カーネルはもう書き込み不能なデッドブロックをどのように処理しますか? – marmottus

+0

@marmottus - 変化するセクターについては、入手するのがかなり簡単です。単にlseekコマンドを変更し、mtd_info構造体から消去サイズを使用するだけです。不良ブロック(生のフラッシュ上)はあなたの責任です...ほとんどのフラッシュチップは、通常はハードウェアで行われているBBMとウェアレベリングを担当する何らかの種類のFTL(フラッシュ変換レイヤー)を実装しています。あなたのNANDフラッシュのスペックは確かにわかります – Mike