{"id":1609,"date":"2015-07-19T10:11:30","date_gmt":"2015-07-19T10:11:30","guid":{"rendered":"http:\/\/blog.rastersoft.com\/?p=1609"},"modified":"2016-06-04T19:01:58","modified_gmt":"2016-06-04T19:01:58","slug":"generando-gentoo-para-el-webtv","status":"publish","type":"post","link":"https:\/\/blog.rastersoft.com\/?p=1609","title":{"rendered":"Generando Gentoo para el WebTV"},"content":{"rendered":"<p>Nota: actualizado el parche para BusyBox.<\/p>\n<p>Estos d\u00edas estoy bastante liado con el <em>trabajo-que-paga-las-facturas<\/em>, pero por suerte he podido sacar un rato para cacharrear. Me he puesto con el WebTV (que tengo bastante abandonado desde que me compr\u00e9 la Raspberry Pi) y he decidido intentar meter un sistema \u00abdecente\u00bb. \u00bfA qu\u00e9 me refiero? Pues a que, por defecto, la m\u00e1xima versi\u00f3n de Debian que puede correr es wheezy, que ya es old-stable. La estable actual (jessie) necesita un n\u00facleo m\u00e1s reciente, y se niega a trabajar con el que trae el WebTV (2.6.22).<\/p>\n<p>Ante esto decid\u00ed probar con Gentoo, a ver si consegu\u00eda compilarlo todo. A continuaci\u00f3n indicar\u00e9 como lo hice.<\/p>\n<p>NOTA: para los que no quieran leerse este tocho, en mi web est\u00e1 disponible <a href=\"http:\/\/www.rastersoft.com\/descargas\/entorno_gentoo_mipsel_webtv.tar.bz2\">este entorno Gentoo completo para WebTV, ya compilado y listo para usar<\/a>.<\/p>\n<p>Para empezar, me baj\u00e9 la <a href=\"http:\/\/distfiles.gentoo.org\/releases\/amd64\/autobuilds\/current-stage3-amd64\/\" target=\"_blank\">stage 3 de Gentoo para X86_64<\/a>, baj\u00e9 tambi\u00e9n la <a href=\"http:\/\/distfiles.gentoo.org\/snapshots\/\" target=\"_blank\">\u00faltima lista de paquetes de portage<\/a>, y descomprim\u00ed \u00e9sta \u00faltima en <em>\/usr<\/em> de la stage 3. Con ello ya pude lanzar un contenedor de gentoo con<\/p>\n<div class=\"mycode\">\n<pre class=\"mycode\">sudo systemd-nspawn -D \/directorio\/con\/la\/stage3 \/bin\/bash<\/pre>\n<\/div>\n<p>Aqu\u00ed toca primero preparar el sistema para hacer crossdev. Esto se puede repasar en una entrada anterior: <a href=\"https:\/\/blog.rastersoft.com\/?p=292\">Emergiendo<\/a>.<\/p>\n<p>Una vez dentro intent\u00e9 hacer un <em>crossdev<\/em> para compilar una gentoo para <em>mipsel<\/em> usando<\/p>\n<div class=\"mycode\">\n<pre class=\"mycode\">crossdev --kernel 2.6.22 -t mipsel -v<\/pre>\n<\/div>\n<p>Por desgracia fallaba: se empe\u00f1aba en utilizar las cabeceras de la versi\u00f3n 2.4.36. \u00bfQu\u00e9 pasaba? Pues que aunque en los repositorios de Gentoo s\u00ed existen las cabeceras del kernel 2.6.22, \u00e9stas no est\u00e1n disponibles en la lista de <em>ebuilds<\/em> de portage.<\/p>\n<p>Ante esto empec\u00e9 a buscar y probar, y finalmente con la ayuda de la gente de IRC del canal #Gentoo-kernel consegu\u00ed el <a href=\"https:\/\/sources.gentoo.org\/cgi-bin\/viewvc.cgi\/gentoo-x86\/sys-kernel\/linux-headers\/linux-headers-2.6.22-r2.ebuild\" target=\"_blank\"><em>ebuild<\/em> de las cabeceras para la versi\u00f3n 2.6.22-r2<\/a>. Sin embargo tuve que grabarlo en <em>\/usr\/portage\/sys-kernel\/linux-headers<\/em> con el nombre <em>linux-headers-2.6.22-r3<\/em>, pues la R3 es la versi\u00f3n disponible en el repositorio.<\/p>\n<p>Tras ello actualic\u00e9 el fichero <em>Manifest<\/em> para que encontrase el nuevo <em>ebuild<\/em> con<\/p>\n<div class=\"mycode\">\n<pre class=\"mycode\">ebuild \/usr\/portage\/sys-kernel\/linux-headers\/linux-headers-2.6.22-r3.ebuild manifest<\/pre>\n<\/div>\n<p>Prob\u00e9 de nuevo a generar el <em>crossdev<\/em> pero segu\u00eda intentando usar la versi\u00f3n 2.4.36&#8230; porque la versi\u00f3n 2.6.22-r3 es posterior a la 2.6.22 <em>a secas<\/em>. Cambiando el par\u00e1metro en <em>crossdev<\/em> solucion\u00f3 el problema.<\/p>\n<div class=\"mycode\">\n<pre class=\"mycode\">crossdev --kernel 2.6.22-r3 -t mipsel -v<\/pre>\n<\/div>\n<p>Por desgracia, ahora me encontraba con otro: ocurr\u00eda un error durante la instalaci\u00f3n de las cabeceras:<\/p>\n<div class=\"mycode\">\n<pre class=\"mycode\">HOSTCC  scripts\/unifdef\r\nscripts\/unifdef.c:209:25: error: conflicting types for 'getline'\r\n static Linetype         getline(void);\r\n                         ^\r\nIn file included from scripts\/unifdef.c:70:0:\r\n\/usr\/include\/stdio.h:678:20: note: previous declaration of 'getline' was here\r\n extern _IO_ssize_t getline (char **__restrict __lineptr,\r\n                    ^\r\nscripts\/Makefile.host:118: recipe for target 'scripts\/unifdef' failed\r\nmake[1]: *** [scripts\/unifdef] Error 1\r\nMakefile:927: recipe for target 'headers_install' failed\r\nmake: *** [headers_install] Error 2\r\nemake failed<\/pre>\n<\/div>\n<p>Tocaba buscar m\u00e1s soluciones. Afortunadamente esta era sencilla: bastaba con editar el fichero <em>unifdef.c<\/em> y sustituir todas las ocurrencias de <em>getline<\/em> por otra cosa, como por ejemplo <em>get_line<\/em>. Prepar\u00e9 el siguiente parche para ello:<\/p>\n<div class=\"mycode\">\n<pre class=\"mycode\">--- a\/scripts\/unifdef.c\r\n+++ b\/scripts\/unifdef.c\r\n@@ -206,7 +206,7 @@ static void             done(void);\r\n static void             error(const char *);\r\n static int              findsym(const char *);\r\n static void             flushline(bool);\r\n-static Linetype         getline(void);\r\n+static Linetype         get_line(void);\r\n static Linetype         ifeval(const char **);\r\n static void             ignoreoff(void);\r\n static void             ignoreon(void);\r\n@@ -512,7 +512,7 @@ process(void)\r\n \r\n \tfor (;;) {\r\n \t\tlinenum++;\r\n-\t\tlineval = getline();\r\n+\t\tlineval = get_line();\r\n \t\ttrans_table[ifstate[depth]][lineval]();\r\n \t\tdebug(\"process %s -&gt; %s depth %d\",\r\n \t\t    linetype_name[lineval],\r\n@@ -526,7 +526,7 @@ process(void)\r\n  * help from skipcomment().\r\n  *\/\r\n static Linetype\r\n-getline(void)\r\n+get_line(void)\r\n {\r\n \tconst char *cp;\r\n \tint cursym;\r\n<\/pre>\n<\/div>\n<p>Y entonces me encontr\u00e9 con el problema de como aplicarlo durante la generaci\u00f3n del <em>crossdev<\/em>. La cosa no era sencilla, porque se empe\u00f1a en comprobar los valores de <em>sha256, sha512 <\/em>y <em>whirlpool<\/em> de todo lo que baje. En teor\u00eda se pueden a\u00f1adir parches manualmente en <em>\/etc\/portage\/patches<\/em>, pero tras probar de todo no consegu\u00ed que funcionase, as\u00ed que al final fui a la soluci\u00f3n <em>cazurra<\/em> y met\u00ed el comando de parcheado directamente en el <em>ebuild<\/em>. Para ello edit\u00e9 el fichero <em>\/usr\/portage\/sys-kernel\/linux-headers\/linux-headers-2.6.22-r3.ebuild<\/em> y lo dej\u00e9 como sigue:<\/p>\n<div class=\"mycode\">\n<pre class=\"mycode\"># Copyright 1999-2007 Gentoo Foundation\r\n# Distributed under the terms of the GNU General Public License v2\r\n# $Header: \/var\/cvsroot\/gentoo-x86\/sys-kernel\/linux-headers\/Attic\/linux-headers-2.6.22-r2.ebuild,v 1.11 2008\/04\/12 22:24:36 vapier dead $\r\n\r\nETYPE=\"headers\"\r\nH_SUPPORTEDARCH=\"alpha amd64 arm cris hppa m68k mips ia64 ppc ppc64 s390 sh sparc x86\"\r\ninherit kernel-2\r\ndetect_version\r\n\r\necho ${PV}\r\necho ${PATCH_VER}\r\n\r\nPATCH_VER=\"3\"\r\nSRC_URI=\"mirror:\/\/gentoo\/gentoo-headers-base-${PV}.tar.bz2\"\r\n[[ -n ${PATCH_VER} ]] &amp;&amp; SRC_URI=\"${SRC_URI} mirror:\/\/gentoo\/gentoo-headers-${PV}-${PATCH_VER}.tar.bz2\"\r\n\r\nKEYWORDS=\"-* alpha amd64 arm hppa ia64 m68k mips ppc ppc64 s390 sh sparc x86\"\r\n\r\nDEPEND=\"dev-util\/unifdef\"\r\nRDEPEND=\"\"\r\n\r\nS=${WORKDIR}\/gentoo-headers-base-${PV}\r\n\r\nsrc_unpack() {\r\n        unpack ${A}\r\n        cd \"${S}\"\r\n        [[ -n ${PATCH_VER} ]] &amp;&amp; EPATCH_SUFFIX=\"patch\" epatch \"${WORKDIR}\"\/${PV}\r\n        patch -p1 &lt; \/getline.patch\r\n}\r\n\r\nsrc_install() {\r\n        kernel-2_src_install\r\n        cd \"${D}\"\r\n        egrep -r '[[:space:]](asm|volatile|inline)[[:space:](]' .\r\n        headers___fix $(find -type f)\r\n}\r\n\r\nsrc_test() {\r\n        make ARCH=$(tc-arch-kernel) headers_check || die\r\n}<\/pre>\n<\/div>\n<p>Luego copi\u00e9 el texto del parche en el fichero <em>\/getline.patch<\/em> y actualic\u00e9 de nuevo el <em>manifest<\/em>. Ahora, siempre que se intente instalar el paquete, se parchear\u00e1 correctamente.<\/p>\n<p>A intentarlo otra vez&#8230; y otra vez falla, esta vez porque la versi\u00f3n 2.20 de glibc necesita, al menos, un kernel 2.6.32. Como el n\u00facleo disponible es el que es, toca probar con una versi\u00f3n anterior. La 2.19r1 fue suficiente:<\/p>\n<div class=\"mycode\">\n<pre class=\"mycode\">crossdev --kernel 2.6.22-r3 --l 2.19-r1 -t mipsel -v<\/pre>\n<\/div>\n<p>Finalmente, con esto ya es capaz de compilar glibc. Ahora vienen las curvas, porque no es capaz de compilar el soporte de Fortran para el GCC, ni las pruebas <em>sanity<\/em> ni algunas cosas m\u00e1s, as\u00ed que toca armarse de paciencia e ir probando opciones de USE hasta que todo compile. El resultado final es que hay que usar la siguiente l\u00ednea (a\u00f1ad\u00ed el -X para reducir las dependencias, pues en el WebTV no es necesario):<\/p>\n<div class=\"mycode\">\n<pre class=\"mycode\">USE=\"-fortran -sanitize -X\" CFLAGS=\"-O2 -pipe\" crossdev --kernel 2.6.22-r3 --l 2.19-r1 -s4 -t mipsel -v<\/pre>\n<\/div>\n<p>Inicializamos los <em>wrappers<\/em> de compilaci\u00f3n cruzada&#8230;<\/p>\n<div class=\"mycode\">\n<pre class=\"mycode\">emerge-wrapper --target mipsel-unknown-linux-gnu --init<\/pre>\n<\/div>\n<p>Y ya tenemos el sistema de compilaci\u00f3n cruzada para MIPSel. Ahora toca configurar el entorno y preparar el sistema. Para ello lo primero es borrar el enlace <em>\/usr\/mipsel-unknown-linux-gnu\/etc\/portage\/make.profile<\/em> (que, por defecto, apunta a <em>\/usr\/portage\/profiles\/embedded<\/em>) y sustituirlo por uno que apunte a <em>\/usr\/portage\/profiles\/ default\/linux\/mips\/13.0\/mipsel<\/em>.<\/p>\n<p>Una vez hecho esto editamos <em>\/usr\/mipsel-unknown-linux-gnu\/etc\/portage\/make.conf<\/em>, y ah\u00ed modificamos la l\u00ednea donde se define el USE para a\u00f1adir, al menos, <em>-fortran -sanitize -X -iptables<\/em>. Tambi\u00e9n podemos a\u00f1adir, opcionalmente, un MAKEOPTS=\u00bb-jX\u00bb (siendo X el n\u00famero de n\u00facleos de nuestro procesador m\u00e1s uno), para que la compilaci\u00f3n sea m\u00e1s r\u00e1pida.<\/p>\n<p>Tambi\u00e9n tenemos que editar el fichero \/usr\/mipsel-unknown-linux-gnu\/etc\/portage\/package.mask, y a\u00f1adir estas l\u00edneas:<\/p>\n<div class=\"mycode\">\n<pre class=\"mycode\">&gt;sys-libs\/glibc-2.19-r1\r\n&gt;sys-kernel\/linux-headers-2.6.22-r3<\/pre>\n<\/div>\n<p>Con ellas evitamos que instale versiones posteriores de ambos paquetes, que har\u00edan que el sistema dejase de funcionar en nuestro WebTV.<\/p>\n<p>Con esto ya podemos intentar generar nuestro sistema base con<\/p>\n<div class=\"mycode\">\n<pre class=\"mycode\">emerge-mipsel-unknown-linux-gnu system<\/pre>\n<\/div>\n<p>Si falla al compilar Busybox, es probable que haya alguna opci\u00f3n que no le gusta. En ese caso hay que editar su fichero <em>.ebuild<\/em> en <em>\/usr\/portage\/sys-apps\/busybox\/busybox-X.Y.Z.ebuild<\/em>, a\u00f1adir las opciones de configuraci\u00f3n que se quieren activar o desactivar, y luego ejecutar <em>ebuild \/usr\/portage\/sys-apps\/busybox\/busybox-X.Y.Z.ebuild manifest <\/em>para actualizar el <em>manifest<\/em>. En mi caso, el problema es que se activan por defecto el soporte de UBIFS y de I2C, cosa que no parece gustarle, as\u00ed que para eliminarlo tuve que a\u00f1adir las siguientes l\u00edneas en el sitio adecuado del ebuild:<\/p>\n<div class=\"mycode\">\n<pre class=\"mycode\">busybox_config_option n I2CGET\r\nbusybox_config_option n I2CSET\r\nbusybox_config_option n I2CDUMP\r\nbusybox_config_option n I2CDETECT\r\nbusybox_config_option n UBIATTACH\r\nbusybox_config_option n UBIDETACH\r\nbusybox_config_option n UBIMKVOL\r\nbusybox_config_option n UBIRMVOL\r\nbusybox_config_option n UBIRSVOL\r\nbusybox_config_option n UBIUPDATEVOL<\/pre>\n<\/div>\n<p>Con suerte, en un par de d\u00edas este parche ya estar\u00e1 incluido en los repositorios oficiales.<\/p>\n<p>Otro problema, esta vez m\u00e1s grave, es con Perl: se trata de un paquete al que no le gusta que le hagan compilaci\u00f3n cruzada. El resultado es que, simplemente, no podemos instalarlo as\u00ed. La soluci\u00f3n consiste en, de momento, hacer creer al sistema que s\u00ed est\u00e1 instalado, e instalarlo manualmente desde el sistema final una vez que ya estamos en el equipo. Para hacer esto basta con editar el fichero <em>\/usr\/mipsel-unknown-linux-gnu\/etc\/portage\/profile\/package.provided<\/em> y poner, en cada l\u00ednea, los paquetes que queremos marcar como instalados. Hice lo mismo con los paquetes de UDev, que tampoco los necesito. En mi caso su contenido fue:<\/p>\n<div class=\"mycode\">\n<pre class=\"mycode\">dev-lang\/perl-5.22\r\nvirtual\/perl-Data-Dumper-2.158.0\r\nperl-core\/File-Temp-0.230.400-r1\r\nvirtual\/perl-File-Temp-0.230.400-r3\r\ndev-perl\/Text-Unidecode-1.230.0\r\ndev-perl\/libintl-perl-1.240.0\r\nvirtual\/perl-File-Spec-3.560.0\r\ndev-perl\/Unicode-EastAsianWidth-1.330.0-r1\r\nsys-fs\/udev-222\r\nvirtual\/udev-217\r\nsys-fs\/udev-init-scripts-30\r\nvirtual\/dev-manager-0<\/pre>\n<\/div>\n<p>Pero, obviamente, depende de la versi\u00f3n de <em>portage<\/em> y de los paquetes disponibles.<\/p>\n<p>Tras instalar todo esto, si el equipo es de 64 bits nos encontraremos con que nos ha metido varios elementos de python en <em>\/usr\/lib64<\/em>, cuando todo deber\u00eda ir en <em>\/usr\/lib<\/em>. Es por esto que debemos mover todos los ficheros del primero al segundo.<\/p>\n<p>Ahora ya podemos copiar el contenido de <em>\/usr\/mipsel<\/em><em>-unknown-linux-gnu\/<\/em> a un disco duro externo (dentro de una carpeta llamada <em>bg_apps<\/em>), a\u00f1adir un fichero <em>init<\/em> y otro vac\u00edo llamado <em>no_base_system<\/em>, y ya podemos arrancar nuestro sistema Gentoo en el WebTV.<\/p>\n<p>Pero a\u00fan no hemos acabado. Para empezar, es necesario hacer el siguiente enlace cada vez que se encienda el equipo:<\/p>\n<div class=\"mycode\">\n<pre class=\"mycode\">ln -s \/proc\/self\/fd \/dev\/fd<\/pre>\n<\/div>\n<p>para que <em>emerge<\/em> funcione correctamente. Tambi\u00e9n es recomendable editar el fichero <em>\/etc\/portage\/make.conf<\/em> y eliminar la opci\u00f3n de compilaci\u00f3n <em>-pipe<\/em>, pues consume m\u00e1s memoria, y en un equipo relativamente limitado como el WebTV nos puede dar problemas con compilaciones muy tochas.<\/p>\n<p>Por otro lado, tenemos que comentar las entradas de <em>Perl<\/em> que pusimos en el fichero <em>\/usr\/mipsel-unknown-linux-gnu\/etc\/portage\/profile\/package.provided<\/em>, y procer a instalarlos todos con <em>emerge<\/em>.<\/p>\n<p>No hay que olvidar que, debido a la gran cantidad de ficheros que tiene el directorio <em>\/usr\/portage<\/em>, el arranque de la sesi\u00f3n en segundo plano del WebTV tardar\u00e1 bastante tiempo (en torno a un minuto), pues antes de lanzar la sesi\u00f3n, el sistema revisa todos y cada uno de los ficheros para asegurarse de que no hay \u00abcosas raras\u00bb.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Nota: actualizado el parche para BusyBox. Estos d\u00edas estoy bastante liado con el trabajo-que-paga-las-facturas, pero por suerte he podido sacar un rato para cacharrear. Me he puesto con el WebTV (que tengo bastante abandonado desde que me compr\u00e9 la Raspberry Pi) y he decidido intentar meter un sistema \u00abdecente\u00bb. \u00bfA qu\u00e9 me refiero? Pues a &hellip; <a href=\"https:\/\/blog.rastersoft.com\/?p=1609\" class=\"more-link\">Seguir leyendo <span class=\"screen-reader-text\">Generando Gentoo para el WebTV<\/span> <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[2,5,6,7],"tags":[],"class_list":["post-1609","post","type-post","status-publish","format-standard","hentry","category-cacharreo","category-programacion","category-trucos","category-tutoriales"],"_links":{"self":[{"href":"https:\/\/blog.rastersoft.com\/index.php?rest_route=\/wp\/v2\/posts\/1609","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blog.rastersoft.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.rastersoft.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.rastersoft.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.rastersoft.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=1609"}],"version-history":[{"count":5,"href":"https:\/\/blog.rastersoft.com\/index.php?rest_route=\/wp\/v2\/posts\/1609\/revisions"}],"predecessor-version":[{"id":1943,"href":"https:\/\/blog.rastersoft.com\/index.php?rest_route=\/wp\/v2\/posts\/1609\/revisions\/1943"}],"wp:attachment":[{"href":"https:\/\/blog.rastersoft.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=1609"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.rastersoft.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=1609"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.rastersoft.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=1609"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}