Blog 2019/2/3
<- previous | index | next ->
This weekend I resurrected an old NSLU2 which I had somehow gotten stuck into a non-bootable state.
Here are some notes on that process, on the off-chance that anyone else is still hanging onto one of these (this is a 266MHz ARM5 box with 32MB RAM -- not many people have the patience for it when a Raspberry Pi Zero W is only $10!).
Note: older versions of the NSLU2 shipped running at 133MHz, but can be easily and safely overclocked to 266MHz (later versions shipped at 266MHz). See http://www2.nslu2-linux.org/wiki/pmwiki.php?pagename=HowTo/OverClockTheSlug
If you are still running at 133MHz, you should overclock before proceeding, unless you truly have the patience of a saint. You can cat /proc/cpuinfo
to check if you are overclocked (if you are, your BogoMIPS should be close to 266).
Martin Michlmayer has a bunch of excellent guides on getting Debian Linux installed on the NSLU2, and also hosts some binary images of a working Debian wheezy install:
- His instructions: https://www.cyrius.com/debian/nslu2/unpack/
- filesystem tarball
- firmware image
My mirror of those files, in case his page goes away:
Martin's instructions on putting the NSLU2 into "upgrade mode":
- Disconnect any disks and/or devices from the USB ports.
- Power off the NSLU2
- Press and hold the reset button (accessible through the small hole on the back just above the power input).
- Press and release the power button to power on the NSLU2.
- Wait for 10 seconds watching the ready/status LED. After 10 seconds it will change from amber to red (old older NSLU2) or dark orange (on newer machines). Immediately release the reset button.
- The NSLU2 ready/status LED will flash alternately dark orange and green (there is a 1 second delay before the first green). The NSLU2 is now in upgrade mode.
Note: getting the device to come up in "upgrade mode" was a bit finicky for me. I had to have it already plugged into the network switch, otherwise it would come up in some sort of "failed to reach upgrade mode" state, in which the LED was blinking orange / off rather than red / green. When this would happen, upslug2 would fail with [no NSLU2 machines found in upgrade mode]
.
With the NSLU2 in upgrade mode (LED flashing red / green), and a Raspberry Pi plugged into the same network switch, I was able to flash the firmware (upslug2 -i sda2-3.2.0-4
):
root@raspberrypi:~/nslu2# upslug2 -i sda2-3.2.0-4
LKG7CCC62 00:0f:66:7c:cc:62 Product ID: 1 Protocol ID:0 Firmware Version: R23V63 [0x2363]
Upgrading LKG7CCC62 00:0f:66:7c:cc:62
. original flash contents * packet timed out
! being erased - erased
u being upgraded U upgraded
v being verified V verified
Display:
<status> <address completed>+<bytes transmitted but not completed>
Status:
* timeout occured + sequence error detected
7fffff+000000 ...VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
Rebooting... done
Plug a USB flash drive into a linux box. To figure out which device node it attached as, run dmesg
and look at the last few lines of output:
[72497.029403] usb 1-1.5: new high-speed USB device number 14 using dwc_otg
[72497.160592] usb 1-1.5: New USB device found, idVendor=0781, idProduct=5580
[72497.160605] usb 1-1.5: New USB device strings: Mfr=1, Product=2, SerialNumber=3
[72497.160613] usb 1-1.5: Product: Extreme
[72497.160621] usb 1-1.5: Manufacturer: SanDisk
[72497.160629] usb 1-1.5: SerialNumber: AA010525152125170478
[72497.161685] usb-storage 1-1.5:1.0: USB Mass Storage device detected
[72497.165211] scsi host0: usb-storage 1-1.5:1.0
[72498.180390] scsi 0:0:0:0: Direct-Access SanDisk Extreme 0001 PQ: 0 ANSI: 6
[72498.181672] sd 0:0:0:0: Attached scsi generic sg0 type 0
[72498.183021] sd 0:0:0:0: [sda] 31277232 512-byte logical blocks: (16.0 GB/14.9 GiB)
[72498.183737] sd 0:0:0:0: [sda] Write Protect is off
[72498.183753] sd 0:0:0:0: [sda] Mode Sense: 53 00 00 08
[72498.184187] sd 0:0:0:0: [sda] Write cache: enabled, read cache: enabled, doesn't support DPO or FUA
[72498.187992] sda: sda1 sda2
[72498.191104] sd 0:0:0:0: [sda] Attached SCSI removable disk
For me, it comes up as /dev/sda
, because my Raspberry Pi's root disk is at /dev/mmcblk0
. If you are using a linux laptop, your root disk will likely be /dev/sda
, and so the flash drive will likely come up as /dev/sdb
.
Partition a USB flash drive into two partitions:
- 32MB bootable
- (the rest)
MAKE SURE YOU DON'T ACCIDENTALLY PARTITION THE DISK ON YOUR LAPTOP by using the wrong device name! If you are unsure, run df
to check.
When you are sure, partition the disk:
cfdisk /dev/sda
Make the filesystems:
mkfs.ext2 /dev/sda1
mkfs.ext3 /dev/sda2
Mount the filesystems and unpack the tarball.
mount /dev/sda2 /mnt
mkdir /dev/sda1 /mnt/boot
mount /dev/sda1 /mnt/boot
cd /mnt
cat ~/base.tar.bz2 | bunzip2 | tar x
While you have the filesystem mounted, you need to make a couple of tweaks:
- Martin's partition scheme used separate partitions for
/home
,swap
, etc. We'll just use two partitions. Here's my/mnt/etc/fstab
:
# /etc/fstab: static file system information.
#
# <file system> <mount point> <type> <options> <dump> <pass>
proc /proc proc defaults 0 0
/dev/sda2 / ext3 errors=remount-ro 0 1
/dev/sda1 /boot ext2 defaults 0 2
/swap none swap sw 0 0
- Create a swap file:
dd if=/dev/zero of=/mnt/swap bs=1M count=256 && mkswap /mnt/swap
Now unmount the flash drive:
cd
umount /mnt/boot
umount /mnt
sync
You should be able to boot the NSLU2 at this point.
It will take about a minute before the NSLU2 is reachable via ssh.
You can use nmap
to scan for the NSLU2 to figure out which IP address it came up with. It should be a Cisco-Linksys
device:
root@raspberrypi:~# nmap -sn 192.168.2.*
Starting Nmap 7.40 ( https://nmap.org ) at 2019-02-02 19:45 CST
...
Nmap scan report for 192.168.2.9
Host is up (0.00046s latency).
MAC Address: 00:0F:66:XX:XX:XX (Cisco-Linksys)
Log in as root, with the password "root".
Martin mentions the following steps to customize your NSLU2 once it boots up:
- change the root password
passwd
- add normal user accounts
adduser foo
- regenerate the SSH key (since the private key is included in the base system on my web page) by running:
rm /etc/ssh/ssh_host*
dpkg-reconfigure openssh-server
- edit
/etc/apt/sources.list
and use a Debian mirror close to you and then type:apt-get update
- (for me, this is ftp.us.debian.org)
- run
ntpdate pool.ntp.org
to make sure the clock is always up-to-date; otherwise attempts to install new packages might fail due to GPG verification errors (for the first time, you'll probably have to setup the clock manually using thedate
command). - upgrade your system using
apt-get dist-upgrade
to make sure you have the latest updates. - change the timezone with
dpkg-reconfigure tzdata
- setup locales with
dpkg-reconfigure locales
- edit
/etc/hostname
to change the hostname. - edit
/etc/hosts
and change the hostname and domain in the second line.
You can free up some RAM by making a few additional tweaks:
- Disable some services if you don't need them:
update-rc.d portmap disable
update-rc.d rpcbind disable
update-rc.d nfs-common disable
update-rc.d openbsd-inetd disable
update-rc.d atd disable
- If you don't need local mail (i.e. you don't plan on running any cron jobs):
update-rc.d exim4 disable
(or you can replace it with something like ssmtp).
Replace systemd
with the older sysvinit
system:
apt-get install sysvinit-core
apt-get remove --purge --auto-remove systemd
Prevent any systemd
packages from being installed by pinning it. Create a file /etc/apt/preferences.d/systemd
with this in it:
Package: *systemd*
Pin: release *
Pin-Priority: -1
Hmm, the above syntax doesn't seem to be compatible with cupt
, which fails with:
E: invalid condition '*'
E: (at the file '//etc/apt/preferences.d/systemd', line 2)
E: unable to parse preferences
So you may not be able to pin systemd
if you use cupt
.
Disable cgmanager
and cgproxy
(we don't be running any containers on the NSLU2):
-
update-rc.d cgmanager disable
-
update-rc.d cgproxy disable
-
Disable the serial console on
/dev/ttyS0
. Edit/etc/inittab
and comment out theT0:23:respawn:/sbin/getty -L ttyS0 115200 linux
line. -
Ah, nope! Debian switched to
systemd
, so/etc/inittab
is not you you configure the tty's anymore. Instead, runsystemctl mask [email protected]
.
Using a static IP address will prevent dhclient
from running. Configure your /etc/network/interfaces
file, e.g.:
auto eth0
iface eth0 inet static
address 192.168.2.199
netmask 255.255.255.0
gateway 192.168.2.1
You can edit /etc/passwd
and set your user shells to /bin/dash
, which is a bit lighter than bash
.
You can also use dropbear
as a lightweight replacement for openssh
:
apt-get install dropbear
Edit /etc/default/dropbear
and change NO_START=1
to NO_START=0
.
Then disable openssh:
update-rc.d ssh disable
rsyslog
uses up a fair amount of RAM:
$ ps aux
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 416 0.4 7.2 31224 2060 ? Ssl 08:56 0:00 /usr/sbin/rsyslogd -n
You can replace it with the syslogd which comes with busybox: apt-get install busybox-syslogd
.
By default, it will log to a ring buffer in RAM. Configure it to log to a file instead by editing /etc/default/busybox-syslogd
and change the line SYSLOG_OPTS="-C128"
to SYSLOG_OPTS="-O/var/log/messages"
. This is much lighter weight:
$ ps aux
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 1227 0.0 1.6 2428 464 ? Ss 09:30 0:00 /sbin/syslogd -O/var/log/messages
After all of that, this is what my non-kernel processes look like:
top - 09:57:12 up 2 min, 1 user, load average: 0.12, 0.14, 0.06
Tasks: 42 total, 1 running, 41 sleeping, 0 stopped, 0 zombie
%Cpu(s): 0.3 us, 1.3 sy, 0.0 ni, 98.4 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
KiB Mem: 28400 total, 26240 used, 2160 free, 2544 buffers
KiB Swap: 262140 total, 0 used, 262140 free. 16124 cached Mem
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
1317 root 20 0 3516 1352 992 R 1.6 4.8 0:00.75 top
322 root 20 0 11344 1328 968 S 0.0 4.7 0:00.56 udevd
1300 root 20 0 2884 1048 820 S 0.3 3.7 0:01.99 dropbear
1208 root 20 0 3460 892 700 S 0.0 3.1 0:00.02 cron
1212 message+ 20 0 5576 844 540 S 0.0 3.0 0:00.00 dbus-daemon
1 root 20 0 2992 824 692 S 0.0 2.9 0:02.38 init
1301 root 20 0 1848 572 488 S 0.0 2.0 0:00.08 dash
1131 root 20 0 2424 512 432 S 0.0 1.8 0:00.05 klogd
1134 root 20 0 2428 480 408 S 0.0 1.7 0:00.06 syslogd
1262 root 20 0 2424 408 304 S 0.0 1.4 0:00.01 dropbear
Not bad!
I also tweaked the swappiness. Add the line vm.swappiness=
to /etc/sysctl.conf
and then echo 1 > /proc/sys/vm/swappiness
.
cupt
[1][2][3] is an alternative to apt
which is much faster. One of the slowest parts of using the NSLU2 is waiting for apt to read the package index, etc (this is because the main Packages file is gigantic plaintext file).
You can configure cupt
to avoid xz
and bz2
index files. Create a file /etc/cupt/cupt.conf.d/compression
:
cupt::update::compression-types
{
uncompressed::priority "103";
lzma::priority "102";
gz::priority "101";
bz2::priority "99";
xz::priority "98";
};
(Then run cupt update
).
There is also an indexing cronjob which seems to slow the machine to a crawl. Disable it:
chmod -x /etc/cron.weekly/apt-xapian-index
Note that jessie is the last version of Debian to support the NSLU2, according to Martin.
Before upgrading, I made a few hacks / tweaks:
- Upgrading the kernel seems to hose my NSLU2, at which point I had to start over with the install. The second time around, I pinned the kernel to prevent it from being upgraded. Create a file
/etc/apt/preferences.d/kernel
and put this in it:
Package: linux-image-ixp4xx
Pin: version 3.2+46
Pin-Priority: 1000
- In my case, even though the kernel was pinned, the upgrade ended up triggering
update-initramfs
andflash-kernel
to run, which also seemed to hose my NSLU2 (I was able to recover just by runningupslug2 -i sda2-3.2.0-4
). If I were to do this again, I would attempt to disableupdate-initramfs
andflash-kernel
:
ln -s /bin/true /usr/local/sbin/update-initramfs
ln -s /bin/true /usr/local/sbin/flash-kernel
Now, onto the upgrade:
- edit
/etc/apt/sources.list
to point to jessie:
deb http://ftp.us.debian.org/debian/ jessie main
deb http://security.debian.org/ jessie/updates main
- Then
apt-get update
andapt-get dist-upgrade
Thanks for this it was useful. I only needed to follow your "Upgrade To Jessie" bit as I already had wheezy on my 3 slugs.
The symlink trick and pinning the kernel works well.
This may come in handy for those that need ssl:
https://github.com/xenetis/letsencrypt-expiration