Skip to content

Instantly share code, notes, and snippets.

@Malayke
Last active December 1, 2018 05:34
Show Gist options
  • Save Malayke/20755cbfca5c971f12eb6e4a7552a725 to your computer and use it in GitHub Desktop.
Save Malayke/20755cbfca5c971f12eb6e4a7552a725 to your computer and use it in GitHub Desktop.

Mounting JFFS2 Images on a Linux PC

It is possible to mount a binary JFFS2 image on a Linux PC without a flash device. This can be useful for examining the contents of the image, making required changes, and creating a new image in any format. When a JFFS2 image is copied directly from a JFFS2 flash partition, the resulting image is the size of the source partition, regardless of how much space is actually used for storage. Mounting the filesystem and using the mkfs.jffs2 utility to create a new image will result in a JFFS2 image without blank nodes. This can also be used to create multiple images for flashes with different characteristics, such as erase block sizes. This page describes two different methods of mounting JFFS2 images on a Linux PC.

This procedure requires that the following kernel modules are available or built-in to the kernel on the development machine: mtdram, mtdblock, jffs2, block2mtd, and loop.

Mounting JFFS2 Images using RAM

One method of mounting JFFS2 images uses the mtdram module to emulate an MTD device using system RAM. This works well for JFFS2 images that are less than approximately 32 MB but will not work for larger images since it requires allocating a large amount of system RAM. The basic steps of this process are as follows:

  1. Load mtdram and mtdblock modules.
  2. Use the dd command to copy the JFFS2 image to /dev/mtdblock0.
  3. Mount /dev/mtdblock0 as a JFFS2 filesytem.

In order to simplify this process, EMAC has created a script which takes the JFFS2 image, mount point, and the erase block size of the image as parameters. The default erase block size for this script is 128 KiB, which is the correct value for most NOR flashes used on EMAC products and some NAND flashes. The eraseblock size can be determined from the contents of /proc/mtd from the system that the image was copied from or created for. For example, if the value of the "erasesize" parameter is 00040000, the erase block size for the device is 256 KiB (0x40000 = 262144 bytes, 262144 / 1024 = 256 KiB). The jffs2_mount_mtdram.sh script is shown below.

#!/bin/bash

## Script to mount jffs2 filesystem using mtd kernel modules.
## EMAC, Inc. 2009

if [[ $# -lt 2 ]]
then
    echo "Usage: $0 FSNAME.JFFS2 MOUNTPOINT [ERASEBLOCK_SIZE]"
    exit 1
fi

if [ "$(whoami)" != "root" ]
then
    echo "$0 must be run as root!"
    exit 1
fi

if [[ ! -e $1 ]]
then
    echo "$1 does not exist"
    exit 1
fi

if [[ ! -d $2 ]]
then
    echo "$2 is not a valid mount point"
    exit 1
fi

if [[ "$3" == "" ]]
then
	esize="128"
else
	esize="$3"
fi

# cleanup if necessary
umount /dev/mtdblock0 &>/dev/null
modprobe -r mtdram &>/dev/null
modprobe -r mtdblock &>/dev/null

modprobe mtdram total_size=32768 erase_size=$esize || exit 1
modprobe mtdblock || exit 1
dd if="$1" of=/dev/mtdblock0 || exit 1
mount -t jffs2 /dev/mtdblock0 $2 || exit 1

echo "Successfully mounted $1 on $2"
exit 0

To mount an image with 256 KiB erase block size named rootfs.jffs2 on /mnt/jffs2 using jffs2_mount_mtdram.sh, run the script as shown below:

developer@ldc:~$ sudo ./jffs2_mount_mtdram.sh rootfs.jffs2 /mnt/jffs2 256

Once this has been done, the contents of the image should be accessible at /mnt/jffs2.

Changes made to the mounted filesystem will not affect the original JFFS2 image.

Mounting JFFS2 Images using a Loop Device

A second method for mounting JFFS2 images utilizes a loop device. This method is appropriate for larger images that cannot be mounted successfully with the mtdram approach. The process requires the following steps:

  1. Load loop, block2mtd, and jffs2 modules
  2. Create a loop device
  3. Set the block2mtd parameters for the loop device
  4. Mount the JFFS2 image

EMAC has created a script to simplify this process that takes the JFFS2 image, mount point, and image erase block size as parameters. The default erase block size for this script is 128 KiB, which is the correct value for most NOR flashes used on EMAC products and some NAND flashes. See the description of determining the correct erase block size to use in the previous section. The jffs2_mount_loop.sh script is shown below.

#!/bin/bash

## Script to mount jffs2 filesystem using mtd kernel modules.
## EMAC, Inc. 2011

if [[ $# -lt 2 ]]
then
    echo "Usage: $0 FSNAME.JFFS2 MOUNTPOINT [ERASEBLOCK_SIZE]"
    exit 1
fi

if [ "$(whoami)" != "root" ]
then
    echo "$0 must be run as root!"
    exit 1
fi

if [[ ! -e $1 ]]
then
    echo "$1 does not exist"
    exit 1
fi

if [[ ! -d $2 ]]
then
    echo "$2 is not a valid mount point"
    exit 1
fi

if [[ "$3" == "" ]]
then
	esize="128"
else
	esize="$3"
fi

# cleanup if necessary
umount /tmp/mtdblock0 &>/dev/null
umount $2 &>/dev/null
modprobe -r jffs2 &>/dev/null
modprobe -r block2mtd &>/dev/null
modprobe -r mtdblock &>/dev/null
sleep 0.25
losetup -d /dev/loop1 &>/dev/null
sleep 0.25

modprobe loop || exit 1
losetup /dev/loop1 "$1" || exit 1
modprobe block2mtd || exit 1
modprobe jffs2 || exit 1
if [[ ! -e /tmp/mtdblock0 ]]
then
    mknod /tmp/mtdblock0 b 31 0 || exit 1
fi

echo "/dev/loop1,${esize}KiB" > /sys/module/block2mtd/parameters/block2mtd

mount -t jffs2 /tmp/mtdblock0 "$2" || exit 1

echo "Successfully mounted $1 on $2"
exit 0

Usage for this script is identical to the jffs2_mount_mtdram.sh script discussed in the previous section.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment