lunes, 9 de agosto de 2010

El regreso del freak: The Super Duper ISO booter

Desde el comienzo de los tiempos el ser humano buscó un modo de bootear una imagen iso desde un pendrive de forma automágica, es decir, sin tocar un solo archivo de configuracion, por el solo expediente de colocarla en una carpeta. Siglos han pasado desde entonces, y para que semejante hazaña sea posible fue necesario que primero se inventaran (o descubrieran según seamos aristotélicos o platónicos) los pulgares oponibles, las herramientas, el lenguaje, la rueda, el fuego, la imprenta, la electricidad, las computadoras, los cds, las imagenes ISO, los puertos usb, los discos extraibles, syslinux, grub4dos y grub2.

A nosotros, seres humanos que vivimos una época en la que todo lo anterior existe, nos queda entonces la obligación de disfrutar de nuestros inpulsos frikis haciendo uso de las herramientas a nuestro alcance.

En eso me encontraba cuando empece a investigar el entonces nuevo grub2, descubriendo que incorpora un interprete LUA, que hasta donde pude ver (tengo la referencia del lenguaje para leer, solo me da paja hacerlo) es un lenguaje de programación similar a C y que puede usarse como lenguaje scripting. Y entonces me surgió la curiosidad de saber si bootmanager+scripting me podían dar el famoso boot automático de isos por el que varios lectores preguntaron al comienzo de las andadas de este, su blog amigo, cuando incursionabamos en pendrives booteables. Y resultó que sí.

Y el pueblo: ¿Quiere saber de que se trata?

O mejor dicho: si no quiere saberlo, puede saltar directamente a la sección "Todo masticado", en la que encontrara una bonita descarga con, justamente, todo masticado.

Para los que quieran saber de que se trata, les cuento: Se trata de una coleccion de utilidades, scripts archivos de configuración robados de otros proyectos y colocados todos juntos para que funcione. Para dar crédito a los autores originales vos a explicar como funciona.

El script de instalacion es una modificacion (y semi traduccion) del que se encuentra al final de la pagina del hirens para bootear por usb, y se encarga de copiar los archivos grub.exe, syslinux.conf, menu.lst, sgd.iso y m.lua a la raíz del pendrive. Luego crea el directorio /iso y mueve sgd.iso ahi, y al final instala el sector de arranque de syslinux en el pendrive. Con esto tenemos todo instalado.

Al bootear, el pendrive lee el sector de arranque y carga el syslinux. Este lee el archivo de configuración syslinux.cfg y carga el grub4dos (grub.exe modificado para que no saltee el floppy) , que lee el menu.lst y carga la iso del Super Grub Disk (modificada para agregarle la entrada del Super Duper Iso Booter) , que lee el script m.lua (que es modificacion del script bootiso.lua que trae el SGD2) y nos muestra un menú con todas las iso que haya en el directorio /iso. Cuando seleccionamos una entrada del menú, grub2 vuelve a cargar grub4dos, con parametros de configuración que mapean la iso y bootean desde el sector de arranque.

Y por qué es tan complicado?

Es complicado porque al hacerlo me encontré con algunos problemas:

- No instalo directamente grub4dos como arranque porque syslinux es mas compatible con maquinas viejas, y de todos modos uso grub.exe después.
- No puedo bootear la iso desde syslinux porque no lo soporta.
- No pude editar el floppy de SGD2 porque no pude montarlo en linux o en windows. Si alguien quiere hacerlo y poner el grub.cfg de la iso lo espero en mediafire.
- No puedo generar el menú desde grub4dos porque no soporta scripts.
- No puedo bootear las iso desde grub2 porque no soporta chainload, y eso nos deja sin bootear muchas cosas (el hirens, por ejemplo. O el silverdisk).

Verán que son muchos items, poniendo solo los que se me ocurrieron y no pude resolver. Por otra parte, la ventaja del método actual es que nos quedan a la vista un syslinux.cfg y un menu.lst para agregarle lo que queramos!

Un poco de código:

CorraMe.bat

@echo off
echo.
set udrv=
for %%x in (syslinux.cfg syslinux.exe grub.exe menu.lst sgd.iso m.lua) do if

not exist files\%%x goto error
set /p udrv=Ingrese la letra del disco USB (Por ejemplo F:)
if "%udrv%"=="" goto nodrv
echo.
echo !! CUIDADO !!
echo.
echo ESTO INSTALARA SYSLINUX EN %udrv%
echo PRESIONE CUALQUIER TECLA PARA CONTINUAR (O CIERRE ESTA VENTANA)
pause
echo Copiando archivos al pendrive ...
for %%x in (syslinux.cfg grub.exe menu.lst sgd.iso m.lua) do echo copy /y

files\%%x %udrv%\ && copy /y files\%%x %udrv%\
for %%x in (syslinux.cfg grub.exe menu.lst sgd.iso m.lua) do if not exist

%udrv%\%%x goto errcopy
mkdir %udrv%\iso
move %udrv%\sgd.iso %udrv%\iso

echo Instalando el boot en el USB...
echo files\syslinux.exe -ma %udrv% -f
files\syslinux.exe -ma %udrv%
if errorlevel 0 goto ok
echo syslinux.exe error
pause
goto end
:ok
echo done
pause
goto end
:nodrv
echo nothing is selected
pause
goto end
:errcopy
echo Error while copying
pause
goto end
:error
echo file(s) missing (syslinux.cfg syslinux.exe grub.exe menu.lst sgd.iso

m.lua)
pause
:end



Este es el "instalador", modificacion del que viene en el paquete de syslinux del hirens. Primero chequea que existan los archivos necesarios en /files, después pide la letra de la unidad y copia los archivos. crea el directorio /iso y mueve ahi el sgd.iso .Despues escribe el boot en el mbr y sale, Lo que sigue son los mensajes de error que nos muestra si algo falla. Verán que no están traducidos, con lo que notarán mi lazyness.

Syslinux.cfg

default /grub.exe

Simple, carga el grub.

Menu.lst

timeout 2
default 0

title SuperGrubDisk ISO
find --set-root /iso/sgd.iso
map /iso/sgd.iso (0xff) || map --mem /iso/sgd.iso (0xff)
map --hook
root (0xff)
chainloader (0xff)

Encuentra la iso del super grub disk, la mapea directamente o en memoria y bootea desde ahi. Esta forma de cargar las iso en grub4dos está robada del proyecto winsetupfromusb.

Grub.cfg (dentro de la iso)

...
#Super iso booter
menuentry "Super duper iso booter" {
search -f --set /m.lua
configfile /m.lua
}
...

Agregado la entrada del menu. Search es el reemplazo de find (diferencia entre grub4dos y grub2), y se pasa como archivo de configuracion el script que genera el menu

m.lua

#!lua

isofolder = "/iso"

function enum_file (name)
local title = string.match (name, "(.*)%.[iI][sS][oO]")

if (title) then
local source = "search -f --set /grub.exe \n linux /grub.exe --config-file=\"root (hd0,0); map /iso/" .. name .." (0xff) || map --mem /iso/" .. name .. " (0xff); map --hook; root (0xff); chainloader (0xff)\" "

grub.add_menu (source, title)
print ("titulo: "..title.. " ruta: "..source)
end
end

grub.enum_file (enum_file, isofolder)

Este es el mas robado (lo que implica que no hubiera podido programarlo yo sin leer muuuucho mas)! Para mas datos, está robado específicamente del script listisos.lua de esta pagina de ubuntuforums. Crea una funcion que por cada archivo terminado en .iso (mayuscula o minuscula) agrega una entrada del menu con los parametros definidos en source y title. Yo solo le cambié la llamada a la funcion bootiso.lua por la llamada directa a grub4dos con los parametros de arranque.

Y listo!

Todo masticado!


Acá tienen la descarga del instalador en rar. Se descomprime en cualquier lado (el escritorio, por ejemplo, aunque yo lo dejaría en el pendrive por si hay que restaurar) y al ejecutar CorraMe.bat pregunta la letra de la unidad y se instala ahí.
Para agregar una iso al menu solo hay que copiarla en la carpeta /iso en el pendrive.


Notas:

- Cuidado! Si hay otro sector de arranque, syslinux.cfg o menu.lst en la raiz del pendrive hagan un backup antes de instalar, porque el CorraMe.bat sobreescribe sin preguntar.
- El grub4dos intenta mapear la imagen directamente, y si falla lo hace en memoria. Esto último sucede cuando la imagen iso esta fragmentada en el pendrive, y aparte de ser lento consume memoria, por lo que si vamos a tirar isos de 700Mb en la carpeta, es recomendable wincontig.
- Desde seven o vista, hay instrucciones en la última posdata!
- Las isos booteadas no siempre andan.
- Puede fallar!



PD: para toquetear los archivos de configuracion y probar, les recomiendo este probador de boot basado en qemu (robado del paquete UBCD4Win) .

PD2: (Arreglado. No les debo nada) .Les debo los links a las paginas de hirens, grub4dos, grub2, syslinux, lua, wincontig, UBCD4WIN y mil mas. Capaz que mas tarde, es decir dentro de seis meses, con mi ritmo de publicación.

PD3: Soy lento para despedirme y escribo muchas posdatas. Pero si alguien prueba esto deje un comentario, para saber que no soy el único friki al que le interesa esto. O que si.

PD5: Enjoy!

PD4: En W7 o Vista tenemos una problema: necesitamos ser administradores para poder escribir el mbr, pero el sistema cambia el path a \windows\system32 cuando ponemos el modo administrador, con lo que el batch no encuentra los archivos. Para solucionar eso debemos:
1) Abrir una consola en modo administrador. Eso se hace buscando en el menu "cmd", y después con boton derecho sobre el ícono "Ejecutar como administrador".
2) Cambiar el path al lugar donde tenemos el archivo CorraMe.bat. En mi pendrive, el comando es cd "F:\boot tools\SuperIsoBooter"
3) Ejecutar el batch a mano desde la consola.
4) Debería funcionar!
Of course, si alguien tiene una solucion mas elegante, lo espero en los comentarios y será agradecido. No eternamente, pero agradecido.