Difference between revisions of "Novena/Embedian Build"

From Studio Kousagi Wiki
Jump to: navigation, search
(whew!)
 
(wiki style, a few updates)
Line 1: Line 1:
NOTE: these instructions are probably not complete?
+
''NOTE: these instructions are in flux''
  
Use the embedian cross-compilation toolchain to generate binaries that will
+
How to use the embedian cross-compilation toolchain to generate binaries that will
run on armhf hardware using an x86/amd64 build host.
+
run on armhf hardware using a debian-based x86/amd64 build host.
  
 
These directions require a physical micro SD card; partitioning happens "in
 
These directions require a physical micro SD card; partitioning happens "in
Line 13: Line 13:
 
==Prepare Cross-Compile Toolchain on Build Host==
 
==Prepare Cross-Compile Toolchain on Build Host==
  
There aren't toolchain packages in wheezy yet, so if your build host is wheezy
+
You need to add the embedian repositories to your sources.list.
add squeeze to your /etc/apt/sources.list (don't replace any wheezy lines, just
+
 
 +
There aren't toolchain packages in (emdebian) wheezy yet, so if your build host is wheezy
 +
add (emdebian) squeeze to your /etc/apt/sources.list (don't replace any wheezy lines, just
 
copy the wheezy deb line and replace "wheezy" with "squeeze"), then apt-get
 
copy the wheezy deb line and replace "wheezy" with "squeeze"), then apt-get
 
update. This shouldn't clobber your system too bad as the wheezy packages will
 
update. This shouldn't clobber your system too bad as the wheezy packages will
almost always be prefered to squeeze packages.
+
almost always be prefered to squeeze packages. My sources.list on my (wheezy) build machine
 +
looked like this in January 2013:
 +
<pre>
 +
# primary
 +
deb    http://http.debian.net/debian/  wheezy  main  contrib
 +
deb-src http://http.debian.net/debian/  wheezy  main  contrib
  
Install (at least) these debian packages:
+
# security
 +
deb    http://security.debian.org/  wheezy/updates  main contrib 
 +
deb-src http://security.debian.org/  wheezy/updates  main contrib
  
  build-essential multistrap qemu-user-static gparted device-tree-compiler
+
# emdebian  
  u-boot-tools
+
deb http://www.emdebian.org/debian/ wheezy main  
 +
deb http://www.emdebian.org/debian/ sid main 
 +
deb http://http.debian.net/debian/  squeeze main contrib
 +
</pre>
  
 +
IIRC the main toolchain package is <tt>gcc-4.7-arm-linux-gnueabi</tt>.
 +
 +
Also install (at least) these debian packages:
 +
<pre>
 +
build-essential multistrap qemu-user-static gparted device-tree-compiler u-boot-tools bc
 +
</pre>
 
Note that 'gparted' is a GUI and will pull in X dependancies; if you build on a
 
Note that 'gparted' is a GUI and will pull in X dependancies; if you build on a
 
remote server you could do the partitioning steps on a different machine.
 
remote server you could do the partitioning steps on a different machine.
  
Check out these repositories from github (don't have links b/c github is
+
Check out these repositories from github:
blocked in china):
 
  
 
* meta-kosagi from github/sutajiokousagi (novena branch): https://github.com/sutajiokousagi/meta-kosagi
 
* meta-kosagi from github/sutajiokousagi (novena branch): https://github.com/sutajiokousagi/meta-kosagi
Line 38: Line 55:
  
 
==Build u-boot==
 
==Build u-boot==
 +
 
Checkout the custom u-boot-imx6: https://github.com/sutajiokousagi/u-boot-imx6
 
Checkout the custom u-boot-imx6: https://github.com/sutajiokousagi/u-boot-imx6
  
Line 43: Line 61:
  
 
Enter top directory and build:
 
Enter top directory and build:
 
+
<pre>
    export CROSS_COMPILE=arm-linux-gnueabi-
+
export CROSS_COMPILE=arm-linux-gnueabi-
    make novena_config
+
make novena_config
    make
+
make
 
+
</pre>
 
Grab the resulting 'u-boot.imx' for later.
 
Grab the resulting 'u-boot.imx' for later.
  
Line 63: Line 81:
 
penultimate line (i.mx6-specific?), and change "custom1" to whatever you want:
 
penultimate line (i.mx6-specific?), and change "custom1" to whatever you want:
  
    #!/usr/bin/env bash
+
<pre>
    export ARCH=arm
+
#!/usr/bin/env bash
    export DEB_HOST_ARCH=armhf
+
export ARCH=arm
    export CONCURRENCY_LEVEL=`grep -m1 cpu\ cores /proc/cpuinfo | cut -d : -f 2`
+
export DEB_HOST_ARCH=armhf
    fakeroot make-kpkg --arch arm --cross-compile arm-linux-gnueabi- --initrd --append-to-version=-custom1 kernel_image kernel_headers
+
export CONCURRENCY_LEVEL=`grep -m1 cpu\ cores /proc/cpuinfo | cut -d : -f 2`
    make ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- EXTRAVERSION=-custom1 UIMAGE_LOADADDR=10008000 uImage
+
fakeroot make-kpkg --arch arm --cross-compile arm-linux-gnueabi- --initrd --append-to-version=-custom1 kernel_image kernel_headers
    cp arch/arm/boot/uImage uImage
+
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- EXTRAVERSION=-custom1 UIMAGE_LOADADDR=10008000 uImage
 +
cp arch/arm/boot/uImage uImage
 +
</pre>
  
 
If you are using a newer -stable kernel than the one use to generate the
 
If you are using a newer -stable kernel than the one use to generate the
.config, the first compile will prompt you to select a whole boatload of NEW
+
<tt>.config</tt>, the first compile will prompt you to select a whole boatload of NEW
 
configuration options (new optional features in the kernel sources). If you run
 
configuration options (new optional features in the kernel sources). If you run
 
in to this, keep hitting enter to accept all the defaults.
 
in to this, keep hitting enter to accept all the defaults.
  
Run the cross_build.sh script to build.
+
Run the <tt>cross_build.sh</tt> script to build.
  
Grab the resulting uImage file and rename it uImage-novena.bin.
+
Grab the resulting uImage file and rename it <tt>uImage-novena.bin</tt>.
  
 
==Build a Basic Debian armhf wheezy rootfs with multistrap and qemu==
 
==Build a Basic Debian armhf wheezy rootfs with multistrap and qemu==
Line 97: Line 117:
 
In a new directory, create a multistrap configuration file like the below,
 
In a new directory, create a multistrap configuration file like the below,
 
called novena.conf. Add any extra packages you want to the long list:
 
called novena.conf. Add any extra packages you want to the long list:
 +
<pre>
 +
[General]
 +
arch=armhf
 +
cleanup=true
 +
noauth=false
 +
aptsources=Debian
 +
bootstrap=Debian
  
    [General]
+
[Debian]
    arch=armhf
+
packages=file i2c-tools screen build-essential base-files openssh-server wget iproute net-tools hostname udev isc-dhcp-client parted dosfstools apt iputils-ping dialog iptables less traceroute apt-utils dnsutils lsof vim-tiny sudo locales ethtool pciutils git-core ifupdown manpages man-db firmware-linux-free kmod iw wireless-tools wpasupplicant hostapd rfkill 
    cleanup=true
+
 
    noauth=false
+
keyring=debian-archive-keyring
    aptsources=Debian
+
suite=wheezy
    bootstrap=Debian
+
source=http://http.debian.net/debian/
   
+
</pre>
    [Debian]
 
    packages=file i2c-tools screen build-essential base-files openssh-server wget iproute net-tools hostname udev isc-dhcp-client parted dosfstools apt iputils-ping dialog iptables less traceroute apt-utils dnsutils lsof vim-tiny sudo locales ethtool pciutils git-core kmod ifupdown
 
    keyring=debian-archive-keyring
 
    suite=wheezy
 
    source=http://http.debian.net/debian/
 
  
 
To build the first (unconfigured) stage of the rootfs, run:
 
To build the first (unconfigured) stage of the rootfs, run:
 
+
<pre>
    sudo multistrap -f novena.conf -d armhf
+
sudo multistrap -f novena.conf -d armhf
 
+
</pre>
 
Rename the resulting 'armhf' directory to 'rootfs', and tar it up as a backup
 
Rename the resulting 'armhf' directory to 'rootfs', and tar it up as a backup
 
copy. Then make the following basic changes *AS ROOT* in the rootfs directory
 
copy. Then make the following basic changes *AS ROOT* in the rootfs directory
Line 120: Line 142:
 
minimal requirements; package configuration and udev will help, but this won't
 
minimal requirements; package configuration and udev will help, but this won't
 
be a polished OS:
 
be a polished OS:
 
+
<pre>
    # sudo-s omitted
+
# sudo-s omitted
    echo "novena" > etc/hostname
+
echo "novena" > etc/hostname
    touch etc/fstab
+
touch etc/fstab
    touch etc/resolv.conf
+
touch etc/resolv.conf
    mkdir dev/pts
+
mkdir dev/pts
    mknod dev/console c 5 1
+
mknod dev/console c 5 1
    mknod dev/random c 1 8
+
mknod dev/random c 1 8
    mknod dev/urandom c 1 9
+
mknod dev/urandom c 1 9
    mknod dev/null c 1 3
+
mknod dev/null c 1 3
    mknod dev/ptmx c 5 2
+
mknod dev/ptmx c 5 2
 
+
</pre>
Copy the build host's /usr/bin/qemu-arm-static to
+
Copy the build host's <tt>/usr/bin/qemu-arm-static</tt> to
rootfs/usr/bin/qemu-static-arm.
+
<tt>rootfs/usr/bin/qemu-static-arm</tt>.
  
 
Create a config.sh script in top level of the rootfs:
 
Create a config.sh script in top level of the rootfs:
 
+
<pre>
    # config.sh script
+
# config.sh script
    export DEBIAN_FRONTEND=noninteractive DEBCONF_NONINTERACTIVE_SEEN=true
+
export DEBIAN_FRONTEND=noninteractive DEBCONF_NONINTERACTIVE_SEEN=true
    export LC_ALL=C LANGUAGE=C LANG=C
+
export LC_ALL=C LANGUAGE=C LANG=C
    /var/lib/dpkg/info/dash.preinst install
+
/var/lib/dpkg/info/dash.preinst install
    dpkg --configure -a
+
dpkg --configure -a
    mount proc -t proc /proc
+
mount proc -t proc /proc
    dpkg --configure -a
+
dpkg --configure -a
    umount /proc
+
umount /proc
 
+
</pre>
 
Run it:
 
Run it:
   
+
<pre>
    sudo chroot rootfs /config.sh
+
sudo chroot rootfs /config.sh
 
+
</pre>
 
Remove unnecessary files:
 
Remove unnecessary files:
 
+
<pre>
    sudo rm /usr/bin/qemu-static-arm
+
sudo rm /usr/bin/qemu-static-arm
    sudo rm /config.sh
+
sudo rm /config.sh
 
+
</pre>
 
Add a minimal rootfs/etc/hosts:
 
Add a minimal rootfs/etc/hosts:
    127.0.0.1      localhost.localdomain localhost novena
+
<pre>
    # The following lines are desirable for IPv6 capable hosts
+
127.0.0.1      localhost.localdomain localhost novena
    ::1    ip6-localhost ip6-loopback
+
# The following lines are desirable for IPv6 capable hosts
    fe00::0 ip6-localnet
+
::1    ip6-localhost ip6-loopback
    ff00::0 ip6-mcastprefix
+
fe00::0 ip6-localnet
    ff02::1 ip6-allnodes
+
ff00::0 ip6-mcastprefix
    ff02::2 ip6-allrouters
+
ff02::1 ip6-allnodes
 +
ff02::2 ip6-allrouters
 +
</pre>
  
 
Add a crude rootfs/etc/network/interfaces:
 
Add a crude rootfs/etc/network/interfaces:
 +
<pre>
 +
auto lo
 +
iface lo inet loopback
  
    auto lo
+
auto eth0
    iface lo inet loopback
+
iface eth0 inet dhcp
 
+
    hwaddress ether 00:11:22:33:44:55
    auto eth0
+
</pre>
    iface eth0 inet dhcp
 
            hwaddress ether 00:11:22:33:44:55
 
 
 
 
Edit rootfs/etc/inittab and allow logins on serial console (modify the similar tty1 line):
 
Edit rootfs/etc/inittab and allow logins on serial console (modify the similar tty1 line):
 +
<pre>
 +
1:2345:respawn:/sbin/getty 115200 ttymxc1
 +
</pre>
 +
Edit <tt>rootfs/etc/shadow</tt> and remove the '*' character after root (to set a null
 +
password).
  
    1:2345:respawn:/sbin/getty 115200 ttymxc1
+
<span style="color:red">
 
+
'''WARNING: only root will be able to login, with blank password!'''
Edit rootfs/etc/shadow and remove the '*' character after root (to set a null
+
</span>
password). NOTE: only root will be able to login, with blank password (!!!).
 
   
 
 
Ensure that all files in the rootfs are owned by root:root, not a user:
 
Ensure that all files in the rootfs are owned by root:root, not a user:
 
+
<span>
    sudo chown -R root:root rootfs/*
+
sudo chown -R root:root rootfs/*
 
+
</span>
 
Then double check the "tweaks" below.
 
Then double check the "tweaks" below.
  
 
==rootfs Tweaks (even for recycled images)==
 
==rootfs Tweaks (even for recycled images)==
 
Set some serial login on ttymxc1 (edit etc/inittab):
 
Set some serial login on ttymxc1 (edit etc/inittab):
 
+
<pre>
    1:2345:respawn:/sbin/getty 115200 ttymxc1
+
1:2345:respawn:/sbin/getty 115200 ttymxc1
 
+
</pre>
Set MAC address in etc/network/interfaces to:
+
(optional) Set MAC address in etc/network/interfaces to:
 
+
<pre>
    hwaddress 00:11:22:33:44:55
+
hwaddress 00:11:22:33:44:55
 +
</pre>
  
 
==Partition a blank SD card==
 
==Partition a blank SD card==
Line 208: Line 236:
  
 
==Build device tree file==
 
==Build device tree file==
You need the 'device-tree-compiler' package for the next bit.
+
You need the <tt>device-tree-compiler</tt> package for the next bit.
  
 
Grab novena.dts and imx6q.dtsi from the meta-kosagi repo:
 
Grab novena.dts and imx6q.dtsi from the meta-kosagi repo:
 
+
<pre>
    meta-kosagi/recipes-kernel/linux/linux-novena/novena.dts
+
meta-kosagi/recipes-kernel/linux/linux-novena/novena.dts
    meta-kosagi/recipes-kernel/linux/linux-novena/imx6q.dtsi
+
meta-kosagi/recipes-kernel/linux/linux-novena/imx6q.dtsi
 
+
</pre>
 
Grab skelton.dtsi from the linux-stable sources (checked out previously):
 
Grab skelton.dtsi from the linux-stable sources (checked out previously):
 
+
<pre>
    linux-stable/arch/arm/boot/dts/skeleton.dtsi
+
linux-stable/arch/arm/boot/dts/skeleton.dtsi
 
+
</pre>
 
Compile the device tree file:
 
Compile the device tree file:
 
+
<pre>
    dtc -I dts -O dtb -R 8 -p 0x3000 -o uImage-novena.dtb novena.dts
+
dtc -I dts -O dtb -R 8 -p 0x3000 -o uImage-novena.dtb novena.dts
 
+
</pre>
Grab the resulting uImage-novena.dtb file for later.
+
Grab the resulting <tt>uImage-novena.dtb</tt> file for later.
  
 
==Compile the u-boot boot script==
 
==Compile the u-boot boot script==
You need 'u-boot-tools' for the next bit.
+
You need <tt>u-boot-tools</tt> for the next bit.
  
 
Grab boot.script from the meta-kosagi repo:
 
Grab boot.script from the meta-kosagi repo:
 
+
<pre>
    meta-kosagi/recipes-bsp/u-boot/u-boot-imx/boot.script
+
meta-kosagi/recipes-bsp/u-boot/u-boot-imx/boot.script
 
+
</pre>
 
Compile the boot script (careful, confusing file names!):
 
Compile the boot script (careful, confusing file names!):
 
+
<pre>
    mkimage -A arm -O linux -a 0 -e 0 -T script -C none -n "Boot script" -d boot.script boot.scr
+
mkimage -A arm -O linux -a 0 -e 0 -T script -C none -n "Boot script" -d boot.script boot.scr
 
+
</pre>
Grab the resulting boot.src file for later.
+
Grab the resulting <tt>boot.src</tt> file for later.
  
 
==Assemble Everything==
 
==Assemble Everything==
Copy the u-boot.imx file built above to the padded space at the begining of the
+
Copy the <tt>u-boot.imx</tt> file built above to the padded space at the begining of the
 
card:
 
card:
 +
<pre>
 +
$ dd if=u-boot.imx of=/dev/sdb bs=512 conv=notrunc seek=2
 +
</pre>
 +
Mount the FAT boot partition to <tt>/mnt</tt>.
  
    $ dd if=u-boot.imx of=/dev/sdb bs=512 conv=notrunc seek=2
+
Copy boot.src and uImage-novena.dtb over to /mnt, keeping their names. Copy the uImage kernel file to <tt>/mnt/uImage-novena.bin</tt>.
 
 
Mount the FAT boot partition to /mnt.
 
 
 
Copy boot.src and uImage-novena.dtb over to /mnt, keeping their names. Copy the uImage kernel file to /mnt/uImage-novena.bin.
 
  
 
unmount the FAT boot patition and mount the ext partition to /mnt.
 
unmount the FAT boot patition and mount the ext partition to /mnt.
  
 
Delete any old rootfs files (if you didn't just re-partition the disk), and copy over the whole rootfs:
 
Delete any old rootfs files (if you didn't just re-partition the disk), and copy over the whole rootfs:
 
+
<pre>
    $ sudo rsync -arv ./rootfs/ /mnt/
+
$ sudo rsync -arv ./rootfs/ /mnt/
 
+
</pre>
 
unmount the disk, it's ready to go!
 
unmount the disk, it's ready to go!
  
 
==Result!==
 
==Result!==
  root@novena:~# uname -a
+
<pre>
  Linux novena 3.8.0-custom1 #2 SMP Tue Jan 22 04:20:12 UTC 2013 armv7l GNU/Linux
+
root@novena:~# uname -a
  root@novena:~# cat /etc/os-release     
+
Linux novena 3.8.0-custom1 #2 SMP Tue Jan 22 04:20:12 UTC 2013 armv7l GNU/Linux
  PRETTY_NAME="Debian GNU/Linux 7.0 (wheezy)"
+
root@novena:~# cat /etc/os-release     
  NAME="Debian GNU/Linux"
+
PRETTY_NAME="Debian GNU/Linux 7.0 (wheezy)"
  VERSION_ID="7.0"
+
NAME="Debian GNU/Linux"
  VERSION="7.0 (wheezy)"
+
VERSION_ID="7.0"
  ID=debian
+
VERSION="7.0 (wheezy)"
  ANSI_COLOR="1;31"
+
ID=debian
  HOME_URL="http://www.debian.org/"
+
ANSI_COLOR="1;31"
  SUPPORT_URL="http://www.debian.org/support/"
+
HOME_URL="http://www.debian.org/"
  BUG_REPORT_URL="http://bugs.debian.org/"
+
SUPPORT_URL="http://www.debian.org/support/"
 
+
BUG_REPORT_URL="http://bugs.debian.org/"
 +
</pre>
 
reboot time: about 13 seconds
 
reboot time: about 13 seconds
 
shutdown time: 3-4 seconds
 
shutdown time: 3-4 seconds
Line 276: Line 305:
  
 
To try and steal a u-boot header from existing disk:
 
To try and steal a u-boot header from existing disk:
 
+
<pre>
    dd if=/dev/sdb of=snag.bin bs=512 skip=2 count=500
+
dd if=/dev/sdb of=snag.bin bs=512 skip=2 count=500
 
+
</pre>
 
and write:
 
and write:
 
+
<pre>
    dd if=snag.bin of=/dev/sdb bs=512 seek=2 count=500
+
dd if=snag.bin of=/dev/sdb bs=512 seek=2 count=500
 
+
</pre>
 
If a MAC address isn't assigned for eth0 at boot (eg, if ifupdown package isn't
 
If a MAC address isn't assigned for eth0 at boot (eg, if ifupdown package isn't
 
installed), you will get:
 
installed), you will get:
 
+
<pre>
    root@novena:~# ifconfig eth0 up
+
root@novena:~# ifconfig eth0 up
    SIOCSIFFLAGS: Cannot assign requested address
+
SIOCSIFFLAGS: Cannot assign requested address
 
+
<pre>
 
Workaround:
 
Workaround:
    ifconfig eth0 hw ether 00:11:22:33:44:55
+
<pre>
    ifconfig eth0 up
+
ifconfig eth0 hw ether 00:11:22:33:44:55
 +
ifconfig eth0 up
 +
</pre>
  
 
==TODO==
 
==TODO==
 
* add i2c thing to rc.local: "i2cset -y 1 0x08 0x66 0x48 || true"
 
* add i2c thing to rc.local: "i2cset -y 1 0x08 0x66 0x48 || true"

Revision as of 03:22, 3 July 2013

NOTE: these instructions are in flux

How to use the embedian cross-compilation toolchain to generate binaries that will run on armhf hardware using a debian-based x86/amd64 build host.

These directions require a physical micro SD card; partitioning happens "in place" instead of using loop-mounted .img files.

These directions assume you basically know what you are doing; eg, be careful dd'ing directly to the micro SD card and that you don't accidentally dd to an important disk, resulting in a loss of all data.

Prepare Cross-Compile Toolchain on Build Host

You need to add the embedian repositories to your sources.list.

There aren't toolchain packages in (emdebian) wheezy yet, so if your build host is wheezy add (emdebian) squeeze to your /etc/apt/sources.list (don't replace any wheezy lines, just copy the wheezy deb line and replace "wheezy" with "squeeze"), then apt-get update. This shouldn't clobber your system too bad as the wheezy packages will almost always be prefered to squeeze packages. My sources.list on my (wheezy) build machine looked like this in January 2013:

# primary
deb     http://http.debian.net/debian/  wheezy  main  contrib
deb-src http://http.debian.net/debian/  wheezy  main  contrib

# security
deb     http://security.debian.org/  wheezy/updates  main contrib  
deb-src http://security.debian.org/  wheezy/updates  main contrib

# emdebian  
deb http://www.emdebian.org/debian/ wheezy main  
deb http://www.emdebian.org/debian/ sid main  
deb http://http.debian.net/debian/  squeeze main contrib 

IIRC the main toolchain package is gcc-4.7-arm-linux-gnueabi.

Also install (at least) these debian packages:

build-essential multistrap qemu-user-static gparted device-tree-compiler u-boot-tools bc

Note that 'gparted' is a GUI and will pull in X dependancies; if you build on a remote server you could do the partitioning steps on a different machine.

Check out these repositories from github:

The linux-stable git checkout could take ages (and is huge), so you might want to just grab a tarball of 3.7.4.

Build u-boot

Checkout the custom u-boot-imx6: https://github.com/sutajiokousagi/u-boot-imx6

As of Jan 2013, use ddrsetup branch (else *-staging?).

Enter top directory and build:

export CROSS_COMPILE=arm-linux-gnueabi-
make novena_config
make

Grab the resulting 'u-boot.imx' for later.

Build Kernel

Install whatever general build tools. Might in particular need 'lzop' for building uImages.

Grab linux-stable upstream: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable.git

As of Jan 2013, testing with 3.8-rc (not linux-stable).

Copy in meta-kosagi/recipes-kernel/linux/linux-novena/defconfig as .config

Create this script as cross_build.sh; note the UIMAGE_LOADADDR=10008000 on penultimate line (i.mx6-specific?), and change "custom1" to whatever you want:

#!/usr/bin/env bash
export ARCH=arm
export DEB_HOST_ARCH=armhf
export CONCURRENCY_LEVEL=`grep -m1 cpu\ cores /proc/cpuinfo | cut -d : -f 2`
fakeroot make-kpkg --arch arm --cross-compile arm-linux-gnueabi- --initrd --append-to-version=-custom1 kernel_image kernel_headers
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- EXTRAVERSION=-custom1 UIMAGE_LOADADDR=10008000 uImage
cp arch/arm/boot/uImage uImage

If you are using a newer -stable kernel than the one use to generate the .config, the first compile will prompt you to select a whole boatload of NEW configuration options (new optional features in the kernel sources). If you run in to this, keep hitting enter to accept all the defaults.

Run the cross_build.sh script to build.

Grab the resulting uImage file and rename it uImage-novena.bin.

Build a Basic Debian armhf wheezy rootfs with multistrap and qemu

These are crude, manual, slow directions, included for completeness. Pretty much nobody should do things this way, any targeted application of the novena board would have images generated by a script or better build process. Perhaps even the Debian installer will be sufficient.

You might also be able to use a generic debian wheezy armhf rootfs tarball if you have one sitting around.

We'll use multistrap, configure the packages with qemu, then edit the configuration by hand. This follows http://wiki.debian.org/Multistrap#Steps_for_Squeeze_and_later.

Install the qemu-user-static and multistrap packages.

In a new directory, create a multistrap configuration file like the below, called novena.conf. Add any extra packages you want to the long list:

[General]
arch=armhf
cleanup=true
noauth=false
aptsources=Debian
bootstrap=Debian

[Debian]
packages=file i2c-tools screen build-essential base-files openssh-server wget iproute net-tools hostname udev isc-dhcp-client parted dosfstools apt iputils-ping dialog iptables less traceroute apt-utils dnsutils lsof vim-tiny sudo locales ethtool pciutils git-core ifupdown manpages man-db firmware-linux-free kmod iw wireless-tools wpasupplicant hostapd rfkill  

keyring=debian-archive-keyring
suite=wheezy
source=http://http.debian.net/debian/

To build the first (unconfigured) stage of the rootfs, run:

sudo multistrap -f novena.conf -d armhf

Rename the resulting 'armhf' directory to 'rootfs', and tar it up as a backup copy. Then make the following basic changes *AS ROOT* in the rootfs directory (you don't need to chroot) before configuring the packages. These are just the minimal requirements; package configuration and udev will help, but this won't be a polished OS:

# sudo-s omitted
echo "novena" > etc/hostname
touch etc/fstab
touch etc/resolv.conf
mkdir dev/pts
mknod dev/console c 5 1
mknod dev/random c 1 8
mknod dev/urandom c 1 9
mknod dev/null c 1 3
mknod dev/ptmx c 5 2

Copy the build host's /usr/bin/qemu-arm-static to rootfs/usr/bin/qemu-static-arm.

Create a config.sh script in top level of the rootfs:

# config.sh script
export DEBIAN_FRONTEND=noninteractive DEBCONF_NONINTERACTIVE_SEEN=true
export LC_ALL=C LANGUAGE=C LANG=C
/var/lib/dpkg/info/dash.preinst install
dpkg --configure -a
mount proc -t proc /proc
dpkg --configure -a
umount /proc

Run it:

sudo chroot rootfs /config.sh

Remove unnecessary files:

sudo rm /usr/bin/qemu-static-arm
sudo rm /config.sh

Add a minimal rootfs/etc/hosts:

127.0.0.1       localhost.localdomain localhost novena
# The following lines are desirable for IPv6 capable hosts
::1     ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters

Add a crude rootfs/etc/network/interfaces:

auto lo
iface lo inet loopback

auto eth0
iface eth0 inet dhcp
    hwaddress ether 00:11:22:33:44:55

Edit rootfs/etc/inittab and allow logins on serial console (modify the similar tty1 line):

1:2345:respawn:/sbin/getty 115200 ttymxc1

Edit rootfs/etc/shadow and remove the '*' character after root (to set a null password).

WARNING: only root will be able to login, with blank password! Ensure that all files in the rootfs are owned by root:root, not a user: sudo chown -R root:root rootfs/* Then double check the "tweaks" below.

rootfs Tweaks (even for recycled images)

Set some serial login on ttymxc1 (edit etc/inittab):

1:2345:respawn:/sbin/getty 115200 ttymxc1

(optional) Set MAC address in etc/network/interfaces to:

hwaddress 00:11:22:33:44:55

Partition a blank SD card

Use the gparted GUI.

Delete all existing partitions on the micro SD card.

Create a ~32MB FAT32 partition labeled 'boot' with at least 512KB of padding in front of it (by default there is 1MB of padding), call it 'boot'.

Create a ~500MB ext3 partition.

Commit changes.

Build device tree file

You need the device-tree-compiler package for the next bit.

Grab novena.dts and imx6q.dtsi from the meta-kosagi repo:

meta-kosagi/recipes-kernel/linux/linux-novena/novena.dts
meta-kosagi/recipes-kernel/linux/linux-novena/imx6q.dtsi

Grab skelton.dtsi from the linux-stable sources (checked out previously):

linux-stable/arch/arm/boot/dts/skeleton.dtsi

Compile the device tree file:

dtc -I dts -O dtb -R 8 -p 0x3000 -o uImage-novena.dtb novena.dts

Grab the resulting uImage-novena.dtb file for later.

Compile the u-boot boot script

You need u-boot-tools for the next bit.

Grab boot.script from the meta-kosagi repo:

meta-kosagi/recipes-bsp/u-boot/u-boot-imx/boot.script

Compile the boot script (careful, confusing file names!):

mkimage -A arm -O linux -a 0 -e 0 -T script -C none -n "Boot script" -d boot.script boot.scr

Grab the resulting boot.src file for later.

Assemble Everything

Copy the u-boot.imx file built above to the padded space at the begining of the card:

$ dd if=u-boot.imx of=/dev/sdb bs=512 conv=notrunc seek=2

Mount the FAT boot partition to /mnt.

Copy boot.src and uImage-novena.dtb over to /mnt, keeping their names. Copy the uImage kernel file to /mnt/uImage-novena.bin.

unmount the FAT boot patition and mount the ext partition to /mnt.

Delete any old rootfs files (if you didn't just re-partition the disk), and copy over the whole rootfs:

$ sudo rsync -arv ./rootfs/ /mnt/

unmount the disk, it's ready to go!

Result!

root@novena:~# uname -a
Linux novena 3.8.0-custom1 #2 SMP Tue Jan 22 04:20:12 UTC 2013 armv7l GNU/Linux
root@novena:~# cat /etc/os-release     
PRETTY_NAME="Debian GNU/Linux 7.0 (wheezy)"
NAME="Debian GNU/Linux"
VERSION_ID="7.0"
VERSION="7.0 (wheezy)"
ID=debian
ANSI_COLOR="1;31"
HOME_URL="http://www.debian.org/"
SUPPORT_URL="http://www.debian.org/support/"
BUG_REPORT_URL="http://bugs.debian.org/"

reboot time: about 13 seconds shutdown time: 3-4 seconds

Hacks

To try and steal a u-boot header from existing disk:

dd if=/dev/sdb of=snag.bin bs=512 skip=2 count=500

and write:

dd if=snag.bin of=/dev/sdb bs=512 seek=2 count=500

If a MAC address isn't assigned for eth0 at boot (eg, if ifupdown package isn't installed), you will get:

root@novena:~# ifconfig eth0 up
SIOCSIFFLAGS: Cannot assign requested address
<pre>
Workaround:
<pre>
ifconfig eth0 hw ether 00:11:22:33:44:55
ifconfig eth0 up

TODO

  • add i2c thing to rc.local: "i2cset -y 1 0x08 0x66 0x48 || true"