Sunday, 19 January 2014

Installing Linux on ZyXel NSA-320 - Part 3 - Boot and install OS from USB

Warning: This process will erase data on your primary hard disk!

You may be wondering why you needed to get a telnet back door in Part 1.  Well, when I did this previously, I didn't have a serial cable and it was easier (but extremely risky) just to reflash the nand with uboot by writing a file over the flash device in /dev.  However, the NSA320 already has u-boot in flash so nothing needs modifying there.  Plus, with the serial cable, you get access to the system via the serial console.  I am using a modified Nokia serial cable, plugged into the serial connector on the NSA320.


I have also used an SD card reader as a USB host device, since I didn't have a USB drive to hand.  You can see the serial cable plugged into the serial connector on the NSA320 motherboard.

To get started, download the following tarball:

nsa320-alarm.tar.gz

You need to unpack the contents of this tarball to a FAT formatted USB drive.  In my case, this is the SD card I have connected via the card reader on the USB port in the picture.  You should find four files in the tarball, used by u-boot to boot into the ArchLinux distro.  But before you can do that, you need to get the root file system tarball and place that on the USB drive as well.  You can download the ArchLinux root fs here:

ArchLinuxARM-armv5te-latest.tar.gz

When you copy to the USB drive, you need to rename it to just rootfs.tgz.  Once copying has finished, sync disks a couple of times and unmount the USB drive.  Connect it up to the front USB port on the NSA-320 and connect up your serial cable.  Run up minicom as root:

# minicom -D /dev/ttyUSB0

Now when you power on the NSA-320, you can monitor the install process.  Essentially, the stock OS on the NSA320 looks for files and scripts on the USB drive if attached.  If a certain script is present, it will execute the script.  The script on the USB drive is the ArchLinux installer that unpacks the rootfs.tgz to the primary hard drive, after repartitioning it and formatting it with an EXT file system.  It takes a while dependent on the size of the hard drive, but once complete it will reboot and boot the kernel from the primary hard disk's boot partition.  The boot partition doesn't get mounted automatically in fstab, so just remember to mount it before you install a new kernel.  Otherwise, your new kernel will be installed to the boot directory on the root file system and will never be booted by u-boot.


In order to get the DHCP client to obtain an address dynamically, some extra work is needed to ensure a hardware flag is set that prevents this.  There is a script I created post install that fixes this and requires a subsequent reboot.  The script is installed as a systemd script, to ensure the flag is set on each boot, in case the device is powered off for a prolonged period and the capacitor loses its state.  I have made the following guide on creating the script and installing it as a systemd script.

The script can be downloaded from: power_resume

Follow-up for power_resume

I initially had some trouble configuring netctl to reliably bring up the eth0 interface and noticed it was already up before having enabled it.  After creating the video above, I did some further reading.  It seems that there is a "roaming" network daemon that is started to handle network connections for certain interfaces - netctl-ifplugd.  This handles cables being connected/disconnected and wireless connections coming in and going out of range.  With this enabled and enabling the netctl@eth0 profile, conflicts occur with shutting down and starting up the DHCP client daemon.  The solution is not to enable the netctl@eth0 profile and stick with the netctl-ifplugd profile that is configured by default.  In order to make the power_resume script work, you just need to modify the dependency line in the systemd configuration script:

[Install]
WantedBy=netctl-ifplugd@eth0.service

Changing that and then enabling and disabling the power_resume service (to reinstall it) should fix it.

Follow-up number two...

Well, second thing I learnt today is that you don't place your systemd configuration files in the /etc/systemd directory.  This is the location of enabled services, so systemd is likely to get confused if you drop something in here without it being enabled.  The actual location for system configuration is in /usr/lib/systemd.  From this directory, any service can be enabled or disabled using the systemctl command.