Linux Mainline en CHIP
Compilé Linux mainline para la CHIP.En este texto cuento como fue el proceso que llevé a cabo para compilar linux mainline para la CHIP desde la primera vez que la enchufé.
CHIP es una computadora single-board fabricada por Next Thing Co. (NTC), lanzado como open-source hardware corriendo open-source software. Fue anunciado como “la primera computadora del mundo de $ 9”. Mas info en Wikipedia.
Tabla de contenidos
Flasheando
La primera vez que alimenté a la CHIP los leds prendian, pero no tenía salida de video. Usé el script de la siguiente guía para flashearla.
http://www.chip-community.org/index.php/Flash_from_command_line
Otra guía para flashear sin conexión y en español (por Alejandro Gaut): https://gitlab.com/snippets/1866690
Luego de flashearla, los leds empezaron a parpadear, pero seguía sin video, a prueba y error, descubrí que debía conectar la salida de audio R del RCA (roja) a la entrada de video (amarilla).
Una vez que el Debian de NTC booteó, y luego de jugar un buen rato a Celeste Classic, empecé a compilar linux mainline.
Compilar
Pasos sacados de aqui.
Cross compiling toolchain:
sudo apt-get install gcc-arm-linux-gnueabihf binutils-arm-linux-gnueabihf
Linux Mainline:
git clone git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
# sino sólo el último commit
git clone --depth 1 git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
Kernel config:
cp arch/arm/configs/sunxi_defconfig .config
Configurar kernel:
make ARCH=arm CROSS_COMPILE=/usr/bin/arm-linux-gnueabihf- menuconfig
No se si esto es tan importante:
IMPORTANT: add a local version suffix. Follow the menus:
General setup --->
() Local version - append to kernel release
Compilar kernel:
make -j13 ARCH=arm CROSS_COMPILE=/usr/bin/arm-linux-gnueabihf-
El parametro -j debería ser el numero de cores de tu procesador + 1.
Modulos (tal vez esto no sea necesario):
export WORKSPACE=./build
make ARCH=arm CROSS_COMPILE=/usr/bin/arm-linux-gnueabihf- INSTALL_MOD_PATH=$WORKSPACE modules_install
Esto instalará los modulos en $WORKSPACE/lib
(después será copiado a la CHIP).
Mover
Elimina los symlinks build
y source
de lib/
porque [s]cp -r
los seguirá.
export RELEASE=5.2.0-rc1vv1
unlink lib/modules/$RELEASE/build
unlink lib/modules/$RELEASE/source
Ahora tendrás que configurar un servidor ssh en la CHIP, no debería ser muy complicado.
Copiá todo a un directorio temporal a la CHIP:
scp arch/arm/boot/dts/sun5i-r8-chip.dtb chip@chip:tmp
scp -r build/lib/modules/$RELEASE arch/arm/boot/zImage .config System.map chip@chip:tmp
Y luego movelo a donde corresponda:
workspace source location | destination on CHIP |
---|---|
arch/arm/boot/zImage | /boot/vmlinuz-$RELEASE |
.config | /boot/config-$RELEASE |
System.map | /boot/System.map-$RELEASE |
lib/modules/$RELEASE | /lib/modules/$RELEASE |
Conectando
Pasos sacado de aquí.
Necesitamos un cable USB-UART y conectarlo como se debe. (TODO: Agregar foto)
- Ground pin 1
- TX pin 3
- RX pin 5
CABLE ROJO NO, nada de +5v.
Luego instalar screen:
sudo apt-get install screen
Conecta el lado del USB a la pc, y lanza screen:
screen /dev/ttyUSB0 115200
Chequeá la salida de ls /dev/tty*
antes y despues de conectar la CHIP para
encontar el archivo correcto.
Si te sale
screen is terminating error
, probá con:
sudo screen /dev/ttyUSB0 115200
Ahora bootea tu CHIP (conectala a la alimentación).
Tenes 3 segundos para parar el proceso de booteo y tener acceso a la shell de u-boot.
U-Boot SPL 2016.01-00088-g99c771f (Dec 09 2016 - 22:29:06)
DRAM: 512 MiB
CPU: 1008000000Hz, AXI/AHB/APB: 3/2/2
Trying to boot from NAND
U-Boot 2016.01-00088-g99c771f (Dec 09 2016 - 22:29:06 +0000) Allwinner Technology
CPU: Allwinner A13 (SUN5I)
I2C: ready
DRAM: 512 MiB
NAND: 8192 MiB
video-mode 720x480-24@60 not available, falling back to 1024x768-24@60
Setting up a 720x480i composite-ntsc console (overscan 40x20)
In: serial
Out: serial
Err: serial
Net: usb_ether
starting USB...
No controllers found
Hit any key to stop autoboot: 0
=>
Booteando
La memoria NAND MLC que tiene la CHIP no está soportada en Linux Mainline.
Por lo que lo siguiente va a tirar kernel panic porque no encuentra un rootfs
.
Pero, técnicamente, Linux arranca.
La solución, es bootear con un rootfs a través de NFS por usb, en modo usb-device-ethernet, que está en la siguiente sección.
Los pasos para bootear serían:
editenv bootcmd
# cambiar `for path in ${bootpaths}; do run boot_$path; done` por `run boot_noinitrd`
editenv boot_noinitrd
# cambiar el path del kernel `/boot/zImage` a `/boot/vmlinuz-$RELEASE`
run boot
Para copypastear (cambiá el valor de $RELEASE
):
setenv bootcmd "run test_fastboot; if test -n ${fel_booted} && test -n ${scriptaddr}; then echo (FEL boot); source ${scriptaddr}; fi; run boot_noinitrd"
setenv boot_noinitrd "mtdparts; ubi part UBI; ubifsmount ubi0:rootfs; ubifsload $fdt_addr_r /boot/sun5i-r8-chip.dtb; ubifsload $kernel_addr_r /boot/vmlinuz-$RELEASE; bootz $kernel_addr_r - $fdt_addr_r"
run boot
Rootfs
Usé debootstrap:
sudo apt install debootstrap
Generar el rootfs para la CHIP (armhf = 32bits):
mkdir /nfs/chip
cd /nfs/chip
debootstrap --arch armhf stable chip http://deb.debian.org/debian/
NFS
Pasos sacados de aquí.
NFS server:
cat /etc/exports
/nfs/chip 192.168.0.0/16(rw,sync)
Iniciar el servidor
sudo systemctl restart nfs-server.service
IPs
Bootear en Debian de NTC para chequear el servidor NFS.
Cuando conecto la CHIP, me aparece una nueva interfaz de red usb0,
que udev la renombra a enp3s0f0u1 (ver dmesg | tail
).
En el server (server~seven~7):
sudo ip addr add 192.168.1.7/24 dev enp3s0f0u1
En la CHIP (chip~two~2):
sudo ip addr add 192.168.1.2/24 dev usb0
Chequear ping de una maquina a otra, y si va bien:
sudo mount 192.168.1.7:/nfs/chip tmp/
Nuestro servidor NFS está andando, ahora sólo hay que compilar nuestro Linux
con soporte usb ethernet (g_ether
).
Recompilar
Pasos sacados de aquí.
Activar USB_ETH
con menuconfig
.
Symbol: USB_ETH [=m]
Prompt: Ethernet Gadget (with CDC Ethernet support)
Defined at drivers/usb/gadget/Kconfig:628
Depends on: <choice> && NET
Location:
-> Kernel configuration
-> Device Drivers
-> USB support (USB_SUPPORT [=y])
-> USB Gadget Support (USB_GADGET [=y])
-> USB Gadget Drivers (<choice> [=m])
Compilar, copiar y mover como antes.
Bootear posta
Reiniciar la CHIP (sudo reboot
) y parar U-Boot.
Con setenv definir:
setenv g_ether.dev_addr de:ad:be:af:00:01
setenv g_ether.host_addr de:ad:be:af:00:00
setenv ip 192.168.1.2:192.168.1.7::255.255.255.0:chip:usb0:none
setenv nfsroot 192.168.1.7:/nfs/chip
setenv nfsload mtdparts; ubi part UBI; ubifsmount ubi0:rootfs; ubifsload $fdt_addr_r /boot/sun5i-r8-chip-ml.dtb; ubifsload $kernel_addr_r /boot/vmlinuz-$RELEASE
setenv nfsargs setenv bootargs root=/dev/nfs rw nfsroot=${nfsroot},v3 ip=${ip} rootfstype=nfs g_ether.dev_addr=${g_ether.dev_addr} g_ether.host_addr=${g_ether.host_addr} rootwait
setenv nfs_bootcmd "run nfsload ; run nfsargs ; bootz $kernel_addr_r - $fdt_addr_r"
Podes guardar las variables permanentemente con
saveenv
.
Y finalmente, bootear con:
run nfs_bootcmd
# uname -a
Linux chip 5.2.0-rc1vv1-gf49aa1de9 #5 SMP Fri May 24 18:07:53 -03 2019 armv7l GNU/Linux
El log completo se encuentra acá.