{"Samsung K9F1208U0B",NAND_MFR_SAMSUNG, 0x76, 26, 0, 3, 0x4000, 0}的分析

發佈一個patch,在附件中。該patch主要是針對Samsung flash芯片K9f1208U0B的體系結構信息進行設置。全部的修改該只有一行代碼,但是分析工作是更加重要,以下的陳述針對flash芯片的移植工作的流程以及思考方向。
   
    整個u-boot在arm體系環境下的引導過程是從lib_arm 目錄下board.c void start_armboot (void)函數開始的。在其中第305行,見到如下函數的調用。
 

nand_init();        /* go init the NAND */


    該函數的主要作用就是進行flash芯片的初始化工作。該函數位drivers/nand_legacy
/nand_legacy.c 文件的第99行。實現代碼很簡短如下所示:

void nand_init(void)
{
        S3C2410_NAND * const nand = S3C2410_GetBase_NAND();

        NF_Init();

        printf ("%4lu MB/n", nand_probe((ulong)nand) >> 20);
}


    其中在nand_probe()函數內實現了對flash芯片的掃描過程,提到掃描的過程就不得不涉及到一個非常重要的結構體nand_chip,這個結構體定義在include/linux/mtd/nand_legacy.h中。該結構體包含了很多關於flash結構信息的變量,並且在drivers/nand_legacy/nand_legacy.c的第217行定義瞭如下的數組:

    struct nand_chip nand_dev_desc[CFG_MAX_NAND_DEVICE] = {{0}};


    每個flash device都佔用一個該數組的節點。隨後在nand_probe()中第622行調用的NanD_IdentChip()函數,會讀取一個flash設備的ID信息,識別、並存放到nand_dev_desc[]中。NanD_IdentChip函數的原型如下:
   

static int NanD_IdentChip(struct nand_chip *nand, int floor, int chip)

  
    該函數的職責爲通過與flash芯片通訊獲得flash ID,併到已存在的一個flash硬件列表中去尋找ID所對應的芯片,並獲得該芯片所對應的flash的體系結構信息
    以上指責包括兩大重要操作:
          (1)讀取flash ID信息。
          (2)查找硬件列表。
    而通過(2)我們就可以直接的定位到移植點,並展開移植工作。

    在讀取ID結束後,該段代碼程序會爲兩個變量進行賦值,一個是fmr,另一個則是id。經過一些基本判斷工作後,將進入硬件列表的掃描過程中,代碼如下:

    for (i = 0; nand_flash_ids[i].name != NULL; i++) {
        if (mfr == nand_flash_ids[i].manufacture_id &&
            id == nand_flash_ids[i].model_id) {
#ifdef NAND_DEBUG
            printf("Flash chip found:/n/t Manufacturer ID: 0x%2.2X, "
                   "Chip ID: 0x%2.2X (%s)/n", mfr, id,
                   nand_flash_ids[i].name);
#endif
            if (!nand->mfr) {
                nand->mfr = mfr;
                nand->id = id;

    .........................
    .........................

  
    在掃描中,我發現它會去掃描一個結構體列表,並且比對mfr以及id的信息,這個結構體列表爲nand_flash_dev結構體類型的nand_flash_ids[],聲明在include/linux/mtd/nand_ids.h頭文件中,打開該頭文件,就可以看到這個結構體數組的信息:

static struct nand_flash_dev nand_flash_ids[] = {
{"Toshiba TC5816BDC",     NAND_MFR_TOSHIBA, 0x64, 21, 1, 2, 0x1000, 0},
{"Toshiba TC5832DC",      NAND_MFR_TOSHIBA, 0x6b, 22, 0, 2, 0x2000, 0},
              ..........................
{"Samsung Unknow 64M",    NAND_MFR_SAMSUNG, 0x76, 26, 0, 3, 0x4000, 0},
{"Samsung KM29W32000",    NAND_MFR_SAMSUNG, 0xe3, 22, 0, 2, 0x2000, 0},
{"Samsung unknown 4Mb",   NAND_MFR_SAMSUNG, 0xe5, 22, 0, 2, 0x2000, 0},


    而其中Samsung Unknow 64M就是在我輸入nand info時顯示給我的終端信息的一部分。因此有了一種豁然開朗的感覺。之後的任務就是搞清楚nand_flash_dev結構體的結構類型,並根據Samsung的數據手冊填寫結構體信息就可以解決flash芯片的移植問題了。

    該結構體定義在include/linux/mtd/nand_legacy.h中結構體如下:

struct nand_flash_dev {
    char * name;           //完整的設備名稱
    int manufacture_id;    // 表示生產商的編號
    int model_id;          //設備id號
    int chipshift;         //總共容納地址的位數
    char page256;          //flash的頁字節數是否爲256
    char pageadrlen;       //地址需要多少字節數減一(行列地址總共)
    unsigned long erasesize; //擦寫block的單位大小
    int bus16;             //是否爲16位總線
};


    根據以上的結構我在nand_flash_ids中填寫上了一個信的體系結構信息:

{"Samsung K9F1208U0B",NAND_MFR_SAMSUNG, 0x76, 26, 0, 3, 0x4000, 0},


    編譯燒寫後,運行nand info後出現的不再是Samsung unknow 64M,而是Samsung K9F1208U0B了。

    到此爲止,flash芯片的移植工作基本完成。

    題外話:
    nand info 命令就是通過訪問nand_dev_desc[]數組來顯示flash相關的信息的。代碼在common/cmd_nand.c中第696行:
   

    case 2:
        if (strcmp (argv[1], "info") == 0) {
            int i;

            putc ('/n');

            for (i = 0; i < CFG_MAX_NAND_DEVICE; ++i) {
                if (nand_dev_desc[i].ChipID ==
                    NAND_ChipID_UNKNOWN)
                    continue;    /* list only known devices */
                printf ("Device %d: ", i);
                nand_print (&nand_dev_desc[i]);
            }
            return 0;

 

 

 

轉載:http://blogold.chinaunix.net/u1/51351/showart_408277.html

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章