NETGEAR is aware of a growing number of phone and online scams. To learn how to stay safe click here.
Forum Discussion
Sandshark
Jan 30, 2020Sensei
Why does NAS firmware update if unit is booted diskless?
I have reported before that booting a ReadyNAS with no drives installed resulted in the firmware in flash being updated. The response fomr the Netgear mod was that that was not possible, I beg t...
EHCanadian
Jan 31, 2020Star
Lets look at the x86\initrd.gz\initrd\init file from the firmware.
I have not looked at older versions of the readynas firmware or any varent other then the x86_64.
So subject to history/version and hardware.
v6.10.2 on a x86_64
#!/bin/sh
#ReadyNASOS 6.x.x usb recovery script
DBG="/dev/null"
mount -t proc proc /proc
mount -t sysfs sysfs /sys
mount -t devpts devpts /dev/pts
echo 3 > /proc/sys/kernel/printk
mdev -s
debug="no"
lcd="/proc/LCD"
SIZE=224
arch=`uname -m | cut -c 1-3`
netup() {
ifconfig lo up
addr=168
connected="no"
for eth in /sys/class/net/eth? ; do
nic=$(basename $eth)
ifconfig $nic up
RETRY=0
while [ $RETRY -lt 8 ]; do
if udhcpc -q -n -i $nic; then
connected=$nic
break 2
fi
RETRY=$(($RETRY+1))
usleep 250000
done
if [ $RETRY -eq 8 ]; then
echo "#### DHCP fail for $nic, use static ip 192.168.168.$addr"
ifconfig $nic 192.168.168.$addr
fi
addr=$(($addr+1))
done
if [ $connected != "no" ]; then
IP=`ifconfig $nic | grep "inet " | awk '{print $2}'|cut -f2 -d:`
else
IP=`ifconfig eth0 | grep "inet " | awk '{print $2}'|cut -f2 -d:`
fi
}
sethotid() {
mac3=`ifconfig eth0 | grep "HWaddr" | awk '{print $5}' | cut -f3 -d:`
mac4=`ifconfig eth0 | grep "HWaddr" | awk '{print $5}' | cut -f4 -d:`
mac5=`ifconfig eth0 | grep "HWaddr" | awk '{print $5}' | cut -f5 -d:`
mac6=`ifconfig eth0 | grep "HWaddr" | awk '{print $5}' | cut -f6 -d:`
mac3=$((0x${mac3} & 0x7f))
# ten to 0x
mac3=`echo $mac3 | awk '{printf("%0x\n",$0)}'`
echo "Hostid: ${mac3}${mac4}${mac5}${mac6}"
echo -ne "\x${mac6}\x${mac5}\x${mac4}\x${mac3}" > /etc/hostid
}
#our lcd can display 16 characters per line
clear_lcd() {
if [ -e $lcd ]; then
echo "1 \" \"" > $lcd
echo "2 \" \"" > $lcd
fi
}
lcd_line1() {
[ -e $lcd ] && echo "1 \"$1\"" > $lcd
}
lcd_line2() {
[ -e $lcd ] && echo "2 \"$1\"" > $lcd
}
rescue_shell() {
echo "Booting into debug mode..."
netup
sethotid
telnetd
echo "TELNET Mode" > /.os_status
PORT="TELNET"
cat /proc/cpuinfo | grep -q -i Annapurna && cp -a -f /etc/fw_env.config.alpine /etc/fw_env.config
if [ $debug = "yes" ]; then
PORT=`rnutil remote_access -p`
echo "Support: $PORT" > /.os_status
rnutil remote_access -b
echo "IP: $IP"
echo "PORT: $PORT"
fi
clear_lcd
lcd_line1 "DEBUG: $PORT"
lcd_line2 $IP
raidard
exec /bin/ash
}
show_error() {
echo "ERROR: ${1}!"
rescue_shell
}
get_sys_type_x86() {
PRODUCT_NAME=$( cat /sys/class/dmi/id/product_name | tr -d ' ')
echo "Model name: $PRODUCT_NAME"
if [ $PRODUCT_NAME = 'ReadyNAS312' -o $PRODUCT_NAME = 'ReadyNAS314' -o $PRODUCT_NAME = 'ReadyNAS316' ]; then
SYSTYPE='RN312_RN314_RN316'
elif [ $PRODUCT_NAME = 'ReadyNAS516' -o $PRODUCT_NAME = 'ReadyNAS716' ]; then
SYSTYPE='RN516_RN716'
elif [ $PRODUCT_NAME = 'ReadyNAS3220' -o $PRODUCT_NAME = 'ReadyNAS4220' ]; then
SYSTYPE='3220_4220'
elif [ $PRODUCT_NAME = 'ReadyNAS3130' -o $PRODUCT_NAME = 'ReadyNAS3138' ]; then
SYSTYPE='3130'
elif [ $PRODUCT_NAME = 'ReadyNAS526X' -o $PRODUCT_NAME = 'ReadyNAS626X' ]; then
SYSTYPE='RN526'
elif [ $PRODUCT_NAME = 'ReadyNAS3312' -o $PRODUCT_NAME = 'ReadyNAS4312' ]; then
SYSTYPE='RR3312'
#4360 product name , differnet ?
elif [ $PRODUCT_NAME = 'ReadyNASRR4360X' -o $PRODUCT_NAME = 'ReadyNASRR4360S' ]; then
SYSTYPE='RR3312'
fi
if [ -z $SYSTYPE ]; then
sku=`cat /sys/class/dmi/id/product_sku`
#4360 usb path is the same with 3312/4312
if [ $sku = "RR4360" ]; then
SYSTYPE='RR3312'
# 524/528/628 same with RN526/626
elif [ $sku = "RN524X" -o $sku = "RN528X" -o $sku = "RN628X" ]; then
SYSTYPE='RN526'
elif [ $sku = "RN422" -o $sku = "RN424" -o $sku = "RN426" -o $sku = "RN428" ]; then
SYSTYPE='RN422'
elif [ $sku = "RR2304" -o $sku = "RR2312" ]; then
SYSTYPE='RR2304'
# 3312V2/4312V2 should only have CPU upgrade on 3312/4312
elif [ $sku = "RR3312V2" -o $sku = "RR4312SV2" -o $sku = "RR4312XV2" ]; then
SYSTYPE='RR3312'
fi
fi
}
find_boot_device_x86() {
echo -n "Searching for internal boot flash device..."
for i in `seq 1 60`; do
# This should be the path for the internal USB port
if [ $SYSTYPE = "RN516_RN716" ]; then
DEV_PATH=/sys/devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.1/2-1.1:1.0/host*/target*/*/block/*
elif [ $SYSTYPE = "RN312_RN314_RN316" ]; then
DEV_PATH=/sys/devices/pci0000:00/0000:00:1d.7/usb1/1-1/1-1:1.0/host*/target*/*/block/*
elif [ $SYSTYPE = "3220_4220" ]; then
DEV_PATH=/sys/devices/pci0000:00/0000:00:1f.2/ata3/host*/target*/*/block/*
elif [ $SYSTYPE = '3130' ]; then
DEV_PATH=/sys/devices/pci0000:00/0000:00:16.0/usb1/1-1/1-1.2/1-1.2:1.0/host*/target*/*/block/*
elif [ $SYSTYPE = "RN526" ]; then
DEV_PATH=/sys/devices/pci0000:00/0000:00:14.0/usb2/2-4/2-4:1.0/host*/target*/*:0:0:0/block/*
elif [ $SYSTYPE = "RR3312" ]; then
DEV_PATH=/sys/devices/pci0000:00/0000:00:14.0/usb1/1-4/1-4:1.0/host*/target*/*:0:0:0/block/*
elif [ $SYSTYPE = "RN422" ]; then
DEV_PATH=/sys/devices/pci0000:00/0000:00:15.0/usb1/1-2/1-2:1.0/host*/target*/*:0:0:0/block/*
elif [ $SYSTYPE = "RR2304" ]; then
DEV_PATH=/sys/devices/pci0000:00/0000:00:15.0/usb1/1-1/1-1:1.0/host*/target*/*:0:0:0/block/*
else
echo "I do not know the internal boot flash location!"
DEV_PATH="*"
break
fi
BOOT_FLASH=$(basename $DEV_PATH)
grep -q ${BOOT_FLASH}$ /proc/partitions && break
usleep 250000
done
if [ "$BOOT_FLASH" = "*" ]; then
echo "Did not find boot flash!"
show_error "Could not find internal flash device!"
fi
mdev -s
echo "$BOOT_FLASH"
BOOT_FLASH="/dev/${BOOT_FLASH}"
}
update_flash_x86() {
MD5SUM=$(dd if=$IMAGE bs=16384 count=1 2>/dev/null | grep -a info:: | sed -e 's/.*md5sum=//' -e 's/,.*//')
if ! [ "$MD5SUM" = "`dd if=$IMAGE bs=16384 skip=1 2>/dev/null | md5sum | awk '{ print $1 }'`" ]; then
show_error "flash image checksum does not match!"
fi
cd /tmp/flash
dd if=$IMAGE bs=16384 skip=1 2>/dev/null | tar x || show_error "OS image extraction failed!"
rm -rf bios loader
mount -t msdos ${BOOT_FLASH}1 /boot_flash
if ! [ -s "syslinux.cfg" ]; then
cp /sysroot/syslinux.cfg .
fi
if [ $SYSTYPE = "NVX" ]; then
rm -f kernel
mv kernel.up kernel
else
rm -f kernel.up
fi
cp * /boot_flash || show_error "could not update flash device!"
sync
umount /boot_flash
umount /sysroot
cd /
}
verify_checksum() {
if ! mount -t msdos ${BOOT_FLASH}1 /boot_flash; then
echo "verify_checksum: Could not mount boot flash"
return 1
fi
cd /boot_flash
if ! md5sum -cs csums.md5; then
echo "verify_checksum failed"
cd /
umount /boot_flash
return 2
fi
cd /
umount /boot_flash
return 0
}
update_flash_x86_raw() {
if ! mount -t vfat ${EXTERNAL_FLASH} /sysroot; then
echo "update_flash_x86_raw: could not mount external flash"
return 1
fi
RAW=`ls /sysroot/ReadyNASOS-*-x86_64*.raw | head -n1`
if [ ! -s "$RAW" ]; then
echo "No raw file exist, use img file to update"
umount /sysroot
return 2
fi
#verify raw file -- TBD
echo -n "Use raw file to update..."
if ! dd if=$RAW bs=1M of=${BOOT_FLASH}; then
echo "DD raw file fail"
umount /sysroot
return 3
fi
echo "done"
#verify checksum
echo -n "Verify checksum..."
blockdev --rereadpt $BOOT_FLASH
mdev -s
if verify_checksum; then
echo "done"
else
umount /sysroot
return 4
fi
umount /sysroot
return 0
}
write_flash_x86() {
find_external_boot_device
find_boot_device_x86
mkdir /tmp/flash
if mount -t msdos ${BOOT_FLASH}1 /boot_flash; then
[ -f /boot_flash/vpd ] && cp /boot_flash/vpd /tmp/flash/
umount /boot_flash
fi
#Check if there is raw image which can be used for update
if update_flash_x86_raw; then
return 0
fi
echo -n "Formatting boot flash device..."
if [ $SYSTYPE = "RN516_RN716" ]; then
mkdiskimage $BOOT_FLASH 1024 8 32
#elif [ $SYSTYPE = "RN526" -o $SYSTYPE = "RR3312" ]; then
# mkdiskimage -M $BOOT_FLASH $SIZE 64 32
else
mkdiskimage -M $BOOT_FLASH $SIZE 64 32
fi
blockdev --rereadpt $BOOT_FLASH
mdev -s
mkdosfs ${BOOT_FLASH}1 > /dev/null
syslinux -i ${BOOT_FLASH}1
# Copy back VPD as first order
mount -t msdos ${BOOT_FLASH}1 /boot_flash
[ -f /tmp/flash/vpd ] && cp /tmp/flash/vpd /boot_flash/
umount /boot_flash
echo "done"
mount -t vfat ${EXTERNAL_FLASH} /sysroot || show_error "could not mount external flash"
IMAGE=`ls /sysroot/ReadyNASOS-*-x86_64.img | head -n1`
[ -s "$IMAGE" ] || show_error "no source flash image found"
echo -n "Writing internal USB boot flash device..."
update_flash_x86
echo "done"
}
get_sys_type_arm() {
SYSTYPE=$(cat /proc/cmdline | grep bdtype | sed -e 's/.*bdtype=//')
[ $SYSTYPE = "rn2120-v2" ] && SYSTYPE="rn2120"
}
find_boot_device_arm() {
echo -n "Searching for internal boot flash device..."
for i in `seq 1 60`; do
# This should be the path for the internal nand flash
BOOT_FLASH=ubi0_0
[ -c "/dev/${BOOT_FLASH}" ] && break
usleep 250000
done
if [ $i -eq 60 ]; then
echo "Did not find boot flash!"
show_error "Could not find internal flash device!"
fi
mdev -s
echo "mtd rootfs: $BOOT_FLASH"
BOOT_FLASH="/dev/${BOOT_FLASH}"
}
find_RN25_external_boot_device() {
echo -n "Searching for external boot flash device..."
for j in `seq 1 60`; do
# This should be the path for the front SDCARD port
for mb in /sys/block/mmcblk?; do
EXTERNAL_FLASH=$(basename $mb)
if grep -q ${EXTERNAL_FLASH}p1 /proc/partitions; then
mdev -s
if ! mount -t vfat /dev/${EXTERNAL_FLASH}p1 /sysroot >/dev/null 2>/dev/null; then
rm -f /dev/${EXTERNAL_FLASH}p1
continue
fi
IMAGE=`ls /sysroot/ReadyNASOS-*-arm.img 2>/dev/null | head -n1`
if [ ! -s "$IMAGE" ]; then
umount /sysroot
continue
fi
break
fi
done
[ -s "$IMAGE" ] && break
usleep 250000
done
if [ $j -eq 60 ]; then
echo "Could not find RN25 external boot flash!"
show_error "Could not find RN25 external flash device!"
fi
umount /sysroot
echo "$EXTERNAL_FLASH"
EXTERNAL_FLASH="/dev/${EXTERNAL_FLASH}"
}
find_external_boot_device() {
echo -n "Searching for external boot flash device..."
found="no"
for i in `seq 1 60`; do
mdev -s
# This should be the path for the front USB port
# try mount raw device first
for sd in /sys/block/sd?; do
EXTERNAL_FLASH=$(basename $sd)
if ! mount -t vfat /dev/${EXTERNAL_FLASH} /sysroot >/dev/null 2>/dev/null; then
continue
fi
IMAGE=`ls /sysroot/ReadyNASOS-*.img 2>/dev/null | head -n1`
if [ ! -s "$IMAGE" ]; then
umount /sysroot
continue
fi
found="yes"
break
done
# try mount partion 1 ~ 4
if [ $found = 'no' ];then
for p in `seq 1 4`; do
for sd in /sys/block/sd?; do
dev=$(basename $sd)
EXTERNAL_FLASH=$dev$p
if ! mount -t vfat /dev/${EXTERNAL_FLASH} /sysroot >/dev/null 2>/dev/null; then
continue
fi
IMAGE=`ls /sysroot/ReadyNASOS-*.img 2>/dev/null | head -n1`
if [ ! -s "$IMAGE" ]; then
umount /sysroot
continue
fi
break 2
done
done
fi
[ -s "$IMAGE" ] && break
usleep 250000
done
if [ $i -eq 60 ]; then
echo "Could not find external boot flash!"
show_error "Could not find external flash device!"
fi
umount /sysroot
echo "$EXTERNAL_FLASH"
EXTERNAL_FLASH="/dev/${EXTERNAL_FLASH}"
}
update_flash_arm() {
MD5SUM=$(dd if=$IMAGE bs=16384 count=1 2>/dev/null | grep -a info:: | sed -e 's/.*md5sum=//' -e 's/,.*//')
if ! [ "$MD5SUM" = "`dd if=$IMAGE bs=16384 skip=1 2>/dev/null | md5sum | awk '{ print $1 }'`" ]; then
show_error "flash image checksum does not match!"
fi
[ ! -d /tmp/flash ] && mkdir /tmp/flash
cd /tmp/flash
dd if=$IMAGE bs=16384 skip=1 2>/dev/null | tar x || show_error "OS image extraction failed!"
for fl in /sysroot/u-boot-${SYSTYPE}-*; do
[ -f $fl ] || break
cp -f $fl /tmp/flash
echo "done"
done
for fl in /tmp/flash/u-boot-${SYSTYPE}-*; do
[ -f $fl ] || break
FLNAME=$(basename $fl)
flash_erase /dev/mtd0 0 0
nandwrite -p /dev/mtd0 ./$FLNAME
echo "done"
done
for fl in /tmp/flash/kernel.${SYSTYPE}; do
[ -f $fl ] || break
FLNAME=$(basename $fl)
flash_erase /dev/mtd2 0 0
nandwrite -p /dev/mtd2 ./$FLNAME
done
# there is only kernel/kernel.arm/kernel.alpine from 6.4.0
if [ ! -f /tmp/flash/kernel.${SYSTYPE} ]; then
if [ $SYSTYPE = "rn202" -o $SYSTYPE = "rn204" -o $SYSTYPE = "rn212" -o $SYSTYPE = "rn214" ]; then
#Alpine series
if [ -f /tmp/flash/kernel.alpine ]; then
mv /tmp/flash/kernel.alpine /tmp/flash/kernel
sed -i -e '/kernel$/d' -e 's/kernel.alpine/kernel/' /tmp/flash/csums.md5
fi
fi
if [ -f /tmp/flash/kernel ]; then
flash_erase /dev/mtd2 0 0
nandwrite -p /dev/mtd2 ./kernel
fi
fi
for fl in /tmp/flash/initrd*; do
[ -f $fl ] || break
FLNAME=$(basename $fl)
flash_erase /dev/mtd3 0 0
nandwrite -p /dev/mtd3 ./$FLNAME
done
# copy files to ubifs, then dual boot supported by uboot works
# Manufactures use new nand flash with low quatility which has more bad blocks then boot from /dev/mtd1 may fail
# JustinM add feathers to let uboot fallback to boot kernel/initrd from ubifs
cp /tmp/flash/* /boot_flash || show_error "could not update ubifs!"
sync
umount /boot_flash
umount /sysroot
cd /
}
format_mtd4() {
echo -n "Internal flash crashed, format it..."
ubidetach -m 4
flash_erase /dev/mtd4 0 0
sleep 1
ubiattach /dev/ubi_ctrl -m 4
sleep 1
ubimkvol /dev/ubi0 -N rootfs -m
sleep 1
echo "done"
}
write_flash_arm() {
mdev -s
## find external boot usb device
if [ $SYSTYPE = "rn25" -o $SYSTYPE = "s2000" -o $SYSTYPE = "folio" ]; then
find_RN25_external_boot_device
mount -t vfat ${EXTERNAL_FLASH}p1 /sysroot || show_error "could not mount external flash"
else
find_external_boot_device
mount -t vfat ${EXTERNAL_FLASH} /sysroot || show_error "could not mount external flash"
fi
if [ -f /sysroot/NTGR_DEBUG.* ]; then
echo "Found debug flag file"
debug="yes"
umount /sysroot
rescue_shell
fi
#internal mtd rootfs
if ubiattach /dev/ubi_ctrl -m 4; then
echo "Internal flash attached"
else
format_mtd4
fi
mdev -s
find_boot_device_arm
[ ! -d /boot_flash ] && mkdir /boot_flash
if mount -t ubifs ${BOOT_FLASH} /boot_flash; then
rm -f /boot_flash/root.tlz
fi
mdev -s
IMAGE=`ls /sysroot/ReadyNASOS-*-arm.img | head -n1`
[ -s "$IMAGE" ] || show_error "no source flash image found"
echo -n "Writing internal nand flash device..."
update_flash_arm
echo "done"
}
enter_debug_mode() {
if [ $SYSTYPE = "rn25" -o $SYSTYPE = "s2000" -o $SYSTYPE = "folio" ]; then
find_RN25_external_boot_device
mount -t vfat ${EXTERNAL_FLASH}p1 /sysroot || show_error "could not mount external flash"
else
find_external_boot_device
mount -t vfat ${EXTERNAL_FLASH} /sysroot || show_error "could not mount external flash"
fi
if [ -f /sysroot/NTGR_DEBUG.* ]; then
echo "Found debug flag file"
debug="yes"
umount /sysroot
rescue_shell
else
umount /sysroot
fi
}
echo "Starting USB Recovery..."
lcd_line1 " ReadyNAS "
lcd_line2 " USB Recovery "
echo "ARCH: $arch"
if [ $arch = "x86" ]; then
get_sys_type_x86
elif [ $arch = "arm" ]; then
get_sys_type_arm
fi
if [ -z $SYSTYPE ]; then
show_error "Get systype failed!"
else
echo "Got systype=$SYSTYPE"
fi
enter_debug_mode
if [ $arch = "x86" ]; then
write_flash_x86
else
write_flash_arm
fi
clear_lcd
echo "Recovery Done"
lcd_line1 "Recovery Done"
sleep 1
/sbin/poweroff -fHow does the unit boot up?
serial 0 115200 0 timeout 30 prompt 1 default Normal label Normal kernel kernel append initrd=initrd.gz reason=normal label FactoryDefault kernel kernel append initrd=initrd.gz reason=factory label OSReinstall kernel kernel append initrd=initrd.gz reason=os_reinstall label TechSupport kernel kernel append initrd=initrd.gz reason=diag label SkipVolCheck kernel kernel append initrd=initrd.gz reason=skip_fsck label MemoryTest kernel memtest label TestDisks kernel kernel append initrd=initrd.gz reason=test_disks
The x-flex raid by default is enabled and will assimilate any non usb hardware. So that
needs to be disabled after you flash/recover the device.
What device do you have?
Sandshark
Feb 01, 2020Sensei
Was there something specific you wanted to point out in that boot code? Note that I'm not interested in the method it uses, I want to know why someone has chosen that it does this automatic update at all. I did not intentionally update it and did not want an update to occur. I just booted it with no drives installed. It is, as best I can tell, contrary to all the Netgear documentation.
As I said in my original message, I have seen this occur on an RN4200V2 and Ultra4 converted to OS6, and also on an RN312. I can understand that the converted legacy devices could have an issue, since I'm sure there isn't a lot of testing going on with them. But the 312 is a native OS6 device.
- EHCanadianFeb 01, 2020Star
Na, Just that support doesn't know what they are talking about for the most part.
So I posted the init to show you how they actual dev's did things, What you see is the actual
conditions scripted by the software team that causes the system to try to correct itself.
The readynas os itself has services in debian that auto run at boot that self update itself.
Overall they took the approach to code in micro automated management with the assumption
that we are inexperienced and has simple methods to self manage the unit.
However I have not seen them code in version control. Since we are all told that we need to update
to a speific version before applying the next. Whom do not listen end up in using the usbbootrecovery
or brinking the internal flash.
But you can turn services of that enable the self update.
Deleting the startup entries usualy casues them to return.
The interal flash has its own boot manager that boots to /dev/sda and does the automating of installing itself,
Thus enabling the system to update itself.
- mdgmFeb 01, 2020Virtuoso
The update server provides the recommended update from any given version and that's where they would get it from.
Not sure what the relevance of the USB Boot Recovery init file is. The init file in the firmware itself is different.
Related Content
NETGEAR Academy
Boost your skills with the Netgear Academy - Get trained, certified and stay ahead with the latest Netgear technology!
Join Us!