歡迎您光臨本站 登入註冊首頁

概述

寫在前面    現在linux對mtd設備支持的好得多,遠沒有我當時(大概2.5年前吧)做得那麼複雜了,這裡仍然要發原文,是因為想給初學者提供一個參考思路,介紹……

寫在前面
     現在linux對mtd設備支持的好得多,遠沒有我當時(大概2.5年前吧)做得那麼複雜了,這裡仍然要發原文,是因為想給初學者提供一個參考思路,介紹一下我對linux的學習了解的整個過程,希望對大家有借鑒意義。但是,建議還是使用最新的mtd補丁,新版本的mtd包括了對2k page 的nand flash的支持,要使用大於128MB的Nand flash,就用這個吧。文件系統方面,建議在Nor flash上,使用jffs2(jffs3也有,但是,我沒用過,沒有發言權)。在Nand flash上強烈建議使用yaffs,這比jffs2快很多,而且支持direct模式,在其他系統,比如:uCOS-II、winCE等都可以使用。我已經做到了在uCOS-II下和Linux下通過yaffs文件系統實現共享。但是,要想使用2k page的nand flash,只有使用yaffs2了。現在,yaffs2開源的代碼有點問題,不能直接和mtd設備配合使用,稍作修改可以實現,有興趣,我可以專門再寫一片yaffs2的移植心得。

下面是,很早以前的心得了.....

uclinux下Nand Flash的JFFS2文件系統的移植
    繼續上一篇《uClinux下移植Ne2000兼容的網卡驅動程序》中介紹的平台和操作系統,開始寫JFF2的感想。雖然JFFS2的移植弄出來有一段時間了,但是,前一段時間忙著期末考試,無心寫心得。昨天總算考完了,我就繼續羅嗦那段時期的經歷吧,希望把我遇到的問題和解決的方法和大家共享。錯誤之處也請不吝指出。

    我使用的uClinux的硬體平台還是44B0那個板子具體的情況參見《uClinux下移植Ne2000兼容的網卡驅動程序》中的介紹。Flash我用的是三星公司的K9F2808——16MByte的Nand Flash。

    開始,先看看有沒有其他人的經驗或者文章什麼。用uclinux和jffs2關鍵詞google了一下,找到了很多亂七八糟的東西,感覺唯一有用的也就是《The Linux MTD, JFFS HOWTO》,這篇文章寫的比較細,我就是看這個逐漸地入了門。

    首先,make menuconfig,把mtd打開。可是,發現我拿到的內核中,沒有這個mtd選項。比較一下,發現uClinux-dist-20030305裡面,編譯4510的時候,就有mtd這個選項。比較鬱悶,不過還是不甘心,仔細看看arch/armnommu/config.in文件,發現如下:

if [ "$CONFIG_ALIGNMENT_TRAP" = "y" ]; then
source drivers/mtd/Config.in
fi

    這就是問題了。不過還是不清楚這個CONFIG_ALIGNMENT_TRAP是幹什麼的。從字面上猜測可能是處理非對齊異常的。不過,如果我在前面定義了CONFIG_ALIGNMENT_TRAP,那麼我的內核就不能正常的運行,看了半天源碼,也沒看懂,算了,索性把這個就給註釋掉了(因為uClinux-dist-20030305裡面就沒有這個if)。這樣,mtd就可以使用了。

    接下來就是定製內核,在MTD中,開啟CONFIG_MTD_PARTITIONS、CONFIG_MTD_CHAR、CONFIG_MTD_BLOCK,選中NAND Device Support中的全部選項(因為我用的是Nand Flash)。再到File system中選重JFFS2文件系統。

    系統是怎麼載入底層的Flash設備呢,很容易在/drivers/mtd/nand/目錄下找到相關的代碼。先看看Makefile,有如下一行:

obj-$(CONFIG_MTD_NAND_SPIA) = spia.o

    看來只有編譯的時候定義了CONFIG_MTD_NAND_SPIA,spia.c才可以被編譯。spia.c是一個關鍵的問題,Nand Flash的驅動程序就是從這裡載入的。我不想改spia.c中的東西,就照著spia.c複製了一個文件arm_nand.c,在/drivers/mtd/nand/Makefile中添加

obj-$(CONFIG_MTD_NAND_ARM) =arm_nand.o

並修改drivers/mtd/nand/config.in文件,添加如下內容:

if [ "$CONFIG_ARM" = "y" ]; then
dep_tristate 'NAND Flash device on ARM board' CONFIG_MTD_NAND_ARM $CONFIG_MTD_NAND
fi

    這樣,在定製內核的時候,只要是ARM的開發平台就可以使用我的這個arm_nand.c驅動程序了。這個arm_nand.c代碼(原來的spia.c),很容易讀懂,就是不熟悉Nand Flash的人,對照著晶元的Datasheet也很快就能看明白,需要改的就是你的板子上的Nand Flash幾個控制信號線(主要是ALE、CLE、CE)的地址,輸入輸出的地址等等。我為了以後方便,把這些地址都通過宏定義放到了config.in中。


然後,在arm_nand.c代碼中,最關鍵的就是partition_info的定義,我改成如下:

const static struct mtd_partition partition_info[] = {
/* { name: "SPIA flash partition 1",
offset: 0,
size: 2*1024*1024 },*/
#ifdef CONFIG_ARCH_S3C44B0
{ name: "Nand flash partition",
offset: 2*1024*1024,
size: 14*1024*1024 }
#endif
};

#define NUM_PARTITIONS 1

很容易理解,因為我的nand flash中,前2M的空間,用於存放uclinux的kernel和romdisk,啟動的時候通過bootloader載入到內存中。所以,這個空間是不能用的。剩下的14MB,就是劃分成一個Flash盤準備上JFFS2了。

這樣,似乎就可以了。編譯內核,然後運行,結果有如下錯誤:

readb called, but not implemented<2>kernel BUG at traps.c

readb的這個問題其實很簡單,用SourceInsight跟蹤基層調用就知道,是因為在我的44b0的這個移植版本中根本就沒有readb的定義,在include/asm-armnommu/arch-s3c44b0/io.h文件中添加:

#define readb(b) __arch_getb(b)
#define readw(b) __arch_getw(b)
#define readl(b) __arch_getl(b)
#define writeb(v,b) __arch_putb(v,b)
#define writew(v,b) __arch_putw(v,b)
#define writel(v,b) __arch_putl(v,b)

其中__arch_xxx也是在這個文件中定義,或者可以乾脆直接(*(volatile unsigned xxx *)(xxx))。好了,系統啟動,果然,找到Nand Flash:

NAND device: Manufacture ID: 0xec, Chip ID: 0x73 (Samsung KM29U128T)
Creating 1 MTD partitions on "Samsung KM29U128T":
0x00200000-0x01000000 : "Nand flash partition"
mtd: Giving out device 0 to Nand flash partition

系統啟動以後,用cat /proc/mtd,可以顯示如下信息。

dev: size erasesize name
mtd0: 00e00000 00004000 "Nand flash partition"

沒錯了,Nand Flash的信息,容量,還有擦除的block的大小都沒有問題。

然後,按照《The Linux MTD, JFFS HOWTO》所說,編譯mtd工具,我是從網上下的mtd-snapshot-20030508,用mkfs.jffs2生成jffs2的映象文件(jffs2.img),這個和genromfs差不多。然後,在交叉編譯mtd-snapshot-20030508,主要是用erase來擦除Flash。

接著,編輯romdisk,在/dev目錄下,建立創建文件@mtd0,c,90,0、@mtdblock0,b,31,0。這就是用來訪問的設備了。前者是字元設備類型,後者是block類型。

下面就可以用在目標板上

cp /var/mnt/jffs2.img /dev/mtd0

把前面生成的jffs2格式的映象複製到mtd0設備中就是我們的Nand Flash了。

結果,發現系統死掉了。5555555555

在內核中把所有的跟蹤信息開啟,發現系統是在drivers/mtd/nand/nand.c中的nand_write_ecc中死掉了。用printk繼續定位,把結果鎖定在了下面的調用

wake_up (&this->wq);

因為我對系統內核不了解,當時連這個wake_up的函數是幹什麼的都不知道:(,用SourceInsight跟蹤了好幾天都沒有頭緒,最後,乾脆放棄了,整天上課的時候捧著一本《Linux內核源碼情景分析》來看(主要是上冊),感覺寫得不錯,幾天下來,收穫頗豐。不過,感還是不能解決前面的問題……


[admin via 研發互助社區 ] uclinux下Nand Flash的JFFS2文件系統的移植已經有4863次圍觀

http://cocdig.com/docs/show-post-42400.html