Wednesday, August 20, 2008

MTD study

partition assigning & tools of MTD

Target

  • Assigning MTD partition
    • from kernel source
    • from u-boot
  • 以 jffs2 格式,掛載 mtd device (Nand Flash)
  • Cross Compiling mtd-utils for arm
  • Modify ramdisk by cpio
  • mtd-utils test

Assigning MTD partition

  • from kernel source
    • 預設會讀取 kernel soruce 裡的定義,在此為 arch/arm/mach-omap2/board-2430sdp-flash.c
    • 修改 mtd_partition nand_partitions 以符合所需
      static struct mtd_partition nand_partitions[] = {
      {
      .name = "XLDR",
      .offset = 0,
      .size = 8*(32*512), /* 128 KB */
      .mask_flags = MTD_WRITEABLE /* force read-only */
      },
      {
      .name = "UBOOT",
      .offset = MTDPART_OFS_APPEND,
      .size = 16*(32*512), /* 256 KB */
      .mask_flags = MTD_WRITEABLE /* force read-only */
      },
      {
      .name = "uKernel",
      .offset = MTDPART_OFS_APPEND,
      .size = 1408*1024,
      },
      {
      .name = "uRamdisk",
      .offset = MTDPART_OFS_APPEND,
      .size = 3*1024*1024, /* 3 MB */
      },
      {
      .name = "UnUsed",
      .offset = MTDPART_OFS_APPEND,
      .size = MTDPART_SIZ_FULL,
      },
      };
  • from u-boot
    • 確定 kernel source configure 中有開啟 CONFIG_MTD_CMDLINE_PARTS
    • 確定 u-boot source 中 CONFIG_BOOTCOMMAND 設定正確。(include/configs/omap2430sdp.h)
      #define CONFIG_BOOTCOMMAND "nand read 80F00000 60000 160000;
      nand read 84000000 1C0000 300000;bootm 80F00000 84000000"
      • 將 image 從 flash_address=60000 搬到 ram_address=80F00000, size=160000
        • 0x160000 = 1408K (uKerkel)
      • 將 image 從 flash_address=1C0000 搬到 ram_address=84000000 , size=300000
        • 0x300000 = 3M (uRamdisk)
      • bootm: boot application image from memory
    • mtd 的 name 必需與 kernel source 中定義的名字一樣,才會有效。
      • kernel source, arch/arm/mach-omap2/board-2430sdp-flash.c
        static struct platform_device sdp_nand_device = {
        .name = "omap2-nand",
        .id = -1,
        .dev = {
        .platform_data = &sdp_nand_data,
        },
        };
      • 確定 u-boot source CONFIG_BOOTARGS 設定正確。 u-boot source, include/configs/omap2430sdp.h
        #define CONFIG_BOOTARGS "root=/dev/ram0 console=ttyS2,115200n8
        mtdparts=omap2-nand:128K(XLoad),256K(UBoot),1408K(uKernel),3M(uRamdisk),-(unused)"
  • 確定 mtd partition 是否正確
    • cat /proc/mtd
    • demsg

Mount mtd device (NAND Flash) with jffs2

  • 確定 kernel 中的 CONFIG_JFFS2_FS=y 有選取,否則會造成無法掛載,Errmsg: No Such Device
    mount -t jffs2 /dev/mtdblock3 /mnt

Cross Compiling mtd-utils for arm

  • Cross compile zlib
    wget http://www.zlib.net/zlib-1.2.3.tar.gz
    tar xzvf zlib-1.2.3.tar.gz
    cd zlib-1.2.3
    CC=arm-none-linux-gnueabi-gcc LDSHARED="arm-linux-ld -shared" ./configure --shared
    make
    make prefix=/home/ryan/armlinux/zlib install
  • Cross compile lzo
    wget http://www.oberhumer.com/opensource/lzo/download/lzo-2.03.tar.gz
    tar xzvf lzo-2.03.tar.gz
    cd lzo-2.03
    CC=arm-none-linux-gnueabi-gcc ./configure --host=arm-linux --prefix=/home/ryan/armlinux/lzo
    make
    make install
  • Cross compile mtd-utils
    # apt-get install git-core
    git clone git://git.infradead.org/mtd-utils.git
    cd mtd-utils
    vi Makefile
    make WITHOUT_XATTR=1
    • 必需修改 Makefile
      ryan@ryan-ubuntu8:~/git$ diff mtd-utils/Makefile mtd-utils.git/Makefile -u
      --- mtd-utils/Makefile 2008-08-06 15:05:03.000000000 +0800
      +++ mtd-utils.git/Makefile 2008-08-06 15:06:53.000000000 +0800
      @@ -6,8 +6,14 @@
      SBINDIR=$(EXEC_PREFIX)/sbin
      MANDIR=$(PREFIX)/share/man
      INCLUDEDIR=$(PREFIX)/include
      +ZLIBCPPFLAGS=-I/home/ryan/armlinux/zlib/include
      +LZOCPPFLAGS=-I/home/ryan/armlinux/lzo/include
      +ZLIBLDFLAGS=-L/home/ryan/armlinux/zlib/lib
      +LZOLDFLAGS=-L/home/ryan/armlinux/lzo/lib

      -#CROSS=arm-linux-
      +CROSS=arm-none-linux-gnueabi-
      CC := $(CROSS)gcc
      CFLAGS ?= -O2 -g
      CFLAGS += -Wall
      @@ -47,7 +53,7 @@
      .SUFFIXES:

      all: $(TARGETS)
      - make -C $(BUILDDIR)/ubi-utils
      + make -C ubi-utils

      IGNORE=${wildcard $(BUILDDIR)/.*.c.dep}
      -include ${IGNORE}
      • ZLIBCPPFLAGS, LZOCPPFLAGS, ZLIBLDFLAGS, LZOLDFLAGS 是用來指定所需的 zlib/lzo 的 include/lib 在何處,所以在cross compile時需要由我們自行指定
      • make WITHOUT_XATTR=1,make command to compile without Posix ACL。若無指定時會出現以下錯誤時 Ref
        > mips-linux-cc -I./include -g -O3 -G0 -pipe -fpic -fPIC -msoft-float
        > -mabi=32 -march=mips32r2 -mtune=34kc -g -c -o mkfs.jffs2.o mkfs.jffs2.c
        > -g -Wp,-MD,./.mkfs.jffs2.c.dep
        > mkfs.jffs2.c:69:21: sys/acl.h: No such file or directory
        > mkfs.jffs2.c: In function `formalize_posix_acl':
        > mkfs.jffs2.c:1084: error: `ACL_USER_OBJ' undeclared (first use in this
        .....


Modify ramdisk by cpio

  • 解壓縮
    mkdir ramdisk
    cd ramdisk
    cpio -i -F ../ramdisk.cpio
  • 打包
    find ./ -print | cpio -ivH newc -O ../ramdisk.cpio
  • 當 ramdisk size 有更改,需要調整 size 時,有幾處需要更改 (kernel, uboot, ReadyImageForOST.bat),在此假設 ramdisk 調整為4M
    • u-boot/include/configs/omap2430sdp.h
       #define CFG_NAND_BOOT
      -#define CONFIG_BOOTCOMMAND "nand read 80F00000 60000 160000;
      nand read 84000000 1C0000 300000;bootm 80F00000 84000000"
      +#define CONFIG_BOOTCOMMAND "nand read 80F00000 60000 160000;
      nand read 84000000 1C0000 400000;bootm 80F00000 84000000"
      //#define CFG_NO_FLASH I like to add this one but...
      //#define CFG_NAND_LEGACY
      //#define CFG_ENV_IS_IN_NAND
      @@ -160,7 +160,7 @@
    • 注意kernel 裡定義 mtd partition 的地方 或 u-boot CONFIG_BOOTARGS 要改,不然操作時會出現未知的錯誤(ex: erase/write/read 錯地方,因為 partition 配置錯誤)

mtd-utils test

  • 確認所規劃的 mtd 是否正常, Ref
    bash-3.2# cat /proc/mtd
    dev: size erasesize name
    mtd0: 00020000 00020000 "XLDR"
    mtd1: 00040000 00020000 "UBOOT"
    mtd2: 00160000 00020000 "uKernel"
    mtd3: 00400000 00020000 "uRamdisk"
    mtd4: 00040000 00020000 "Test1"
    mtd5: 00100000 00020000 "Test2"
    mtd6: 0f900000 00020000 "UnUsed"
    #mtd_debug info /dev/mtdX (不能使用mtdblockX, mtdblockX 只是提供用來 mount 而已)
    bash-3.2# mtd_debug info /dev/mtd5
    <6>MTD_open
    MTD_open
    <6>MTD_ioctl
    MTD_ioctl
    <6>MTD_ioctl
    MTD_ioctl
    mtd.type = MTD_NANDFLASH<6>MTD_close
    MTD_close

    mtd.flags = MTD_CAP_NANDFLASH
    mtd.size = 1048576 (1M)
    mtd.erasesize = 131072 (128K)
    mtd.writesize = 2048 (2K)
    mtd.oobsize = 64
    regions = 0
  • 將 /dev/mtd5 裡的資料以 HEX 方式 dump 出來看
    nand_dump -p -f /tmp/mtd3 /dev/mtd3
    less /tmp/mtd5
  • erase 完後,再 dump 出來看看,會發現 erase 的部份,數值均為 ff
    flash_erase /dev/mtd5

  • flashcp,若有出現 Attempt to write not page aligned data 的訊息,表示不按頁對齊的方式是不被允許的 (在此是指 2K)。我們可以以下列來操作,將寫滿了 0 的 2k 檔案寫入 flash 就ok了。
    dd if=/dev/zero of=/tmp/zero.img bs=1k count=2
    flashcp /tmp/zero.img /dev/mtd5
    #會發現寫入成功,此時可以 nanddump 出來看看,發現其值全為0

No comments: