Skip to content

Instantly share code, notes, and snippets.

@cellularmitosis
Last active February 19, 2023 11:35
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save cellularmitosis/5e48cca67a54ad436b6d259919549812 to your computer and use it in GitHub Desktop.
Save cellularmitosis/5e48cca67a54ad436b6d259919549812 to your computer and use it in GitHub Desktop.
Notes on resurrecting an old NSLU2

Blog 2019/2/3

<- previous | index | next ->

Resurrecting the NSLU2

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

Overclock to 266MHz

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

Revert to Michlmayer's firmware image

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:

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

Prepare a disk using Michlmayer's filesystem tarball

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

Post-boot fixin's

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 the date 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.

Free up some RAM

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 the T0: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, run systemctl mask serial-getty@ttyS0.service.

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!

Performance tweaks

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

Upgrade to Jessie

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 and flash-kernel to run, which also seemed to hose my NSLU2 (I was able to recover just by running upslug2 -i sda2-3.2.0-4). If I were to do this again, I would attempt to disable update-initramfs and flash-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 and apt-get dist-upgrade
@cellularmitosis
Copy link
Author

A note on order of operations: I actually performed most of the tweaks after upgrading to jessie. You may need to do the same to get the same results.

@drwhitehouse
Copy link

drwhitehouse commented Oct 23, 2021

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment