Cross Install Gentoo

From Pandora Wiki
Jump to: navigation, search

Introduction

These instructions are for installing a recent Gentoo Linux on the OpenPandora handheld console. The system will be installed and booted from a SD-card. The Gentoo Linux will be cross-compiled on another desktop computer also running Gentoo Linux.

It is not necessary to follow all instructions exactly. Some of them can be changed to your own needs.

The system currently supports only the text console and no X11 or sound. Also a lot of features are missing. See "Open issues" at the end.

Prerequisites

These instructions assume the following prerequisites:

  • Good knowledge in Gentoo Linux.
  • A desktop computer running Gentoo Linux. Other Linux is, of course, also possible but requires proper adaption of these instructions.
  • An OpenPandora handheld console.
  • A SD-card with least 8 GB size.
  • A USB cable to connect the Pandora to the desktop computer.

Improvement

Due to the constant changes of the Linux kernel, GNU software, etc. this document will be outdated very quick. To avoid this, help is always appreciated improving this document. If you can update, improve, add or complete this document, don't hesitate to do so.


Prepare/install cross compile system

To perform the cross-compilation a cross compiler and QEmu must be installed on the desktop computer. QEmu will help a lot for compiling packages which will not properly cross compile.


Install cross compiling system

For compiling software for an ARM controller a cross compiler must be installed.

We can use ARMv7 using either soft float (armv7a-softfp-linux-gnueabi) or hard float (armv7a-hardfloat-linux-gnueabi).

export CROSSDEV_TARGET=armv7a-softfp-linux-gnueabi

or

export CROSSDEV_TARGET=armv7a-hardfloat-linux-gnueabi

The additional portage tree in "/usr/local/portage-crossdev" will hold all information for emerging the cross build system (cross compiler and tools).

To prepare emerging a cross compiler, execute the following commands.

su
umask 0022

emerge -av crossdev

mkdir -p /usr/local/portage-crossdev/{profiles,metadata}

echo 'local-crossdev' >/usr/local/portage-crossdev/profiles/repo_name
echo 'masters = gentoo' >/usr/local/portage-crossdev/metadata/layout.conf
echo 'thin-manifests = true' >>/usr/local/portage-crossdev/metadata/layout.conf
chown -R portage:portage /usr/local/portage-crossdev

echo '[local-crossdev]' >/etc/portage/repos.conf/crossdev.conf

echo 'location = /usr/local/portage-crossdev' \
>>/etc/portage/repos.conf/crossdev.conf

echo 'priority = 10' >>/etc/portage/repos.conf/crossdev.conf
echo 'masters = gentoo' >>/etc/portage/repos.conf/crossdev.conf
echo 'auto-sync = no' >>/etc/portage/repos.conf/crossdev.conf

The portage tree for emerging the cross build system is set up. Now we have to find out which versions of the cross build components are about to be installed. The target system will get binutils, gcc, glibc and linux-headers of a certain version. The same version should be installed in the cross build system.

export BINUTILS_VER=$(grep -le 'KEYWORDS.* arm' \
/usr/portage/sys-devel/binutils/binutils-*.ebuild | tail -1 | \
awk 'match($0, ".*/binutils-(.*).ebuild", v) { print(v[1]); }')

export GCC_VER=$(grep -le 'KEYWORDS.* arm' \
/usr/portage/sys-devel/gcc/gcc-*.ebuild | tail -1 | \
awk 'match($0, ".*/gcc-(.*).ebuild", v) { print(v[1]); }')

export GLIBC_VER=$(grep -le 'KEYWORDS.* arm' \
/usr/portage/sys-libs/glibc/glibc-*.ebuild | tail -1 | \
awk 'match($0, ".*/glibc-(.*).ebuild", v) { print(v[1]); }')

export LINUX_HEADERS_VER=$(grep -le 'KEYWORDS.* arm' \
/usr/portage/sys-kernel/linux-headers/linux-headers-*.ebuild | tail -1 | \
awk 'match($0, ".*/linux-headers-(.*).ebuild", v) { print(v[1]); }')

Now emerge the cross compiler.

crossdev --binutils $BINUTILS_VER --gcc $GCC_VER --libc $GLIBC_VER \
--kernel $LINUX_HEADERS_VER --target $CROSSDEV_TARGET


Install QEmu

A lot of packages will not cross compile properly. QEmu will help for these packages. Install it to emulate an ARM controller.

Edit /etc/portage/make.conf.

nano /etc/portage/make.conf

And add the following lines.

QEMU_SOFTMMU_TARGETS=""
QEMU_USER_TARGETS="arm"

Also enable the use flag static-user. This builds QEmu as static binary. QEmu will be used later in a chroot environment of an ARM controller and will be unable to access needed shared libraries. So it must contain all these libraries by building it in a static way.

euse -E static-user

All the needed libraries for QEmu must also be available as library archive (static libs). Emerging QEmu will request to emerge these libraries as static variants, also. Create and add these libraries in the file "/etc/portage/package.use/qemu". Look which libraries are needed.

emerge -pv qemu

And add them with the use flag static-libs. Here is an Example:

>=net-misc/curl-7.53.0 static-libs
>=sys-apps/attr-2.4.47-r2 static-libs
>=media-libs/libsdl-1.2.15-r9 static-libs
>=sys-apps/dtc-1.4.1 static-libs
>=app-arch/bzip2-1.0.6-r7 static-libs
>=x11-libs/pixman-0.34.0 static-libs
>=dev-libs/libpcre-8.40-r1 static-libs
>=sys-libs/libseccomp-2.3.0 static-libs
>=net-fs/libnfs-1.9.7 static-libs
>=dev-libs/cyrus-sasl-2.1.26-r9 static-libs
>=dev-libs/gmp-6.1.0 static-libs
>=dev-libs/libaio-0.3.110 static-libs
>=sys-fs/xfsprogs-4.5.0 static-libs
>=sys-libs/zlib-1.2.11 static-libs
>=media-libs/libjpeg-turbo-1.5.0 static-libs
>=sys-libs/libcap-ng-0.7.8 static-libs
>=dev-libs/openssl-1.0.2k static-libs
>=dev-libs/glib-2.50.3-r1 static-libs
>=virtual/jpeg-0-r2:0 static-libs
>=media-libs/libpng-1.6.27 static-libs
>=sys-libs/ncurses-6.0-r1 static-libs

Emerge QEmu.

emerge qemu
udevadm trigger -c add /dev/kvm

QEmu will execute ARM binaries on the desktop computer as if it would have an ARM controller. To achieve this, register foreign binaries and start the systemd service.

ln -s /usr/share/qemu/binfmt.d/qemu.conf /etc/binfmt.d/qemu.conf
systemctl start systemd-binfmt

Now our desktop computer is able to execute ARM binaries as well as his own binaries.


Install GIT

To get the kernel sources, GIT will be needed. Emerge it.

emerge git

Exit the root shell.

exit

Now the cross build system is ready to compile a Gentoo Linux for the Pandora.


Install system

Prepare target file system

To build the system for the Pandora about 10 GB disk space is needed. Create a directory "CrossDev" to store all data there.

mkdir CrossDev
cd CrossDev

In this directory two more directories will be created:

  • One to store and build the Linux kernel.
  • Another will store the whole system for the Pandora including QEmu which is not really a part of the system for Pandora, but it is needed as long as the building process runs.
  • Some files and archives.

First get the Gentoo base system "stage3-armv7a-*.tar.bz2". Download it from a suitable mirror of the Gentoo distribution. See https://www.gentoo.org/downloads/mirrors for a list of mirrors.

Go to the directory "releases/arm/autobuilds". According to your target, enter

  • "current-stage3-armv7a" for soft float (armv7a-softfp-linux-gnueabi),
  • "current-stage3-armv7a_hardfp" for hard float (armv7a-hardfloat-linux-gnueabi).

There is a stage 3 file for ARMv7. Download this archive.

Example:

wget http://mirror.eu.oneandone.net/linux/distributions/gentoo/gentoo/\
releases/arm/autobuilds/current-stage3-armv7a/stage3-armv7a-20161129.tar.bz2

or

wget http://mirror.eu.oneandone.net/linux/distributions/gentoo/gentoo/\
releases/arm/autobuilds/current-stage3-armv7a_hardfp/\
stage3-armv7a_hardfp-20161129.tar.bz2

As long as we are cross compiling, we use "/usr/$CROSSDEV_TARGET" as working directory. The cross compiler looks for libraries there and uses many references to this directory. That's why "/usr/$CROSSDEV_TARGET" will be saved, so it can be restored after the build.

su
umask 0022
tar -cpjf ${CROSSDEV_TARGET}-saved.tar.bz2 -C /usr $CROSSDEV_TARGET

Unpack the stage 3 archive into "/usr/$CROSSDEV_TARGET".

tar --xattrs --numeric-owner -xpjf stage3-*.tar.bz2 -C /usr/$CROSSDEV_TARGET

Sometimes there is a lot of garbage in the "tmp" directory. Remove it.

rm -rf /usr/$CROSSDEV_TARGET/tmp/*

Exit the root shell and go back to our working directory.

exit


Compile/install kernel

The standard Gentoo kernel will not run on the Pandora (or, at least, takes too much effort to make it run), so download a current kernel from https://goldelico.com using GIT.


Download kernel

Download the kernel with GIT.

git clone git://git.goldelico.com/gta04-kernel.git
cd gta04-kernel


Compile kernel

Prepare an environment to cross compile the kernel. First call another shell instance for saving the current environment. This instance is not really necessary but it is more convenient because the saved environment is restored after exiting the new shell.

bash
umask 0022
export ARCH=arm CROSS_COMPILE=${CROSSDEV_TARGET}-
export PS1="($ARCH) $PS1"

Now a default configuration for the kernel will be created.

make omap2plus_defconfig

A lot of configuration must be done to make the kernel work. To ease this use kernel-config which will configure a running kernel for the Pandora. It uses the name "pherkad" as computer name. Change this to any name you like in the config file. Calling oldconfig might be necessary if "kernel-config" is too old for the current gta04-kernel.

cp ../kernel-config .config
make oldconfig
make menuconfig

In "General setup/Local version" change "-pherkad" to any name you like. But use "-" as prefix.

Build the kernel and the device tree "omap3-pandora-600mhz.dtb". Pandora users with 1 GHz units can use "omap3-pandora-1ghz.dts". Use as much CPU cores as you have for the compiling process.

export CPUS="$(grep processor /proc/cpuinfo | wc -l)"
make -j$CPUS zImage
make -j$CPUS modules
make omap3-pandora-600mhz.dtb

Convert the kernel into an image for the U-Boot loader. Use any name you like for "Linux-pherkad".

mkimage -A arm -O linux -T kernel -C none -a 0x80008000 -e 0x80008000 -n \
'Linux-pherkad' -d arch/arm/boot/zImage arch/arm/boot/uImage

Generate a "boot.scr" file which loads the kernel image and the correct device tree.

Keep an eye to the bootargs. It uses the following commands:

  • Start the systemd as init process: "init=/lib/systemd/systemd".
  • Be quiet: "quiet". This can be removed while development.
  • Show a splash screen: "splash". There is currently no splash screen, so this
  • Use the root file system at: "root=/dev/mmcblk0p2". Take care to use the same partition as described below.
  • Use Ext 4 root file system: "rootfstype=ext4".
  • Wait for root file system: "rootwait".
  • Mount initially read only: "ro". systemd will remount it later as RW.
  • Use the following SWAP partition for hibernation/resume: "resume=/dev/mmcblk0p3". This is currently not used.

The file "boot.txt" will be converted to the boot script "boot.src".

cat >boot.txt <<EOF
if itest.w *0x4830a204 == 0x102f
then
    setenv devicetree omap3-pandora-1ghz
else
    setenv devicetree omap3-pandora-600mhz
fi
setenv defaultdisplay lcd
setenv bootargs "init=/lib/systemd/systemd quiet splash \
root=/dev/mmcblk0p2 rootfstype=ext4 rootwait ro resume=/dev/mmcblk0p3"
ext2load mmc 0:1 0x825f0000 /boot/\${devicetree}.dtb
ext2load mmc 0:1 0x80300000 /boot/uImage-pherkad
bootm 0x80300000 - 0x825f0000
EOF

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

Exit the kernel build environment.

exit

Install kernel

The installation of the kernel into the target directory must be done as root. Create the "boot" directory for the kernel, device tree and boot script and copy them to the target directory.

su
umask 0022
cp arch/arm/boot/uImage /usr/$CROSSDEV_TARGET/boot/uImage-pherkad
cp .config /usr/$CROSSDEV_TARGET/boot/config-pherkad
cp System.map /usr/$CROSSDEV_TARGET/boot/System.map-pherkad
cp arch/arm/boot/dts/omap3-pandora-600mhz.dtb /usr/$CROSSDEV_TARGET/boot/.
cp boot.scr /usr/$CROSSDEV_TARGET/boot/.

Create a link for the boot directory. This is used if the boot directory is an own partition and the boot loader wants to load the kernel from "boot/uImage-*". In our case it is not really necessary.

(cd /usr/$CROSSDEV_TARGET/boot; ln -s . boot)

Install all kernel modules into "target/lib/modules". The symbolic link is for the cross compiling process to find the kernel configuration.

make ARCH=arm CROSS_COMPILE=${CROSSDEV_TARGET}- \
INSTALL_MOD_PATH=/usr/$CROSSDEV_TARGET modules_install

(DIR="$PWD"; cd /usr/$CROSSDEV_TARGET/usr/src; ln -s $DIR linux)
cd ..


Compile system

Now it's time to cross compile the whole Gentoo system. The base system is already installed in the "target" directory. All the binaries there will be compiled again with our own cross compiler. Also a lot of new packages (more binaries) will be installed.


Prepare cross development system

Go to the target and copy all portage configurations from the desktop computer to the target system, since we want to use the desktop computer system as base of the Pandora system. This must be done as root.

export FROM_DIR="$PWD"
cd /usr/$CROSSDEV_TARGET

Edit the "make.conf" file.

nano etc/portage/make.conf

Change some of the lines there. You might copy some of the contents from the desktop computer but be sure to have the same CHOST as the CROSSDEV_TARGET. Especially add or change for the following:

CFLAGS="-O2 -pipe -march=armv7-a -mfpu=vfpv3-d16 -mfloat-abi=softfp \
-mfpu=neon -fno-stack-protector"

or

CFLAGS="-O2 -pipe -march=armv7-a -mfpu=vfpv3-d16 -mfloat-abi=hard \
-mfpu=neon -fno-stack-protector"
CXXFLAGS="${CFLAGS}"
USE="systemd <and a lot of your own use flags>"
LINGUAS="en de"
L10N="en de"
FEATURES="sandbox -preserve-libs clean-logs unmerge-orphans buildpkg"
VIDEO_CARDS="omapfb"
INPUT_DEVICES="evdev keyboard mouse"
MAKEOPTS="-j<number of CPU cores>"
PORTAGE_COMPRESS=""
PORTAGE_NICENESS=3
PORTAGE_IONICE_COMMAND="ionice -c 3 -p \${PID}"
PORTAGE_ELOG_CLASSES="warn error log"
PORTAGE_ELOG_SYSTEM="save"
PORT_LOGDIR="/var/log/portage"

PORT_LOGDIR_CLEAN="find \"\${PORT_LOGDIR}\" -type f ! -name \"summary.log*\" \
-mtime +7 -delete"

EMERGE_DEFAULT_OPTS="--alphabetical --nospinner --quiet-build --usepkg=y \
--binpkg-respect-use=y"

GENTOO_MIRRORS="<enter your mirrors>"
PKGDIR="/usr/portage/packages/${CHOST}"

It is recommended to activate the build of binary packages. The cross compilation will fail to build some packages, so QEmu will build all packages again. It is not necessary to build good cross compiled packages by QEmu again. Using binary packages will avoid this and save a lot of time.

To avoid mixing up the binary packages of the desktop comuter and the Pandora set PKGDIR accordingly. Example: "/usr/portage/packages/${CHOST}"

Also copy and edit some package specific files from your desktop computer.

cp -r /etc/portage/package.* etc/portage/.

Edit the files in "etc/portage/package.*" and configure the portage tree.

sed -i "s/amd64/arm/g" etc/portage/package.keywords/*
rm -r etc/portage/package.keywords/cross*
rm -r etc/portage/package.mask/cross*
rm etc/portage/package.use/cross*
rm etc/portage/package.env/cross*

mkdir etc/portage/repos.conf
cp usr/share/portage/config/repos.conf etc/portage/repos.conf/gentoo.conf
rm -f etc/portage/make.profile

(cd etc/portage && \
ln -s /usr/portage/profiles/default/linux/arm/13.0/armv7a/desktop make.profile)

Copy the world file from the desktop computer and remove all packages which should not be installed on the Pandora system.

cp /var/lib/portage/world var/lib/portage/world
nano var/lib/portage/world


Prepare cross-compilation and QEmu environment

A lot of packages will fail but we will keep going the emerge process and compile the failed packages again with QEmu.

But first update the compiler tools in the target system. They will be needed later in the QEmu environment. If they fail here, try to do it in the QEmu part.

Copy the static QEmu binary to the target system and set up portage for the target system.

cp /usr/bin/qemu-arm usr/bin/.
mkdir -p usr/portage
touch usr/portage/.keep

Do some standard setup for the target system. Copy some personal configurations to the root account.

cp -L /etc/resolv.conf etc/.
cp -r etc/skel/. root/.

cp /root/.bashrc /root/.dir_colors /root/.screenrc /root/.toprc \
/root/.xsession root/.

Some nice tools like htop are worth to install them on the Pandora.

mkdir -m0700 root/.config
cp -r /root/.config/htop root/.config/.

To access the root account with ssh, copy its configuration. This copies the "id_*" files, also. Don't do this if you deliberately take care about security.

cp -r /root/.ssh/. root/.ssh/.

Start cross compilation

Set up a cross compilation environment (use a third shell instance).

bash
export CBUILD=x86_64-pc-linux-gnu
export CHOST=$CROSSDEV_TARGET
export ROOT=$PWD
export PORTAGE_CONFIGROOT=$ROOT
export PS1="($CHOST) $PS1"

Try to cross compile all packages.

$CHOST-emerge -a binutils glibc linux-headers gcc
$CHOST-emerge -a linux-firmware
$CHOST-emerge -ae @world

If one of them fails, save the resume list.

$CHOST-emerge -p --resume | grep "^\[[eb].*\]" | grep -ve "^\[blocks" | \
cut -b 18- | cut -d " " -f1 | awk '{ print("=" $0); }' >tmp/packages.txt

Now go to "Continue cross-compilation with QEmu".

Continue cross-compilation with QEmu

Enter the chroot environment and emerge the failed package again (the first one in the packages.txt file).

The portage tree will be mounted into the target system.

In the chroot environment it might be necessary to switch the compiler. Check if the same version of gcc is used than the cross compiler with "gcc-config -l". Set the correct version before starting "emerge".

mkdir -p $PWD/run/systemd/resolve
cp /run/systemd/resolve/resolv.conf $PWD/run/systemd/resolve/.
mount --rbind /proc $PWD/proc
mount --make-rslave $PWD/proc
mount --rbind /sys $PWD/sys
mount --make-rslave $PWD/sys
mount --rbind /dev $PWD/dev
mount --make-rslave $PWD/dev
mount --rbind /usr/portage $PWD/usr/portage
chroot $PWD /bin/bash
unset CBUILD CHOST ROOT PORTAGE_CONFIGROOT
env-update
source /etc/profile
cd
source ./.bashrc
export PS1="(chroot) $PS1"
emerge -aB1 $(head -1 /tmp/packages.txt)
exit
umount -l usr/portage
umount -l dev sys proc

After fixing the failed package(s), continue with the cross compiler.

cat tmp/packages.txt | xargs $CHOST-emerge -1

If one of them fails again, save the resume list.

$CHOST-emerge -p --resume | grep "^\[[eb].*\]" | grep -ve "^\[blocks" | \
cut -b 18- | cut -d " " -f1 | awk '{ print("=" $0); }' >tmp/packages.txt
  • Go back to "Continue cross-compilation with QEmu" until all packages are merged

successfully.*

Remove some leftover temporary files.

rm -rf /var/tmp/portage/* /usr/$CROSSDEV_TARGET/var/tmp/portage/* \
/usr/$CROSSDEV_TARGET/tmp/packages.txt


Fix lib64-problem

Some cross compiled packages install their libraries into the "lib64" directory. This is not used on the Pandora. So we have to copy all contents from "lib64" to "lib" and set a link for "lib64".

rsync -avc usr/lib64/. usr/lib/.
rm -rf usr/lib64
(cd usr && ln -s lib lib64)


Configure system

Set the key map for Pandora in the console and, as usual in Gentoo, configure the target system.

Use to make the Pandora keyboard work on the console. (keymap-pandora.map)

And disable the suspend mode for handling the lid switch (this does currently not work).

cp "$FROM_DIR/keymap-pandora.map" etc/.
chmod 644 etc/keymap-pandora.map
echo >etc/vconsole.conf "KEYMAP=/etc/keymap-pandora.map"
echo >>etc/vconsole.conf "FONT=eurlatgr"
sed -i 's/#HandleLidSwitch=suspend/HandleLidSwitch=ignore/g' etc/systemd/logind.conf

Set up the mount table. Every line in "etc/fstab" will be commented out and new entries added. The file system labels are used to mount the partitions.

sed -ie "s,^/,#/,g" etc/fstab

cat >>etc/fstab <<EOF
LABEL=phlnx_boot        /boot   ext2    noatime                         1 2
LABEL=phlnx_root        /       ext4    errors=remount-ro,noatime       1 1
LABEL=phlnx_home        /home   ext4    noatime,nodev,nosuid            1 2
EOF

Enter the chroot environment again.

mount --rbind /proc $PWD/proc
mount --make-rslave $PWD/proc
mount --rbind /sys $PWD/sys
mount --make-rslave $PWD/sys
mount --rbind /dev $PWD/dev
mount --make-rslave $PWD/dev
mount --rbind /usr/portage $PWD/usr/portage
chroot $PWD /bin/bash
unset CBUILD CHOST ROOT PORTAGE_CONFIGROOT
env-update
source /etc/profile
cd
source ./.bashrc
export PS1="(chroot) $PS1"

Set a password for root.

passwd

Update the configuration files and read/clear all news from portage.

dispatch-conf
eselect news list
eselect news read
eselect news purge

Enter the time zone and generate the locale info you want (example: enable all lines with en_US and de_DE).

echo "Europe/Berlin" >/etc/timezone
emerge --config sys-libs/timezone-data
nano -w /etc/locale.gen
locale-gen

Use en_US.utf8 (entry #9) as locale.

eselect locale list
eselect locale set 9

Set up mount table, the machine ID and host name.

ln -sf /proc/self/mounts /etc/mtab
systemd-machine-id-setup
echo >/etc/machine-info "PRETTY_HOSTNAME=Pherkad"
echo >/etc/hostname "pherkad"
ln -snf /run/systemd/resolve/resolv.conf /etc/resolv.conf
systemctl enable systemd-resolved.service

Exit the chroot environment.

exit
umount -l usr/portage
umount -l dev sys proc

Remove the QEmu binary. It is not used anymore.

rm usr/bin/qemu-arm

Also remove some leftovers from the cross compiler and the link to our kernel sources.

rm -f etc/portage/profile/package.provided
rm -f sys-include
rm -f usr/src/linux

Copy back the target system and restore the previous cross compiler state.

cd "$FROM_DIR"
mkdir $CROSSDEV_TARGET
rsync -a /usr/$CROSSDEV_TARGET/. $CROSSDEV_TARGET/.
rm -rf /usr/$CROSSDEV_TARGET
tar -xpjf ${CROSSDEV_TARGET}-saved.tar.bz2 -C /usr
rm ${CROSSDEV_TARGET}-saved.tar.bz2

Exit the root shell.

exit

Update system

To update the system, use a similar approach as in the cross compilation phase. Define CROSSDEV_TARGET as in "Install cross compiling system".


Start cross-compilation

Set up a cross compilation environment (become root and use a second shell instance again).

cd CrossDev
su
umask 0022
tar -cpjf ${CROSSDEV_TARGET}-saved.tar.bz2 -C /usr $CROSSDEV_TARGET
rm -rf /usr/$CROSSDEV_TARGET
mkdir /usr/$CROSSDEV_TARGET
rsync -a $CROSSDEV_TARGET/. /usr/$CROSSDEV_TARGET/.
exit

Check status of our own modifications and stash them. Update the kernel.

cd gta04-kernel
git status
git stash push
git pull
git stash pop

Compile and install the kernel.

bash
umask 0022
export ARCH=arm CROSS_COMPILE=${CROSSDEV_TARGET}-
export PS1="($ARCH) $PS1"
make oldconfig
make menuconfig
export CPUS="$(grep processor /proc/cpuinfo | wc -l)"
make -j$CPUS zImage
make -j$CPUS modules
make omap3-pandora-600mhz.dtb

mkimage -A arm -O linux -T kernel -C none -a 0x80008000 -e 0x80008000 -n \
'Linux-pherkad' -d arch/arm/boot/zImage arch/arm/boot/uImage

cat >boot.txt <<EOF
if itest.w *0x4830a204 == 0x102f
then
    setenv devicetree omap3-pandora-1ghz
else
    setenv devicetree omap3-pandora-600mhz
fi
setenv defaultdisplay lcd
setenv bootargs "init=/lib/systemd/systemd quiet splash \
root=/dev/mmcblk0p2 rootfstype=ext4 rootwait ro resume=/dev/mmcblk0p3"
ext2load mmc 0:1 0x825f0000 /boot/\${devicetree}.dtb
ext2load mmc 0:1 0x80300000 /boot/uImage-pherkad
bootm 0x80300000 - 0x825f0000
EOF

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

exit
su
umask 0022
cp arch/arm/boot/uImage /usr/$CROSSDEV_TARGET/boot/uImage-pherkad
cp .config /usr/$CROSSDEV_TARGET/boot/config-pherkad
cp System.map /usr/$CROSSDEV_TARGET/boot/System.map-pherkad
cp arch/arm/boot/dts/omap3-pandora-600mhz.dtb /usr/$CROSSDEV_TARGET/boot/.
cp boot.scr /usr/$CROSSDEV_TARGET/boot/.
rm -rf /usr/$CROSSDEV_TARGET/lib/modules/*

make ARCH=arm CROSS_COMPILE=${CROSSDEV_TARGET}- \
INSTALL_MOD_PATH=/usr/$CROSSDEV_TARGET modules_install

(DIR="$PWD"; cd /usr/$CROSSDEV_TARGET/usr/src; ln -s $DIR linux)
cd ..

Prepare cross development system.

export FROM_DIR="$PWD"
cd /usr/$CROSSDEV_TARGET
cp /usr/bin/qemu-arm usr/bin/.
bash
export CBUILD=x86_64-pc-linux-gnu
export CHOST=$CROSSDEV_TARGET
export ROOT=$PWD
export PORTAGE_CONFIGROOT=$ROOT
export PS1="($CHOST) $PS1"

Clean up unused binary packages, optionally install new packages and start updating all installed packages by cross compilation.

eclean -d packages
$CHOST-emerge -a <pkgs>

and/or

$CHOST-emerge -auDN --with-bdeps=y @world

If one of them fails, save the resume list.

$CHOST-emerge -p --resume | grep "^\[[eb].*\]" | grep -ve "^\[blocks" | \
cut -b 18- | cut -d " " -f1 | awk '{ print("=" $0); }' >tmp/packages.txt

Continue cross-compilation with QEmu.

mkdir -p $PWD/run/systemd/resolve
cp /run/systemd/resolve/resolv.conf $PWD/run/systemd/resolve/.
mount --rbind /proc $PWD/proc
mount --make-rslave $PWD/proc
mount --rbind /sys $PWD/sys
mount --make-rslave $PWD/sys
mount --rbind /dev $PWD/dev
mount --make-rslave $PWD/dev
mount --rbind /usr/portage $PWD/usr/portage
chroot $PWD /bin/bash
unset CBUILD CHOST ROOT PORTAGE_CONFIGROOT
env-update
source /etc/profile
cd
source ./.bashrc
export PS1="(chroot) $PS1"
emerge -aB1 $(head -1 /tmp/packages.txt)
exit
umount -l usr/portage
umount -l dev sys proc

After fixing the failed package(s), continue with the cross compiler.

cat tmp/packages.txt | xargs $CHOST-emerge -1

If one of them fails again, save the resume list.

$CHOST-emerge -p --resume | grep "^\[[eb].*\]" | grep -ve "^\[blocks" | \
cut -b 18- | cut -d " " -f1 | awk '{ print("=" $0); }' >tmp/packages.txt

Go back to "Continue cross-compilation with QEmu" until all packages are merged successfully.

Update the configuration files and read/clear all news from portage. Remove some leftovers temporary files and exit the cross compilation environment.

$CHOST-emerge -a --depclean

Enter the chroot environment, fix all missing dynamics and edit updated configurations.

mount --rbind /proc $PWD/proc
mount --make-rslave $PWD/proc
mount --rbind /sys $PWD/sys
mount --make-rslave $PWD/sys
mount --rbind /dev $PWD/dev
mount --make-rslave $PWD/dev
mount --rbind /usr/portage $PWD/usr/portage
chroot $PWD /bin/bash
unset CBUILD CHOST ROOT PORTAGE_CONFIGROOT
env-update
source /etc/profile
cd
source ./.bashrc
export PS1="(chroot) $PS1"
revdep-rebuild -i -- -a --usepkg=n
dispatch-conf
eselect news list
eselect news read
eselect news purge
emaint --check all

If something is reported wrong by "emain", fix it.

emaint --fix <...>

Check if everything is OK.

eix-test-obsolete -b

Read any messages from portage.

eread
exit
umount -l usr/portage
umount -l dev sys proc

Remove some leftover temporary files and QEmu.

rm -rf /var/tmp/portage/* /usr/$CROSSDEV_TARGET/var/tmp/portage/* \
/usr/$CROSSDEV_TARGET/tmp/packages.txt

rm -rf /usr/$CROSSDEV_TARGET/run/systemd
rm -f usr/src/linux
rm usr/bin/qemu-arm
exit

Copy back the target system and restore the previous cross compiler state.

cd "$FROM_DIR"
rsync -a /usr/$CROSSDEV_TARGET/. $CROSSDEV_TARGET/.
rm -rf /usr/$CROSSDEV_TARGET
tar -xpjf ${CROSSDEV_TARGET}-saved.tar.bz2 -C /usr
rm ${CROSSDEV_TARGET}-saved.tar.bz2
exit


Optional: Remove cross compiler

If the cross build system is no more used, it can be removed by the following commands.

su
crossdev --clean $CROSSDEV_TARGET
rm -rf /usr/portage/packages/x86_64-pc-linux-gnu/cross-$CROSSDEV_TARGET
emaint --fix binhost
emaint --fix world
rm -rf /usr/local/portage-crossdev
rm -rf /usr/libexec/gcc/$CROSSDEV_TARGET
rm -rf /usr/bin/${CROSSDEV_TARGET}*
rm -f /etc/portage/repos.conf/crossdev.conf
rm -f /etc/portage/categories
emerge --depclean crossdev
rm /usr/bin/repositories_configuration-*
exit


Create SD-card partitions phlnx_boot/root/swap/home

Finally the target system is done. Now it's time to copy it to the Pandora.


Pandora

It's recommended to partition the SD-card for the target system on the Pandora. Otherwise the boot loader might refuse to work.

Insert the SD-card in the left slot (mmcblk0) and unmount it if necessary.

Create the following partitions:

  • A boot partition (ext2).
  • A root partition which will contain the target system (at least 4 GB).
  • A home partition which we can use later.
  • A SWAP partition which we can use later.
sudo -s

/sbin/fdisk /dev/mmcblk0
    Create new DOS partition label: o
    Create new partition: n p 1 Return +8M
    Create new partition: n p 2 Return +4G
    Create new partition: n p 3 Return +1G
    Change partition type: t 3 82 (Linux swap)
    Create new partition: n p Return Return
    Write all changes: w

/sbin/mkfs.ext2 -FL phlnx_boot /dev/mmcblk0p1
/sbin/mkfs.ext4 -FL phlnx_root -O ^has_journal /dev/mmcblk0p2
/sbin/mkswap -L phlnx_swap /dev/mmcblk0p3
/sbin/mkfs.ext4 -FL phlnx_home -O ^has_journal /dev/mmcblk0p4
exit


Option #1: Copy target system to SD-card

One of the possibilities to copy the target system to the SD-card on the Pandora is to use a USB cable connecting the Pandora to the desktop computer.

It's also possible to copy it via the WiFi network (see below).


Pandora

Connect the Pandora via USB to the desktop computer. Insert the SD-card in the left slot (mmcblk0). Use menu "System/SD-Mass Storage" to access partition "phlnx_root".


Desktop computer

Mount the root partition and copy the target system. Use the correct "/dev/sd*".

su
mkdir /tmp/mnt
mount /dev/sdc /tmp/mnt
mkdir -p /tmp/mnt/boot
touch /tmp/mnt/boot/.keep
mkdir -p /tmp/mnt/home
touch /tmp/mnt/home/.keep

rsync -av --delete --exclude lost+found --exclude /boot \
CrossDev/$CROSSDEV_TARGET/. /tmp/mnt/.

umount /tmp/mnt


Pandora

Use "System/SD-Mass Storage" again to access phlnx_boot.


Desktop computer

Mount the boot partition and copy boot directory of the target system.

mount /dev/sdc /tmp/mnt
rm -f /tmp/mnt/uImage-pherkad

rsync -av --delete --exclude lost+found \
CrossDev/$CROSSDEV_TARGET/boot/. /tmp/mnt/.

umount /tmp/mnt
rmdir /tmp/mnt
exit


Pandora

End SD-Mass Storage.


Option #2: Copy target system to SD-card via WiFi network

Pandora

Copy all files from the desktop computer to the SD-card partitions. Use the same CROSSDEV_TARGET and FROM_DIR environment settings as on the desktop computer.

sudo -s
export REMOTE=mizar.spdns.de
export FROM_DIR=/home/jgeiss/Data/Systems/Pandora/Pherkad/Linux/Gentoo/CrossDev
export CROSSDEV_TARGET=armv7a-hardfloat-linux-gnueabi

mkdir -p /media/phlnx_root/boot
touch /media/phlnx_root/boot/.keep

rsync -av --numeric-ids --delete --exclude lost+found --exclude /boot \
$REMOTE:$FROM_DIR/$CROSSDEV_TARGET/. /media/phlnx_root/.

rsync -av --delete --exclude lost+found \
$REMOTE:$FROM_DIR/$CROSSDEV_TARGET/boot/. /media/phlnx_boot/.

exit


Boot the new system

Reboot the Pandora and hold the right shoulder button until the boot menu appears.

Sometimes it is necessary to switch off the Pandora for 10-60 seconds.

Choose "boot from SD1:1".

It the boot works well, login as root and play around.


Optional: USB-networking

To use networking to the desktop computer via USB cable, execute the following commands on both systems.


Pandora

modprobe g_ether
ifconfig usb0 192.168.129.3 netmask 255.255.255.0
route add default gw 192.168.129.2
systemctl start sshd


Desktop computer

Configure the corresponding network interface.

ifconfig enp0s20u1u1 192.168.129.2 netmask 255.255.255.0

Now you should be able to connect to the Pandora.

ssh root@192.168.129.3


Shutdown Pandora

To shutdown the Pandora system enter the following command.

systemctl poweroff


Open issues

The following things are currently not working and need to be implemented/fixed:

  • WiFi interface is missing
  • twl: not initialized
  • omapfb omapfb: no displays, failed to setup omapfb
  • omap2_set_init_voltage: unable to find boot up OPP vor ...
  • __nand_correct_data: uncorrectable ECC error
  • Buffer I/O error on dev mtdblock0, logical block 0, async page read
  • Kernel panic at system shutdown