Skip to content

Commit

Permalink
Initial version
Browse files Browse the repository at this point in the history
  • Loading branch information
gbcreation committed Feb 24, 2019
1 parent 61b547b commit 5ced0a4
Show file tree
Hide file tree
Showing 2 changed files with 284 additions and 1 deletion.
116 changes: 115 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,116 @@
# alarm-helios4-image-builder
Build ArchLinux ARM image for the Helios4 NAS

This Bash script creates an [ArchLinux ARM](https://archlinuxarm.org/) image for the **Helios4 NAS** ready to be written on microSD card.

[Helios4](https://kobol.io/helios4/) is an powerful Open Source and Open Hardware Network Attached Storage (NAS) made by Kobol Innovations Pte. Ltd. It harnesses its processing capabilities from the ARMADA 38x-MicroSoM from SolidRun.

The resulting image file contains:
* a Linux kernel [configured and patched](https://github.com/gbcreation/linux-helios4) for Helios4. Especially to make the second fan detected.
* the udev rules for hardware monitoring.
* the configuration file and patch for fancontrol originally provided by the Kobol Team for Armbian.
* the mdadm bash script originally provided by the Kobol Team for Armbian, to report mdadm error events using the Red Faut LED (LED2).

## Requirements

This script expects to be used on a x86 system running ArchLinux. It needs `qemu-arm-static` to work. You can install it using the **[qemu-user-static](https://aur.archlinux.org/packages/qemu-user-static/)** or **[qemu-user-static-bin](https://aur.archlinux.org/packages/qemu-user-static-bin/)** packages from the AUR.

## Usage

> **Note:** this script needs to execute commands as the superuser. If not run as root, it will re-run itself using sudo. **It is highly recommanded to review this script and understand what it does before running it on your system.**
```
$ git clone https://github.com/gbcreation/alarm-helios4-image-builder.git
$ cd alarm-helios4-image-builder
$ sh ./build-archlinux-img-for-helios4.sh
```

Once the image file is created, write it to a microSD card using [Etcher](http://etcher.io) or the `dd` command:

```
$ dd bs=4M if=ArchLinuxARM-helios4-2019-02-24.img of=/dev/sdX conv=fsync
```

Insert the microSD card to the Helios4 and enjoy Arch Linux ARM on you NAS.

## Known bugs

* LEDs do not light up on disk access.

## What does this script do?

Here are all the steps performed by the script:

* Check if the `qemu-arm-static` executable is installed (see Requirements above).
* Check if script is run as root. Re-run itself using `sudo` if not.
* Check if the following packages are installed (automatically install them if not):
* [arch-install-scripts](https://www.archlinux.org/packages/extra/any/arch-install-scripts/): use `arch-chroot` to enter to the created chroot
* [arm-none-eabi-gcc](https://www.archlinux.org/packages/community/x86_64/arm-none-eabi-gcc/): ARM cross compiler used to compile the u-boot bootloader
* [uboot-tools](https://www.archlinux.org/packages/community/x86_64/uboot-tools/): use `mkimage` to compile the u-boot script
* Download the root ArchLinux ARM filesystem / patches / Linux packages for Helios4 :
* [ArchLinuxARM-armv7-latest.tar.gz](http://os.archlinuxarm.org/os/ArchLinuxARM-armv7-latest.tar.gz): the generic ArchLinux ARMv7 root filesystem
* [90-helios4-hwmon.rules](https://raw.githubusercontent.com/armbian/build/master/packages/bsp/helios4/90-helios4-hwmon.rules): udev rules for hardware monitoring
* [fancontrol_pwm-fan-mvebu-next.conf](https://raw.githubusercontent.com/armbian/build/master/packages/bsp/helios4/fancontrol_pwm-fan-mvebu-next.conf): fancontrol configuration file
* [mdadm-fault-led.sh](https://raw.githubusercontent.com/armbian/build/master/packages/bsp/helios4/mdadm-fault-led.sh): Bash script used by mdadm to report error events using the Red Faut LED (LED2)
* [fancontrol.patch](https://raw.githubusercontent.com/helios-4/build/helios4/packages/bsp/helios4/fancontrol.patch): patch for the fancontrol script fixing 'too many arguments' error message and setting pwm to minimum speed when fancontrol exits (see [this comment](https://forum.armbian.com/topic/6033-helios4-support/?page=2&tab=comments#comment-49490) on the Armbian forum from gprovost).
* [linux-helios4-4.20.11-1-armv7h.pkg.tar.xz](https://github.com/gbcreation/linux-helios4/releases/download/4.20.11-1/linux-helios4-4.20.11-1-armv7h.pkg.tar.xz) and [linux-helios4-headers-4.20.11-1-armv7h.pkg.tar.xz](https://github.com/gbcreation/linux-helios4/releases/download/4.20.11-1/linux-helios4-headers-4.20.11-1-armv7h.pkg.tar.xz): Linux kernel patched for Helios4 (see https://github.com/gbcreation/linux-helios4)
* Create a new image file on disk. Change the `ÌMG_FILE` variable in script to set the image filename.
* Create a new partition in the image file using `fdisk`.
* Mount the image file as a loop device using `losetup`, forcing the kernel to scan the partition table to detect the partition inside.
* Format the partition as ext4.
* Mount the formatted partition to the `./img/` sub-directory. Change the `MOUNT_DIR` variable in script to set the target directory.
* Extract ArchLinuxARM-armv7-latest.tar.gz to `./img/`.
* Copy `90-helios4-hwmon.rules` to `./img/etc/udev/rules.d`. Patch it to replace the `armada_thermal` device name by `f10e4078.thermal`.
* Copy Helios4 Linux packages to `./img/root`.
* Copy `qemu-arm-static` to `./img/usr/bin`.
* Register qemu-arm-static as ARM interpreter in the host kernel
* Use `arch-chroot` to enter to the `./img/` chroot and then:
* initialize the Pacman keyring
* populate the Arch Linux ARM package signing keys
* upgrade the Arch Linux ARM system
* install the Helios4 Linux kernel
* install lm_sensors
* enable the fancontrol service to start on boot
* Remove Helios4 Linux packages from `./img/root`.
* Remove `qemu-arm-static` from `./img/usr/bin`.
* Apply `fancontrol.patch` to `./img/usr/sbin/fancontrol`.
* Copy the fancontrol configuration file `fancontrol_pwm-fan-mvebu-next.conf` to `./img/etc/fancontrol`.
* Make the `lm75` kernel module loaded on boot by creating `./img/etc/modules-load.d/lm75.conf`.
* Copy `mdadm-fault-led.sh` to `./img/usr/bin` and set the `PROGRAM` directive to `/usr/sbin/mdadm-fault-led.sh` in `./img/etc/mdadm.conf`.
* Create the u-boot script `./img/boot/boot.cmd`.
* Use `mkimage` to compile `./img/boot/boot.cmd` to `./img/boot/boot.scr`.
* Unmount the image file partition.
* Clone the `helios-4/u-boot` Git repository and compile the u-boot bootloader.
* Copy the compiled u-boot bootloader to the loop device.
* Unmount the loop device

## About loop devices and mounted partitions

If the script stops due to errors, the image file can still be mounted as a loop device, and its partition mounted to the `./img/` sub-directory. Before running the script again, ensure that the `./img` is unmounted:

```
$ sudo umount ./img
```

Check also if the image file is still mounted as a loop device:

```
$ sudo losetup -a
```

If so, umount it:

```
$ sudo losetup -d /dev/loopX
```

## Thanks

Thanks to:

* the **Kobol Team** for this great piece of Open Hardware that is Helios4 NAS
* **Aditya** from the Kobol Team for his valuable help on explaining various patches and configuration files
* **Summers** from the Arch Linux ARM forum for his precious advices and encouraging responses

## License

MIT. Copyright (c) Gontran Baerts
169 changes: 169 additions & 0 deletions build-archlinux-img-for-helios4.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,169 @@
#!/bin/bash
#
# Bash script creating an Arch Linux ARM image for the Helios4 NAS.
#
# Author: Gontran Baerts
# Repository: https://github.com/gbcreation/linux-helios4
# License: MIT
#

set -e

# Configuration
DOWNLOADER="aria2c --continue=true -x 4"
IMG_DIR="./"
IMG_DIR=`readlink -f "${IMG_DIR}"`
IMG_FILE="ArchLinuxARM-helios4-$(date +%Y-%m-%d).img"
IMG_SIZE="2G"
MOUNT_DIR="./img"
ALARM_ROOTFS="http://os.archlinuxarm.org/os/ArchLinuxARM-armv7-latest.tar.gz"

sources=("${ALARM_ROOTFS}"
'https://raw.githubusercontent.com/armbian/build/master/packages/bsp/helios4/90-helios4-hwmon.rules'
'https://raw.githubusercontent.com/armbian/build/master/packages/bsp/helios4/fancontrol_pwm-fan-mvebu-next.conf'
'https://raw.githubusercontent.com/armbian/build/master/packages/bsp/helios4/mdadm-fault-led.sh'
'https://raw.githubusercontent.com/helios-4/build/helios4/packages/bsp/helios4/fancontrol.patch'
'https://github.com/gbcreation/linux-helios4/releases/download/4.20.11-1/linux-helios4-4.20.11-1-armv7h.pkg.tar.xz'
'https://github.com/gbcreation/linux-helios4/releases/download/4.20.11-1/linux-helios4-headers-4.20.11-1-armv7h.pkg.tar.xz')
md5sums=('63bd1c55905af69f75cf4c046a89280a'
'f0162acfa70e2d981c11ec4b0242d5bd'
'7e1423c3e3b8c3c8df599a54881b5036'
'0a5bfbea2f1d65b936da6df4085ee5f2'
'ae5cf06e8a03d1f5845bb962846b281d'
'c4c8f8fc8ef8b81a40723d5d0bdfc5b2'
'8093f539fdae4dd5cb290063b09b3205')

echo_step () {
echo -e "\e[1;32m ${@} \e[0m\n"
}


echo_step "\nArchLinux ARM image builder for Helios4 NAS"

which qemu-arm-static >/dev/null 2>&1 || {
echo 'This script needs qemu-arm-static to work. Install qemu-user-static or qemu-user-static-bin from the AUR.'
exit 1
}

if [[ $EUID != 0 ]]; then
echo This script requires root privileges, trying to use sudo
sudo "$0"
exit $?
fi

echo_step Install script dependencies...
pacman -Sy --needed --noconfirm arch-install-scripts arm-none-eabi-gcc uboot-tools

for i in ${!sources[*]}; do
echo_step Download ${sources[i]}...
${DOWNLOADER} "${sources[i]}"
if [ "`md5sum ${sources[i]##*/} | cut -d ' ' -f1`" != "${md5sums[i]}" ]; then
echo Wrong MD5 sum for ${sources[i]}.
exit 1
fi
done

echo_step Create ${IMG_DIR}/${IMG_FILE} image file...
dd if=/dev/zero of="${IMG_DIR}/${IMG_FILE}" bs=1 count=0 seek=${IMG_SIZE}

echo_step Create partition...
fdisk "${IMG_DIR}/${IMG_FILE}" <<EOF
o
n
p
1
w
EOF

echo_step Mount loop image...
LOOP_MOUNT=`losetup --partscan --show --find "${IMG_DIR}/${IMG_FILE}"`

echo_step Format partition ${LOOP_MOUNT}p1...
# mkfs.ext4 -F -L alarm-helios4 "${LOOP_MOUNT}p1"
mkfs.ext4 -qF -L alarm-helios4 "${LOOP_MOUNT}p1"

echo_step Mount image partition ${LOOP_MOUNT}p1 to ${MOUNT_DIR}...
mkdir -p "${MOUNT_DIR}"
mount "${LOOP_MOUNT}p1" "${MOUNT_DIR}"

echo_step Extract ${ALARM_ROOTFS##*/} to ${MOUNT_DIR}...
bsdtar -xpf "${ALARM_ROOTFS##*/}" -C "${MOUNT_DIR}"

echo_step Copy hwmon to fix device mapping...
sed -e 's/armada_thermal/f10e4078.thermal/' 90-helios4-hwmon.rules > ${MOUNT_DIR}/etc/udev/rules.d/90-helios4-hwmon.rules

echo_step Copy linux-helios4 packages to ${MOUNT_DIR}/root...
cp linux-helios4-*-armv7h.pkg.tar.xz ${MOUNT_DIR}/root

echo_step Copy `which qemu-arm-static` to ${MOUNT_DIR}/usr/bin...
cp `which qemu-arm-static` ${MOUNT_DIR}/usr/bin

echo_step Register qemu-arm-static as ARM interpreter in the kernel...
[ ! -f /proc/sys/fs/binfmt_misc/register ] && echo ':arm:M::\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x28\x00:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/usr/bin/qemu-arm-static:CF' > /proc/sys/fs/binfmt_misc/register

echo_step Initialize pacman-key, update ARM system and install lm_sensors...
arch-chroot ${MOUNT_DIR} bash -c "
pacman-key --init &&
pacman-key --populate archlinuxarm &&
pacman -Syu --noconfirm --ignore linux-armv7 &&
(yes | pacman -U /root/linux-helios4-*-armv7h.pkg.tar.xz) &&
pacman -S --noconfirm lm_sensors &&
systemctl enable fancontrol.service
"

echo_step Remove linux-helios4 packages to ${MOUNT_DIR}/root...
rm -f ${MOUNT_DIR}/root/linux-helios4-*-armv7h.pkg.tar.xz

echo_step Remove qemu-arm-static from ${MOUNT_DIR}/usr/bin...
rm -f ${MOUNT_DIR}/usr/bin/qemu-arm-static

echo_step Patch fancontrol...
patch ${MOUNT_DIR}/usr/sbin/fancontrol fancontrol.patch

echo_step Copy fancontrol config...
cp fancontrol_pwm-fan-mvebu-next.conf ${MOUNT_DIR}/etc/fancontrol

echo_step Configure loading of lm75 kernel module on boot...
echo "lm75" > ${MOUNT_DIR}/etc/modules-load.d/lm75.conf

echo_step Copy mdadm-fault-led script and modify mdadm configuration...
cp mdadm-fault-led.sh ${MOUNT_DIR}/usr/sbin
echo "PROGRAM /usr/sbin/mdadm-fault-led.sh" >> ${MOUNT_DIR}/etc/mdadm.conf

echo_step Copy u-boot boot.cmd to ${MOUNT_DIR}/boot...
cat << 'EOF' > "${MOUNT_DIR}/boot/boot.cmd"
part uuid ${devtype} ${devnum}:${bootpart} uuid
setenv bootargs console=${console} root=PARTUUID=${uuid} rw rootwait
load ${devtype} ${devnum}:${bootpart} ${kernel_addr_r} /boot/zImage
load ${devtype} ${devnum}:${bootpart} ${fdt_addr_r} /boot/dtbs/${fdtfile}
load ${devtype} ${devnum}:${bootpart} ${ramdisk_addr_r} /boot/initramfs-linux.img
bootz ${kernel_addr_r} ${ramdisk_addr_r}:${filesize} ${fdt_addr_r}
EOF

echo_step Compile boot.cmd...
mkimage -A arm -O linux -T script -C none -a 0 -e 0 -n "Helios4 boot script" -d "${MOUNT_DIR}/boot/boot.cmd" "${MOUNT_DIR}/boot/boot.scr"

echo_step Unmount image partition...
umount "${MOUNT_DIR}"

echo_step Build U-Boot...
[ ! -d "u-boot" ] && git clone https://github.com/helios-4/u-boot.git -b helios4
cd u-boot
[ ! -f u-boot-spl.kwb ] && {
export ARCH=arm
export CROSS_COMPILE=arm-none-eabi-
make mrproper
make helios4_defconfig
make -j${nproc}
}

echo_step Copy u-boot to ${LOOP_MOUNT}...
dd if=u-boot-spl.kwb of="${LOOP_MOUNT}" bs=512 seek=1
cd -

echo_step Unmount loop partition...
losetup -d "${LOOP_MOUNT}"

echo_step done

0 comments on commit 5ced0a4

Please sign in to comment.