Guía para la Compilación de MINIX Laboratorio de Sistemas Operativos Guía para la Compilación de MINIX _________________________________________ 1 Introducción__________________________________________________________________1 Realización de Backups de Códigos modificados __________________________________________ 1 Compilación e Instalación de MINIX _____________________________________________2 Algunas formas de generar una imagen de MINIX _________________________________________ 2 Instalación de la nueva imagen de MINIX ________________________________________________ 2 Los archivos Makefiles y el comando Make ________________________________________3 El archivo makefile__________________________________________________________________ Ejecutando make____________________________________________________________________ Reglas implícitas____________________________________________________________________ Algunos Ejemplos___________________________________________________________________ Laboratorio de Sistemas Operativos 3 4 4 5 Introducción En este documento se tratan los temas relacionados con la modificación, compilación, generación de la imagen de Kernel para MINIX y la forma de utilizarla para bootear el minix. Para generar la imagen de kernel, se usan utilitarios para simplificar la tarea, pero dichos utilitarios deben estar bien configurados para poder tener los resultados buscados. Razón por la cual comenzaremos revisando algunos temas que parecen ser insignificantes pero muy necesarios. Realización de Backups de Códigos modificados La generación de backups de los fuentes es muy necesaria, si se están realizando modificaciones sobre ellos. Los fuentes se encuentran en el filesystem de minix en el directorio /usr/src. Una posible forma de realizar el backup es haciendo una copia de la partición de minix y otra es haciendo una copia de los archivos fuentes comprimidos. 1) Generar una copia del filesystem de MINIX. Este procedimiento puede ser muy sencillo, si se instaló el MINIX sobre DOS, o sea que se ejecuta el minix mediante el comando “ boot.com <imagen> “ de DOS. En este caso basta con realizar una copia del archivo <imagen> la cual puede ser comprimida y ocuparía aproximadamente 5 MB. Si este no es el caso, entonces se puede realizar una operativa similar, pero haciendo una copia de la partición completa mediante el comando cat de LINUX sobre la partición de MINIX, pero para ello se debe tener en la misma máquina, en otra partición, instalado el LINUX. Si no se trata de alguno de los escenarios anteriores, entonces se deberá realizar la segunda opción antes mencionada “copia de los fuentes en disquette”. 2) Generar una copia de las fuentes a disquette. Para llevar a cabo esto, se debe generar un disquete para backup. Utilizando para esto un disquette previamente formateado y ejecutando el siguiente comando: Mkfs –i200 /dev/fd0 Una vez generado el filesystem en el disquete, se deberá montarlo con el comando mount /dev/fd0 /fd0. A partir de ese momento se puede copiar los archivos que se desean resguardar. Si se desea guardar toda la estructura de directorios se puede utilizar los siguiente comandos: cd /usr/src/tools make clean cd ../lib make clean cd /usr/src tar cf /fuentes.tar kernel mm fs ../include lib/posix lib/syscall cd / compress fuentes.tar mv lab.tar.Z /fd0 Cabe señalar que los comandos make clean eliminan todos los archivos objects generados por el compilador que se indican en los archivos Makefile y por lo tanto la información de dichos archivos deberá estar actualizada. Cuando se utiliza este método para realizar el backup de los archivos se debe tener especial cuidado de no sacar el disquete sin antes desmontarlo usando el comando umount /fd0 A.R.G. Laboratorio de Sistemas Operativos 1/5 Compilación e Instalación de MINIX Para compilar minix se utiliza el comando make y los archivos Makefiles. Es importante que se pueda entender las reglas utilizadas por el comando make en los Makefiles y que los mismos estén actualizados. Cada parte de minix puede ser compilada por separado, para ello se utiliza el comando: make <modulo> donde modulo puede ser boot, kernel, mm, fs o tools En el caso que se desee realizar un compilación completa del minix, se puede ejecutar el comando: make programs en el directorio tools. Si la compilación de las partes fue satisfactoria, se linkearán generando un archivo imagen image, que contiene la imagen del nuevo kernel de MINIX. Otra forma de realizar la compilación es usando el comando make hdboot en el directorio tools. Algunas formas de generar una imagen de MINIX A continuación se enumeran las posibles formas de realizar una generación y copia de la imagen de MINIX. make make fdboot make hdboot Esto genera todas las diferentes partes del kernel y las junta en un archivo llamado image De la misma forma arriba pero luego genera un disquete booteable que puede ser usado para iniciar el sistema. Se le pide que ingrese cual es el nombre del device para el disquete Primero crea el archivo image y luego lo copia en el directorio /minix. Si ya hay dos imágenes en ese directorio entonces se elimina la mas nueva para generar espacio. El monitor elige la imagen mas nueva en /minix para bootear, pero se puede usar el comando ls minix del monitor para ver las imágenes presentes y setear la variable image a la que corresponda. Las imágenes en /minix usan (release,versión,revision) como nombres para poder distinguirlas. Instalación de la nueva imagen de MINIX Cuando se genera una imagen nueva, no se debe borrar la imagen original, por si existe algún error no esperado. La forma de utilizar la nueva imagen, es indicando en el monitor de MINIX, cual es la nueva imagen con la que debería inicializar el sistema. Esto se realiza presionando ESC, cuando aparece el menú inicial al arrancar el minix. En el prompt del monitor se puede ejecutar el comando set para ver los valores de las variables y ejecutar el comando image=<imagennueva>, donde <imagennueva> debe indicar el camino completo hasta la imagen generada. A.R.G. Laboratorio de Sistemas Operativos 2/5 Los archivos Makefiles y el comando Make Dado que la cantidad de archivos a compilar cada vez que se genera una imagen de kernel, se usa el comando make con los archivos makefiles correspondientes. Esta sección tiene el objetivo de presentar el make y las reglas de los makefiles para los casos que se deban modificar dichas reglas. El programa make puede ocuparse de compilar sólo aquellos módulos del programa que sean necesarios y de automatizar casi cualquier proceso: generación de archivos DVI a partir de los fuentes en \LaTeX, ejecución de programas a los que pasamos muchas opciones y que no queremos escribir cada vez, etc. Básicamente, se nutre de información proporcionada por el usuario especificada en un archivo: • Nombres de los archivos, que aparecen en los comandos. • Dependencias entre archivos. (archivos necesarios para cumplir con el pedido) Esto es importante ya que sólo trabajará si los archivos que le especificamos que cree (o alguno de los que depende) ha sido modificado desde la última vez que se llamó a make. Así no será necesario compilar los programas al completo, sino sólo aquellos archivos que hayamos modificado, con el consiguiente ahorro de tiempo y recursos que supone. • Reglas internas del make. Se refiere, por ejemplo, a reconocer el tipo de archivo por su extensión y realizar las acciones apropiadas si no está actualizado. Por ejemplo, make reconoce como archivos objeto los que tienen las extensión .o. Entonces, si el archivo correspondiente, pero con extensión .c ha cambiado, nos lo compilará automáticamente sin tener que especificárselo explícitamente. El funcionamiento es sencillo. Cada vez que llamamos a make éste busca un archivo de configuración; generalmente Makefile o makefile en el directorio actual, aunque es posible especificarle cuál. Luego, ejecutará los comandos que se le ordenen con el archivo Makefile o makefile. Para ello primero comprueba que los archivos de los que depende el proceso en cuestión están actualizados. Si no lo están, probablemente llevará a cabo alguna acción (como por ejemplo, compilar un fuente para tener el objeto). Si alguna dependencia falla, esto es, algún archivo no existe y no tiene forma de crearlo, el programa dará un error y se detendrá. Si no, ejecutará los comandos indicados hasta el final. El archivo makefile Las macros nos ayudarán a simplificar el trabajo. Muchas veces es conveniente especificar una lista de archivos, o de opciones, que vamos a pasar a varios programas. Si la lista es muy larga es mejor definir una macro que represente toda esta lista. Las macros se especifican en la cabecera del archivo, antes de las reglas. Una macro puede tener cualquier nombre compuesto por caracteres alfanuméricos. A la hora de insertarla en la regla correspondiente, ha de ir precedida del signo peso $ y si consta de más de un carácter, el nombre de la macro debe ir entre paréntesis (el peso se pone fuera). Las reglas constan de tres partes: • Una etiqueta, que usaremos en la llamada al programa make . Cada etiqueta distingue un grupo de acciones a realizar. • Un conjunto de dependencias, esto es, aquellos archivos que son necesarios para llevar a cabo las acciones que corresponden a la etiqueta. • Los comandos a ejecutar, aquí especificamos lo que queremos hacer realmente: compilar, generar un nuevo formato, cargar un programa en memoria, etc. A.R.G. Laboratorio de Sistemas Operativos 3/5 Hay que tener en cuenta que, para cada línea de comando, make creará un proceso distinto, por ejemplo, estas líneas indican a make que cambie de directorio y, a parte, que compile el archivo prueba.c. all: cd .. gcc prueba.c Si el archivo prueba.c está en el directorio padre obtendremos un error porque realmente no hemos cambiado de directorio. Lo correcto sería: all: cd ..; prueba.c La forma en la que se escriben las reglas es esta: etiqueta : [dependencia1 ...] [;comandos] [# comentarios] [(tabulación) comandos] [# comentarios] Ejecutando make Generalmente escribiremos simplemente make y él mismo se encargará, guiado por el archivo makefile, de llevar a cabo aquello que le pedimos. Si hacemos esto, make buscará la primera etiqueta de todas y hará aquello que especifica. Otras veces queremos que nos ejecute los comandos especificados en otra etiqueta. Esto es tan simple como escribir make nombre_de_la_etiqueta. Cada comando que ejecute make nos aparecerá escrito por pantalla. Si deseamos que algún comando no lo escriba, podemos poner una @ delante del comando en cuestión para que no lo haga. Además del nombre de la etiqueta, es posible pasarle otras opciones. Hay bastantes, pero las más útiles son: Ignora todos los errores que encuentre durante el proceso. No parará cuando -i encuentre alguno, sino que seguirá ejecutando comandos hasta el final. No escribe en pantalla los comandos conforme los va ejecutando. -s No usa las reglas internas ni las que se refieren a los sufijos. -r Escribe los comandos que deberían ejecutarse, pero no lo hace. Incluso las líneas -n que comienzan con "@". Actualiza las fechas de los comandos, como si se hubiesen ejecutado los comandos -t correspondientes. Devuelve cero o distinto de cero dependiendo de si el archivo objetivo está -q actualizado o no. Escribe en pantalla el conjunto completo de macros y reglas. -p Permite especificar el nombre del archivo de configuración. Se supone que el -f siguiente argumento es el nombre de dicho archivo. En la página manual del make se puede encontrar una lista completa de todas las opciones. Reglas implícitas A la hora de tratar con archivos, make es capaz de reconocerlos a partir de la extensión (o sufijo) que lleven. Entonces, dado un archivo concreto, si alguno de los archivos de los que depende ha sido modificado, si ha reconocido el tipo puede actualizarlo de manera eficiente. Es posible que make se engañe si usamos algunos de los sufijos que reconoce para otras cosas, así que aquí se incluye una pequeña relación de ellos: .c archivo fuente de código C. .f archivo fuente de Fortran. .s archivo fuente de Ensamblador. .y archivo fuente de Bison-Yacc. A.R.G. Laboratorio de Sistemas Operativos 4/5 Algunos Ejemplos Como se puede apreciar en el siguiente ejemplo si una línea es demasiado larga, podemos poner una contrabarra y continuar en la línea siguiente, tanto en la definición de macros como en la de comandos. La etiqueta all se refiere a la creación del ejecutable final, mientras que comp se encarga de compilar los fuentes y save para hacer una copia de seguridad de todo el trabajo. Realmente, la eitqueta comp sobra, según las reglas implícitas del make. FILES= flectura.c fagnadir.c agnadir.c ini.c estad.c varios.c mensaje.c flujo.c\ describe.c juntar.c selec.c ordenar.c OFILES=flectura.o fagnadir.o agnadir.o ini.o estad.o varios.o mensaje.o flujo.o\ describe.o juntar.o selec.o ordenar.o PFILE= main.c LIBS= -lm NOMBRE= xx all: $(OFILES) gcc -g -o $(NOMBRE) $(OFILES) $(PFILE) $(LIBS) comp: $(FILES) gcc -g -c $(FILES) save: tar cvfz /home/xx.tgz /home/xx En el siguiente caso si un programa llamado hello ya existe entonces se le compara la fecha con hello.c y hello.h y si alguno de estos dos archivos han cambiado desde que se creó hello se recompila hello, caso contrario no se hace nada. hello : hello.cc hello.h g++ hello.cc -o hello En el próximo ejemplo se generan primero los archivos objetos y luego se linkea el programa ejecutable lab13. El argumento -c en g++ significa que solo genere el archivo .o. Como esta clase de cosas es común existen reglas por defecto que hacen esto automáticamente. default : lab13 lab13 : lab13.o openfiles.o g++ lab13.o openfiles.o -o lab13 openfiles.o : openfiles.cc openfiles.h g++ openfiles.cc -o openfiles.o -c lab13.o : lab13.cc openfiles.h g++ lab13.cc -o lab13.o -c En el último ejemplo no existen reglas para generar los archivos objetos correspondientes a los archivos .cc. Esto se debe a la existencia de las reglas implícitas del make, en caso que no exista una regla asociada al archivo .o se ejecutará por defecto la siguiente regla: $(CPP) $(CPPFLAGS) -o *.o *.cc -c TARG = program_name OFILES = support_obj1.o support_obj2.o support_obj3.o ... CPP = g++ CPPFLAGS = -g -O2 -Wall default : $(TARG) $(TARG) : $(TARG).o $(OFILES) $(CPP) $(CPPFLAGS) -o $(TARG) $(TARG).o $(OFILES) A.R.G. Laboratorio de Sistemas Operativos 5/5