Examine ARM9 Firmware without Updating

From NAS-Central Buffalo - The Linkstation Wiki
Revision as of 19:11, 21 April 2010 by Maddes (Talk | contribs)

Jump to: navigation, search


Contents

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.

Firmware Design

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).

Examine a Firmware Update on a PC

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-04-19

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

#!/bin/sh

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.

#!/bin/sh

#
# Copyright (C) 2010 Matthias Buecher (http://www.maddes.net/)
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
# http://www.gnu.org/licenses/gpl-2.0.txt
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# 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

# Unzip initrd.img if available
[ -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'
}

# Backup stock initrd.buffalo
[ -f 'initrd.buffalo' ] && [ ! -f 'initrd.buffalo.stock' ] && {
	echo 'Creating backup of initrd.buffalo...'
	cp 'initrd.buffalo' 'initrd.buffalo.stock'
}

# Remove U-Boot header from initrd.buffalo
[ -f 'initrd.buffalo' ] && [ ! -f 'initrd.gz' ] && [ ! -f 'initrd' ] && {
	echo 'Creating initrd.gz...'
	dd if='initrd.buffalo' of='initrd.gz' ibs=64 skip=1
}

# Extract initrd.gz
[ -f 'initrd.gz' ] && [ ! -f 'initrd' ] && {
	echo 'Getting initrd...'
	gunzip 'initrd.gz'
}

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

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

# copy linuxrc from initrd to be able to create a complete root filesystem
[ ! -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
}

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).

#!/bin/sh

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

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

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

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


# Unzip hddrootfs.img if available
[ -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'
}

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

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

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

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

# create boot content
[ ! -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'