Search
Close this search box.

Create your own 14.04.2 LTS Ubuntu server for Odroid U3 with WIFI support

I created this guide for me to keep track of what I’m doing and I’m sure it can be of some help to some people.
At this time, I didn’t find an up to date image of Ubuntu server 14.04.2 with WIFI on forums or downloads of Hardkernel site. I decided to create my own. Here is how…

If you don’t want to go through all this procedure, just download the ready to use image below:
ubuntu-server-14.04.2-STFB.img

You can also check the MD5sum:
md5sum

Setting up the environment

Just so you know, all the steps from this guide are typed being root. If not, please use sudo.

cd ~ ;
mkdir ubuntu-server;
cd ubuntu-server;
export GUIDE=`pwd`;
export SDCARD=/dev/sdd; (your sdcard location)

Preparing the system

apt-get install build-essential libqt4-dev perl python git
apt-get install pkg-config
apt-get install ncurses-dev

Downloading all the needed stuff

Pre-Built bootloaders

wget odroid.in/guides/ubuntu-lfs/boot.tar.gz

Kernel Sources

git clone --depth 1 https://github.com/hardkernel/linux.git -b odroid-3.8.y odroid-3.8.y

Toolchain for Crossbuild

wget odroid.in/guides/ubuntu-lfs/arm-unknown-linux-gnueabi.tar.xz

Ubuntu’s rootfs

http://cdimage.ubuntu.com/ubuntu-core/releases/14.04/release/ubuntu-core-14.04.2-core-armhf.tar.gz

 U-Boot tools

apt-get install u-boot-tools

Building and Putting things on Place

Emptying your card

Be aware it can take some time…

dd if=/dev/zero of=$SDCARD bs=1M

Installing bootloaders

tar xvfz boot.tar.gz;
cd boot;
chmod +x sd_fusing.sh;
./sd_fusing.sh $SDCARD;
cd ..;

Create Partitions

We will use two partitions, one for kernel and one for rootfs.
The kernel partition is a fat32 type. The rootfs is a ext4 partition with no journaling (to not wear the non mechanical drive) and no atime as mount option (the number of writes to a disk for relatime mount is close to double relative to a noatime mount).

Please assure that the first partition starts at least 3072 sectors away from the 1st sector as we need to reserve space for the bootloader.

sudo fdisk $SDCARD

Follow those steps to create partitions:

n
p
1
3072
+64M
n
p
2
134144
+500M
t
1
c
w

after all this, lets call partprobe to get our new partitions read by the kernel

partprobe

Format and mount our partitions

mkfs.vfat -n boot $SDCARD"1"
mkfs.ext4 -L rootfs $SDCARD"2"

Partitions are now formatted. Lets change the UUID of the ext4 partition.

uuidgen (get the generated UUID number and use it below)
tune2fs $SDCARD"2" -U <UUID>

Lets disable journaling to prevent excessive wear of your card

tune2fs -O ^has_journal $SDCARD"2"
mkdir /mnt/rootfs
mkdir /mnt/boot
mount $SDCARD"1" /mnt/boot
mount $SDCARD"2" /mnt/rootfs
mkdir TEMP
cd TEMP
tar xvfz ../ubuntu-core-14.04.2-core-armhf.tar.gz

We copy all rootfs files to the card:

mv * /mnt/rootfs (don't do a cp it will not work)
cd ..
rmdir TEMP

Building the kernel

First lets decompress our toolchain, then modify some options with menuconfig.

tar -Jxf arm-unknown-linux-gnueabi.tar.xz
cd odroid-3.8.y
make clean
make odroidu_defconfig
make menuconfig

Activate the CONFIG_DEVTMPFS option in the kernel to auto mount /dev at boot.
Go to:
“Device Drivers —> ”
“Generic Driver Options —> ”
and select:
“Automount devtmpfs at /dev, after the kernel mounted the rootfs “

Then exit and compile:

export ARCH=arm
export CROSS_COMPILE=../arm-unknown-linux-gnueabi/bin/arm-unknown-linux-gnueabi-
make -j8

I use -j8 because my computer is a quad-core with hyper-threading so 8 threads are available. You can configure it to match your computer.

Install the kernel and modules that we just built

cp arch/arm/boot/zImage /mnt/boot
make ARCH=arm INSTALL_MOD_PATH=/mnt/rootfs modules_install

Voila ! Kernel installed !

Create a initial Boot Script for our first boot

We need to create a boot.scr for the first boot.
We will create the boot.txt and the boot.scr from the boot.txt. The mkimage line is the one that creates the boot.scr

cd /mnt/boot
cat << __EOF__ | sudo tee boot.txt
setenv initrd_high "0xffffffff"
setenv fdt_high "0xffffffff"
setenv bootcmd "fatload mmc 0:1 0x40008000 zImage; bootm 0x40008000"
setenv bootargs "console=tty1 console=ttySAC1,115200n8 root=/dev/mmcblk0p2 rootwait rw mem=2047M"
boot
__EOF__
mkimage -A arm -T script -C none -n boot -d ./boot.txt boot.scr

Add a user

We’ll create a user under a already running linux and copy what we find in /etc/passwd + /etc/shadow on the very same files on the rootfs partition.
We’ll add an odroid user (pwd is odroid)
Add this on /etc/passwd (/mnt/roofs/etc..)

odroid:x:1000:1000:Odroid,,,:/home/odroid:/bin/bash

And this to /etc/shadow (/mnt/roofs/etc/shadow)

odroid:$6$bxAeyx/I$6AsxhIROljfKnbBGqfUigl1GUdelkkfFlJNiVciICHYVk18GHgbV8AmRyFt6dZZKtSPAlSVgwuW.ZxP1YarVG.:16516:0:99999:7:::

And the odroid user to this groups for him to be able to do sudos (/etc/group)
adm:x:4:syslog:odroid
cdrom:x:24:odroid
sudo:x:27:odroid

And add this group:
odroid:x:1000:

Create home for our user

cd /mnt/rootfs/home
mkdir odroid
chown -R odroid: odroid
chmod 700 odroid

Add the .bashrc file in odroid user home:

cd odroid
vi .bashrc

Add this in this file:

# ~/.bashrc: executed by bash(1) for non-login shells.
# see /usr/share/doc/bash/examples/startup-files (in the package bash-doc)
# for examples

# If not running interactively, don't do anything
case $- in
*i*) ;;
*) return;;
esac

# don't put duplicate lines or lines starting with space in the history.
# See bash(1) for more options
HISTCONTROL=ignoreboth

# append to the history file, don't overwrite it
shopt -s histappend

# for setting history length see HISTSIZE and HISTFILESIZE in bash(1)
HISTSIZE=1000
HISTFILESIZE=2000

# check the window size after each command and, if necessary,
# update the values of LINES and COLUMNS.
shopt -s checkwinsize

# If set, the pattern "**" used in a pathname expansion context will
# match all files and zero or more directories and subdirectories.
#shopt -s globstar

# make less more friendly for non-text input files, see lesspipe(1)
[ -x /usr/bin/lesspipe ] && eval "$(SHELL=/bin/sh lesspipe)"

# set variable identifying the chroot you work in (used in the prompt below)
if [ -z "${debian_chroot:-}" ] && [ -r /etc/debian_chroot ]; then
debian_chroot=$(cat /etc/debian_chroot)
fi

# set a fancy prompt (non-color, unless we know we "want" color)
case "$TERM" in
xterm-color) color_prompt=yes;;
esac

# uncomment for a colored prompt, if the terminal has the capability; turned
# off by default to not distract the user: the focus in a terminal window
# should be on the output of commands, not on the prompt
#force_color_prompt=yes

if [ -n "$force_color_prompt" ]; then
if [ -x /usr/bin/tput ] && tput setaf 1 >&/dev/null; then
# We have color support; assume it's compliant with Ecma-48
# (ISO/IEC-6429). (Lack of such support is extremely rare, and such
# a case would tend to support setf rather than setaf.)
color_prompt=yes
else
color_prompt=
fi
fi

if [ "$color_prompt" = yes ]; then
 PS1='${debian_chroot:+($debian_chroot)}\[\033[01;32m\]\u@\h\[\033[00m\]:\[\033[01;34m\]\w\[\033[00m\]\$ '
else
 PS1='${debian_chroot:+($debian_chroot)}\u@\h:\w\$ '
fi
unset color_prompt force_color_prompt

# If this is an xterm set the title to user@host:dir
case "$TERM" in
xterm*|rxvt*)
 PS1="\[\e]0;${debian_chroot:+($debian_chroot)}\u@\h: \w\a\]$PS1"
 ;;
*)
 ;;
esac

# enable color support of ls and also add handy aliases
if [ -x /usr/bin/dircolors ]; then
 test -r ~/.dircolors && eval "$(dircolors -b ~/.dircolors)" || eval "$(dircolors -b)"
 alias ls='ls --color=auto'
 #alias dir='dir --color=auto'
 #alias vdir='vdir --color=auto'

 alias grep='grep --color=auto'
 alias fgrep='fgrep --color=auto'
 alias egrep='egrep --color=auto'
fi

# some more ls aliases
alias ll='ls -alF'
alias la='ls -A'
alias l='ls -CF'

# Add an "alert" alias for long running commands. Use like so:
# sleep 10; alert
alias alert='notify-send --urgency=low -i "$([ $? = 0 ] && echo terminal || echo error)" "$(history|tail -n1|sed -e '\''s/^\s*[0-9]\+\s*//;s/[;&|]\s*alert$//'\'')"'

# Alias definitions.
# You may want to put all your additions into a separate file like
# ~/.bash_aliases, instead of adding them here directly.
# See /usr/share/doc/bash-doc/examples in the bash-doc package.

if [ -f ~/.bash_aliases ]; then
 . ~/.bash_aliases
fi

# enable programmable completion features (you don't need to enable
# this, if it's already enabled in /etc/bash.bashrc and /etc/profile
# sources /etc/bash.bashrc).
if ! shopt -oq posix; then
 if [ -f /usr/share/bash-completion/bash_completion ]; then
 . /usr/share/bash-completion/bash_completion
 elif [ -f /etc/bash_completion ]; then
 . /etc/bash_completion
 fi
fi

Then add the .profile file which gets the .bashrc to be executed:

# ~/.profile: executed by Bourne-compatible login shells.

if [ "$BASH" ]; then
if [ -f ~/.bashrc ]; then
. ~/.bashrc
fi
fi

mesg n
chown odroid: .*

Don’t forget to update the rights:

chmod 640 .bashrc .profile

Networking

We also need to create some files for your network to be managed (appear if you do ifconfig and get ip addresses automaticaly). Add those 2 files (you can do a ifconfig -a on the booted device to check which interfaces are available)

In /mnt/rootfs/etc/network/interfaces.d add a “eth0” file containing:

auto eth0
iface eth0 inet dhcp

Do the same for the WIFI interface (if needed):

auto wlan0
iface wlan0 inet dhcp

Now we must configure our Odroid to get the WIFI

The following steps are for the WiFi Module 4 (MediaTek, formerly Ralink, RT5572N chipset). I don’t know if it will work with the module 3. If you have an other type of chipset, I’ll create a post relative to drivers later.

Download the RT2870 firmware here:
http://www.mediatek.com/en/downloads/     (get the RT2870_Firmware_V22.zip file)

Extract and copy the file to the firmware lib:

mkdir /mnt/rootfs/lib/firmware
cp rt2870.bin /mnt/rootfs/lib/firmware/

Add this to rc.local to:
– improve performance of WIFI chipset
– to remove those messages in syslog “rt2800usb_entry_txstatus_timeout: Warning – TX status timeout for entry 8 in queue 0”

/sbin/iwconfig wlan0 power off

wlan0 config with DHCP

auto wlan0
iface wlan0 inet dhcp
wpa-ssid <your SSID>
wpa-ap-scan 1
wpa-scan-ssid 1
wpa-key-mgmt WPA-PSK
wpa-group CCMP TKIP
wpa-proto RSN WPA
wpa-psk <your WIFI password>

wlan0 config with static IP

auto wlan0
iface wlan0 inet static
wpa-ssid <your SSID>
wpa-ap-scan 1
wpa-scan-ssid 1
wpa-key-mgmt WPA-PSK
wpa-group CCMP TKIP
wpa-proto RSN WPA
wpa-psk <your WIFI password>

address <IP>
netmask 255.255.255.0
gateway <IP gateway>
dns-nameservers nameserver <DNS server 1> <DNS server 2>

If you don’t have a WIFI dongle installed, just move the wlan0 config file out of /etc/network/interface.d and save it to odroid user home dir like this:

mv /mnt/rootfs/etc/network/interfaces.d/wlan0 /mnt/rootfs/home/odroid

This to avoid some waiting time at boot.

Adding the Samsung hardware decoder firmware

Get the S5MFC-Firmware.zip file here and unzip it in /mnt/rootfs/lib/firmware.

Configuring FSTAB

cat << __EOF__ >> /mnt/rootfs/etc/fstab
UUID=<UUID of the ext4 partition> / ext4 errors=remount-ro,noatime 0 1
/dev/mmcblk0p1 /media/boot vfat defaults,rw,owner,flush,umask=000 0 0
tmpfs /tmp tmpfs nodev,nosuid,mode=1777 0 0
__EOF__

(to know uuid of partitions just use blkid)

Adding Odroid utility

This is usefull to resize the root partition without unmounting it.
Get the axel package from https://launchpad.net/ubuntu/trusty/armhf/axel/2.4-1
You will install it later once booted.
You will also install the odroid utility after boot.

cd /mnt/rootfs/home/odroid/
wget http://launchpadlibrarian.net/86884292/axel_2.4-1_armhf.deb
chown odroid: axel_2.4-1_armhf.deb 

Umount and be ready to boot!

sync
cd
umount /mnt/boot
umount /mnt/rootfs

First boot and Configurations

Now, we are ready to do our first boot and do final configuration.
Remove the card from your computer and connect to your board.
login with the odroid user (password is odroid).

First we’ll update and add some necessary things like the ssh server so that we can connect remotely via SSH and some wireless tools (for those using WIFI):

apt-get update
apt-get upgrade
apt-get install curl
apt-get install ssh-server
apt-get install wpasupplicant
apt-get install wireless-tools

Then install the odroid utility:

wget https://raw.githubusercontent.com/mdrjr/odroid-utility/master/odroid-utility.sh;
chmod +x odroid-utility.sh;
mv odroid-utility.sh /usr/local/bin

You can then execute the odroid-utility to resize the root partition.

Et voila! Now you can shutdown and save this ubuntu server you just have finished to create! 🙂

Save this created disk image

How to dd only used part and not entire empty zone of the disk.
First of all we need to know the partition sizes:

fdisk -l

This is my result of this command:

Disk /dev/sdd: 7818 MB, 7818182656 bytes
241 heads, 62 sectors/track, 1021 cylinders, total 15269888 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x1088774c

Device Boot Start End Blocks Id System
/dev/sdd1 3072 134143 65536 c W95 FAT32 (LBA)
/dev/sdd2 134144 1158143 512000 83 Linux

2nd partition ends at 1158143.
So, I can backup everything up to the end which in MB will be:
1158143  * 512 / 1024 / 1024 = 566MB
I’ll add some extra caution, we’ll go for 570MB.

So command to backup will be:

dd if=/dev/sdd conv=sync,noerror bs=1M count=570 | gzip -c > backup.img.gz

If you want to backup the whole disk:

dd if=/dev/sdd conv=sync,noerror bs=1M | gzip -c > backup.img.gz

Here is how to restore an image to the card:
Copy disk image to EMMC/SD card:

gzip -d <my.odroid.image.img.gz>
dd if=<my.odroid.image.img> of=</dev/path/of/card> bs=1M conv=fsync

Hope that helps ! 😉

Share the Post:

Related Posts