如何在44B0開發板ARMSYS上建立基於Nandflash的JFFS2文件系統

    本文描述了如何基於一款以S3C44B0X為核心的ARMSYS開發板的基礎上建立Nandflash的MTD(Memory Technology Devices)驅動和JFFS2 (Journaling Flash File System2)文件系統。

關鍵詞:uClinux Nandflash MTD JFFS2 文件系統 S3C44B0X ARMSYS

本文參考資料:
    有關MTD和JFFS2的基礎知識:http://www.linux-mtd.infradead.org/tech/nand.html
    uClinux下MTD和JFFS2在M5407C3開發板上的移植:
     http://www.enseirb.fr/~kadionik/embedded/uclinux/mtd/howto_mtd.html

點擊這裡下載該文檔的pdf文件:

1.概述

1.1關於Nandflash

    以S3C44B0X為核心的ARMSYS開發板採用的Nandflash是三星公司的K9F2808芯片。它的存儲空間以頁為單位。1頁是由 512字節的數據和16字節的備用空間組成(備用空間可以用來存儲ECC(糾錯碼),壞塊信息和文件系統相關的數據)。這裡我們僅考慮數據空間即可。因此 可以認為K9F2808每頁大小為512字節。32頁組成一個塊,因此塊的大小為16K(0x4小空間為0x4000字節。
    對芯片的讀/寫/擦除命令的寫入都是通過置高CLE引腳同時向I/O0~I/O7寫入命令代碼字節來完成。地址的寫入則是通過置高ALE引腳同時 寫入地址字節來完成。對Nandflash的操作僅需要對幾條信號線進行控制即可完成了。

    /RE和 /WE信號線則可以由相應的bank選擇線與CPU的/OE和/WE邏輯與來控制。在ARMSYS上是採用bank1選擇線,因此Nandflash在系統中的映射地址是0x200000。
I/O 0-7聯接到CPU的數據總線D0-D7(D15). /WP直接接VCC而/SE直接接地即可。
    R/B,/CE,CLE ,ALE和都應當聯接CPU的GPIO引腳。ARMSYS中採用了PC0~PC3。
以上都是對我們移植MTD有用的信息。可以通過查看K9F2808的Datasheet來了解關於該器件更詳細的信息。

1.2關於支持Nandflash的文件系統

    現在僅有少量的文件系統支持各種類型的Nandflash設備:

  • JFFS2 和 YAFFS 支持 NAND Flash芯片和 SmartMediaCard(智能多媒體卡)
  • NTFL支持 DiskOnChip 設備  
  • 來自 M-Systems的TRUEFFS支持 DiskOnChip設備
  • 由SSFDC論壇定義的SmartMedia(智能多媒體卡)的 DOS-FAT 文件系統

    其中JFFS2 是一個開源的文件系統。JFFS2支持原始的NAND芯片同時支持SmartMediaCard。關於JFFS2的詳細信息可以查看http://sources.redhat.com/jffs2/ 。JFFS2還提供文件的壓縮和解壓服務,這對小型的flash很有用處。JFFS2中包括了對壞塊的管理,糾錯並提供在Nandflash上使用的可用於工業用途的可靠穩定的文件系統。

1.3軟件層次

JFFS2的建立包括4個層次:

a) JFFS2:文件系統驅動
b) MTD:存儲技術設備驅動Memory Technology Devices driver
c) NAND:通用Nand驅動
d) 特定的硬件驅動

其中MTD驅動提供給JFFS2一個掛載點。通用NAND驅動提供必要的識別、讀、寫和擦除功能。與特定的硬件相關的功能函數則由底層的硬件驅動提供。

2.準備工作

2.1解壓uClinux移植包

我們還是採用uClinux在ARMSYS上的移植包:uClinux-ARMSYS-20040801.tar.gz來完成JFFS2的移植的工作。
uClinux-ARMSYS-20040801.tar.gz是移植自uClinux-dist-20040408.tar.gz,在很多方面比早先的 20030522版本要完善很多,這也使我們的工作變得方便很多。這裡我們使用的內核版本是Linux 2.4.24。
將uClinux-ARMSYS-20040801.tar.gz拷貝到/home/下,運行解壓:

tar xvzf uClinux-ARMSYS-20040801.tar.gz

解壓結束後會在/home/下生成uClinux-dist目錄。

2.2安裝編譯環境
將arm-elf-tools-20030314.sh拷貝到根目錄,運行安裝:

sh arm-elf-tools-20030314.sh

3.修改drivers/mtd/nand/下的幾個文件

3.1修改Config.in

    在文件Linux-2.4.x/drivers/mtd/nand/Config.in查找到CONFI_CPU_S3C44B0X,在其中加入一行(以下用粗體顯示)對於ARMSYS開發板的選項:

if [ "$CONFIG_CPU_S3C44B0X" = "y" ]; then
dep_tristate ' NAND Flash device on FS44B0-CORE V2.00 board' CONFIG_MTD_NAND_S3C44B0X $CONFIG_MTD_NAND
dep_tristate ' NAND Flash device on ARMSYS board' CONFIG_MTD_NAND_ARMSYS $CONFIG_MTD_NAND
fi
這樣在後面進行配置(make menuconfig)時就可以看到關於ARMSYS的選項了。

3.2修改Makefile

在文件Linux-2.4.x/drivers/mtd/nand/Makefile中,加入一行(以下用粗體顯示):

#
# linux/drivers/nand/Makefile
#
# $Id: Makefile,v 1.10 2002/12/01 13:23:05 gleixner Exp $

O_TARGET := nandlink.o

export-objs := nand.o nand_ecc.o nand_ids.o

obj-$(CONFIG_MTD_NAND) += nand.o nand_ecc.o
obj-$(CONFIG_MTD_NAND_SPIA) += spia.o
obj-$(CONFIG_MTD_NAND_AUTCPU12) += autcpu12.o
obj-$(CONFIG_MTD_NAND_EDB7312) += edb7312.o
obj-$(CONFIG_MTD_NAND_IDS) += nand_ids.o
obj-$(CONFIG_MTD_NAND_S3C44B0X) += s3c44b0x.o
obj-$(CONFIG_MTD_NAND_ARMSYS) += armsys_44b0x.o

include $(TOPDIR)/Rules.make

這樣在運行對內核的Make時,就會編譯我們待會要加入的armsys_44b0x.c文件了。

3.3加入armsys_44b0x.c文件

    在Linux-2.4.x/drivers/mtd/nand/目錄下加入armsys_44b0x.c文件。該文件可以在這裡下載。armsys_44b0x.c文件是基於同一目錄中的其它文件修改的。例如spia.c文件。armsys_44b0x.c只需要根據ARMSYS的硬件電路(參考第1.1節)在上面做一些修改就可以了。
主要做了修改的幾處如下:

第一處,
#define ARMSYS_IO_BASE 0x01d20000 /*GPIO相關寄存器的起始地址*/
#define ARMSYS_FIO_BASE 0x2000000 /*Nandflash映射的起始地址*/
#define ARMSYS_PEDR 0x0014
/* 控制CLE,ALE和NCE腳的port C的數據寄存器相對於GPIO寄存器起始地址的偏移量*/
#define ARMSYS_PEDDR 0x0010
/*控制CLE,ALE和NCE腳的port C的控制寄存器相對於GPIO寄存器起始地址的偏移量*/

第二處
#ifdef CONFIG_MTD_PARTITIONS
/*
* 定義flash設備的分區
*/
const static struct mtd_partition partition_info[] = {
{ name: "ARMSYS flash partition 1",
offset: 2*1024*1024,
size: 6*1024*1024 },
{ name: "ARMSYS flash partition 2",
offset: 8*1024*1024,
size: 6*1024*1024 }

};
#define NUM_PARTITIONS 2
#endif

第三處,
/*
* 特定硬件的控制線操作
*/
void armsys_hwcontrol(int cmd){

switch(cmd){

case NAND_CTL_SETCLE: (*(volatile unsigned *) (armsys_io_base + armsys_pedr)) |= 0x04; break;
case NAND_CTL_CLRCLE: (*(volatile unsigned *) (armsys_io_base + armsys_pedr)) &= ~0x04; break;

case NAND_CTL_SETALE: (*(volatile unsigned *) (armsys_io_base + armsys_pedr)) |= 0x08; break;
case NAND_CTL_CLRALE: (*(volatile unsigned *) (armsys_io_base + armsys_pedr)) &= ~0x08; break;

case NAND_CTL_SETNCE: (*(volatile unsigned *)(armsys_io_base + armsys_pedr)) &= ~0x02; break;
case NAND_CTL_CLRNCE: (*(volatile unsigned *) (armsys_io_base + armsys_pedr)) |= 0x02; break;
     }
}

第四處,
/*設置GPIO Port C 的控制寄存器從而使得Nandflash對應的控制引腳的輸入/輸出配置正確 */
(*(volatile unsigned *) (armsys_io_base + armsys_peddr)) = 0x0f00ff54;

4.添加mtdX和mtdblockX設備
修改/vendors/Samsung/44B0/Makefile文件。
在DEVICES = \
………
的最後加上:
(Tab)\
(Tab)mtd0,c,90,0(Tab)mtd1,c,90,2
(Tab)\
(Tab)mtdblock0,b,30,0(Tab)mtdblock1,b,30,1

這裡(Tab)表示輸入Tab鍵

5.配置內核
下面就可以開始配置內核和用戶選項了。
打開終端。
# cd /home/uClinux-dist
# make menuconfig

進入uClinux配置(uClinux v3.1.0 Configuration),選中「Kernel/Library/Defaults Selectionà」敲空格進入。選中內核設置項和用戶選項:
[*] Customize Kernel Settings
[*] Customize Vendor/User Settings

建議通過直接載入我們提供的內核配置文件Config_Kernel(點擊這裡下載)和用戶配置文件Config_User(點擊這裡下載)來完成配置。將Config_Kernel拷貝到uClinux-dist/Linux-2.4.x目錄下,將Config_User拷貝到uClinux-dist/Config目錄下。

回到終端,按下ESC鍵兩次,敲回車退出。進入內核配置(Linux Kernel v2.4.24-uc0 Configuration),選中「Load an Alternate Configuration File」,敲空格鍵進入,輸入Config_Kernel文件名,按回車退出。內核選項就被設置好了。

按下ESC鍵,敲回車保存設置。自動切換到用戶選項配置。同樣選中「Load an Alternate Configuration File」,敲空格鍵進入,輸入Config_User文件名,按回車退出。用戶選項就被設置好了。

也可以手動修改。手動修改的步驟如下:
進入內核配置(Linux Kernel v2.4.24-uc0 Configuration)。

5.1選擇支持可載入的模塊
選中「Loadable mudule supportà」,敲空格進入。選中第1項:
[*] Enable loadable module support
按ESC退出。

5.2對MTD進行配置
選中「Memory Technology Device (MTD)-->」,敲空格進入。需要選中的項目如下:

<*> Memory Technology Device (MTD) support
[*] Debugging
(0) Debugging verbosity (0= quiet, 3=noisy)
<*> MTD partitioning support
………
--- User Modules And Translation Layers
<*> Direct char device access to MTD devices
<*> Caching block device access to MTD devices

選中「NAND Flash Device Drivers -à」,敲空格進入。需要選中的項目如下:

<*> NAND Device Support
………
<*> NAND Flash device on ARMSYS board
這一條就是我們修改前面的Config.in文件的結果。
敲兩次ESC退出MTD配置。

5.3對文件系統進行配置
選中「File system -->」,敲空格進入。需要選中的項目如下:
<*> Journalling Flash File System v2 (JFFS2) support
(0) JFFS2 debugging verbosity (0 = quiet, 2 = noisy )
敲兩次ESC,敲回車,退出內核配置。

6.配置用戶選項

進入用戶選項配置。

6.1對MTD工具進行配置

選中「Flash Tools-->」,敲空格鍵進入。需要選中的項目如下:
[*] mtd-utils
[*] erase
[*] eraseall
………
[*] mkfs.jffs2
敲ESC鍵退出。

6.2對BusyBox進行配置

選中「BusyBox-->」,敲空格鍵進入。需要選中的項目如下:
………
[*] mount
………
[*] umount
………
[*] vi
敲2次ESC鍵,並回車保存。
到此為之,所需的配置選項就全部設好了。下面就開始編譯了。

7.編譯uClinux

按下面的步驟進行編譯:

# make dep
# make lib_only
# make user_only
# make romfs
# make image
# make

編譯成功後,在uClinux-dist/目錄下產生images目錄,其中的3個文件:image.ram, image.rom和romfs.img就是我們可以使用的二進制文件。

8.下載與啟動

8.1下載

利用ARMSYS提供的Bootloader通過USB接口下載2個二進制文件:

l image.ram(文件改名為imageram.bin)下載到地址0x0c008000;
l romfs.img(文件改名為romfs.img)下載到地址0x0c600000;

8.2啟動

從0xc008000地址處開始運行,可以從超級終端上觀察到如下所示的輸出信息:

Linux version 2.4.24-uc0 (root@localhost) (gcc version 2.95.3 20010315 (release)
(ColdFire patches - 20010318 from http://fiddes.net/coldfire/)(uClinux XIP and shared lib patches from http://www.snapgear.com/)) #108 六 9月 25 20:11:04 CST 2004
Processor: Samsung S3C44B0X revision 0
Architecture: S3C44B0X
On node 0 totalpages: 2048
zone(0): 0 pages.
zone(1): 2048 pages.
zone(2): 0 pages.
Kernel command line: root=/dev/rom0 init=/linuxrc
Calibrating delay loop... 31.84 BogoMIPS
Memory: 8MB = 8MB total
Memory: 6900KB available (970K code, 152K data, 36K init)
Dentry cache hash table entries: 1024 (order: 1, 8192 bytes)
Inode cache hash table entries: 512 (order: 0, 4096 bytes)
Mount cache hash table entries: 512 (order: 0, 4096 bytes)
Buffer cache hash table entries: 1024 (order: 0, 4096 bytes)
Page-cache hash table entries: 2048 (order: 1, 8192 bytes)
POSIX conformance testing by UNIFIX
Linux NET4.0 for Linux 2.4
Based upon Swansea University Computer Society NET3.039
Starting kswapd
JFFS2 version 2.1. (C) 2001 Red Hat, Inc., designed by Axis Communications AB.
ttyS0 at I/O 0x1d00000 (irq = 3) is a S3C44B0
ttyS1 at I/O 0x1d04000 (irq = 2) is a S3C44B0
Blkmem copyright 1998,1999 D. Jeff Dionne
Blkmem copyright 1998 Kenneth Albanowski
Blkmem 1 disk images:
0: C600000-C65FFFF [VIRTUAL C600000-C65FFFF] (RO)
RAMDISK driver initialized: 16 RAM disks of 1024K size 1024 blocksize
NAND device: Manufacture ID: 0xec, Chip ID: 0x73 (Samsung NAND 16MB 3,3V)
Creating 2 MTD partitions on "NAND 16MB 3,3V":
0x00200000-0x00800000 : "ARMSYS flash partition 1"
mtd: Giving out device 0 to ARMSYS flash partition 1
0x00800000-0x00e00000 : "ARMSYS flash partition 2"
mtd: Giving out device 1 to ARMSYS flash partition 2

VFS: Mounted root (romfs filesystem) readonly.
Freeing init memory: 36K
Shell invoked to run file: /etc/rc
Command: hostname Samsung
Command: /bin/expand /etc/ramfs.img /dev/ram0
Command: mount -t proc proc /proc
Command: mount -t ext2 /dev/ram0 /var
Command: mkdir /var/config
Command: mkdir /var/tmp
Command: mkdir /var/log
Command: mkdir /var/run
Command: mkdir /var/lock
Command: cat /etc/motd
Welcome to
____ _ _
/ __| ||_|
_ _| | | | _ ____ _ _ _ _
| | | | | | || | _ \| | | |\ \/ /
| |_| | |__| || | | | | |_| |/ \
| ___\____|_||_|_| |_|\____|\_/\_/
| |
|_|

For further information check:
http://www.uclinux.org/

Command:
Execution Finished, Exiting

Sash command shell (version 1.1.1)
/>

其中的黑體部分說明系統已經識別到了K9F2808器件,並創建了2個MTD分區。還可以到proc目錄中看一下MTD分區表:
/> cd proc
/proc> cat mtd
dev: size erasesize name
mtd0: 00600000 00004000 "ARMSYS flash partition 1"
mtd1: 00600000 00004000 "ARMSYS flash partition 2"

/proc>

到dev目錄下查看一下mtd設備:
/proc> cd /dev
/dev> ls
console
cua0
cua1
kmem
mem
mtd0
mtd1
mtdblock0
mtdblock1

null
ptyp0
………
urandom
zero
/dev>
有了上面的結果就說明MTD設備已經配置好了。下面我們就要創建一個JFFS2映像文件,並將它拷貝到MTD分區中。

9.創建和拷貝JFFS2映像文件

在目標板上運行以下的命令行:
/dev> cd /var/tmp
/var/tmp> mkdir jffs2
/var/tmp> c
/var/tmp/jffs2> vi file1
Hello, this is JFFS2 on Nandflash.
/var/tmp/jffs2> cat file1
Hello, this is JFFS2 on Nandflash.
/var/tmp/jffs2> mkdir folder1
/var/tmp/jffs2> mkdir folder2
/var/tmp/jffs2> mkdir folder3
/var/tmp/jffs2> cd ..
/var/tmp> mkfs.jffs2 -d jffs2 -o jffs2.img
/var/tmp> ls
jffs2
jffs2.img
/var/tmp>eraseall /dev/mtd0
………
/var/tmp> cp jffs2.img /dev/mtd0
MTD_open
MTD_write
MTD_close
/var/tmp>
同樣可以使用/dev/mtd1,那麼在下面的Mount中要使用mtdblock1。

10.Mount/umount JFFS2分區

10.1 Mount

在目標板上運行以下命令行:
/var/tmp> mount -t jffs2 /dev/mtdblock0 /mnt
/var/tmp>

這樣就mount上/mnt了。查看proc/mounts的內容:
/mnt> cd /proc
/proc> cat mounts
rootfs / rootfs rw 0 0
/dev/root / romfs ro 0 0
/proc /proc proc rw 0 0
/dev/ram0 /var ext2 rw 0 0
/dev/mtdblock0 /mnt jffs2 rw 0 0
/proc>

我們還可以看看現在mnt下面的內容:
/var/tmp> cd /mnt
/mnt> ls
file1
folder1
folder2
folder3
/mnt> cat file1
Hello, this is JFFS2 on Nandflash.
/mnt>
這樣我們就可以在/mnt下操作Nandflash中的文件內容。例如:
/mnt> rm file1
/mnt> vi file2
This is ARMSYS board.
/mnt> ls
file2
folder1
folder2
folder3
/mnt>

10.2 umount
在開發板上運行以下命令行:
/> umount /mnt
/> cd mnt
/mnt> ls
/mnt>

11.JFFS2文件系統的使用
由於Nandflash是非易失性的存儲器,因此保存在其中的內容不會隨掉電而消失。因此,在第一次成功完成了第9和第10步驟之後,以後只要直接運行第 10步的mount即可。我們可以試試看。關閉開發板電源,再重新打開,同樣下載和啟動uClinux。啟動後直接輸入如下的命令行:
/> mount -t jffs2 /dev/mtdblock0 /mnt
/> cd /mnt
/mnt> ls
file2
folder1
folder2
folder3
/mnt>
我們看到Nandflash中的第1分區還是保存著上次操作的內容。

如果你希望再每次uClinux啟動時,自動將Nandflash的第1分區mount到/mnt目錄,可以在/vendors/Samsung/44B0目錄下的rc文件中加入1行即可:
mount –t jffs2 /dev/mtdblock0 /mnt


arrow
arrow
    全站熱搜
    創作者介紹
    創作者 Bluelove1968 的頭像
    Bluelove1968

    藍色情懷

    Bluelove1968 發表在 痞客邦 留言(0) 人氣()