Difference between revisions of "Novena/Embedian Build"
(whew!) |
m (moved Novena/DebianBuildProcess to Novena/Embedian Build) |
||
(3 intermediate revisions by 2 users not shown) | |||
Line 1: | Line 1: | ||
− | NOTE: these instructions are | + | ''NOTE: these instructions are in flux'' |
− | + | How to use the embedian cross-compilation toolchain to generate binaries that will | |
− | run on armhf hardware using | + | 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 | ||
+ | |||
+ | # 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 | ||
+ | </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 | + | Check out these repositories from github: |
− | |||
* 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- | ||
+ | make novena_config | ||
+ | make | ||
+ | </pre> | ||
+ | Grab the resulting 'u-boot.imx' for later. | ||
+ | |||
− | + | ==Compile the u-boot boot script== | |
− | + | You need <tt>u-boot-tools</tt> for the next bit. | |
− | |||
− | Grab the | + | Grab boot.script from the meta-kosagi repo: |
+ | <pre> | ||
+ | wget https://raw.github.com/sutajiokousagi/meta-kosagi/novena/recipes-bsp/u-boot/u-boot-imx/boot.script | ||
+ | </pre> | ||
+ | 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 | ||
+ | </pre> | ||
+ | Grab the resulting <tt>boot.src</tt> file for later. | ||
==Build Kernel== | ==Build Kernel== | ||
Line 63: | Line 95: | ||
penultimate line (i.mx6-specific?), and change "custom1" to whatever you want: | penultimate line (i.mx6-specific?), and change "custom1" to whatever you want: | ||
− | + | <pre> | |
− | + | #!/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 | ||
+ | </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 <tt>uImage-novena.bin</tt>. | ||
+ | |||
+ | ==Build device tree file== | ||
+ | You need the <tt>device-tree-compiler</tt> package for the next bit. | ||
− | Grab the resulting | + | 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/imx6q.dtsi | ||
+ | </pre> | ||
+ | Grab skelton.dtsi from the linux-stable sources (checked out previously): | ||
+ | <pre> | ||
+ | linux-stable/arch/arm/boot/dts/skeleton.dtsi | ||
+ | </pre> | ||
+ | Compile the device tree file: | ||
+ | <pre> | ||
+ | dtc -I dts -O dtb -R 8 -p 0x3000 -o uImage-novena.dtb novena.dts | ||
+ | </pre> | ||
+ | Grab the resulting <tt>uImage-novena.dtb</tt> file for later. | ||
==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 149: | ||
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 | ||
+ | |||
+ | [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/ | |
− | + | </pre> | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
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 | |
− | + | </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 174: | ||
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 | |
− | + | 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 | |
− | + | </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 | + | <tt>rootfs/usr/bin/qemu-arm-static</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 | |
− | + | 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 | |
− | + | </pre> | |
Run it: | Run it: | ||
− | + | <pre> | |
− | + | sudo chroot rootfs /config.sh | |
− | + | </pre> | |
Remove unnecessary files: | Remove unnecessary files: | ||
− | + | <pre> | |
− | + | sudo rm /usr/bin/qemu-arm-static | |
− | + | sudo rm /config.sh | |
− | + | </pre> | |
Add a minimal rootfs/etc/hosts: | Add a minimal rootfs/etc/hosts: | ||
− | + | <pre> | |
− | + | 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 | ||
+ | </pre> | ||
Add a crude rootfs/etc/network/interfaces: | Add a crude rootfs/etc/network/interfaces: | ||
+ | <pre> | ||
+ | auto lo | ||
+ | iface lo inet loopback | ||
− | + | auto eth0 | |
− | + | iface eth0 inet dhcp | |
− | + | hwaddress ether 00:11:22:33:44:55 | |
− | + | </pre> | |
− | |||
− | |||
− | |||
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). | ||
− | + | <span style="color:red"> | |
+ | '''WARNING: only root will be able to login, with blank password!''' | ||
+ | </span> | ||
− | |||
− | |||
− | |||
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: | ||
− | + | <pre> | |
− | + | sudo chown -R root:root rootfs/* | |
− | + | </pre> | |
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 | |
− | + | </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 | |
+ | </pre> | ||
==Partition a blank SD card== | ==Partition a blank SD card== | ||
Line 207: | Line 268: | ||
Commit changes. | Commit changes. | ||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
==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>. | ||
− | + | 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>. | |
− | |||
− | |||
− | |||
− | 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/ | |
− | + | </pre> | |
unmount the disk, it's ready to go! | unmount the disk, it's ready to go! | ||
==Result!== | ==Result!== | ||
− | + | <pre> | |
− | + | 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/" | |
+ | </pre> | ||
reboot time: about 13 seconds | reboot time: about 13 seconds | ||
shutdown time: 3-4 seconds | shutdown time: 3-4 seconds | ||
Line 276: | Line 308: | ||
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 | |
− | + | </pre> | |
and write: | and write: | ||
− | + | <pre> | |
− | + | 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 | |
− | + | SIOCSIFFLAGS: Cannot assign requested address | |
− | + | </pre> | |
Workaround: | Workaround: | ||
− | + | <pre> | |
− | + | 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 -f -y 1 0x08 0x66 0x48 || true" |
Latest revision as of 06:46, 12 October 2014
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.
Contents
- 1 Prepare Cross-Compile Toolchain on Build Host
- 2 Build u-boot
- 3 Compile the u-boot boot script
- 4 Build Kernel
- 5 Build device tree file
- 6 Build a Basic Debian armhf wheezy rootfs with multistrap and qemu
- 7 rootfs Tweaks (even for recycled images)
- 8 Partition a blank SD card
- 9 Assemble Everything
- 10 Result!
- 11 Hacks
- 12 TODO
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:
- meta-kosagi from github/sutajiokousagi (novena branch): https://github.com/sutajiokousagi/meta-kosagi
- u-boot-imx6 from github/sutajiokousagi (ddrsetup branch): https://github.com/sutajiokousagi/u-boot-imx6
- linux-stable from kernel.org (eg, 3.7.4 tag): https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable.git
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.
Compile the u-boot boot script
You need u-boot-tools for the next bit.
Grab boot.script from the meta-kosagi repo:
wget https://raw.github.com/sutajiokousagi/meta-kosagi/novena/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.
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 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.
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-arm-static.
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-arm-static 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.
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
Workaround:
ifconfig eth0 hw ether 00:11:22:33:44:55 ifconfig eth0 up
TODO
- add i2c thing to rc.local: "i2cset -f -y 1 0x08 0x66 0x48 || true"