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 ! 😉