This page looks best with JavaScript enabled

Gentoo Raspberrypi Installation

 ·  🎃 kr0m

Let’s install Gentoo on our Raspberrypi, it’s just a proof of concept since binary compilation takes too long on this hardware. In future articles, we will explain how to compile using distcc and cross-dev ;)

We generate the necessary partitions:

fdisk -l /dev/mmcblk0

Disposit. Inicio Comienzo Fin Bloques Id Sistema
/dev/mmcblk0p1 * 2048 1050623 524288 c W95 FAT32 (LBA)
/dev/mmcblk0p2 1050624 2099199 524288 82 Linux swap / Solaris
/dev/mmcblk0p3 2099200 61497343 29699072 83 Linux

NOTE: The minimum size of a FAT32 partition is 512Mb.

We create the boot, swap, and root file systems:

mkfs.msdos -F 32 /dev/mmcblk0p1 -n Boot
mkswap /dev/mmcblk0p2
swapon /dev/mmcblk0p2
mkfs.ext4 /dev/mmcblk0p3

We mount the partitions:

mount /dev/mmcblk0p3 /mnt/rpigentoo/
mkdir -p /mnt/rpigentoo/boot
mount /dev/mmcblk0p1 /mnt/rpigentoo/boot
cd /mnt/rpigentoo

We download the stage:

wget http://distfiles.gentoo.org/releases/arm/autobuilds/current-stage3-armv6j_hardfp/stage3-armv6j_hardfp-20140605.tar.bz2
tar xvjpf stage3-armv6j_hardfp-20140605.tar.bz2
rm stage3-armv6j_hardfp-20140605.tar.bz2

We download the portage:

wget distfiles.gentoo.org/snapshots/portage-latest.tar.bz2
tar xvjf portage-latest.tar.bz2 -C /mnt/rpigentoo/usr/
rm portage-latest.tar.bz2

We download the Rasp firmware files:

cd /mnt/rpigentoo/tmp
git clone –depth 1 git://github.com/raspberrypi/firmware/
cd firmware/boot
cp * /mnt/rpigentoo/boot/
cp -r ../modules /mnt/rpigentoo/lib/
cd /mnt/rpigentoo/
rm -rf /mnt/rpigentoo/tmp/firmware

We chroot:

Now we must chroot to our Rasp root dir, but it is not possible to chroot from a different architecture, AMD64 –> ARM.

Therefore, we will make a workaround using qemu, which will execute the commands inside the chroot emulating the ARM architecture.

For this to work, we must have the following enabled in the kernel:

Executable file formats / Emulations ---> [*] Kernel support for MISC binaries

Once the chroot is done, the OS no longer knows anything about the previous system. In reality, a binary from the outside is being executed, in this case qemu inside a chroot with ARM architecture. When executing the commands, q-emu will look for AMD64 q-emu libraries in the chroot (ARM). To avoid this, we will compile q-emu statically. Compiling qemu statically in Gentoo can be complicated, so we will download the Debian version and extract the statically compiled qemu binary using alien:
http://http.us.debian.org/debian/pool/main/q/qemu/

We extract the deb:

alien -t qemu-user-static_1.6.0+dfsg-2_amd64.deb
mkdir qemu-user-static
cd qemu-user-static
mv ../qemu-user-static-1.6.0+dfsg.tgz ./
tar xvzf qemu-user-static-1.6.0+dfsg.tgz

We will configure our OS so that when it detects that a binary compiled for the ARM architecture is being executed, it does so through qemu. We will execute a wrapper that in turn will execute /opt/qemu-arm-rpi/qemu-arm.

The steps that will be executed are:

chroot /bin/bash -- This bash is ARM --> /opt/qemu-arm-rpi/qemu-wrapper --> /opt/qemu-arm-rpi/qemu-arm

We copy the ARM interpreter:

mkdir -p /mnt/rpigentoo/opt/qemu-arm-rpi/
cp ./usr/bin/qemu-arm-static /mnt/rpigentoo/opt/qemu-arm-rpi/qemu-arm

We compile the wrapper:

vi /mnt/rpigentoo/opt/qemu-arm-rpi/qemu-wrapper.c


#include <string.h>
#include <unistd.h>

int main(int argc, char **argv, char **envp) {
char *newargv[argc + 3];
newargv[0] = argv[0];
newargv[1] = "-cpu";
newargv[2] = "arm1176";
memcpy(&newargv[3], &argv[1], sizeof(*argv) * (argc - 1));
newargv[argc + 2] = NULL;
return execve("/opt/qemu-arm-rpi/qemu-arm", newargv, envp);
}
cd /mnt/rpigentoo/opt/qemu-arm-rpi/
gcc -static qemu-wrapper.c -o qemu-wrapper

We configure the OS to execute the wrapper in case it is ARM:

If you have Kernel support for MISC binaries as a module:

[ -d /proc/sys/fs/binfmt_misc ] || modprobe binfmt_misc
[ -f /proc/sys/fs/binfmt_misc/register ] || mount binfmt_misc -t binfmt_misc /proc/sys/fs/binfmt_misc
echo ‘:arm_rpi:M::x7fELFx01x01x01x00x00x00x00x00x00x00x00x00x02x00x28x00:xffxffxffxffxffxffxffx00xffxffxffxffxffxffxffxffxfexffxffxff:/opt/qemu-arm-rpi/qemu-wrapper:’ > /proc/sys/fs/binfmt_misc/register

Prepare the chroot environment:

cp -L /etc/resolv.conf /mnt/rpigentoo/etc/
mount -t proc proc /mnt/rpigentoo/proc
mount -t sysfs sysfs /mnt/rpigentoo/sys
mount -o bind /dev /mnt/rpigentoo/dev
mount –rbind /sys /mnt/rpigentoo/sys
mount –rbind /dev /mnt/rpigentoo/dev

Enter:

chroot /mnt/rpigentoo /bin/bash
env-update
source /etc/profile
export PS1="(Im_IN) $PS1"

NOTE: If we experience memory problems, we must define the variable: QEMU_RESERVED_VA

export QEMU_RESERVED_VA=“0xf7000000”

Configure Gentoo normally:

emerge –sync
eselect profile list
eselect profile set 23

default/linux/arm/13.0/armv6j
nano -w /etc/portage/make.conf
USE="-X -gnome -kde -ipv6 -mono -doc -java -fortran -openmp"
cp /usr/share/zoneinfo/Europe/Madrid /etc/localtime

Define the boot config parameters:

nano -w /boot/cmdline.txt

dwc_otg.lpm_enable=0 console=ttyAMA0,115200 kgdboc=ttyAMA0,115200 console=tty1 root=/dev/mmcblk0p3 rootfstype=ext4 elevator=deadline rootwait

Continue with the system config:

nano -w /etc/fstab

/dev/mmcblk0p1 /boot vfat auto,noatime 1 2
/dev/mmcblk0p3 / ext4 noatime 0 1
/dev/mmcblk0p2 none swap sw 0 0
nano -w /etc/conf.d/hostname
nano -w /etc/conf.d/net
config_eth0=( "dhcp" )
cd /etc/init.d/
ln -s net.lo net.eth0
rc-update add net.eth0 default
nano -w /etc/hosts
nano -w /etc/rc.conf
nano -w /etc/conf.d/keymaps
rc-update add swclock boot
rc-update del hwclock boot
nano -w /etc/locale.gen
es_ES.utf8 UTF-8
es_ES@euro ISO-8859-15
locale-gen
nano -w /etc/env.d/02locale
LANG="es_ES.utf8"
LC_COLLATE="C"
env-update && source /etc/profile
export PS1="(Im_IN) $PS1"
grep -v rootfs /proc/mounts > /etc/mtab
echo “# Dummy comment to disable new udev naming schema, by Kr0m;)” > /etc/udev/rules.d/80-net-name-slot.rules
emerge syslog-ng
rc-update add syslog-ng default
emerge vixie-cron
rc-update add vixie-cron default
emerge dhcpcd vim
useradd -m -G users,wheel,audio -s /bin/bash USER_NAME
rc-update add sshd default
nano -w /etc/inittab
# SERIAL CONSOLES
#s0:12345:respawn:/sbin/agetty 9600 ttyS0 vt100
#s1:12345:respawn:/sbin/agetty 9600 ttyS1 vt100
emerge -av sys-libs/gpm
rc-update add gpm default
emerge -av gentoolkit portage-utils
/usr/bin/equery list ‘*’ > /etc/portage/package.list
passwd
emerge –update –newuse –deep –ask @world

NOTE: If the gcc version is updated

gcc-config -l
gcc-config 1
env-update && source /etc/profile
export PS1="(Im_IN) $PS1"
emerge –oneshot libtool
etc-update
export PS1="(Im_IN) $PS1"
exit
cd
umount /mnt/rpigentoo/dev
umount /mnt/rpigentoo/sys
umount /mnt/rpigentoo/proc
umount /mnt/rpigentoo/boot
umount /mnt/rpigentoo/
umount binfmt_misc

With this, we will have the SD card ready to plug into the Rasp and work. In future articles, we will explain how to compile using distcc and cross-dev ;)

If you liked the article, you can treat me to a RedBull here