08
22

JFFS2 file system-老而彌堅的檔案系統

會想寫這個東西的介紹是因為之前在酷學園看到有人提到如何在embedded system上做firmware upgrade, firmware upgrade每家公司的做法都不一樣,但目標都差不多,不外乎bootloader , linux kernel , file system upgrade,有強一點的公司還有做upgrade failure save的功能,而我這邊舉一個很簡單的例子,示範如何在embedded device上做linux kernel的upgrade,並且用jffs2 file system當我們的根檔案系統

JFFS2自2.6開始支援NAND Flash, NAND Flash與NOR Flash的設計理念差很多,為了cost down, NAND flash減少了在NOR Flash上不必要的位址線,改為page read/write方式存取,以QT2410的NAND Flash為例,一次的讀/寫,都是以512 byte為單位,所以Linux為了NAND Flash新增了NFTL(NAND Flash Transition Layer),NFTL最主要的目的,是讓EXT2,EXT3...等不是FLASH專屬的file system讀寫nand flash,而JFFS2或YAFFS都可以不透過NFTL進行FLASH read/write(2009.1.19修改),而細節部份小弟不多說了,google一找都一堆資料

我這邊的範例都是以QT2410為我的目標板,首先下載linux-2.6.26,修改Makefile,把ARCH改為arm,CROSS_COMPILE改為arm-linux-,修改完後,輸入指令make arch/arm/configs/s3c2410_defconfig,進入menuconfig並在MTD選單中選取NFTL support,接著再修改arch/arm/plat-s3c24xx/common-smdk.c這個檔案(修改於2008.9.23),找到smdk_default_nand_part並把這個structure內容修改如下(這邊的動作就是修改flash partition table,第一個partition是bootloader,第二個是linux kernel image,第三個是root file system)

  1. static struct mtd_partition smdk_default_nand_part[] = { 
  2. [0] = { 
  3. .name = "Boot Agent",
  4. .offset = 0,
  5. .size = SZ_256K,
  6. .mask_flags = MTD_CAP_ROM,
  7. },
  8. [1] = { 
  9. .name = "S3C2410 flash partition 1(Kernel)",
  10. .offset = SZ_2M,
  11. .size = SZ_4M,
  12. .mask_flags = MTD_CAP_ROM,
  13. },
  14. [2] = { 
  15. .name = "S3C2410 flash partition 2(File system)",
  16. .offset = SZ_8M,
  17. .size =SZ_8M,
  18. //.mask_flags = 0,
  19. } 
  20. }

修改完後就試著編譯kernel

接著開始製做jffs2 root file system,先cross compile busybox,再製作device符號表,這邊要特別注意device符號表中的mtd0,mtd1,mtd2和mtdblock0, mtdblock1, mtdblock2,上述的符號表一定要有,而且mtd0, mtd1, mtd2的minor number為0, 2 ,4(如果不這樣設定,無法進行flash erase),請參考下面圖片

下載mtd utility,並cross-compile,把flase_eraseall和nandwrite拷貝到root file system的/bin資料夾下,用mkfs.jffs2這個工具製做root file system,請參考下面範例

  1. mkfs.jffs2 --pad=0x00800000 --eraseblock=0x4000 -l -n --root=fs/ -o root.jffs2

mkfs.jffs的參數說明如下

(1)-r : 指定要做成image的源資料夾.
(2)-o : 指定輸出image檔案的文件名.
(3)-e : 每一塊要抹除的block size,預設是64KB.要注意,不同的flash, 其block size會不一樣.
(4)--pad (-p): 用16進制來表示所要輸出檔案的大小,也就是root.jffs2的size。很重要的是, 為了不浪費flash空間, 這個值最好符合flash driver所規劃的區塊大小.

最後修正u-boot的環境變數和kernel command,請參考下面範例

  1. wk=nand erase 200000 400000;tftp 30000000 uImage;nand write 30000000 200000 400000 
  2. wf=nand erase 800000 3e00000;tftp 32000000 root.jffs2;nand write 32000000 800000 0x00800000;tftp 30008000 uImage;bootm 
  3. bootcmd=nand read 30008000 200000 400000; bootm 30008000 
  4. bootargs=mem=64M console=ttySAC0 root=/dev/mtdblock2 rootfstype=jffs2

以我的flash partition table為例,我把kernel擺在mtd1,所以我只要針對這塊區域進行firmware upgrade即可,這邊假設新的kernel image為/usr/uImage,用以下步驟進行firmware upgrade
1. flash_eraseall /dev/mtd1
2. nandwrite -p /dev/mtd1 /usr/uImage
執行畫面如下所示

整個過程大致上是這樣,因為我還沒把網路驅動起來,所以先擺個kernel image在usr資料夾下,等下次有空再介紹cs8900a的linux drvier撰寫方式,和搭配web server做remote firmware upgrade

 

標籤: embedded
評論: 5 | 引用: 0 | 閱讀: 26882
  • 1 
Justin [ 2009-06-22 17:46 | 回覆 | 編輯 刪除 ]
想請教您一點,
您於內文中提到"而且mtd0, mtd1, mtd2的minor number為0, 2 ,4(如果不這樣設定,無法進行flash erase)",
請問這是什麼意思呢?
為何不能0,1,2呢?
感激不盡 :)
Joey [ 回復於2011-04-29 11:03 郵箱 | 編輯 刪除 ]
That is mtd rule. You can check mtd web sit.
http://www.linux-mtd.infradead.org/index.html
lin [ 2011-04-28 00:46 | 回覆 | 編輯 刪除 ]
如果要upgrade root file system 的話應該怎麼做呢?
因為如果系統正在讀那塊rootfs,但是又要蓋過他?
Joey [ 回復於2011-04-29 11:04 郵箱 | 編輯 刪除 ]
dual partition for dual boot
lin [ 2011-05-12 10:07 | 回覆 | 編輯 刪除 ]
您好 不太懂這個意思
dual partition for dual boot?
是說我要切兩塊都來放rootfs,只要更新過的話就去開另一塊,
我要怎麼利用uboot指令做到這樣呢?
當在升級的時候寫另一個分割區,然後重開機的時候要重那個分割區開起來

不知道有沒有範例可以參考
謝謝:)
  • 1 
發表評論
暱 稱: 密 碼:
網 址: E - mail:
驗證碼: 驗證碼圖片 選 項:
頭 像:
內 容: