Odroid Xu4 PortaLAN

From kipiki
Jump to: navigation, search

Summary

I wanted to build a machine that would provide me with the ability to build out a portable version of what I had made and was trying to enhance at our local Makerspace/Hackerspace JaxHax that sadly folded a few years ago. This machine provides fun and useful services to whatever group I go to. Services range from simple internet access point to filesharing/distribution, PXE boot for images and rescue services, along with many other services (see machine purpose section). I really enjoy not only building neat machines but having a really cool machine that allows people to connect and share and interact.
One of major points for this project is to help enhance the local Jacksonville community with something that allows me to come in, sit a machine down, and have something that I can say I'm bringing and people will know will work. This will allow them to bring their equiptment so we can collaborate, work and/or play together. Jacksonville's social-tech scene is fairly devoid of actual tech, and this project is one of my most-involved and best stabs at resolving this problem.
This is still a live document and project, being added to and refined, look for it to be updated in the future.

Machine purpose

This is what the machine will do when its running/clients connect to it
It will connect to a pre-defined wireless internet connection then it will provide the following services:

  • DHCP - to clients inside it's network
  • DNS - local addressing along with blocking of virus/malware/porn/fakenews via Stephen black's hostfile https://github.com/StevenBlack/hosts
  • Routing - to allow clients to get to the interwebs and to each other
  • Access Point - spawn an access point using HostAP
  • (future) TFTP/PXE - allow clients to boot off the network for things such as os images for local organizations+troubleshooting (like linux/windows images) and potentially things like vulnerable images that people could boot vm's of and attack.
  • Fileserver - allow clients to download (and potentially upload) material such as conference videos/audio/ctf and other material
    • FTP - pureftpd (one I'm using, more security oriented) or proftpd or vsftpd
    • HTTP - apache/lighttpd
    • (future) bittorrent - rtorrent/opentracker
    • (potential) emule?/other p2p host
  • (future) IRC server/other local chat server
  • (future) Proxy for gaming/OS update services (high bandwidth) to save on bandwidth and speed up downloads a lot

Hardware

Harbor Freight knock off pelican case 1800 - https://www.harborfreight.com/1800-watertight-protective-case-9-316-in-63518.html
Odroid Xu4: https://ameridroid.com/products/odroid-xu4
32GB EMMC: also from ameridroid
2x Wireless card TL-WN722N v1: <link removed> - I would advise STRONGLY against getting v2 or v3 (rtl8188eu, 2357:010c) of this card. Only v1 (atheros) chipset seems to work alright for a non-hacked up version of hostapd. Others require custom drivers and hostap builds that do not seem to play well with the XU4. Most sellers that say they give v1 seem to still give v2/3, there does not seem to be a way to tell on the outside of the packaging.
Wireless card alternative - Alfa AWUS036NEH (rt2800usb) - https://www.amazon.com/gp/product/B0035GWTKK/ works for hostapd and client for me.
1x 32GB MicroSD: https://www.amazon.com/gp/product/B073JWXGNT
60mm fan (cooling/airflow): https://www.amazon.com/gp/product/B00N1Y493Q
Lenovo advanced plug -> square (sacrafice) for power: https://www.amazon.com/gp/product/B00FYYOWVU (this will be used with one of the 20V 90W power bricks I have laying around)
2x USB3 SATA iii drive atapters with external power & UASP: https://www.amazon.com/gp/product/B06WWLCYC3
2x Buck 12V regulator - https://www.pololu.com/product/2855
Buck 5V regulator - https://www.pololu.com/product/2865
USB 2 - Gearhead USB 2 hub
USB 2 1' extension - https://www.amazon.com/gp/product/B01HN1GSE0s (for wireless cards)

Power

2x drive, adapters come with 12v2A bricks, drive manufacture says 7W read, bricks can deliver 24W, some say rule of thumb is 25W/Drive, so lets calculate in the max possible to not have brownout, 50W
xu4 - 5v up to 4A - 20W
5V 2A overhead on selected regulator for other devices (fans/whatever): 10W
Total power from power brick (peak): 80W
Total power from power brick (nominal): TBD:
Total power supplied from IBM standard (large) brick: 90W

Magi-Portaserver Power diagram.jpg

Physical Buildout

In this section I will be showing the buildout, it took me about 12 hours for the primary build all-told, much of the time was spent with needling over things like trying not to destroy the gigabit switch and its tiny data leads. This is ordered by the order that I built it in.

Here we have most of the parts laid out that I was working on building.
Some parts were replaced such as the white usb cables (did not work with the wireless adapter), usb 3 hub replaced with usb 2 (drives directly connected to xu4 now).
Magi 1 mostparts.jpg

These are the hard drive controllers (outside of their cases) and with their new power leads soldered on.
Magi 2 hddctrl.jpg Magi 3 hdd withpower.jpg

This is the ODroid XU4. They are coming out with a newer board here pretty soon that does all kinda fancy things and will cost more, but this is what I had at the time and built my project around, if you wanna build a similar box, you may want to look at the newer project board, but the XU4 is storied and has most/all of the bugs worked out by the community (and here, thats why you're here :).
Magi 4 odroidxu4.jpg

5V Buck transformer (step down). This lil guy will take our 20V and step it down to 5V.
Magi 5 5vbuck.jpg

I pulled this gigabit switch out of its case, stripped most of the plastic off of one of the ports (left some on for stability since the board is pinned through the pcb by only 2 plastic pegs). Heated up the pins and pulled the pins out of their holes and soldered a cable into them after homing it all out using a multimeter to determine where the cables and pins on the sacraficial cable lined up to be sure. I ended up accidently pulling off 2 of the traces so I had to solder directly into the transformer on those leads. I tried to be careful with the soldering but they were so close and the wires so small that they were shorting, so tried hot glue to isolate them from each other. That did not work, so I ended up just using flags made out of gaffers tape and that seems to work well. If the leads short out on this the switch just protects itself by restarting, not good for sure but keeps the magic smoke from getting out.
Magi 6 gigeunder.jpg Magi 7 gigetop.jpg

I ended up having to trace out a hard-drive and then poke holes where the mounting holes were, the printable hard drive guides on the interwebs proved to be inaccurate.
Magi 8 hddholeguide.jpg Magi 9 hddmarkins.jpg

Here are the slots I made for the air to go over the hard drives (perhaps I should have made more, the XU4 seems to need more cooling then the harddrives). For the slots I just used a drill and hand slid them then passed some sand paper through to knock the edges down. For the fan I made a template by tracing out the fan, then holding it where I wanted it to be and using a punch to punch guide holes before drilling those. I may expand the holes later to let more air through but for now its an effective finger-detterant with the small holes.
Magi 10 airnhdd holes.jpg Magi 11 airholes.jpg Magi 12 ventouttemplate.jpg Magi 13 ventoutdrilled.jpg

On the initial build I had to figure out how to get everything to fit, and all the connectors to go where I needed them to go, this eventually meant that I needed to stand the XU4 and the switch up on their ends. There are a few problems with this 1> the boards would interact with cables going behind them 2> the boards would interact with the smooth curve of the box's inner wall (pushing them higher) 3> there would be no effective stabilization on the top of the board, leaving only the bottom pinned, and the top to flop around and would be potentially damaging. So my solution was to make shims and use standoffs. I was doing this at about 1am, so there was not much open, and was thinking about something that was sturdy that I could work around the house, I had some aluminum bar, but that was about 4mm thick and I needed something *thin* and *sturdy*. I was thinking a rigid plastic but couldnt think of something I had around the house... Then while kinda poking around, I found a pile of my old 5.56 casings I had collected when I went to the range one time and was thinking of trying my hand at doing refills (until I found out that because 5.56 casing is so thin that is makes it pretty hard to do, and the tools to do it are fairly expensive) so that project got shelved and I just have a bag of cases laying about for whatever purpose... and purpose found! Cut off the thick butt with the primer with a hack saw, just hammered it flat (so its pretty much double-walled) tossed it in the drill press (you could just use a drill) and popped 2 holes in it and bam, shims done! I had to bend em in somewhat and remove some material from the top of the box because its thicker then the bottom but all told it works really really well. I think this would work better then plastic or aluminum, brass is strong but malliable so it makes a good material for this usage.
Magi 14 shim556.jpg Magi 15 shim556nobut.jpg Magi 16 shim556worked.jpg Magi 17 gigewithshim.jpg Magi 18 odroidshims.jpg Magi 19 powerholes.jpg

For our external power, I am using a old 90W 20V IBM thinkpad adapter I had laying around, the system's buck transformer output theoretical max output is 80W, so 90W should be enough to overcome that along with any inefficiencies that may happen in the transfer between 20V -> 12/5V so its pretty perfect for this. I just grabbed a IBM Advanced connector (the female barrel connector) to the slimline connector (the rectangle), lopped off the rectangle right at the end, and stripped it. The wires are not huge, but just spliced some new ones in and ran em to the buck transformers.
Magi 20 ibmlaptopadapter.jpg Magi 21 ibmlaptopadapterinside.jpg

The buck transformers are just hot-glued to the bottom of the case (being careful not to glue components, the boards or leads only are glued), everything seems to be holding up nicely.
Magi 22 powerwiring5v.jpg Magi 23 powerwiring12v.jpg Magi 24 hddwiring.jpg Magi 25 leftview partial.jpg Magi 26 leftview full.jpg

At this point we are done with a lot of the difficult soldered-together components and their mounting, (for the first drive), so lets mount some drives.
Magi 27 frontview.jpg Magi 28 rightviewfull.jpg Magi 29 hddusbhub.jpg

This is a pciture of the first run, making things work, everything seemed to work at this point! I was able to take it down to my local 2600 meeting and show off the initial build, for the components in there at this point this was working to the point of where it was for the last meeting except the components were in a nice easy to carry case.
Magi 30 firstrun.jpg

Now I started mounting the second hard drive on the top of the case, not the greatest space, but when dealing with a tiny case, you gotta find space where you can. I put rubber grommets on the top and bottom of the screw to help with shock absorbsion.
Magi 31 tophddoutside.jpg Magi 32 tophddinsidescrews.jpg Magi 33 tophddinside.jpg

This is one of the 12v buck transformers in the first pic, the second is after I have the power cable test-routed then soldered into the hard drive controller.
Magi 34 12vbuck.jpg Magi 35 hddwithpower.jpg

Power Wire:

  • Yellow 12v
  • White 20v
  • Red 5v
  • Black neutral

Large board: 5v 6A
Small boards: 12v 2.2A
Magi 36 allpower.jpg Magi 37 powerroute.jpg Magi 38 fullview.jpg

This is the teardown of the tplinks that I was attempting to use. The driver status of these guys is pretty poor at the moment in linux, so I ended up needing to find alternatives, but here are the pictures for these guys none-the-less. The mounting position is pretty perfect for em, when I get a new card I'll have to determine where I can put them, hopefully they are similar.
Magi 39 tplinkteardown.jpg Magi 40 tplinkteardown2.jpg Magi 41 tplinkmount.jpg

This is a shot of the antenna cables I'm using to get the signal outside the box, I could have tried to port the antenna out right from where they lay but this is more elegant, also safer and looks nicer. I offset the outside connectors so you could move the antennas into a few configurations (assuming that there are ethernet cables beside it so you couldnt put anything the other direction). One point of this being that you could put the box on its bottom like here or its back or top, where the only connections lie on the two sides (power on one and connections on the other).
Magi 42 antennacables.jpg Magi 43 rpsmaout.jpg Magi 44 ant1.jpg Magi 45 ant2.jpg Magi 46 ant3.jpg

And here's the full view at the end of the main-build process, another picture or two will be forthcoming with the modifications made with different cables and cards I've had to use in the mean time. I'm really happy how it all came out!
Magi 47 fullview.jpg Magi 48 packed.jpg Magi 49 closed.jpg

OS

Core OS: Funtoo
Why Funtoo/Gentoo: You can optimize and customize funtoo/gentoo very well, and their documentation and community support is very good. I enjoy playing with linux, feel free to build the odroid on the default ubuntu that comes with it, or armbian, or whatever you want, but with this I have fine tuned control, and its fun!
Why Funtoo over Gentoo: Funtoo is pretty much just a flavor of gentoo, from what I've read, they split up some of the releases of packages a bit better that may break the distro so sometimes it may be a bit more stable and not break on just some random occasion so I wanted to give it a shot. This build doc should for the most part work for gentoo as well excepting for some things like git inside of portage and profiles instead of eselect, but we'll see as we move through it, it's an adventure.

OS Buildout

Initial image pull and deployment

Per Funtoo's and Gentoo's buildout pages, they suggest you start with the ubuntu image, I have worked on building a from-scratch method of installing, but its tedious to do since I have never done it before, so in the mean time to get it working I'll go with the method provided.

We will be using these materials on the web for our build of Funtoo:

Other resources people may find useful for a buildout:

Building from scratch

This section will hopefully be built out in the future.

If you are interested, on some neat stuff about the back-end on how ODroid works, expand this section. If not, skip to the next section, the section on building from scratch has not been completed.

I don't want these to go to waste, so I'll go ahead and include these in the wiki, if you want to do a scratch build, these resources will give you a leg up, I'll probably get back to this at some point, or maybe not.

Links to information I was diving into at the time

Notes:

Not gonna get really into how to build toolsets here (unless I do a from-scratch build for ya) but the links above have all that material and how to do it, enjoy.

The official Funtoo/Gentoo Build way

Ubuntu pull and flash, gutting, Funtoo laydown
First we will start with pulling the most-current Ubuntu image from ODroid, checking the md5sum and flashing that to our SDCard.

I pulled the newest version of minimal image for the XU4:

On the host machine:

MYDISK=sdf  ##mine was /dev/sdf, replace this value with yours, be it sdc, mmcblk0p, w/e

## grab the images, check em against the md5 sum, whatever image, we are getting rid of it soon.  Default user and pass for this image is root:odroid and odroid:odroid
wget https://odroid.in/ubuntu_16.04lts/ubuntu-16.04.3-4.14-minimal-odroid-xu4-20171213.img.xz
wget https://odroid.in/ubuntu_16.04lts/ubuntu-16.04.3-4.14-minimal-odroid-xu4-20171213.img.xz.md5sum
md5sum -c ubuntu-16.04.3-4.14-minimal-odroid-xu4-20171213.img.xz.md5sum

## you should see:
ubuntu-16.04.3-4.14-minimal-odroid-xu4-20171213.img.xz: OK

## and as root
xz --decompress ubuntu-16.04.3-4.14-minimal-odroid-xu4-20171213.img.xz
sudo dd if=./ubuntu-16.04.3-4.14-minimal-odroid-xu4-20171213.img of=/dev/$MYDISK
sync

# pull the card

On the odroid:

Here I then stuck the card into the odroid, booted (had to reboot once on mine) then logged in.

I wanted to make sure the card worked, the odroid worked, and the / had resized to the full size of the card, I shut off the box gracefully with shutdown -h now and put the card back in the host.

On the host machine:

# most everything here will be done as root so go ahead and escalate privs:
sudo -i

# mount the ubuntu root filesystem, make a directory and backup the modules, firmware and fstab
mount /dev/${MYDISK}2 /mnt
mkdir foo
cp -a /mnt/lib/modules foo/
cp -a /mnt/lib/firmware foo/
cp /mnt/etc/fstab foo/

# unmount the ubuntu root and format that partition with a new filesystem, give it a label
umount /mnt
mkfs.ext4 /dev/${MYDISK}2
e2label /dev/${MYDISK}2 rootfs

# Mount your new filesystem, grab the latest Funtoo stage3 and extract it
mount /dev/${MYDISK}2 /mnt
cd /mnt
wget http://build.funtoo.org/funtoo-current/arm-32bit/odroid-xu4/stage3-latest.tar.xz
tar xpvf stage3-latest.tar.xz

# Grab the material we stole from Ubuntu
cp /root/foo/fstab etc/
cp -a /root/foo/firmware lib/
cp -a /root/foo/modules lib/

# Modify the fstab a bit, the UUID will probably be different since we have a new filesystem
export EDITOR=vim #or nano, emacs, whatever
$EDITOR etc/fstab

## here you replace the UUID=xxx with LABEL=rootfs , I also remove the extra lines at the bottom
LABEL=rootfs / ext4 errors=remount-ro,noatime 0 1
LABEL=boot /boot vfat noauto 0 1

# change the funtoo root pass
mkpasswd -m sha-512

## type in your desired password, copy that line
$EDITOR /mnt/etc/shadow
## replace the second field of root here, it was a * at the time of this writing.  Remove the * and place your string.

# now go back to root's home, unmount /mnt, and mount the first partition back there.
cd
umount /mnt
mount /dev/${MYDISK}1 /mnt

# edit the boot options of the odroid
$EDITOR /mnt/boot.ini
## Replace (on mine it was line 166, funtoo doc said near the top, just search for bootrootfs) this line:
setenv bootrootfs "console=tty1 console=ttySAC2,115200n8 root=UUID=e139ce78-9841-40fe-8823-96a304a09859 rootwait ro fsck.repair=yes net.ifnames=0"
## With this:
setenv bootrootfs "console=tty1 consoleblank=0 root=LABEL=rootfs rootwait ro fsck.repair=yes net.ifnames=0"

At this point, I was able to have a working Funtoo setup and continue with the install doc - https://www.funtoo.org/Install

General setup

Now that we have a basic running system, we can set up some customization that will let us run the XU4 the way that we want.

Start by setting up the network so we can get our starter packages and initial setup stuff. You can either do that with a...
Static IP address:

# as root, on the xu4
cd /etc/init.d/
ln -s netif.tmpl net.eth0

# now edit the network interface (with whatever editor you want)
vi /etc/conf.d/net.eth0

# (inside the file) set up a static interface (check out this doc if you need dhcp instructions: https://www.funtoo.org/Networking )
template="interface"
ipaddr="10.10.10.100/24"
gateway="10.10.10.1"
nameservers="8.8.8.8"

# then make it to where net.eth0 starts at boot
rc-update add net.eth0 default

Or DHCP address (just start dhcpcd, it listens everywhere):

# as root, on the xu4
rc-update add dhcpcd default
rc

Now lets update portage, do our make.conf optimizations for the XU4, and then update all the packages.

# update portage
ego sync

# check out that CHOST is already specified, we are going to go ahead and hard-code it tho in make.conf
# edit make.conf
vi /etc/portage/make.conf

## contents of make.conf
CHOST="armv7a-hardfloat-linux-gnueabi"
CFLAGS="-O2 -pipe -march=armv7-a -mtune=cortex-a15.cortex-a7 -mfpu=neon-vfpv4 -mfloat-abi=hard"
CXXFLAGS="${CFLAGS}"
MAKEOPTS="-j8"
USE=""
EMERGE_DEFAULT_OPTS="-av"
ACCEPT_LICENSE="*"

# (Optional) install screen to detach your terminal and htop to watch your machine's status:
emerge app-misc/screen htop

# update all the packages
emerge -uDN @world

## if you end up wanting to see what the status is of your build once in a while without dropping into the screen, just tail this file: /var/log/emerge.log

## I watched this while things compiled (including my little script below):
watch "cpustatus.sh; tail -1 /var/log/emerge.log; uptime"

Here's a little script I tossed together that just watches the temp and frequencies (in Cx1000 and MHZx1000) to see if you are thermal throttling. I have a full-sized heatsink with no fan, but currently have a 80mm pointing at it for the buildout.

#!/bin/bash
while true; do
cat /sys/devices/virtual/thermal/thermal_zone0/temp \
/sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_cur_freq \
/sys/devices/system/cpu/cpu1/cpufreq/cpuinfo_cur_freq \
/sys/devices/system/cpu/cpu2/cpufreq/cpuinfo_cur_freq \
/sys/devices/system/cpu/cpu3/cpufreq/cpuinfo_cur_freq \
/sys/devices/system/cpu/cpu4/cpufreq/cpuinfo_cur_freq \
/sys/devices/system/cpu/cpu5/cpufreq/cpuinfo_cur_freq \
/sys/devices/system/cpu/cpu6/cpufreq/cpuinfo_cur_freq \
/sys/devices/system/cpu/cpu7/cpufreq/cpuinfo_cur_freq | tr '\n' ' '
sleep 5
echo ""
done

Now set up your timezone and hostname of your system:

ln -sf /usr/share/zoneinfo/EST5EDT /etc/localtime
vi /etc/conf.d/hostname

Build yourself a new user:

useradd -m username
passwd username

And finally set yourself up a nice motd by editing the /etc/motd and reboot:

# use your favorite editor
vi /etc/motd

## put something you like here, feel free to delete what exists

#then reboot
reboot

Now onto more specialized things :)

Applications

Things I needed to install and why after initial install:

  • net-fs/nfs-utils - mounting nfs mounts
  • sys-block/parted - gpt partition larger then 4tb
  • sys-apps/hdparm - changing my wd-red drive's rest state to be less efficient (more performance, less sleepy)
  • sys-apps/ethtool - helping view my physical ethernet's status
  • net-analyzer/vnstat - (add USE flag 'gd' for graphics generation) for viewing speed of traffic over interface and stats
  • sys-process/cronie - cron daemon
  • sys-apps/mlocate - helps find files on the filesystem
  • net-wireless/iw - wireless network configuration utility
  • net-wireless/wpa_supplicant - allows connecting to encrypted access points
  • net-wireless/hostapd - creates a local access point using one of the wireless cards
  • app-editors/vim - I like the vim editor, funtoo comes with nano and vi
  • app-admin/sysklogd - system logger daemon
  • app-admin/logrotate - log rotator
  • net-wireless/wireless-tools - wireless tools
  • dev-util/strace - for low level troubleshooting of processes
  • sys-apps/lshw - great tool for checking hardware and driver status
  • net-dns/bind-tools - host, nslookup, ect

Setting up wireless client

wireless config: wpa_supplicant + dhcp: https://www.funtoo.org/Package:WPA_Supplicant https://wiki.gentoo.org/wiki/Wpa_supplicant

# it was suggested to use wps flag by funtoo documentation, you may have a file package.use or directory that you need to put this into
magi ~ # echo net-wireless/wpa_supplicant wps >> /etc/portage/package.use
# then merge the package
magi ~ # emerge net-wireless/wpa_supplicant
magi ~ # cat /etc/wpa_supplicant/wpa_supplicant.conf
# Allow users in the 'wheel' group to control wpa_supplicant
ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=wheel

# Make this file writable for wpa_gui / wpa_cli
update_config=1

country=US
# For encrypted networks
network={
    ssid="somessid"
    psk=<key or encrypted key>
}
# For open un-encrypted networks
network={
    ssid="someotherssid"
    key_mgmt=NONE
}
magi ~ # ls -ltr /etc/wpa_supplicant/wpa_supplicant.conf
-rw------- 1 root root 306 Feb 11 22:31 /etc/wpa_supplicant/wpa_supplicant.conf
magi ~ # cat /etc/conf.d/net
# this file is left blank for funtoo, gentoo configs usually go here
magi ~ # cat /etc/conf.d/wpa_supplicant
# conf.d file for wpa_supplicant
#
# Please check man 8 wpa_supplicant for more information about the options
# wpa_supplicant accepts.
#
wpa_supplicant_args="-B -i wlan0 -c /etc/wpa_supplicant/wpa_supplicant.conf"
magi ~ # rc-update add wpa_supplicant default
 * service wpa_supplicant added to runlevel default
rc-update add net.wlan0 default
rc-update add dhcpcd default
## in wpa_supplicant.conf if you want to connect to any unsecured network, add this to the end of the config file:
network={
        key_mgmt=NONE
        priority=-999
}

If you would like being more or less secure bout connecting to ap (using bssid mac, not letting repeaters in, ect): https://wiki.gentoo.org/wiki/Wpa_supplicant#Editing_manually

Building a Kernel / Updating a kernel

You may want to do this for updates, or to compile a new driver in (I wanted both)

Go ahead and back up the /boot stuff we made from ubuntu and such

mkdir /boot/backup
cp -rp /boot/* /boot/backup/

Thanks for the assist from this post https://forum.odroid.com/viewtopic.php?f=52&t=1674 that used this article as a template: https://zozs.se/2013/05/23/tp-link-wn725n-in-arch-linux-arm/
another doc: http://odroid.us/mediawiki/index.php?title=Step-by-step_Native_Compiling_a_Kernel http://linux-exynos.org/wiki/ODROID/u-boot https://github.com/hardkernel/linux/tree/odroidxu4-4.14.y/Documentation/admin-guide
note I'm skipping his step 1 where I'm syncing the os kernel (because I'm gonna use this one for the OS kernel)

Goto https://github.com/hardkernel/linux/ and select the branch you want to use, I am using odroidxu4-4.14.y so my url ends up being https://github.com/hardkernel/linux/tree/odroidxu4-4.14.y

On our currently running odroid system, lets just fill in some variables so its easy for everyone to just copy paste things, change yours if they are different:

export KERN=odroidxu4-4.14.y
export KERNURL=https://github.com/hardkernel/linux/tree/odroidxu4-4.14.y

Lets now fetch the new kernel using git and link it.

git clone -b $KERN --single-branch  https://github.com/hardkernel/linux.git $KERN
ln -s $KERN linux

cd to the new linux directory, copy the xu4 default config over to be our default kernel config

cd /usr/src/linux
cp arch/arm/configs/odroidxu4_defconfig .config

If you want to see/edit the config, you can install ncurses by doing this:

make menuconfig
## or just check out the config
less .config

Lets build our kernel

make -j8
## go read a comic: https://xkcd.com/303/  It took mine about 30 min to compile.
## now install the modules and copy the
make modules_install

Now we need to make the initrd, and package it to where the uboot system can read it then copy both to the /boot filesystem (not overwriting the ones that are currently running the system because we want those as backup, you *could* remove those because they are in memory).
you will need to merge dracut (to make initrd) and u-boot-tools (to manipulate initrd image for uboot)
I'm calling mine <name>-xu4-4.14.18.021318 (that's xu4-<kernel>.<date>). Name yours whatever you want.

foo=xu4-4.14.18.021318
emerge dracut u-boot-tools
cd /boot
cp /usr/src/linux/arch/boot/zImage /boot/zImage-${foo}
dracut --gzip "initramfs-${foo}" `cat /usr/src/linux/include/config/kernel.release`
mkimage -A arm -O linux -T ramdisk -C none -a 0 -e 0 -n initramfs -d ./initramfs-${foo} ./uInitrd-${foo}

Lets modify our boot.ini a bit (change the zimage, uinitrd at least, I removed a bunch of comments and a few options/if statements)
If your kernel does not work for whatever reason, just put your storage in another machine, mount /boot, grab the boot.ini backup you made at the beginning of the section and replace it here, and as long as you didnt replace the uInitrd and zImage (or if you did, grab those from the backup), ittl just work and you'll be good to go.
Here you need to put your zImage.whatever name and initrd name that you made in the fatload lines you see below.

vi /boot/boot.ini
 # cat boot.ini
ODROIDXU-UBOOT-CONFIG

# U-Boot Parameters
setenv initrd_high "0xffffffff"
setenv fdt_high "0xffffffff"

# --- HDMI / DVI Mode Selection ---
# ------------------------------------------
# - HDMI Mode
setenv vout "hdmi"
# - DVI Mode (disables sound over HDMI as per DVI compat)
# setenv vout "dvi"

# --- HDMI CEC Configuration ---
# ------------------------------------------
setenv cecenable "false" # false or true
# set to true to enable HDMI CEC

# Enable/Disable ODROID-VU7 Touchscreen
setenv disable_vu7 "false" # false

# CPU Governor Selection
# Available governers: conservative, userspace, powersave, ondemand, performance, schedutil
setenv governor "performance"

# DRAM Frequency
# Supported values: 933 825 728 633 (MHZ)
setenv ddr_freq 825

# External watchdog board enable
setenv external_watchdog "false"
# debounce time set to 3 ~ 10 sec, default 3 sec
setenv external_watchdog_debounce "3"

# HDMI Hot Plug detection
setenv HPD "true"

# Boot args
setenv bootrootfs "console=tty1 consoleblank=0 root=LABEL=rootfs rootwait ro fsck.repair=yes net.ifnames=0"

# Load kernel, initrd, dtb in that order
fatload mmc 0:1 0x40008000 zImage-xu4-4.14.18.021318
fatload mmc 0:1 0x42000000 uInitrd-xu4-4.14.18.021318
fatload mmc 0:1 0x44000000 exynos5422-odroidxu4.dtb

# load flattened device tree support
fdt addr 0x44000000

setenv hdmi_phy_control "HPD=${HPD} vout=${vout}"
if test "${cecenable}" = "false"; then fdt rm /cec@101B0000; fi
if test "${disable_vu7}" = "false"; then setenv hid_quirks "usbhid.quirks=0x0eef:0x0005:0x0004"; fi
if test "${external_watchdog}" = "true"; then setenv external_watchdog "external_watchdog=${external_watchdog} external_watchdog_debounce=${external_watchdog_debounce}"; fi

# final boot args
setenv bootargs "${bootrootfs} ${videoconfig} ${hdmi_phy_control} ${hid_quirks} ${external_watchdog} governor=${governor}"

# set DDR frequency
dmc ${ddr_freq}

# Boot the board
bootz 0x40008000 0x42000000 0x44000000

Module blacklisting

During my first public test of it, it went down, and I saw this process taking up all of the processor, I couldn't figure out what it was doing, couldn't strace it. Later on I got a clue, someone said it was related to a module, so I looked up the module and this guy was for a touch interface... I don't even have one of those, so on the module blacklist it goes! modprobe -r'd it and problem went away, blacklisted the module and we were good to go.

top looked like this

 PID USER      PR  NI    VIRT    RES    SHR S  %CPU %MEM     TIME+ COMMAND
 1022 root     -51   0       0      0      0 R  99.0  0.0 764:59.90 irq/153-ads7846

So just make a file like this, so it doesnt come up at boot

$ cat /etc/modprobe.d/blacklist.conf
# this one causes a proc to be at 100% all the time
blacklist ads7846

If you need to do it right now:

modprobe -r ads7846

I was having problems with getting the version 3 of the tplink usb wireless cards working, the new kernel allowed me to have those work (at least seemingly) out of the box, further testing is necessary. The ID for those cards is 2357:010c. They don't have a description but thats the OS' fault not the kernel, the device shows up now and thats fantastic!

Setting up bridging between eth0 and wlan1

I want to have a single network where clients both physical and wireless can connect and access resources and each other, for this I will be using both my physical interface eth0 and my wireless interface wlan1.

Bridge configuration for wlan0/eth0 - https://www.funtoo.org/Networking#Bridge_Configuration

Make sure you have the right utilities, I had bridge-utilities already

emerge bridge-utils usermode-utilities

Due to things like hostap seeming to be picky about how the rc-update script was named, had to change to netif from net.device... so their documentation is inconsistent.

magi /etc/init.d # ln -s netif.tmpl netif.eth0
magi /etc/init.d # ln -s netif.tmpl netif.wlan1
magi /etc/init.d # ln -s netif.tmpl netif.br0
magi /etc/init.d # rc-update add netif.br0 default
 * service netif.br0 added to runlevel default
magi /etc/init.d # vi /etc/conf.d/netif.eth0
magi /etc/init.d # vi /etc/conf.d/netif.wlan1
magi /etc/init.d # vi /etc/conf.d/netif.br0
magi /etc/init.d # rc-update add netif.eth0 default
 * service netif.eth0 added to runlevel default
magi /etc/init.d # rc-update add netif.wlan1 default
 * service netif.wlan1 added to runlevel default
dan@magi ~ $ cat /etc/conf.d/netif.eth0
template="interface-noip"
dan@magi ~ $ cat /etc/conf.d/netif.wlan1
template="interface-noip"
dan@magi ~ $ cat /etc/conf.d/netif.br0
template="bridge"
ipaddr="10.10.10.1/24"
slaves="netif.eth0 netif.wlan1"
stp="on"
forwarding=1

Its dumb you need to do this, but if you dont ittl autoconfig... Then deny dhcp to the interfaces we dont want dhcp auto-configured to.

dan@magi ~ $ tail -2 /etc/dhcpcd.conf
denyinterfaces eth0 wlan1
dan@magi ~ $ ifconfig -a
br0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 10.10.10.1  netmask 255.255.255.0  broadcast 10.10.10.255
        inet6 fe80::fe88:f751:8c32:3dd0  prefixlen 64  scopeid 0x20<link>
        ether 00:1e:06:30:21:ee  txqueuelen 1000  (Ethernet)
        RX packets 0  bytes 0 (0.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 19  bytes 2906 (2.8 KiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 169.254.192.207  netmask 255.255.0.0  broadcast 169.254.255.255     <<<< this is what you see if your dhcpcd.conf isnt set up with denyinterfaces
        ether 00:1e:06:30:21:ee  txqueuelen 1000  (Ethernet)
        RX packets 0  bytes 0 (0.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 67  bytes 7248 (7.0 KiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536
        inet 127.0.0.1  netmask 255.0.0.0
        inet6 ::1  prefixlen 128  scopeid 0x10<host>
        loop  txqueuelen 1000  (Local Loopback)
        RX packets 0  bytes 0 (0.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 0  bytes 0 (0.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

wlan0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet <internal>  netmask 255.255.255.0  broadcast <internal>
        inet6 fe80::e0d0:855d:cc73:1163  prefixlen 64  scopeid 0x20<link>
        ether f8:1a:67:1e:38:b4  txqueuelen 1000  (Ethernet)
        RX packets 204  bytes 32890 (32.1 KiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 53  bytes 8367 (8.1 KiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

wlan1: flags=4099<UP,BROADCAST,MULTICAST>  mtu 1500
        ether 7c:8b:ca:1d:d2:ce  txqueuelen 1000  (Ethernet)
        RX packets 0  bytes 0 (0.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 0  bytes 0 (0.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

HostAPD

Setting up hostap daemon for software access point running off of wlan1.

Gentoo hostapd document: https://wiki.gentoo.org/wiki/Hostapd

Currently this setup will run you maxed out at about 65Mb/s on 802.11n, you will need to add variables to allow for usage of ht capabilities. Those are described further in this document: https://wireless.wiki.kernel.org/en/users/Documentation/hostapd#Wireless_Interface .. My config will be added here later once I figure out what works for mine consistently.

## initial setup should be (counting from memory)
emerge hostapd
rc-update add hostapd default
#edit config files below to your liking.
## make sure (if funtoo) you have your wireless device set up using netif.<device> else the startup scripts (hardcoded for netif) will not work.

## config files:
magi ~ # cat /etc/conf.d/hostapd
# Space separated List of interfaces which needs to be started before
# hostapd
INTERFACES="wlan1"

# Space separated list of configuration files
CONFIGS="/etc/hostapd/hostapd.conf"

# Extra options to pass to hostapd, see hostapd(8)
OPTIONS=""

magi ~ # cat /etc/hostapd/hostapd.conf
# the interface used by the AP
interface=wlan1
# g simply means 2.4GHz band
hw_mode=g
# the channel to use 1-11
channel=11
# limit the frequencies used to those allowed in the country
ieee80211d=1
# the country code
country_code=US
# 802.11n support
ieee80211n=1
# QoS support
wmm_enabled=1
# the name of the AP
ssid=nameofap
# 1=wpa, 2=wep, 3=both
auth_algs=1
# WPA2 only
wpa=2
# Key management
wpa_key_mgmt=WPA-PSK
rsn_pairwise=CCMP
wpa_passphrase=somepassphrase

dnsmasq

I use this for DHCP and DNS resolutions.

magi ~ # cat /etc/dnsmasq.conf
interface=br0
dhcp-range=10.10.10.100,10.10.10.230,1h
address=/jax2600.lan/10.10.10.1
address=/2600jax.lan/10.10.10.1
address=/jaxlug.lan/10.10.10.1
address=/hackatfscj.lan/10.10.10.1
address=/jaxdlug.lan/10.10.10.1

pureftp

PureFTPd setup, mostly default for the moment.

ChrootEveryone               yes
BrokenClientsCompatibility   no
MaxClientsNumber             50
Daemonize                    yes
MaxClientsPerIP              8
VerboseLog                   no
DisplayDotFiles              yes
AnonymousOnly                yes
NoAnonymous                  no
SyslogFacility               ftp
DontResolve                  yes
MaxIdleTime                  15
LimitRecursion               10000 8
AnonymousCanCreateDirs       no
MaxLoad                      20
AntiWarez                    no
Umask                        133:022
MinUID                       100
AllowUserFXP                 no
AllowAnonymousFXP            no
ProhibitDotFilesWrite        no
ProhibitDotFilesRead         no
AutoRename                   no
AnonymousCantUpload          yes
 AltLog                       stats:/var/log/pureftpd.log
 AltLog                       w3c:/var/log/pureftpd.log
MaxDiskUsage                   99
CustomerProof                yes

lighttpd

LigHTTPd setup, setup to allow for directory services and allow people to traverse.

var.basedir  = "/var/www"
var.logdir   = "/var/log/lighttpd"
var.statedir = "/var/lib/lighttpd"
server.modules = (
    "mod_access",
    "mod_status",
    "mod_accesslog",
    "mod_dirlisting"
)
include "mime-types.conf"
server.username      = "lighttpd"
server.groupname     = "lighttpd"
server.document-root = var.basedir
server.pid-file      = "/var/run/lighttpd.pid"
server.errorlog      = var.logdir  + "/error.log"
server.indexfiles    = ("index.php", "index.html", "index.htm", "default.htm")
server.follow-symlink = "enable"
static-file.exclude-extensions = (".php", ".pl", ".cgi", ".fcgi")
accesslog.filename   = var.logdir + "/access.log"
   dir-listing.activate      = "enable"
url.access-deny = ("~", ".inc")
 status.status-url  = "/server-status"

services

Whats usually running on the system

magi ~ # rc-update show
               binfmt | boot
             bootmisc | boot
              cgroups |                                 sysinit
               cronie |      default
                devfs |                                 sysinit
               dhcpcd |      default
                dmesg |                                 sysinit
              dnsmasq |      default
                 fsck | boot
              hostapd |      default
             hostname | boot
              hwclock | boot
             iptables |      default
              keymaps | boot
            killprocs |                        shutdown
    kmod-static-nodes |                                 sysinit
             lighttpd |      default
                local |      default nonetwork
           localmount | boot
             loopback | boot
              modules | boot
             mount-ro |                        shutdown
                 mtab | boot
            net.wlan0 |      default
            netif.br0 |      default
           netif.eth0 |      default
             netmount |      default
     opentmpfiles-dev |                                 sysinit
   opentmpfiles-setup | boot
               procfs | boot
            pure-ftpd |      default
                 root | boot
            savecache |                        shutdown
                 sshd |      default
                 swap | boot
               sysctl | boot
                sysfs |                                 sysinit
             sysklogd |      default
         termencoding | boot
                 udev |                                 sysinit
              urandom | boot
       wpa_supplicant |      default

My customizations

In /etc/profile I added a line to the end to make the default editor vim:

EDITOR=vim

In cron I added hdparm lines to turn off spindown and power savings for both hard drives because I don't want them doing that (with a long sleep to allow them to spin up first else it will not work)
Also there is a mount -a in there as well, because the drives take too long to come up for the boot process so I just wait a lil bit and mount them. The XU4 boots very fast.

@reboot sleep 60; /root/hddspin.sh
@reboot sleep 10; mount -a

# and inside /root/hddspin.sh
#!/bin/bash
if [ -e /dev/sda ]; then /sbin/hdparm -S 0 -B 255 /dev/sda; fi
if [ -e /dev/sdb ]; then /sbin/hdparm -S 0 -B 255 /dev/sdb; fi

I started vnstat monitoring of my network interfaces for bandwidth:

vnstat -u -i eth0
vnstat -u -i wlan0
vnstat -u -i wlan1

Enabling important services at start and doing some configs:

rc-update add cronie default
rc-update add sysklogd default

Maintaining

Backing up

You would probably want to back up this system before taking to things like defcon and restore it after you get back just to make sure noone has a long-term intrusion
To backup the system fully before going to a risky con or something, take whatever you want to off the large disks, and then pull the main os storage volume, mount on a linux machine, then:

# as root
dd if=/dev/<your device> of=backupname.dd
gzip backupname.dd

Another way you can backup (and preferred normally) would just be to build an rsync job or use some other utility to ship the data off to some other device using either includes or excludes to keep things like /proc /dev /sys /tmp and other 'virtual' directories from being backed up.

Restoring

This would remove all the data on the device you pointed it at, so be careful. Take your trusted backup and restore it over the contents of the card.

# as root
guzip backupname.dd.gz
dd if=backupname.dd of=/dev/<your device>

Updating

  • ego sync
  • emerge -uDN @world

Project thoughts

Ideas on what you could change to make the project different to fit your needs:

  • If you wanted a larger box, you could conceal the antennas inside the box without having problem with signal (by getting the antennas away from the devices and power), this also makes it easier to add other systems like batteries or capacitors internally so if you need to switch from one power source to another the server doesn't go down. (like a mini-battery backup)
  • You could make it waterproof by adding heatsinks and thermal gates, or a watercooling system, if you are going to environments that require a very wet based system (like emergency support)