Modifying the root image

(Set "Modifying the root image" as the Wiki page of the day)
(Block device emulating an MTD device)
 
(30 intermediate revisions not shown)
Line 1: Line 1:
-
{{Midgard article}}
+
This article describes two methods for extending and modifying an existing tablet JFFS2 root image. Note that this article does not work with the "root.jffs2" file for the [[Nokia N900|N900]], as despite the filename, the N900 does not use jffs2. See http://talk.maemo.org/showpost.php?p=403015&postcount=3 for a solution for N900.
-
 
+
== Background ==
-
This HOWTO describes 2 methods for extending and modifying an existing JFFS2 root image of 770.
+
The root filesystem (rootfs) of the tablets is stored in a Journal Flash File System version 2 (JFFS2) format. It resides on one of the partitions on the flash chip in the device. Additionally, a pristine version of the rootfs can be obtained from the [http://tablets-dev.nokia.com/ Nokia official firmware] site.
-
 
+
-
=Background =
+
-
The root filesystem (rootfs) of the Nokia 770 is stored in a Journal Flash File System version 2 (JFFS2) format. It resides on one of the partitions on the flash chip in the Nokia 770. Additionally, a pristine version of the rootfs can be obtained from the [http://tablets-dev.nokia.com/nokia_770.php Nokia official firmware].
+
There are two ways to mount the JFFS2 image:
There are two ways to mount the JFFS2 image:
-
#Have a block device emulate a Memory Technology Device (MTD) via blkmtd (v2.4.x Linux kernels) or block2mtd (v2.6.x Linux kernels)
+
#Have a block device emulate a Memory Technology Device (MTD) via block2mtd.
-
#Have kernel memory emulate a MTD via mtdram
+
#Have kernel memory emulate a MTD via mtdram.
-
 
+
-
=Getting the JFFS2 Image=
+
-
First of all, we need to get the rootfs.jffs2 from the official [http://tablets-dev.nokia.com/nokia_770.php Nokia binary]:
+
-
$ mkdir SE2005_image
+
Note that for a host kernel config you need to enable mtd device support to access/enable jffs2 filesystem support.
-
$ cd SE2005_image
+
-
$ sudo ./flasher --unpack  -F /path_to_file/Nokia_770_SE2005_3_2005_51_13.bin
+
-
Found image 2nd (length 8576)
+
== Getting the JFFS2 image ==
-
Found image secondary (length 79360)
+
First of all, we need to get the rootfs.jffs2 from the official [http://tablets-dev.nokia.com/ Nokia FIASCO image]. After downloading the FIASCO image, run this on it to unpack it (this will give you all of the individual parts of the image):
-
Found image xloader (length 13824)
+
-
Found image initfs (length 1581824)
+
-
Found image kernel (length 1481856)
+
-
Found image rootfs (length 58851328)
+
-
Unpacking 2nd image to file '2nd.bin'...
+
-
Unpacking X-Loader image to file 'xloader.bin'...
+
-
Unpacking secondary image to file 'secondary.bin'...
+
-
Unpacking kernel image to file 'zImage'...
+
-
Unpacking initfs image to file 'initfs.jffs2'...
+
-
Unpacking rootfs image to file 'rootfs.jffs2'...
+
-
=Mounting JFFS2 Image=
+
sudo ./flasher-3.0 --unpack  -F <FIASCO image>
-
It is assume that all these commands will be executed on the development/hacking host and not on the Nokia 770 itself. Also assumed is all these commands will be executed with root privileges (i.e. sudo /bin/sh).
+
-
=='''Block Device Emulating a MTD'''==
+
== Mounting the JFFS2 image ==
-
==='''Linux 2.4.x Kernel'''===
+
These commands will be executed with root privileges on the host machine and not on the device itself.
-
If you are using a Linux 2.4.x kernel, you must have the following kernel modules compiled:
+
-
*CONFIG_MTD (mtdcore)
+
=== Block device emulating an MTD device ===
-
*CONFIG_MTD_PARITIONS (mtdpart)
+
You must have the following kernel modules compiled and installed:
-
*CONFIG_MTD_MTDRAM (mtdram)
+
-
*CONFIG_MTD_BLKMTD (blkmtd)
+
-
*CONFIG_BLK_DEV_LOOP (loop)
+
-
==='''Linux 2.6.x Kernel'''===
+
'''Memory Technology Device (MTD) support  --->'''
-
If you are using a Linux 2.6.x kernel, you must have the following kernel modules compiled:
+
*CONFIG_MTD ( Memory Technology Device (MTD) support )
-
 
+
*CONFIG_MTDBLOCK ( Caching block device access to MTD devices )
-
*CONFIG_MTD (mtdcore)  
+
*CONFIG_MTD_PARITIONS ( MTD partitioning support )  
-
*CONFIG_MTD_PARITIONS (mtdpart)  
+
'''Self-contained MTD device drivers  ---> '''
-
*CONFIG_MTD_MTDRAM (mtdram)  
+
*CONFIG_MTD_MTDRAM ( Test driver using RAM )  
-
*CONFIG_MTD_BLOCK2MTD (block2mtd)  
+
*CONFIG_MTD_BLOCK2MTD ( MTD using block device )  
-
*CONFIG_BLK_DEV_LOOP (loop)  
+
'''Block devices  --->'''
 +
*CONFIG_BLK_DEV_LOOP ( Loopback device support )
 +
'''File systems  --->Miscellaneous filesystems  --->'''
 +
*CONFIG_JFFS2_FS ( Journalling Flash File System v2 (JFFS2) support )
 +
*CONFIG_JFFS2_LZO ( Advanced compression options for JFFS2 --> LZO compression support )
I suggest you do not make these modules statically linked into the kernel. It is more practical to be able to unload these modules when not needed or when you want to start over from scratch.
I suggest you do not make these modules statically linked into the kernel. It is more practical to be able to unload these modules when not needed or when you want to start over from scratch.
Line 61: Line 42:
  losetup /dev/loop0 rootfs.jffs2
  losetup /dev/loop0 rootfs.jffs2
  modprobe mtdblock
  modprobe mtdblock
-
  modprobe blkmtd device=/dev/loop0 ### for Linux 2.4.x
+
  modprobe block2mtd
-
    or
+
  # Note the ,128KiB is needed (on 2.6.26 at least) to set the eraseblock size.
-
  modprobe block2mtd  ### for Linux 2.6.x
+
echo "/dev/loop0,128KiB" > /sys/module/block2mtd/parameters/block2mtd
-
  echo "/dev/loop0" > /sys/module/block2mtd/parameters/block2mtd ### Linux 2.6.x
+
  modprobe jffs2
  modprobe jffs2
 +
# check dmesg
  mount -t jffs2 /tmp/mtdblock0 /media/jffs2
  mount -t jffs2 /tmp/mtdblock0 /media/jffs2
 +
# check dmesg again - if the above mount results in any errors there is a problem...
To unmount and cleanup:
To unmount and cleanup:
  umount /media/jffs2
  umount /media/jffs2
-
  modprobe -r blkmtd ### Linux 2.4.x
+
  modprobe -r block2mtd
-
    or
+
-
  modprobe -r block2mtd ## Linux 2.6.x
+
  modprobe -r mtdblock
  modprobe -r mtdblock
  losetup -d /dev/loop0
  losetup -d /dev/loop0
-
You can use the following Shell script to automate the process.
+
Or use the [[#Shell_script_to_mount/unmount_JFFS2_using_block_device_emulating_MTD|automated shell script]].
-
==Kernel Memory Emulating a MTD==
+
---
-
(Idea originally from Michael Mlivoncic) To mount the JFFS2 image, you perform the following steps:
+
 
 +
Edit in 2019 - Hi. I (i336_) thought I'd leave the eraseblock size off since I'm on kernel 5.1.4.
 +
 
 +
My HDD promptly began seeking a lot for a few seconds (!), and I discovered this was because it was scrambling to keep up with the just-over-30,000 errors jffs had just dumped into syslog.
 +
 
 +
You definitely still need the ",128KiB". :)
 +
 
 +
=== Kernel memory emulating an MTD device ===
 +
 
 +
Note that mtdram requires 88mb of raw ram on a 2gb system to mount a ~2Mb initfs image [Faheem Pervez on -dev ml], it probably won't work well with a rootfs!
 +
 
 +
Use total_size=85892 for mtdram if 65536 is too little.
 +
 
 +
However, if you insist... to mount the JFFS2 image, you perform the following steps:
  mknod /tmp/mtdblock0 b 31 0
  mknod /tmp/mtdblock0 b 31 0
Line 97: Line 90:
  modprobe -r mtdblock
  modprobe -r mtdblock
-
You can use the following Shell script to automate the process.
+
Or use the [[Modifying_the_root_image#Shell_script_to_mount.2Funmount_JFFS2_using_kernel_memory_emulating_MTD|automated shell script]].
-
=Archiving and Extracting the Root Image=
+
== Archiving and extracting the rootfs image ==
-
The image is now accessible under /media/jffs2. Copy the whole image to another directory. This new directory will be used for modifying the image. Extending the currently mounted JFFS2 image is not suggested. Using cp for copying the image to a working directory won't work due to special files in /media/jffs2/dev, for example. This is the reason we use tar. proceed as above, i.e.:
+
The image is now accessible under /media/jffs2. Copy the whole image to another directory. This new directory will be used for modifying the image. Extending the currently mounted JFFS2 image is not suggested. Using cp for copying the image to a working directory won't work due to special files in /media/jffs2/dev, which is why we use tar.  
-
  $ cd /media/jffs2
+
  cd /media/jffs2
-
  $ tar cvzf /my_path/myRootImage.tar.gz .
+
  tar cvzf /my_path/myRootImage.tar.gz .
-
  $ cd $HOME
+
  cd $HOME
-
  $ mkdir myRootImage
+
  mkdir myRootImage
-
  $ cd myRootImage
+
  cd myRootImage
-
  $ tar xvpzf /my_path/myRootImage.tar.gz
+
  tar xvpzf /my_path/myRootImage.tar.gz
-
=Modifying the Copy of Image=
+
== Repacking the image ==
-
Now the image is successfully archived and copied. The working directory  $HOME/myRootImage can now be used for adding packages etc, for example.
+
[http://maemo.org/development/documentation/manuals/2-x/howto_use_flasher_rootfs/ Using the flasher utility and creating the reference root file system]
-
  $ cd $HOME/myRootImage
+
== Modifying the copy of the image ==
-
  $ dpkg -x $HOME/arm_debs/mypackage_arm.deb .
+
Now the image is successfully archived and copied. The working directory $HOME/myRootImage can now be used for adding, changing or modifying packages.
 +
 
 +
cd $HOME/myRootImage
 +
  dpkg -x $HOME/arm_debs/mypackage_arm.deb .
Now we create a new tarball from the working directory of the image.
Now we create a new tarball from the working directory of the image.
-
  $ cd $HOME/myRootImage
+
  cd $HOME/myRootImage
-
  $ tar cvzf $HOME/myNewRootImage.tar.gz .
+
  tar cvzf $HOME/myNewRootImage.tar.gz .
-
=Installing into Nokia 770=
+
== Making the actual jffs2 image ==
-
When the new tarball is created, refer to HOWTO: Using flasher and the reference root filesystem for creating JFFS2 image from the myNewRootImage.tar.gz.
+
-
Use flasher to install the image to Nokia 770.
+
''This was done on a Ubuntu Hardy system and was only done to make an initfs image successfully. I can't ensure this will work (though in theory, it should do) for creating an rootfs.''
-
$ ./flasher --flash-only rootfs -F image.bin -f
+
<ol><li>Install mtd-tools which contains the required mkfs.jffs2.</li></ol>
 +
:<pre> sudo apt-get install mtd-tools </pre>
 +
<ol start="2"><li>Run:</li></ol>
 +
:<pre> sudo mkfs.jffs2 -r myRootImage -o myRootImage.jffs2 -e 128 -l -n </pre>
-
$ ./flasher --rootfs rootfs.jffs2 --flash-only rootfs --flash
+
Where ''myRootImage'' is the root of your new filesystem and ''myRootImage.jffs2'' is the name of the output file. -e 128 specifies a erase size of 128 KiB. 128 KiB is the correct erase size for the initfs. It is correct for an rootfs too.
-
$ ./flasher --enable-rd-mode --reboot
+
== Making the jffs2 image mount faster ==
-
The flash-only parameter is used just to make sure ;-)
+
The jffs2 image that was just created is a plain jffs2 image. That's nice and if you were to flash it, it would work fine but what you can do is use sumtool which makes an summarized JFFS2 image. An summarized JFFS2 image mounts faster than a non-summarized one.
 +
This can be done simply with:
-
=Final remarks=
+
sumtool -i <input jffs2 image> -o <output jffs2 image> -e 128KiB -l -n
-
Tonight, I had to re-flash the first time, as I screwed up a script in /etc/init.d/. For the future, I will try to make a full backup of my productive rootfs, to avoid starting all over again
+
 +
== Installing on the tablet ==
 +
When the new tarball is created,  Using flasher and the reference root filesystem for creating JFFS2 image from the myNewRootImage.tar.gz.
-
--------------------------------------------------------------------------------
+
Use flasher to install the image on the tablet.
-
=Shell script to mount/unmount JFFS2 using Block device Emulating MTD=
+
./flasher-3.0 -r rootfs.jffs2 --f -R
 +
 
 +
== Shell script to mount/unmount JFFS2 using block device emulating MTD ==
Create a shell script (mount_jffs2.sh) from the following:
Create a shell script (mount_jffs2.sh) from the following:
-
<pre>
+
<source lang="bash">
-
#!/bin/sh
+
#!/bin/sh
-
JFFSIMG=$1 # jffs image
+
JFFSIMG=$1 # jffs image
-
LOOP="/dev/loop1" # loop device
+
LOOP="/dev/loop1" # loop device
-
MP="/media/jffs2" # mount point
+
MP="/media/jffs2" # mount point
-
MTDBLOCK="/tmp/mtdblock0" # MTD device file
+
MTDBLOCK="/tmp/mtdblock0" # MTD device file
-
KVER="2.6"
+
KVER="2.6"
-
BLKMTD="block2mtd"
+
BLKMTD="block2mtd"
-
UMNT=""
+
UMNT=""
-
echo "$0" | grep unmount_ >/dev/null 2>&1
+
echo "$0" | grep unmount_ >/dev/null 2>&1
-
[ $? -eq 0 ] && UMNT=1
+
[ $? -eq 0 ] && UMNT=1
-
if [ $# -gt 1 -a x"$2"x = x"unmount"x ]; then
+
if [ $# -gt 1 -a x"$2"x = x"unmount"x ]; then
-
  UMNT=1
+
  UMNT=1
-
fi
+
fi
-
uname -r | egrep '^2\.6' >/dev/null 2>&1
+
uname -r | egrep '^2\.6' >/dev/null 2>&1
-
if [ $? -ne 0 ]; then
+
if [ $? -ne 0 ]; then
-
  KVER="2.4"
+
  KVER="2.4"
-
  BLKMTD=blkmtd
+
  BLKMTD=blkmtd
-
fi  
+
fi  
-
if [ x"${UMNT}"x = x""x ]; then
+
if [ x"${UMNT}"x = x""x ]; then
-
  if [ ! -b ${MTDBLOCK} ] ; then
+
  if [ ! -b ${MTDBLOCK} ] ; then
-
    mknod ${MTDBLOCK} b 31 0 || exit 1
+
    mknod ${MTDBLOCK} b 31 0 || exit 1
-
  fi
+
  fi
-
  lsmod | grep loop >/dev/null 2>&1
+
  lsmod | grep loop >/dev/null 2>&1
-
  if [ $? -ne 0 [; then
+
  if [ $? -ne 0 ]; then
-
    modprobe loop
+
    modprobe loop
-
    [ $? -ne 0 ] && echo "loopback loading failed" && exit 1
+
    [ $? -ne 0 ] && echo "loopback loading failed" && exit 1
-
    sleep 1
+
    sleep 1
-
  fi
+
  fi
-
  losetup ${LOOP} ${JFFSIMG} || exit 1
+
  losetup ${LOOP} ${JFFSIMG} || exit 1
-
  sleep 1
+
  sleep 1
-
  modprobe mtdblock
+
  modprobe mtdblock
-
  if [ x"${KVER}"x = x"2.4"x [; then
+
  if [ x"${KVER}"x = x"2.4"x ]; then
-
    modprobe ${BLKMTD} device=${LOOP} || exit 1
+
    modprobe ${BLKMTD} device=${LOOP} || exit 1
-
  else
+
  else
-
    modprobe ${BLKMTD} || exit 1
+
    modprobe ${BLKMTD} || exit 1
-
    echo "${LOOP}" > /sys/module/block2mtd/parameters/block2mtd
+
    echo "${LOOP}" > /sys/module/block2mtd/parameters/block2mtd
-
  fi
+
  fi
-
  sleep 1
+
  sleep 1
-
  modprobe jffs2
+
  modprobe jffs2
-
  [ ! -d ${MP} ] && mkdir -p ${MP}
+
  [ ! -d ${MP} ] && mkdir -p ${MP}
-
  mount -t jffs2 ${MTDBLOCK} ${MP} || exit 1
+
  mount -t jffs2 ${MTDBLOCK} ${MP} || exit 1
-
else
+
else
-
  umount ${MP}
+
  umount ${MP}
-
  if [ $? -ne 0 ]; then
+
  if [ $? -ne 0 ]; then
-
    echo "Cannot unmount JFFS2 at $MP" && exit 1
+
    echo "Cannot unmount JFFS2 at $MP" && exit 1
-
  fi
+
  fi
-
  modprobe -r jffs2
+
  modprobe -r jffs2
-
  modprobe -r ${BLKMTD}
+
  modprobe -r ${BLKMTD}
-
  modprobe -r mtdblock
+
  modprobe -r mtdblock
-
  sleep 1
+
  sleep 1
-
  losetup -d ${LOOP}
+
  losetup -d ${LOOP}
-
fi  
+
fi  
-
</pre>
+
</source>
Make sure you chmod a+x mount_jffs2.sh to make the shell script executable.
Make sure you chmod a+x mount_jffs2.sh to make the shell script executable.
-
Usage: $ ./mount_jffs2.sh rootfs.jffs2
+
Usage:
 +
 
 +
./mount_jffs2.sh rootfs.jffs2
You can also use this script to unmount and unload the non-utilized kernel modules and loopback reference:
You can also use this script to unmount and unload the non-utilized kernel modules and loopback reference:
-
$ ./mount_jffs2.sh rootfs.jffs2 unmount
+
./mount_jffs2.sh rootfs.jffs2 unmount
-
 
+
-
 
+
-
--------------------------------------------------------------------------------
+
-
=Shell script to mount/unmount JFFS2 using Kernel Memory Emulating MTD=
+
== Shell script to mount/unmount JFFS2 using kernel memory emulating MTD ==
Create a shell script (mount_jffs2.sh) from the following:
Create a shell script (mount_jffs2.sh) from the following:
-
<pre>
+
<source lang="bash">
-
#!/bin/sh
+
#!/bin/sh
-
JFFSIMG=$1 # jffs image
+
JFFSIMG=$1 # jffs image
-
MP="/media/jffs2" # mount point
+
MP="/media/jffs2" # mount point
-
MTDBLOCK="/tmp/mtdblock0" # MTD device file
+
MTDBLOCK="/tmp/mtdblock0" # MTD device file
-
UMNT=""
+
UMNT=""
-
echo "$0" | grep unmount_ >/dev/null 2>&1
+
echo "$0" | grep unmount_ >/dev/null 2>&1
-
[ $? -eq 0 ] && UMNT=1
+
[ $? -eq 0 ] && UMNT=1
-
if [ $# -gt 1 -a x"$2"x = x"unmount"x ]; then
+
if [ $# -gt 1 -a x"$2"x = x"unmount"x ]; then
-
  UMNT=1
+
  UMNT=1
-
fi
+
fi
-
if [ x"${UMNT}"x = x""x ]; then
+
if [ x"${UMNT}"x = x""x ]; then
-
  if [ ! -b ${MTDBLOCK} ] ; then
+
  if [ ! -b ${MTDBLOCK} ] ; then
-
    mknod ${MTDBLOCK} b 31 0 || exit 1
+
    mknod ${MTDBLOCK} b 31 0 || exit 1
-
  fi
+
  fi
-
  modprobe mtdblock
+
  modprobe mtdblock
-
  modprobe mtdram total_size=65536 erase_size=256
+
  modprobe mtdram total_size=65536 erase_size=256
-
  modprobe jffs2
+
  modprobe jffs2
-
  dd if=${JFFSIMG} of=${MTDBLOCK}
+
  dd if=${JFFSIMG} of=${MTDBLOCK}
-
  [ ! -d ${MP} ] && mkdir -p ${MP}
+
  [ ! -d ${MP} ] && mkdir -p ${MP}
-
  mount -t jffs2 ${MTDBLOCK} ${MP}
+
  mount -t jffs2 ${MTDBLOCK} ${MP}
-
else
+
else
-
  umount ${MP}
+
  umount ${MP}
-
  if [ $? -ne 0 ]; then
+
  if [ $? -ne 0 ]; then
-
    echo "Cannot unmount JFFS2 at $MP" && exit 1
+
    echo "Cannot unmount JFFS2 at $MP" && exit 1
-
  fi
+
  fi
-
  modprobe -r jffs2
+
  modprobe -r jffs2
-
  modprobe -r mtdram
+
  modprobe -r mtdram
-
  modprobe -r mtdblock
+
  modprobe -r mtdblock
-
fi  
+
fi  
-
</pre>
+
</source>
Make sure you chmod a+x mount_jffs2.sh to make the shell script executable.
Make sure you chmod a+x mount_jffs2.sh to make the shell script executable.
-
Usage: $ ./mount_jffs2.sh rootfs.jffs2
+
Usage:
 +
./mount_jffs2.sh rootfs.jffs2
You can also use this script to unmount and unload the non-utilized kernel modules:
You can also use this script to unmount and unload the non-utilized kernel modules:
-
$ ./mount_jffs2.sh rootfs.jffs2 unmount
+
./mount_jffs2.sh rootfs.jffs2 unmount
-
 
+
-
 
+
-
--------------------------------------------------------------------------------
+
-
 
+
-
=Maybe one could write a script removing unwanted stuff from that image (sample video, song), changing sudoers, gainroot script, adding sshd, ...=
+
-
 
+
-
[[Category:HowTos]]
+
[[Category:HowTo]]
-
[[Category:Midgard wiki]]
+
[[Category:Wiki page of the day]]
-
[[Category:Wiki page of the Day]]
+

Latest revision as of 07:57, 16 June 2019

This article describes two methods for extending and modifying an existing tablet JFFS2 root image. Note that this article does not work with the "root.jffs2" file for the N900, as despite the filename, the N900 does not use jffs2. See http://talk.maemo.org/showpost.php?p=403015&postcount=3 for a solution for N900.

Contents

[edit] Background

The root filesystem (rootfs) of the tablets is stored in a Journal Flash File System version 2 (JFFS2) format. It resides on one of the partitions on the flash chip in the device. Additionally, a pristine version of the rootfs can be obtained from the Nokia official firmware site.

There are two ways to mount the JFFS2 image:

  1. Have a block device emulate a Memory Technology Device (MTD) via block2mtd.
  2. Have kernel memory emulate a MTD via mtdram.

Note that for a host kernel config you need to enable mtd device support to access/enable jffs2 filesystem support.

[edit] Getting the JFFS2 image

First of all, we need to get the rootfs.jffs2 from the official Nokia FIASCO image. After downloading the FIASCO image, run this on it to unpack it (this will give you all of the individual parts of the image):

sudo ./flasher-3.0 --unpack  -F <FIASCO image>

[edit] Mounting the JFFS2 image

These commands will be executed with root privileges on the host machine and not on the device itself.

[edit] Block device emulating an MTD device

You must have the following kernel modules compiled and installed:

Memory Technology Device (MTD) support --->

  • CONFIG_MTD ( Memory Technology Device (MTD) support )
  • CONFIG_MTDBLOCK ( Caching block device access to MTD devices )
  • CONFIG_MTD_PARITIONS ( MTD partitioning support )

Self-contained MTD device drivers --->

  • CONFIG_MTD_MTDRAM ( Test driver using RAM )
  • CONFIG_MTD_BLOCK2MTD ( MTD using block device )

Block devices --->

  • CONFIG_BLK_DEV_LOOP ( Loopback device support )

File systems --->Miscellaneous filesystems --->

  • CONFIG_JFFS2_FS ( Journalling Flash File System v2 (JFFS2) support )
  • CONFIG_JFFS2_LZO ( Advanced compression options for JFFS2 --> LZO compression support )

I suggest you do not make these modules statically linked into the kernel. It is more practical to be able to unload these modules when not needed or when you want to start over from scratch.

You will use the loopback device (/dev/loop[0-15]) to simulate a block device whose contents are from the JFFS2 image. To mount the JFFS2 image, you perform the following steps:

mknod /tmp/mtdblock0 b 31 0
modprobe loop
losetup /dev/loop0 rootfs.jffs2
modprobe mtdblock
modprobe block2mtd
# Note the ,128KiB is needed (on 2.6.26 at least) to set the eraseblock size.
echo "/dev/loop0,128KiB" > /sys/module/block2mtd/parameters/block2mtd
modprobe jffs2
# check dmesg
mount -t jffs2 /tmp/mtdblock0 /media/jffs2
# check dmesg again - if the above mount results in any errors there is a problem...

To unmount and cleanup:

umount /media/jffs2
modprobe -r block2mtd
modprobe -r mtdblock
losetup -d /dev/loop0

Or use the automated shell script.

---

Edit in 2019 - Hi. I (i336_) thought I'd leave the eraseblock size off since I'm on kernel 5.1.4.

My HDD promptly began seeking a lot for a few seconds (!), and I discovered this was because it was scrambling to keep up with the just-over-30,000 errors jffs had just dumped into syslog.

You definitely still need the ",128KiB". :)

[edit] Kernel memory emulating an MTD device

Note that mtdram requires 88mb of raw ram on a 2gb system to mount a ~2Mb initfs image [Faheem Pervez on -dev ml], it probably won't work well with a rootfs!

Use total_size=85892 for mtdram if 65536 is too little.

However, if you insist... to mount the JFFS2 image, you perform the following steps:

mknod /tmp/mtdblock0 b 31 0
modprobe mtdblock
modprobe mtdram total_size=65536 erase_size=256
modprobe jffs2
dd if=/pathtoimage/rootfs.jffs2 of=/tmp/mtdblock0
mkdir /media/jffs2
mount -t jffs2 /tmp/mtdblock0 /media/jffs2

To unmount and cleanup:

umount /media/jffs2
modprobe -r jffs2
modprobe -r mtdram
modprobe -r mtdblock

Or use the automated shell script.

[edit] Archiving and extracting the rootfs image

The image is now accessible under /media/jffs2. Copy the whole image to another directory. This new directory will be used for modifying the image. Extending the currently mounted JFFS2 image is not suggested. Using cp for copying the image to a working directory won't work due to special files in /media/jffs2/dev, which is why we use tar.

cd /media/jffs2
tar cvzf /my_path/myRootImage.tar.gz .
cd $HOME
mkdir myRootImage
cd myRootImage
tar xvpzf /my_path/myRootImage.tar.gz

[edit] Repacking the image

Using the flasher utility and creating the reference root file system

[edit] Modifying the copy of the image

Now the image is successfully archived and copied. The working directory $HOME/myRootImage can now be used for adding, changing or modifying packages.

cd $HOME/myRootImage
dpkg -x $HOME/arm_debs/mypackage_arm.deb .

Now we create a new tarball from the working directory of the image.

cd $HOME/myRootImage
tar cvzf $HOME/myNewRootImage.tar.gz .

[edit] Making the actual jffs2 image

This was done on a Ubuntu Hardy system and was only done to make an initfs image successfully. I can't ensure this will work (though in theory, it should do) for creating an rootfs.

  1. Install mtd-tools which contains the required mkfs.jffs2.
 sudo apt-get install mtd-tools 
  1. Run:
 sudo mkfs.jffs2 -r myRootImage -o myRootImage.jffs2 -e 128 -l -n 

Where myRootImage is the root of your new filesystem and myRootImage.jffs2 is the name of the output file. -e 128 specifies a erase size of 128 KiB. 128 KiB is the correct erase size for the initfs. It is correct for an rootfs too.

[edit] Making the jffs2 image mount faster

The jffs2 image that was just created is a plain jffs2 image. That's nice and if you were to flash it, it would work fine but what you can do is use sumtool which makes an summarized JFFS2 image. An summarized JFFS2 image mounts faster than a non-summarized one.

This can be done simply with:

sumtool -i <input jffs2 image> -o <output jffs2 image> -e 128KiB -l -n

[edit] Installing on the tablet

When the new tarball is created, Using flasher and the reference root filesystem for creating JFFS2 image from the myNewRootImage.tar.gz.

Use flasher to install the image on the tablet.

./flasher-3.0 -r rootfs.jffs2 --f -R

[edit] Shell script to mount/unmount JFFS2 using block device emulating MTD

Create a shell script (mount_jffs2.sh) from the following:

#!/bin/sh
JFFSIMG=$1 # jffs image
LOOP="/dev/loop1" # loop device
MP="/media/jffs2" # mount point
MTDBLOCK="/tmp/mtdblock0" # MTD device file
KVER="2.6"
BLKMTD="block2mtd"
UMNT=""
 
echo "$0" | grep unmount_ >/dev/null 2>&1
[ $? -eq 0 ] && UMNT=1
if [ $# -gt 1 -a x"$2"x = x"unmount"x ]; then
  UMNT=1
fi
 
uname -r | egrep '^2\.6' >/dev/null 2>&1
if [ $? -ne 0 ]; then
  KVER="2.4"
  BLKMTD=blkmtd
fi 
 
if [ x"${UMNT}"x = x""x ]; then
  if [ ! -b ${MTDBLOCK} ] ; then
    mknod ${MTDBLOCK} b 31 0 || exit 1
  fi
  lsmod | grep loop >/dev/null 2>&1
  if [ $? -ne 0 ]; then
    modprobe loop
    [ $? -ne 0 ] && echo "loopback loading failed" && exit 1
    sleep 1
  fi
  losetup ${LOOP} ${JFFSIMG} || exit 1
  sleep 1
  modprobe mtdblock
  if [ x"${KVER}"x = x"2.4"x ]; then
    modprobe ${BLKMTD} device=${LOOP} || exit 1
  else
    modprobe ${BLKMTD} || exit 1
    echo "${LOOP}" > /sys/module/block2mtd/parameters/block2mtd
  fi
  sleep 1
  modprobe jffs2
  [ ! -d ${MP} ] && mkdir -p ${MP}
  mount -t jffs2 ${MTDBLOCK} ${MP} || exit 1
else
  umount ${MP}
  if [ $? -ne 0 ]; then
    echo "Cannot unmount JFFS2 at $MP" && exit 1
  fi
  modprobe -r jffs2
  modprobe -r ${BLKMTD}
  modprobe -r mtdblock
  sleep 1
  losetup -d ${LOOP}
fi

Make sure you chmod a+x mount_jffs2.sh to make the shell script executable.

Usage:

./mount_jffs2.sh rootfs.jffs2

You can also use this script to unmount and unload the non-utilized kernel modules and loopback reference:

./mount_jffs2.sh rootfs.jffs2 unmount

[edit] Shell script to mount/unmount JFFS2 using kernel memory emulating MTD

Create a shell script (mount_jffs2.sh) from the following:

#!/bin/sh
JFFSIMG=$1 # jffs image
MP="/media/jffs2" # mount point
MTDBLOCK="/tmp/mtdblock0" # MTD device file
UMNT=""
 
echo "$0" | grep unmount_ >/dev/null 2>&1
[ $? -eq 0 ] && UMNT=1
if [ $# -gt 1 -a x"$2"x = x"unmount"x ]; then
  UMNT=1
fi
 
if [ x"${UMNT}"x = x""x ]; then
  if [ ! -b ${MTDBLOCK} ] ; then
    mknod ${MTDBLOCK} b 31 0 || exit 1
  fi
  modprobe mtdblock
  modprobe mtdram total_size=65536 erase_size=256
  modprobe jffs2
  dd if=${JFFSIMG} of=${MTDBLOCK}
  [ ! -d ${MP} ] && mkdir -p ${MP}
  mount -t jffs2 ${MTDBLOCK} ${MP}
else
  umount ${MP}
  if [ $? -ne 0 ]; then
    echo "Cannot unmount JFFS2 at $MP" && exit 1
  fi
  modprobe -r jffs2
  modprobe -r mtdram
  modprobe -r mtdblock
fi

Make sure you chmod a+x mount_jffs2.sh to make the shell script executable.

Usage:

./mount_jffs2.sh rootfs.jffs2

You can also use this script to unmount and unload the non-utilized kernel modules:

./mount_jffs2.sh rootfs.jffs2 unmount