BusyboxBusybox es un ser de herramientas comunes en unix/linux todas metidas en un simple binario muy liviano, ideal para minidistros o sistemas embebidos. Hoy es una herramienta muy poderosa, que llega a incluir binarios de apt o rpm, herramientas para discos, etc.
Se compila como un kernel, con un make menuconfig se accede a un menú de opciones. No vamos a entrar en detalles, solo vamos a ver algunas cosas que vamos a seleccionar:
Busybox Settings -> Busybox Settings -> Enable options for full-blown desktop systems [*]
Busybox Settings -> Installation Options -> BusyBox installation prefix seteado a ~/Curso/initrd/ROOT
De los applets yo quite: rpm, uncompress, unlzma, cpio, ed, patch, todo el debian utils, inetd, sendmail, fetchmail, tftp, tftpd, udhcp server... podría sacar mucho más, pero todo esto se los dejo a uds. Investiguen qué necesitan y qué no.
Al terminar de armar una configuración a gusto y piaccere, hacemos el famoso "make && sudo make install" y nos va a dejar todo en $INITRD_DIR. Tenemos Busybox instalado en nuestro initrd, pero todavía falta para que pueda ser corrido: faltan las librerías que requieren Busybox. En nuestro caso vamos a copiar las del sistema, si quieren libc compiladas por uds. deben seguir otros pasos que no vamos a explicar en el tutorial. Por ultimo, hay una opción de usar
ucLibc,
aquí tienen un tutorial de cómo hacerlo. Pero sigamos con lo nuestro:
shell> cd $INITRD_DIR
shell> ldd bin/busybox # [1]
linux-gate.so.1
(0xb7fd3000)
libcrypt.so.1
/lib/i686/cmov/libcrypt.so.1 (0xb7f8c000)
libm.so.6
/lib/i686/cmov/libm.so.6 (0xb7f66000)
libc.so.6
/lib/i686/cmov/libc.so.6 (0xb7e0a000)
/lib/ld-linux.so.2 (0xb7fd4000)
shell> cp -a /lib/i686/cmov/libcrypt* lib/ # [2]
shell> cp -a /lib/i686/cmov/libm-2.7.so /lib/i686/cmov/libm.so.6 lib/ # [2]
shell> cp -a /lib/i686/cmov/libc-2.7.so /lib/i686/cmov/libc.so.6 lib/ # [2]
shell> cp -a /lib/ld-2.7.so /lib/ld-linux.so.2 lib/ # [2]
[1] vemos que librerías requiere busybox para correr, luego las copiamos a nuestro /lib.
man ldd[2] copiamos una a una las librerías a nuestro /lib, si se fijan bien, la libm-27.so es la librería y libm.so.6 es un link a ella, copiamos las 2.
Ahora podemos probar si busybox puede ejecutarse cuando se encuentre solo en su ambiente, para ello usamos chroot:
shell> chroot $INITRD_DIR /bin/ash # [1]
shell ash> ls
bin dev etc lib linuxrc proc root sbin sys tmp usr var
shell ash> busybox
BusyBox v1.10.1 (2008-07-23 14:01:24 ART) multi-call binary
Copyright (C) 1998-2007 Erik Andersen, Rob Landley, Denys Vlasenko
and others. Licensed under GPLv2.
See source distribution for full notice.
Usage: busybox [function] [arguments]...
or: function [arguments]...
BusyBox is a multi-call binary that combines many common Unix
utilities into a single executable. Most people will create a
link to busybox for each function they wish to use and BusyBox
will act like whatever it was invoked as!
Currently defined functions:
[, [[, addgroup, adduser, adjtimex, ar, arp, arping, ash, awk, basename, brctl, bunzip2, bzcat, bzip2, cal, cat, catv, chattr, chgrp, chmod, chown, chpasswd,
chpst, chroot, chrt, chvt, cksum, clear, cmp, comm, cp, crond, crontab, cryptpw, cut, date, dc, dd, deallocvt, delgroup, deluser, df, diff, dirname, dmesg,
dnsd, dos2unix, du, dumpkmap, echo, egrep, eject, env, envdir, envuidgid, ether-wake, expand, expr, fakeidentd, false, fbset, fdflush, fdformat, fdisk, fgrep,
find, fold, free, freeramdisk, fsck, fsck.minix, ftpget, ftpput, fuser, getopt, getty, grep, gunzip, gzip, halt, hdparm, head, hexdump, hostid, hostname,
httpd, hwclock, id, ifconfig, ifdown, ifenslave, ifup, init, insmod, install, ip, ipaddr, ipcalc, ipcrm, ipcs, iplink, iproute, iprule, iptunnel, kbd_mode,
kill, killall, killall5, klogd, last, length, less, linux32, linux64, linuxrc, ln, loadfont, loadkmap, logger, login, logname, logread, losetup, lpd, lpq,
lpr, ls, lsattr, lsmod, makedevs, md5sum, mdev, mesg, microcom, mkdir, mkfifo, mkfs.minix, mknod, mkswap, modprobe, more, mount, mountpoint, mt, mv, nameif,
nc, netstat, nice, nmeter, nohup, nslookup, od, openvt, passwd, pgrep, pidof, ping, ping6, pivot_root, pkill, poweroff, printenv, printf, ps, pscan, pwd,
raidautorun, rdate, readahead, readlink, readprofile, realpath, reboot, renice, reset, resize, rm, rmdir, rmmod, route, runlevel, runsv, runsvdir, rx, script,
sed, seq, setarch, setconsole, setkeycodes, setlogcons, setsid, setuidgid, sh, sha1sum, slattach, sleep, softlimit, sort, split, stat, strings, stty, su,
sulogin, sum, sv, svlogd, swapoff, swapon, switch_root, sync, sysctl, syslogd, tac, tail, tar, taskset, tcpsvd, tee, telnet, telnetd, test, time, top, touch,
tr, traceroute, true, tty, ttysize, udhcpc, udpsvd, umount, uname, unexpand, uniq, unix2dos, unzip, uptime, usleep, uudecode, uuencode, vconfig, vi, vlock,
watch, watchdog, wc, wget, who, whoami, xargs, yes, zcat, zcip
shell ash> exit
shell>
[1] nos "chrooteamos" dentro del initrd que estamos haciendo y usamos ash, un shell que viene en busybox, porque no tenemos bash _todavia.
man chrootBash y ncursesVamos a usar bash como shell porque nos permite crear scripts más complejos que ash de busybox. El problema es que depende de ncurses o termcap, ya en desuso, por lo que vamos a tener que compilar ncurses:
shell> cd $SRC_DIR
shell> tar xfz ncurses*.tar.gz
shell> cd ncurses*
shell> ./configure --prefix=/usr --mandir=/tmp --infodir=/tmp --includedir=/tmp --without-cxx --without-ada --without-curses-h --with-shared --without-normal -without-debug # [1]
shell> make && sudo make install DESTDIR=$INITRD_DIR # [2]
[1] preparamos la compilación poniendo a ncurses dentro del /usr de nuestro initrd, no necesitamos man, info ni includes, deshabilitamos un par de cosas, compilamos y listo.
[2] debemos compilar con prefix=/usr y luego pasarle dónde instalar para no romper con las referencias al /usr/share
Ahora compilamos bash:
shell> cd $SRC_DIR
shell> tar xfz bash*.tar.gz
shell> cd bash*
shell>LDFLAGS=" -L$INITRD_DIR/usr/lib/ " ./configure --prefix=$INITRD_DIR --mandir=/tmp --infodir=/tmp --includedir=/tmp
shell> make && sudo make install
shell> cd $INITRD_DIR
shell> sudo cp /lib/i686/cmov/libdl* lib/ # [1]
shell> ls -al bin/bash
-rwxr-xr-x 1 root root 2,0M jul 23 15:46 bin/bash
shell> sudo strip --strip-debug bin/bash # [2]
shell> ls -al bin/bash
-rwxr-xr-x 1 root root 805K jul 23 15:47 bin/bash
shell> chroot $INITRD_DIR /bin/bash # [3]
shell bash>
[1] copiamos las librerias que nos hacen falta
[2] hacemos un strip-debug del binario bash para eliminarle los linkeos para debug.
man strip[3] probamos si podemos hacer un chroot con bash. El /bin/bash es opcional, ya que es default en el chroot.
PCIUtilsEl paquete de pciutils incluye el comando lspci que nos va a servir para detectar el hardware instalado y cargar el módulo asignado para dicho hardware. Compilarlo es muy sencillo y luego de compilarlo hay que traer la base de datos del lspci.
shell> cd $SRC_DIR
shell> tar xfz pciutils*.tar.gz
shell> cd pciutils*
shell> make
shell> sudo make install PREFIX=$INITRD_DIR/usr
shell> sudo mkdir -p $INITRD_DIR/usr/local/share/
shell> cp -a /usr/lib/libz.so* $INITRD_DIR/usr/lib/
shell> cp -a /lib/i686/cmov/libresolv* $INITRD_DIR/lib/
shell> chroot $INITRD_DIR
shell> update-pciids
Downloaded daily snapshot dated Wed 2008-07-23 01:05:01
shell> lspci
pcilib: Cannot open /proc/bus/pci
00:00.0 Host bridge: Intel Corporation 82915G/P/GV/GL/PL/910GL Memory Controller Hub (rev 04)
00:02.0 VGA compatible controller: Intel Corporation 82915G/GV/910GL Integrated Graphics Controller (rev 04)
00:1c.0 PCI bridge: Intel Corporation 82801FB/FBM/FR/FW/FRW (ICH6 Family) PCI Express Port 1 (rev 03)
00:1c.1 PCI bridge: Intel Corporation 82801FB/FBM/FR/FW/FRW (ICH6 Family) PCI Express Port 2 (rev 03)
00:1d.0 USB Controller: Intel Corporation 82801FB/FBM/FR/FW/FRW (ICH6 Family) USB UHCI #1 (rev 03)
00:1d.1 USB Controller: Intel Corporation 82801FB/FBM/FR/FW/FRW (ICH6 Family) USB UHCI #2 (rev 03)
00:1d.2 USB Controller: Intel Corporation 82801FB/FBM/FR/FW/FRW (ICH6 Family) USB UHCI #3 (rev 03)
00:1d.3 USB Controller: Intel Corporation 82801FB/FBM/FR/FW/FRW (ICH6 Family) USB UHCI #4 (rev 03)
00:1d.7 USB Controller: Intel Corporation 82801FB/FBM/FR/FW/FRW (ICH6 Family) USB2 EHCI Controller (rev 03)
00:1e.0 PCI bridge: Intel Corporation 82801 PCI Bridge (rev d3)
00:1e.2 Multimedia audio controller: Intel Corporation 82801FB/FBM/FR/FW/FRW (ICH6 Family) AC'97 Audio Controller (rev 03)
00:1f.0 ISA bridge: Intel Corporation 82801FB/FR (ICH6/ICH6R) LPC Interface Bridge (rev 03)
00:1f.1 IDE interface: Intel Corporation 82801FB/FBM/FR/FW/FRW (ICH6 Family) IDE Controller (rev 03)
00:1f.2 IDE interface: Intel Corporation 82801FB/FW (ICH6/ICH6W) SATA Controller (rev 03)
40:00.0 Ethernet controller: Broadcom Corporation NetXtreme BCM5751 Gigabit Ethernet PCI Express (rev 01)
No se preocupen por ese error "pcilib: Cannot open /proc/bus/pci", luego podrán montar el /proc.
Kernel y módulosPara compilar el kernel pueden ver este
tutorial. Lo único que les puedo decir es que armen un kernel lo más generico posible, con todo lo que puedan como múdulo MENOS EL SOPORTE A EXT2.
En la imagen solo necesitamos los módulos, el kernel lo vamos a utilizar para bootear, por lo que si no quieren compilar pueden copiar el /lib/modules/x.y.z a $INITRD_DIR/lib/modules y utilizar el /boot/bzImage-x.y.z para bootear. En caso que hayan compilado, al finalizar hacen:
shell> make modules_install INSTALL_MOD_PATH=$INITRD_DIR