Examine ARM9 Firmware without Updating

About
This article provides two Linux scripts which extract the files of a Firmware Update, so the content can be examined without updating a device. Useful to help someone with another device or to see the initial setup of a device.

One script handles and mounts only the initrd and is useful when modifying an initrd.

Scripts are used instead of separate instructions, so that they can be re-used easily for several different Firmware Updates.

There is an Analysis of the ARM9 boot process available.

Updater
The Updater allows updating a device from Windows.

Details about LSUpdater for LS Pro and LS Live.

initrd.buffalo (or initrd.img)
This file contains the initial ramdisk that provides EM Mode on several devices (LSLv2; please maintain list). EM mode is also used to do the updates.

initrd.img is a zipped (not gzipped) version of initrd.buffalo. Additionally secured/encrypted by a password (these are mostly known).

initrd.buffalo is a U-Boot initrd image, which consists of a 64 bytes long U-Boot header plus a normal gzipped initrd. This file can also be found on the boot partition (/dev/sda1, which is normally mounted to /boot).

If the directory /initrd exists on the root file system (/dev/sda2) then the initrd will be mounted there.

hddrootfs.buffalo.updated (or hddrootfs.img)
This file contains most files for the root file system (/dev/sda2).

hddrootfs.img is a zipped (not gzipped) version of hddrootfs.buffalo.updated. Additionally secured/encrypted by a password (these are mostly known).

hddrootfs.buffalo.updated is a normal gzipped tar archive.

During the Firmware Update this file is copied to the boot partition and then extracted from there to the root file system.

The "missing files" will be copied from the initrd to the root file system. The script function CopyFromInitrdToHdd is defined and called inside /linuxrc of the initrd.

uImage.buffalo
This file contains the Linux kernel.

uImage.buffalo is a U-Boot kernel image, which also contains a special mach-type for the device. This file can also be found on the boot partition (/dev/sda1, which is normally mounted to /boot).

u-boot.buffalo.updated
This file contains U-Boot for the device. This file can also be found on the boot partition (/dev/sda1, which is normally mounted to /boot).

Prerequisites
A Linux distribution either directly on the PC or in a Virtual Machine (e.g. VirtualBox). Also zip and gzip have to be available.

Directory Organisation and Download
To keep directories tidy it is recommended to handle the Stock Firmwares inside a separate directory.

Example: mkdir -p linkstation/stock

Go there and download the wanted Firmware Update from Buffalo. Due to Buffalo's download script the filename will have a leading "index.html?", it is recommended to remove this. Finally unzip it. Normally a corresponding sub-directory will be created.

Example for LSLv2 (HS-DHGL) Firmware 2.10: cd linkstation/stock/ wget -N http://www.buffalo-technology.com/support/getfile/?hs-dhgl_2.10_005.zip ; echo -e '\a' mv index.html?hs-dhgl_2.10_005.zip hs-dhgl_2.10_005.zip unzip hs-dhgl_2.10_005.zip ls -la HS-DHGL_210_005_us/

Scripts
Last version: 2010-06-25

The scripts are also available here, but most not be up-to-date all the time.

Introduction
Either create the following scripts inside the above created linkstation/stock directory, or inside /usr/local/bin if you want to access it from everywhere.

There are two scripts and an additional source file which is used by these.

The first script handles and mounts only the initrd and is useful when modifying an initrd.

The second script creates the root file system and needs the first script to copy the necessary files from the initrd.

The additional file contains script functions that are used by both scripts, e.g. displaying the passwords for img files.

Usage
If the directory containing the scripts is not listed in the PATH environment variable, then the path to the scripts must be stated. If it is stated in PATH, like /usr/local/bin, then the scripts can be called only by their name.

The explanations here assume that the scripts are one directory higher, where also all the downloads are stored. If placed in /usr/local/bin or similar, then just remove "../" from the calls.

a) To create the root file system, go to the extracted Firmware Update and call the script "create_arm9_filesystem.sh". The root file system will be available in the directory called "fs". cd HS-DHGL_210_005_us/ ../create_arm9_filesystem.sh ls -la fs/

b) To mount the initrd, go to the extracted Firmware Update and call the script "mount_arm9_initrd.sh". The initrd will be available in the directory called "INITRD", and can also be modified (see How to modify an initrd). When done unmount the initrd again. cd HS-DHGL_210_005_us/ ../mount_arm9_initrd.sh ls -la INITRD/ umount INITRD/

buffalo_arm9_general.sh
Contains general script functions for both scripts.

For the community: When new passwords are introduced by Buffalo, then please also update the password list here. The current ones are listed in the following articles: Firmware Password, Firmware Update, How to Modify an InitRD, Create a Custom Firmware Image
 * 1) !/bin/sh


 * 1) Copyright (C) 2010 Matthias Buecher (http://www.maddes.net/)
 * 2) Homepage: http://buffalo.nas-central.org/wiki/Examine_ARM9_Firmware_without_Updating
 * 3) This program is free software; you can redistribute it and/or modify
 * 4) it under the terms of the GNU General Public License as published by
 * 5) the Free Software Foundation; either version 2 of the License, or
 * 6) (at your option) any later version.
 * 7) http://www.gnu.org/licenses/gpl-2.0.txt
 * 8) This program is distributed in the hope that it will be useful,
 * 9) but WITHOUT ANY WARRANTY; without even the implied warranty of
 * 10) MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * 11) GNU General Public License for more details.
 * 12) You should have received a copy of the GNU General Public License
 * 13) along with this program; if not, write to the Free Software
 * 14) Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 * 1) You should have received a copy of the GNU General Public License
 * 2) along with this program; if not, write to the Free Software
 * 3) Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 * 1) Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

show_arm9_img_passwords {	cat << __EOF Try one of these passwords when asked: 1NIf_2yUOlRDpYZUVNqboRpMBoZwT4PzoUvOPUp6l # hddrootfs.img (LSLv2) aAhvlM1Yp7_2VSm6BhgkmTOrCN1JyE0C5Q6cB3oBB YvSInIQopeipx66t_DCdfEvfP47qeVPhNhAuSYmA4 # initrd.img (LSP) IeY8omJwGlGkIbJm2FH_MV4fLsXE8ieu0gNYwE6Ty # initrd.img (LSLv2) __EOF }

mount_arm9_initrd.sh
Extracts the initrd and mounts it via a loop device to a given directory. If no directory is stated, then "INITRD" is used. Additionally copies linuxrc out of the initrd and modifies it via sed for the second script.
 * 1) !/bin/sh


 * 1) Copyright (C) 2010 Matthias Buecher (http://www.maddes.net/)
 * 2) Homepage: http://buffalo.nas-central.org/wiki/Examine_ARM9_Firmware_without_Updating
 * 3) This program is free software; you can redistribute it and/or modify
 * 4) it under the terms of the GNU General Public License as published by
 * 5) the Free Software Foundation; either version 2 of the License, or
 * 6) (at your option) any later version.
 * 7) http://www.gnu.org/licenses/gpl-2.0.txt
 * 8) This program is distributed in the hope that it will be useful,
 * 9) but WITHOUT ANY WARRANTY; without even the implied warranty of
 * 10) MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * 11) GNU General Public License for more details.
 * 12) You should have received a copy of the GNU General Public License
 * 13) along with this program; if not, write to the Free Software
 * 14) Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 * 1) You should have received a copy of the GNU General Public License
 * 2) along with this program; if not, write to the Free Software
 * 3) Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 * 1) Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

MOUNTPATH='INITRD'	# default mount point [ -n "$1" ] && MOUNTPATH="$1"

source `dirname "$0"`/buffalo_arm9_general.sh

[ -f 'initrd.img' ] && [ ! -f 'initrd.buffalo' ] && { echo -e 'Getting initrd.buffalo...\n' show_arm9_img_passwords echo -e '\a' unzip 'initrd.img' [ $? -ne 0 ] && exit 1 rm -f 'initrd.img' }
 * 1) Unzip initrd.img if available

[ -f 'initrd.buffalo' ] && [ ! -f 'initrd.buffalo.backup' ] && { echo 'Creating backup of initrd.buffalo...' cp 'initrd.buffalo' 'initrd.buffalo.backup' }
 * 1) Backup initrd.buffalo

[ -f 'initrd.buffalo' ] && [ ! -f 'initrd' ] && { # Check if it is an uImage echo 'Checking for uImage...' UMAGIC=`dd if="initrd.buffalo" ibs=4 count=1 | hexdump -v -e '1/1 "%02X"'` UOS='' UARCH='' UTYPE='' UCOMP=''
 * 1) Create initrd from initrd.buffalo

# No uImage so just copy initrd.buffalo [ '27051956' != "${UMAGIC}" ] && { echo "Not an uImage. Magic word is ${UMAGIC}." cp initrd.buffalo initrd }

# Process uImage [ '27051956' = "${UMAGIC}" ] && { # Get additional information from U-Boot header UOS=`dd if="initrd.buffalo" ibs=1 skip=28 count=1 | hexdump -v -e '1/1 "%02X"'` UARCH=`dd if="initrd.buffalo" ibs=1 skip=29 count=1 | hexdump -v -e '1/1 "%02X"'` UTYPE=`dd if="initrd.buffalo" ibs=1 skip=30 count=1 | hexdump -v -e '1/1 "%02X"'` UCOMP=`dd if="initrd.buffalo" ibs=1 skip=31 count=1 | hexdump -v -e '1/1 "%02X"'` extension='' command=''

[ '03' != "${UTYPE}" ] && { echo "Not a RAMDisk image. uImage type is ${UTYPE}."; } [ '03' = "${UTYPE}" ] && { [ '00' != "${UCOMP}" ] && { extension='.unknown'; command='unknown_compression'; } [ '01' = "${UCOMP}" ] && { extension='.gz'; command='gunzip'; } [ '02' = "${UCOMP}" ] && { extension='.bz2'; command='bunzip2'; }

# Remove U-Boot header echo "Creating initrd${extension}..." dd if='initrd.buffalo' of="initrd${extension}" ibs=64 skip=1

# Extract initrd [ -n "${command}" ] && { echo 'Getting initrd...' "${command}" "initrd${extension}" }		}	} }

[ ! -f 'initrd' ] && { echo 'initrd not found' exit 1 }
 * 1) Check for correct directory

[ ! -d "${MOUNTPATH}" ] && mkdir "${MOUNTPATH}" umount -d "${MOUNTPATH}" 2>/dev/null mount -t ext2 -o loop 'initrd' "${MOUNTPATH}"
 * 1) mount initrd

[ ! -f 'linuxrc' ] && { echo 'Copying and modifying linuxrc...' cp "${MOUNTPATH}/linuxrc". sed -i -e '/CopyFromInitrdToHdd/,/fsck_disks/!D' -e '/fsck_disks/d' -e '{ s#/mnt/#fs/#; s# /# ${MOUNTPATH}/#; s#cp #cp -i #}' linuxrc }
 * 1) copy linuxrc from initrd to be able to create a complete root filesystem

echo "If initrd is nomore needed, please call \"umount ${MOUNTPATH}\" in this directory"

create_arm9_filesystem.sh
Extracts the rootfs archive to "fs" and copies the "missing" files from the initrd via the modified linuxrc (from the first script).
 * 1) !/bin/sh


 * 1) Copyright (C) 2010 Matthias Buecher (http://www.maddes.net/)
 * 2) Homepage: http://buffalo.nas-central.org/wiki/Examine_ARM9_Firmware_without_Updating
 * 3) This program is free software; you can redistribute it and/or modify
 * 4) it under the terms of the GNU General Public License as published by
 * 5) the Free Software Foundation; either version 2 of the License, or
 * 6) (at your option) any later version.
 * 7) http://www.gnu.org/licenses/gpl-2.0.txt
 * 8) This program is distributed in the hope that it will be useful,
 * 9) but WITHOUT ANY WARRANTY; without even the implied warranty of
 * 10) MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * 11) GNU General Public License for more details.
 * 12) You should have received a copy of the GNU General Public License
 * 13) along with this program; if not, write to the Free Software
 * 14) Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 * 1) You should have received a copy of the GNU General Public License
 * 2) along with this program; if not, write to the Free Software
 * 3) Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 * 1) Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

MOUNTPATH='INITRD_for_fs/' source `dirname "$0"`/buffalo_arm9_general.sh


 * 1) XFS support is not needed as...
 * 2) a) hddrootfs.buffalo.updated is a tar file for the root filesystem (/dev/sda2, normally XFS)
 * 3) b) the initial content for the data filesystem in /mnt/disk1 is generated (/dev/sda6, normally XFS)


 * 1) Special note:
 * 2) the rootfs image doesnot contain all files, some files are coming from the initrd (not all initrd files)
 * 3) copy routine CopyFromInitrdToHdd is defined in linuxrc of initrd

[ -f 'hddrootfs.img' ] && [ ! -f 'hddrootfs.buffalo.updated' ] && { echo -e 'Getting hddrootfs.buffalo.updated...\n' show_arm9_img_passwords echo -e '\a' unzip 'hddrootfs.img' [ $? -ne 0 ] && exit 1 rm -f 'hddrootfs.img' }
 * 1) Unzip hddrootfs.img if available

[ ! -f 'hddrootfs.buffalo.updated' ] && { echo 'hddrootfs.buffalo.updated not found' exit 1 }
 * 1) Check for correct directory

[ ! -d 'fs/' ] && mkdir 'fs/'
 * 1) create directory to hold root file system

[ ! -d 'fs/etc/' ] && { echo 'Extracting root filesystem...' tar -x --gzip -f 'hddrootfs.buffalo.updated' -C 'fs/' echo -e '\a' }
 * 1) extract rootfs

[ ! -f 'fs/etc/initrd_ver' ] && { `dirname "$0"`/mount_arm9_initrd.sh "${MOUNTPATH}" source linuxrc CopyFromInitrdToHdd umount "${MOUNTPATH}" rm -rf "${MOUNTPATH}" }
 * 1) copy initrd files

[ ! -d 'fs/boot/' ] && mkdir 'fs/boot/' [ -e 'fs/boot/initrd.buffalo' ] && rm -f 'fs/boot/initrd.buffalo' ln -s '../../initrd.buffalo' 'fs/boot/initrd.buffalo' [ -e 'fs/boot/u-boot.buffalo' ] && rm -f 'fs/boot/u-boot.buffalo' ln -s '../../u-boot.buffalo.updated' 'fs/boot/u-boot.buffalo' [ -e 'fs/boot/uImage.buffalo' ] && rm -f 'fs/boot/uImage.buffalo' ln -s '../../uImage.buffalo' 'fs/boot/uImage.buffalo'
 * 1) create boot content

Links

 * How to Extract an uImage