This document explains how to convert an Intel Edison from Yocto to Debian GNU/Linux. The conversion is done by installing Debian "in place", without having to re-flash the system.
The resulting Debian system will use the Linux kernel and modules already installed on the Yocto system. (If you want to upgrade to the latest Yocto kernel first, you will have to re-flash; download the latest Yocto image and follow these directions.)
You need an Intel Edison and breakout board that provides console access via a USB serial port, such as the Intel Mini Breakout, Intel Arduino Breakout, or Sparkfun Base Block.
The Edison needs a working Linux system with root access and a WiFi connection. If you haven't already set up your Edison, follow these instructions.
Make sure you can log into your Edison, get a root shell, and access
the Internet from the Edison command line (try ping -c3 www.google.com
for example).
The conversion process does not affect the /home
partition,
but backing up your system is still recommended if you've added
anything to the factory-installed system.
You can back up your system onto an SD card if you have the right
hardware, or over the WiFi connection using scp
or rsync
. Details
are beyond the scope of this document.
Boot your Edison system and use minicom
or screen
to connect via
the USB serial connection to the Edison console.
Get a root shell (by logging in as root or by using su
or sudo su
).
On the Edison, download the latest version of debootstrap (1.0.87 as of this writing). All shell commands should be performed as root. This will also make sure your Edison's internet connection is working.
cd /tmp
wget http://ftp.us.debian.org/debian/pool/main/d/debootstrap/debootstrap_1.0.87_all.deb
Install the debootstrap package "by hand".
ar -x debootstrap_1.0.87_all.deb
tar -C / -xvf data.tar.gz
Check the installation.
debootstrap
This should produce a "usage" error message from debootstrap, not a "command not found" message.
You should have about 400MB of free space on the root partiton.
Use df -h /
to check.
If you need to free up additional space, I suggest this:
rm -r /usr/lib/{gcc,jvm,node}
Now we'll use the debootstrap program to create a bare-bones Debian
system in a subdirectory /target
. These instructions use stretch
,
the code name for the Debian "testing" suite at the time of writing.
You can use jessie
instead for the current "stable" suite.
mkdir /target
mount / -o remount,dev
debootstrap --arch i386 stretch /target
This will take a long time (an hour or so).
cp -a /boot/. /target/boot/
cp -a /lib/modules /target/lib/
cp -a /lib/firmware /target/lib
ln -s ../lib/firmware /target/etc/
cp -a /etc/modprobe.d /target/etc/
cp -p /usr/sbin/bluetooth_rfkill_event /target/usr/sbin
cp -p /usr/sbin/brcm_patchram_plus /target/usr/sbin
Replace the contents of /target/etc/fstab
with:
/dev/disk/by-partlabel/rootfs / ext4 nodev,discard,noauto_da_alloc 0 1
/dev/disk/by-partlabel/home /home ext4 nodev,nosuid,discard,noauto_da_alloc 0 2
/dev/disk/by-partlabel/boot /boot vfat nodev,nosuid 0 2
tmpfs /tmp tmpfs defaults
Replace the contents of /target/etc/rc.local
with:
echo V >/dev/watchdog
echo 1 >/sys/devices/virtual/misc/watchdog/disable
bluetooth_rfkill_event >/dev/null 2>&1 &
rfkill unblock bluetooth
exit 0
Create /target/etc/network/interfaces.d/wifi
containing:
auto wlan0
iface wlan0 inet dhcp
wpa-ssid NETWORK-NAME
wpa-psk WIFI-PASSWORD
Chroot into Debian.
chroot /target
exec bash
Set up the root password.
passwd
Add a non-root user.
adduser DESIRED-LOGIN-NAME
Add packages that will be needed to get WiFi running in the new system.
apt-get update
apt-get install rfkill wireless-tools iw wpasupplicant
If you have other favorite Debian packages, you can also install them now, or wait until you've rebooted into Debian "for real".
When you're done, exit from the chroot back into Yocto.
exit
This is the trickiest part.
We want to move the Yocto system (all the root directories like /bin
and
/lib
) out of the way and replace them with the ones we've set up in
the Debian chroot (under /target
).
But those system directories contain the very tools we need to do that
(like /bin/mv
and required libraries in /lib
), and they'll stop
working as soon as we start moving them around. It might be possible
to avoid that problem by doing the entire replacement with a single
mv
command, but if we forget something we'd be stuck.
Instead, we'll execute the necessary commands in the Debian chroot. Normally a chroot doesn't have access to files in its surrounding or "parent" environment, but we can give it access through the magic of "bind mounts":
mkdir /target/new
mount --bind / /target/new
mkdir /old
Once we're in the Debian chroot, we can use the directory /new
to access the real root (/
).
chroot /target
exec bash
Now move almost everything into old
. Exceptions are target
(the
Debian chroot), the old
directory itself, and some mountpoints that
can't be moved because they are in use.
cd /new
mv bin boot etc home lib media opt sbin usr var old
Now, still in the chroot, move the Debian root directories up to the real root.
cd /
mv bin boot dev etc home lib media mnt opt proc root run sbin srv sys target tmp usr var new
At this point, commands will stop working in the chroot, because we've moved the key directories. Exit from the chroot.
exit
The reboot
command probably won't work at this point
because the system is in an unexpected state (it booted as Yocto and
is now almost-Debian). If it doesn't, just power-cycle your Edison.
Your Edison should reboot into Debian, and you should be able to log in as the non-root-user you set up previously.
If the boot fails, you may be able to use the recovery techniques below.
This step can wait until you're comfortable that you no longer need anything from the Yocto system. Once you're ready, remove the remnants of the old system.
rm -f /old /home/root
Here are some miscellaneous emergency techniques that you may be able to use, but they require a fair amount of Linux experience.
Interrupt the boot process by typing return at just the right moment to drop into the U-Boot command prompt.
To see more information during the kernel boot:
setenv bootargs_debug verbose
boot
To boot into "single-user" mode (requires correct root password):
setenv bootargs_target rescue
boot
To boot and reset the root password:
setenv bootargs_debug init=/bin/sh
boot
# once the system boots:
remount / -o rw
passwd