Skip to content

Instantly share code, notes, and snippets.

@ecc1
Last active April 13, 2021 13:16
Show Gist options
  • Save ecc1/015689ab68baf30832fbe125b7cbc693 to your computer and use it in GitHub Desktop.
Save ecc1/015689ab68baf30832fbe125b7cbc693 to your computer and use it in GitHub Desktop.

Converting from Yocto to Debian without re-flashing

Eric Cooper <ecc@cmu.edu>

December 2016

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.)

Equipment and prerequisites

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).

Optional: back up your system

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.

Connect to your Edison

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).

Install debootstrap

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.

Free up disk space

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}

Create a Debian chroot

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).

Set up the Debian system

Copy the Yocto kernel and modules to Debian

    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

Set up /target/etc/fstab

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

Set up /target/etc/rc.local

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

Set up /target/etc/network/interfaces.d/wifi

Create /target/etc/network/interfaces.d/wifi containing:

    auto wlan0
            iface wlan0 inet dhcp
            wpa-ssid NETWORK-NAME
            wpa-psk WIFI-PASSWORD

Perform additonal configuration inside the Debian chroot

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

Replace the Yocto system with Debian

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 moment of truth: reboot into Debian!

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.

Remove the old Yocto system

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

Emergency recovery techniques

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
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment