안녕하세요. 예전에 윤구님하고 저하고 같이 mpc8xx에서 작업한 결과입니다.

MTD와 JFFS2를 이용한 플래시 파일 시스템의 구축
원본 작성: 정윤구 (ykjung@nexcomm.co.kr)
추가 수정: 이재훈 (kingseft@samsung.co.kr)

아래의 내용은 MTD Flahs Device Driver와 더불어 JFFS2 파일 시스템을 이용하
여 플래시 파일 시스템을 구축하는
과정을 정리한 문서이다.

[1단계] MTD 소스를 구하고 설치하기
홈페이지 : http://www.linux-mtd.infradead.org/
ftp : ftp://ftp.uk.linux.org/pub/people/dwmw2/mtd/cvs/
위의 싸이트에서 mtd snap-shot 압축파일을 다운로드 받고 적당한 디렉토리에
압축을 푼다.

압축이 풀린 디렉토리를 /2ndhard/mtd 라 가정하고 실제 리눅스 커널이 있는
디렉토리를 /2ndhard/linux-2.4.4
라고 가정하면 다음과 같이 /2ndhard/mtd 디렉토리의 세부 디렉토리의 내용들
을 이용하고자 하는 커널의
디렉토리들로 복사를 해준다.

mtd 디렉토리에 들어가서 다음과 같이 해당 내역을 커널 디렉토리로 복사하였
다.
cp -dpR kernel /2ndhad/temp2/linux-2.4.4-2001-05-12
cp -dpR fs /2ndhad/temp2/linux-2.4.4-2001-05-12
cp -dpR drivers /2ndhad/temp2/linux-2.4.4-2001-05-12
cp -dpR include /2ndhad/temp2/linux-2.4.4-2001-05-12
cp -dpR util /2ndhad/temp2/linux-2.4.4-2001-05-12


[2단계] 커널 옵션 설정하기
두번째로는 리눅스 커널 옵션의 설정부분이다.
실제 수정되어야 할 부분은 다음과 같다.
1. 램디스크는 이용하지 않는다. CONFIG_BLK_DEV_INITRD 는 선택되지 않아야
한다.
2. JFFS 파일 시스템을 선택한다. CONFIG_FS_JFFS 를 선택한다.
3. Denk의 Flash Device Driver 선택을 해제한다. CONFIG_FLASH 선택을 해제한
다.

전체적인 커널의 설정 부분은 다음과 같다.
먼저 MTD 관련 커널 설정은 다음과 같다.

Memory Technology Devices (MTD)
Arrow keys navigate the menu. selects submenus --->. Highlighted
letters are hotkeys. Pressing
includes, excludes, modularizes features. Press to exit, for
Help. Legend: [*] built-in
[ ] excluded module < > module capable


<*> Memory Technology Device (MTD) support
[ ] Debugging
<*> MTD partitioning support
< > RedBoot partition table parsing
< > Compaq bootldr partition table parsing
< > ARM Firmware Suite partition parsing
--- User Modules And Translation Layers
<*> Direct char device access to MTD devices
<*> Caching block device access to MTD devices
< > FTL (Flash Translation Layer) support
< > NFTL (NAND Flash Translation Layer) support
RAM/ROM/Flash chip drivers --->
Mapping drivers for chip access --->
Self-contained MTD device drivers --->
NAND Flash Device Drivers --->

===============================================================
RAM/ROM/Flash chip drivers
Arrow keys navigate the menu. selects submenus --->. Highlighted
letters are hotkeys. Pressing
includes, excludes, modularizes features. Press to exit, for
Help. Legend: [*] built-in
[ ] excluded module < > module capable


<*> Detect flash chips by Common Flash Interface (CFI) probe
< > Detect non-CFI AMD/JEDEC-compatible flash chips
[*] Flash chip driver advanced configuration options
(BIG_ENDIAN_BYTE) Flash cmd/query data swapping
[*] Specific CFI Flash geometry selection
[ ] Support 8-bit buswidth
[*] Support 16-bit buswidth
[ ] Support 32-bit buswidth
[*] Support 1-chip flash interleave
[ ] Support 2-chip flash interleave
[ ] Support 4-chip flash interleave
<*> Support for Intel/Sharp flash chips
< > Support for AMD/Fujitsu flash chips
< > Support for RAM chips in bus mapping
< > Support for ROM chips in bus mapping
< > Support for absent chips in bus mapping
[ ] Older (theoretically obsoleted now) drivers for non-CFI chips

==================================================================

Mapping drivers for chip access
Arrow keys navigate the menu. selects submenus --->. Highlighted
letters are hotkeys. Pressing
includes, excludes, modularizes features. Press to exit, for
Help. Legend: [*] built-in
[ ] excluded module < > module capable


< > CFI Flash device in physical memory map
< > Sun Microsystems userflash support
< > CFI Flash device mapped on Nora
< > CFI Flash device mapped on Photron PNC-2000
< > CFI Flash device mapped on RPX Lite or CLLF
<*> CFI Flash device mapped on TQM8XXL
< > CFI Flash device mapped on AMD SC520 CDP
< > CFI Flash device mapped on AMD NetSc520
< > CFI Flash device mapped on Arcom SBC-GXx boards
< > CFI Flash device mapped on Arcom ELAN-104NC
< > Flash chip mapping on ITE QED-4N-S01B, Globespan IVR or
custom board
< > CFI Flash device mapping on FlagaDM
< > JEDEC Flash device mapped on Mixcom piggyback card
< > JEDEC Flash device mapped on Octagon 5066 SBC
< > JEDEC Flash device mapped on Tempustech VMAX SBC301
< > Momenco Ocelot boot flash device
< > BIOS flash chip on Intel L440GX boards
==================================================================

다음으로는 Initrd 를 쓰지 않기 위하여 다음과 같이 설정하였다.

Block devices
Arrow keys navigate the menu. selects submenus --->. Highlighted
letters are hotkeys. Pressing
includes, excludes, modularizes features. Press to exit, for
Help. Legend: [*] built-in
[ ] excluded module < > module capable


< > Normal PC floppy disk support
<*> Loopback device support
< > Network block device support
< > RAM disk support

=====================================================================
다음으로는 JFFS 파일 시스템을 선택해 주어야 한다.

File systems
Arrow keys navigate the menu. selects submenus --->. Highlighted
letters are hotkeys. Pressing
includes, excludes, modularizes features. Press to exit, for
Help. Legend: [*] built-in
[ ] excluded module < > module capable


[ ] Quota support
< > Kernel automounter support
< > Kernel automounter version 4 support (also supports v3)
< > Reiserfs support
< > ADFS file system support
< > Amiga FFS file system support (EXPERIMENTAL)
< > Apple Macintosh file system support (EXPERIMENTAL)
< > BFS file system support (EXPERIMENTAL)
< > DOS FAT fs support
< > EFS file system support (read only) (EXPERIMENTAL)
<*> Journalling Flash File System (JFFS) support (EXPERIMENTAL)
(0) JFFS debugging verbosity (0 = quiet, 3 = noisy)
< > Compressed ROM file system support
[ ] Virtual memory file system support (former shm fs)
< > Simple RAM-based file system support
< > ISO 9660 CDROM file system support
< > Minix fs support
< > NTFS file system support (read only)
< > OS/2 HPFS file system support
[*] /proc file system support
[ ] /dev file system support (EXPERIMENTAL)
[*] /dev/pts file system for Unix98 PTYs
< > QNX4 file system support (read only) (EXPERIMENTAL)
< > ROM file system support
<*> Second extended fs support
< > System V and Coherent file system support (read only)
< > UDF file system support (read only)
< > UFS file system support (read only)
====================================================================

Character devices
Arrow keys navigate the menu. selects submenus --->. Highlighted
letters are hotkeys. Pressing
includes, excludes, modularizes features. Press to exit, for
Help. Legend: [*] built-in
[ ] excluded module < > module capable


[*] Virtual terminal
[ ] Support for console on virtual terminal
< > Standard/generic (8250/16550 and compatible UARTs) serial
support
[ ] Non-standard serial port support
[*] Unix98 PTY support
(256) Maximum number of Unix98 PTYs in use (0-2048)
I2C support --->
Mice --->
Joysticks --->
< > QIC-02 tape support
Watchdog Cards --->
< > /dev/nvram support
< > Enhanced Real Time Clock Support
< > Double Talk PC internal speech card support
< > Siemens R3964 line discipline
< > Applicom intelligent fieldbus card support
[ ] /dev/flash
Ftape, the floppy tape device driver --->
< > /dev/agpgart (AGP Support)
[ ] Direct Rendering Manager (XFree86 DRI support)
====================================================================


[3단계] 커널 설정후 .config 확인하기
- 위의 2단계와 같이 커널 설정을 마친후 최종적으로 .config 파일을 확인한
다.
실험에서 설정된 내역은 다음과 같다.

#
# Memory Technology Devices (MTD)
#
CONFIG_MTD=y
# CONFIG_MTD_DEBUG is not set
CONFIG_MTD_PARTITIONS=y
# CONFIG_MTD_REDBOOT_PARTS is not set
# CONFIG_MTD_BOOTLDR_PARTS is not set
# CONFIG_MTD_AFS_PARTS is not set
CONFIG_MTD_CHAR=y
CONFIG_MTD_BLOCK=y
# CONFIG_FTL is not set
# CONFIG_NFTL is not set

#
# RAM/ROM/Flash chip drivers
#
CONFIG_MTD_CFI=y
# CONFIG_MTD_JEDECPROBE is not set
CONFIG_MTD_GEN_PROBE=y
CONFIG_MTD_CFI_ADV_OPTIONS=y
# CONFIG_MTD_CFI_NOSWAP is not set
CONFIG_MTD_CFI_BE_BYTE_SWAP=y
# CONFIG_MTD_CFI_LE_BYTE_SWAP is not set
CONFIG_MTD_CFI_GEOMETRY=y
# CONFIG_MTD_CFI_B1 is not set
CONFIG_MTD_CFI_B2=y
# CONFIG_MTD_CFI_B4 is not set
CONFIG_MTD_CFI_I1=y
# CONFIG_MTD_CFI_I2 is not set
# CONFIG_MTD_CFI_I4 is not set
CONFIG_MTD_CFI_INTELEXT=y
# CONFIG_MTD_CFI_AMDSTD is not set
# CONFIG_MTD_RAM is not set
# CONFIG_MTD_ROM is not set
# CONFIG_MTD_ABSENT is not set
# CONFIG_MTD_OBSOLETE_CHIPS is not set

#
# Mapping drivers for chip access
#
# CONFIG_MTD_PHYSMAP is not set
# CONFIG_MTD_SUN_UFLASH is not set
# CONFIG_MTD_NORA is not set
# CONFIG_MTD_PNC2000 is not set
# CONFIG_MTD_RPXLITE is not set
CONFIG_MTD_TQM8XXL=y
# CONFIG_MTD_SC520CDP is not set
# CONFIG_MTD_NETSC520 is not set
# CONFIG_MTD_SBC_GXX is not set
# CONFIG_MTD_ELAN_104NC is not set
# CONFIG_MTD_DBOX2 is not set
# CONFIG_MTD_CSTM_MIPS_IXX is not set
# CONFIG_MTD_CFI_FLAGADM is not set
# CONFIG_MTD_SOLUTIONENGINE is not set
# CONFIG_MTD_MIXMEM is not set
# CONFIG_MTD_OCTAGON is not set
# CONFIG_MTD_VMAX is not set
# CONFIG_MTD_OCELOT is not set
# CONFIG_MTD_L440GX is not set

#
# Self-contained MTD device drivers
#
# CONFIG_MTD_PMC551 is not set
# CONFIG_MTD_SLRAM is not set
# CONFIG_MTD_LART is not set
# CONFIG_MTD_MTDRAM is not set
# CONFIG_MTD_BLKMTD is not set
# CONFIG_MTD_DOC1000 is not set
# CONFIG_MTD_DOC2000 is not set
# CONFIG_MTD_DOC2001 is not set
# CONFIG_MTD_DOCPROBE is not set

#
# NAND Flash Device Drivers
#
# CONFIG_MTD_NAND is not set




# CONFIG_BLK_DEV_INITRD is not set
# CONFIG_FLASH is not set


[4단계] /2ndhard/linux-2.4.4/drivers/mtd/maps/tqm8xxl.c 파일을 수정하였
다.
실제로 수정된 부분은 다음과 같다.
실험에서는 플래시 메모리의 시작번지는 0x80000000 이고 플래시 메모리의 크
기는 16Mbytes 이므로 0x01000000
으로 지정하였으며 플래시 개수가 1개이므로 Bank 를 1로 설정하였다.
/*
#define FLASH_ADDR 0x40000000
#define FLASH_SIZE 0x00800000
#define FLASH_BANK_MAX 4
*/

/* kingseft */
#define FLASH_ADDR 0x80000000
#define FLASH_SIZE 0x01000000
#define FLASH_BANK_MAX 1
/* end of kingseft */


두번째로 수정된 부분은 Flash width 부분이다.
struct map_info tqm8xxl_map = {
name: "TQM8xxL",
//size: WINDOW_SIZE,
buswidth: 2, /* kingseft */
read8: tqm8xxl_read8,
read16: tqm8xxl_read16,
read32: tqm8xxl_read32,
copy_from: tqm8xxl_copy_from,
write8: tqm8xxl_write8,
write16: tqm8xxl_write16,
write32: tqm8xxl_write32,
copy_to: tqm8xxl_copy_to
};

다음으로 수정된 부분은 플래시 메모리의 크기를 지정해 주는 부분이다.
/* kingseft */
static unsigned long tqm8xxl_max_flash_size = 0x01000000;

다음으로 수정된 부분은 플래시 메모리를 논리적으로 파티션을 나누는 부분이
다.
static struct mtd_partition tqm8xxl_partitions[] = {
{
name: "kernel",
offset: 0x00000000,
size: 0x00100000, /* 1MBytes kernel */
/*mask_flags: MTD_WRITEABLE,*/ /* force read-only */
},
{
name: "ramdisk", /* 8MBytes Ramdisk */
offset: 0x00100000,
size: 0x00800000,
/*mask_flags: MTD_WRITEABLE,*/ /* force read-only */
},
{
name: "user", /* 7MBytes temp */
offset: 0x00900000,
size: 0x00700000,
}
};

다음으로 아래 부분은 실제로 사용할 필요가 없기에 주석처리 하였다.
/* partition definition for second flahs bank */
/*
static struct mtd_partition tqm8xxl_fs_partitions[] = {
{
name: "cramfs",
offset: 0x00000000,
size: 0x00200000,
},
{
name: "jffs",
offset: 0x00200000,
size: 0x00200000,
//size: MTDPART_SIZ_FULL,
}
};
*/

다음으로 수정한 부분은 플래시 초기화 부분에서 시작주소와 플래시의 크기를
지정하는 부분이다.
int __init init_tqm_mtd(void)
{
int idx = 0, ret = 0;
unsigned long flash_addr, flash_size, mtd_size = 0;
/* pointer to TQM8xxL board info data */
bd_t *bd = (bd_t *)__res;

flash_addr = 0x80000000; /*bd->bi_flashstart;*/
flash_size = 0x01000000; /*bd->bi_flashsize; */


다음으로 수정된 부분역시 플래시의 width 를 설정해주는 부분이다.
sprintf(map_banks[idx]->name, "TQM8xxL%d", idx);
map_banks[idx]->buswidth = 2;
map_banks[idx]->read8 = tqm8xxl_read8;
map_banks[idx]->read16 = tqm8xxl_read16;
map_banks[idx]->read32 = tqm8xxl_read32;
map_banks[idx]->copy_from = tqm8xxl_copy_from;
map_banks[idx]->write8 = tqm8xxl_write8;
map_banks[idx]->write16 = tqm8xxl_write16;
map_banks[idx]->write32 = tqm8xxl_write32;
map_banks[idx]->copy_to = tqm8xxl_copy_to;
map_banks[idx]->map_priv_1 =
start_scan_addr + ((idx > 0) ?
(mtd_banks[idx-1] ? mtd_banks[idx-1]->size : 0) : 0);


다음으로 수정된 부분은 아래와 같다.
/*
* Select Static partition definitions
*/
part_banks[0].mtd_part = tqm8xxl_partitions;
part_banks[0].type = "Static image";
part_banks[0].nums = NB_OF(tqm8xxl_partitions);

/*
part_banks[1].mtd_part = tqm8xxl_fs_partitions;
part_banks[1].type = "Static file system";
part_banks[1].nums = NB_OF(tqm8xxl_fs_partitions);
*/

여기까지의 수정작업으로 tqm8xxl.c 의 수정이 끝났다.


[단계5] /2ndhard/linux-2.4.4/fs/Makefile 을 수정한다.
실제로 수정된 부분은 다음과 같다.
원본은 jffs 디렉토리를 나타내지만 jffs2 로 바꾸었다.
subdir-$(CONFIG_JFFS_FS) += jffs2


[단계6] /2ndhard/linux-2.4.4/init/main.c 를 수정한다.
실제 첨가될 부분은 { "mtdblock1", 0x1f01 }, 이다.

: mtdblock1 의 Major = 31, Minor = 1 입니다. 만일 mtdblock0 을 쓰신다면 0x1f00 하시면 되겠죠?
{ "mtdblock1", 0x1f01 },


[단계7] ppcboot에서 bootargs 는 bootargs root=/dev/mtdblock1 로 수정한다.

[단계8] ppcboot에서 bootm 은 bootm <커널주소> 만 지정하고 램디스크 주소
는 지정하지 않는다.

[단계9] 호스트 컴퓨터에서 JFFS 이미지를 만든다.
mkfs.jffs2 -b -d /2ndhard/ramdisk -o ./ramdisk-jffs2


(호스트 PC 가 i386 이면, -b 옵션을 사용하여 big-endian 으로 생성해야 합니
다.)
: target directory 에는 target 에서 사용할 root file system 이 있어야 합 니다.
아참, util 에 있는 것중에서, mkfs.jffs2 등은 호스트에서 실행될 파일이구
요...
erase 같은 것은 target 에서 실행될 파일입니다.
따라서, host 와 target 이 다른경우에는, cross-compile 한것과 안한것을 둘
다 갖고 있으면 좋겠네요...


[단계10] ppcboot에서 mtdblock0 영역에 커널 이미지 다운로드
이 이미지는 mkimage 를 통해서 나온 결과

[단계11] ppcboot 에서 mtdblock1 영역에 JFFS 이미지 다운로드
이 이미지는 mkimage 를 사용하지 않고 단계 9에서 만들어진 이미지를 그대
로 쓴다.