Esta pagina se ve mejor con JavaScript habilitado

Instalación Gentoo Raspberrypi

 ·  🎃 kr0m

Vamos a instalar Gentoo en nuestra Raspberrypi, es solo una prueba de concepto ya que la compilación de los binarios lleva demasiado tiempo en este hardware. En próximos artículos explicaremos como compilar mediante distcc y cross-dev ;)

Generamos las particiones necesarias:

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

NOTA: El mínimo tamaño de una partición FAT32 es de 512Mb

Creamos el sistema de ficheros boot, swap y raíz:

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

Montamos las particiones:

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

Nos bajamos el 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

Nos bajamos el 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

Nos bajamos los ficheros de firmware de la Rasp:

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

Chrooteamos:

Ahora debemos hacer el chroot a nuestro dir root de la Rasp pero no es posible hacer chroot desde una arquitectura distinta a la final, AMD64 –> ARM

Por lo tanto vamos a hacer un workaround mediante qemu, este ejecutará los comandos dentro del chroot emulando la arquitectura ARM.

Para que esto funcione debemos tener habilitado en el kernel:

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

Una vez realizado el chroot el SO ya no sabe nada del sistema anterior, en realidad se está ejecutando un binario del exterior, en este caso qemu dentro de un chroot con arquitectura ARM, al ejecutar los comandos q-emu buscará librerías AMD64 de q-emu en el chroot(ARM), para evitar esto compilaremos q-emu de forma estática. Compilar qemu de forma estática en gentoo puede ser complicado así que vamos a bajarnos la versión de Debian y sacar el binario de qemu compilado estáticamente mediante alien:
http://http.us.debian.org/debian/pool/main/q/qemu/

Destripamos el 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

Vamos a configurar nuestro SO para que cuando detecte que se está ejecutando algún binario compilado para la arquitectura ARM lo haga a través de qemu, nosotros vamos a ejecutar un wrapper que a su vez ejecutará /opt/qemu-arm-rpi/qemu-arm.

Los pasos que se ejecutarán son:

chroot /bin/bash -- Este bash es ARM --> /opt/qemu-arm-rpi/qemu-wrapper --> /opt/qemu-arm-rpi/qemu-arm

Copiamos el interprete de ARM:

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

Compilamos el 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

Configuramos el SO para que ejecute el wrapper en caso de ser ARM:

En caso de tener Kernel support for MISC binaries como módulo:

[ -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

Preparamos el entorno chroot:

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

Entramos:

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

NOTA: Si experimentamos problemas de memoria deberemos definir la variable: QEMU_RESERVED_VA

export QEMU_RESERVED_VA=“0xf7000000”

Configuramos la gentoo de forma normal:

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

Definimos los parámetros de config de arranque:

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

Continuamos con la config del sistema:

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

NOTA: Si se actualiza la versión de gcc

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

Con esto ya tendremos la SD lista para enchufar a la Rasp y funcionar, en próximos artículos explicaremos como compilar mediante distcc y cross-dev ;)

Si te ha gustado el artículo puedes invitarme a un RedBull aquí