First of all, english is not my native language, so i am sorry fo poor english
recovery procedure based on WD scripts, found on original firmware
requirements:
Linux PC (Ubuntu 10.10 for me) with installed parted, mdadm and gcc
WD HDD plugged on your PC (for me - /dev/sdf)
disk-param.sh
#!/bin/sh
###########################################
# � 2010 Western Digital Technologies, Inc. All rights reserved.
#
# definition list for a 1NC product
###########################################
factoryRestoreSettings=/etc/.factory_restore_settings
reformatDataVolume=/etc/.reformat_data_volume
diskWarningThresholdReached=/etc/.freespace_failed
disk=/dev/sdf
dataVolumeDevice="${disk}4"
swapDevice="${disk}3"
rootfsDevice="/dev/md0"
rootfsDisk1="${disk}1"
rootfsDisk2="${disk}2"
blockSize=64k
blockCount=31247
# The fill pattern needs to be verified for every release to manufacturing
backgroundPattern=0xE5
freshInstall.sh
#!/bin/sh
#
# � 2010 Western Digital Technologies, Inc. All rights reserved.
#
# freshInstall.sh
#
PATH=/sbin:/bin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin
. /path/to/parted/disk-param.sh
# create the new disk partitions
./partitionDisk.sh
# clear out any old md superblock data
mdadm --zero-superblock --force --verbose ${rootfsDisk1} > /dev/null
mdadm --zero-superblock --force --verbose ${rootfsDisk2} > /dev/null
sync
mdadm --create ${rootfsDevice} --verbose --raid-devices=2 --level=raid1 --run ${rootfsDisk1} missing
mdadm --wait ${rootfsDevice}
sleep 1
# create the swap partition
mkswap ${disk}3
# format the rootfs raid mirror file system
mkfs.ext3 -c -b 4096 ${rootfsDevice}
# format the data volume file system
mkfs.ext4 -b 65536 -m 0 ${disk}4
#mkfs.xfs -f -b size=65536 ${disk}4
sync
sleep 2
# mount and configure the data volume
# add the second partition to the raid mirror
mdadm ${rootfsDevice} --add --verbose ${rootfsDisk2}
sleep 1
echo
echo "Please wait for raid RE-SYNC to complete.."
sleep 1
mdadm --wait ${rootfsDevice}
mdadm --detail ${rootfsDevice}
echo "Done."
sync
# a reboot is performed by the caller
partitionDisk.sh
#!/bin/sh
#
# � 2010 Western Digital Technologies, Inc. All rights reserved.
#
# partitionDisk.sh
#
PATH=/sbin:/bin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin
. /path/to/disk-param.sh
# Apollo 3G parition layout:
#
# /dev/md0 -RFS
# /dev/${disk}1 - RFS (main)
# /dev/${disk}2 - RFS (backup)
#/dev/${disk}3 - swap
#/dev/${disk}4 - /DataVolume (includes /var)
#
echo "Partition Disk: ${disk}..."
backgroundPattern="${backgroundPattern:-0}"
#
# this script assumes that all preparatory steps have already been taken!
#
# clear any old partitioning data, etc.
if [ -e "${disk}1" ]; then
dd if=/dev/zero of=${disk}1 bs=1M count=32
fi
if [ -e "${disk}2" ]; then
dd if=/dev/zero of=${disk}2 bs=1M count=32
fi
if [ -e "${disk}3" ]; then
dd if=/dev/zero of=${disk}3 bs=1M count=32
fi
if [ -e "${disk}4" ]; then
dd if=/dev/zero of=${disk}4 bs=1M count=32
fi
if [ -e "${disk}" ]; then
# use badblocks here to preseve any background pattern
badblocks -swf -b 1048576 -t ${backgroundPattern} ${disk} 16 0
fi
sync
sleep 2
#parted $disk mklabel msdos
# use a 'here document' to allow parted to understand the -1M
parted $disk --align optimal <<EOP
mklabel gpt
mkpart primary 528M 2576M
mkpart primary 2576M 4624M
mkpart primary 16M 528M
mkpart primary 4624M -1M
set 1 raid on
set 2 raid on
quit
EOP
#parted $disk --align optimal <<EOP
#mklabel gpt
#mkpart primary 16M 2064M
#mkpart primary 2064M 4112M
#mkpart primary 4112M 4624M
#mkpart primary 4624M -1M
#set 1 raid on
#set 2 raid on
#quit
#EOP
# 2064 - 16 = 2048
# 4112 - 2064 = 2048
# 4624 - 4112 = 512
#
sync
sleep 1
parted $disk print
so..
partition new disk and create md-raid on it:
exec freshInstall.sh
from apnc-010303-20110119.deb extract rootfs.img and dd it on new raid:
dd if=rootfs.img of=/dev/md0
mount new rootfs and edit some settings:
mkdir /mnt/rootfs
mount /dev/md0 /mnt/rootfs
cp /mnt/rootfs/usr/local/share/bootmd0.scr /mnt/rootfs/boot/boot.scr
enable ssh
echo "enabled" > /mnt/rootfs/etc/nas/service_startup/ssh
sync
sync
sync
umount /mnt/rootfs
some black-magic for byteorder fixing (PPC BE vs x86 LE)
swap.c
#include <unistd.h>
#include <stdlib.h>
#include <fcntl.h>
#include <stdio.h>
#include <sys/mount.h>
#define MD_RESERVED_BYTES (64 * 1024)
#define MD_RESERVED_SECTORS (MD_RESERVED_BYTES / 512)
#define MD_NEW_SIZE_SECTORS(x) ((x & ~(MD_RESERVED_SECTORS - 1)) - MD_RESERVED_SECTORS)
main(int argc, char *argv[])
{
int fd, i;
unsigned long size;
unsigned long long offset;
char super[4096];
if (argc != 2) {
fprintf(stderr, "Usage: swap_super device\n");
exit(1);
}
fd = open(argv[1], O_RDWR);
if (fd<0) {
perror(argv[1]);
exit(1);
}
if (ioctl(fd, BLKGETSIZE, &size)) {
perror("BLKGETSIZE");
exit(1);
}
offset = MD_NEW_SIZE_SECTORS(size) * 512LL;
if (lseek64(fd, offset, 0) < 0LL) {
perror("lseek64");
exit(1);
}
if (read(fd, super, 4096) != 4096) {
perror("read");
exit(1);
}
for (i=0; i < 4096 ; i+=4) {
char t = super[i];
super[i] = super[i+3];
super[i+3] = t;
t=super[i+1];
super[i+1]=super[i+2];
super[i+2]=t;
}
/* swap the u64 events counters */
for (i=0; i<4; i++) {
/* events_hi and events_lo */
char t=super[32*4+7*4 +i];
super[32*4+7*4 +i] = super[32*4+8*4 +i];
super[32*4+8*4 +i] = t;
/* cp_events_hi and cp_events_lo */
t=super[32*4+9*4 +i];
super[32*4+9*4 +i] = super[32*4+10*4 +i];
super[32*4+10*4 +i] = t;
}
if (lseek64(fd, offset, 0) < 0LL) {
perror("lseek64");
exit(1);
}
if (write(fd, super, 4096) != 4096) {
perror("write");
exit(1);
}
exit(0);
}
gcc swap.c -o swap
mdadm —stop /dev/md0
./swap /dev/sdf1
./swap /dev/sdf2
unplug HDD this from PC, connect it with WD MyBookLive and boot
Firmware restored. Device unbricked.