Вы находитесь на странице: 1из 7

ESO/SOL. Prctica 2.

Mdulos del ncleo


Juan Carlos Prez, Sergio Sez and Ismael Ripoll

ESO/SOL. Prctica 2. Mdulos del ncleo

Table of Contents
Prctica 2. Mdulos del ncleo..........................................................................................................................1
2.1 Introduccin.......................................................................................................................................1
2.2 Los mdulos cargables en Linux.......................................................................................................1
2.3 Programacin de los mdulos............................................................................................................2
2.4 Utilizacin de los mdulos................................................................................................................3
2.5 Tarea a realizar...................................................................................................................................4
2.6 Comprobacin del funcionamiento....................................................................................................5

Prctica 2. Mdulos del ncleo


Ismael Ripoll, Juan Carlos Prez, y Sergio Sez
Sergio Sezssaez@disca.upv.es
Juan Carlos Prezjcperez@disca.upv.es

2.1 Introduccin
Podis guardar vuestros ficheros en discos flexibles, ya que slo es necesario conservar de una sesin
a otra los ficheros fuente que hayis modificado, no el resto de ficheros del ncleo, ni ejecutables, ni
ficheros objeto (.o). Los ficheros modificados siempre sern de un tamao perfectamente manejable.
Para manejar los disquetes podis montarlos con la orden mount(8) o bien usar las "mtools":
mdir(1), mformat(1), mcopy(1), mdel(1), etc.
Recordad siempre borrar todo antes de apagar la mquina.

2.2 Los mdulos cargables en Linux


El ncleo de Linux est organizado siguiendo una arquitectura monoltica, en la cual, todas las partes del
ncleo del sistema operativo (sistemas de ficheros, manejadores de dispositivos, protocolos de red, etc.) estn
enlazadas como una sola imagen (normalmente el fichero /vmlinuz) que es la que se carga y ejecuta en el
arranque del sistema.
Esta estructura podra dar lugar a un sistema poco flexible, ya que cualquier funcionalidad que se le quisiera
aadir al ncleo del sistema requerira una recompilacin completa del mismo. An as, la filosofa de fuentes
abiertos hace Linux mucho ms flexible que otros sistemas operativos en la que los fuentes no estn
disponibles. No obstante, la recompilacin total del ncleo puede resultar engorrosa en las fases de desarrollo
de nuevos manejadores de dispositivo, ampliaciones no oficiales del ncleo, etc.
Esta limitacin desapareci con la incorporacin, en la versin 2.0 de Linux, del soporte para la carga
dinmica de mdulos en el ncleo. Esta nueva caracterstica permite la incorporacin en caliente de nuevo
cdigo al ncleo del sistema operativo, sin necesidad de reinicializar el sistema.
La prctica aborda el desarrollo de dos pequeos mdulos.

Los mdulos son "trozos de sistema operativo", en forma de ficheros objeto (.o), que se pueden insertar y
extraer en tiempo de ejecucin. Dichos ficheros .o se pueden obtener directamente como resultado de la
compilacin de un fichero .c (gcc c prog.c), o como la unin de varios ficheros .o (ld r
f1.o f2.o). La nica caracterstica especial que deben tener estos ficheros, es la de incorporar las
funciones init_module y cleanup_module. Ms adelante veremos su utilidad.
Prctica 2. Mdulos del ncleo

ESO/SOL. Prctica 2. Mdulos del ncleo


Una vez desarrollado un mdulo e insertado en el ncleo, su cdigo pasa a ser parte del propio ncleo, y por
lo tanto se ejecuta en el modo supervisor del procesador (nivel de privilegio 0 en la arquitectura i386), con
acceso a todas las funciones del ncleo, a las funciones exportadas por mdulos previamente insertados, y a
todo el hardware de la mquina sin restricciones.
La nica diferencia con cdigo enlazado en el ncleo es la posibilidad de extraer el mdulo una vez ha
realizado su labor o ha dejado de ser til, liberando as todos los recursos utilizados.

Como quiera que el cdigo de un mdulo puede utilizar cualquier funcin del ncleo, pero no ha sido
enlazado en tiempo de compilacin con l, las referencias a las funciones del ncleo no estn resueltas. As
pues, el proceso de insercin de un mdulo debe seguir una serie de pasos:
1. Obtener las referencias a funciones ofrecidas por el mdulo.
2. Incorporar dichas referencias al ncleo, como referencias temporales (desaparecern con la extraccin
del mdulo).
3. Resolver las referencias a las funciones no resueltas en el mdulo, ya sean a funciones del ncleo,
como a funciones de otro mdulos.
4. Insertar el mdulo en la zona de memoria correspondiente al ncleo.
5. Finalmente, invocar a la funcin init_module del nuevo mdulo.
La extraccin de un mdulo del ncleo se realiza mediante una secuencia similar a la anterior, pero en orden
inverso, donde antes de extraer el mdulo se invoca a la funcin cleanup_module.

2.3 Programacin de los mdulos


La funcin init_module nos van a permitir inicializar el mdulo al insertarlo en el ncleo (equivaldra a la
funcin main de un programa en C). Complementariamente, cleanup_module se usar para liberar los
recursos utilizados cuando se vaya a extraer.
A continuacin vamos a ver cmo podemos crear, insertar y extraer un mdulo. Todo ello acompaado de
algunos ejemplos. Los mdulos son una caracterstica opcional de Linux que se elige cuando se compila el
ncleo, y por lo tanto, nuestro ncleo debe tenerla activada si queremos utlizar est caracterstica del sistema.
Un mdulo se crea a partir de un fuente en "C". A continuacin tenemos un mdulo mnimo:
Fichero ejemplo.c:
#ifndef __KERNEL__
# define __KERNEL__
#endif
#ifndef MODULE
# define MODULE
#endif
#include <linux/module.h>
#include <linux/kernel.h>
int n=1;

2.3 Programacin de los mdulos

ESO/SOL. Prctica 2. Mdulos del ncleo


MODULE_PARM(n,"i");
int init_module(void) {
printk("Entrando. n=%d\n",n);
return 0;
}
void cleanup_module(void) {
printk("Saliendo.\n");
}

La orden de compilacin sera:


# gcc I /usr/src/linux/include O2 c ejemplo.c
Busca en el manual de gcc todas las opciones que aparecen en esa lnea de compilacin.
No te quedes con ninguna duda al respecto!!
Si no entiendes algo, pregntalo.
Para que estn disponibles los ficheros de cabecera necesarios para compilar, los fuentes del ncleo deben
estar en su sitio (/usr/src/linux) y se debe haber ejecutado al menos make xconfig (grabando la
configuracin) y make depend.

El ncleo no dispone de salida estndar, por lo que no podemos utilizar la funcin printf(). A cambio, el
ncleo ofrece una versin de sta, llamada printk(), que funciona casi igual, a excepcin de que el
resultado lo imprime sobre un buffer circular de mensajes (kernel ring buffer).
En el kernel ring buffer es donde se escriben todos los mensajes del ncleo. De hecho, son los mensajes que
vemos cuando arranca Linux. En cualquier momento podemos ver su contenido reciente con la orden dmesg
o su contenido inmediato consultando el fichero /proc/kmsg.
El manejo de los mensajes por el kernel es muy flexible y algo complejo (ver klogd(8) y
/usr/src/linux/include/linux/kernel.h). Concretamente, los primeros 3 caracteres de los
mensajes impresos a travs de printk deben ser <n>, donde n es un nmero entre 0 y 7, ambos inclusive.
KERN_EMERG
KERN_ALERT
KERN_CRIT
KERN_ERR
KERN_WARNING
KERN_NOTICE
KERN_INFO
KERN_DEBUG

System is unusable
Action must be taken immediately
Critical conditions
Error conditions
Warning conditions
Normal but significant condition
Informational
Debuglevel messages

Normalmente, el ncleo est configurado para mostrar por la consola activa los mensajes de prioridad superior
a 6. (Los terminales grficos no son consolas, a no ser que se hayan lanzado explcitamente como tales).

2.4 Utilizacin de los mdulos


La carga de un mdulo se lleva a cabo mediante la orden insmod, que realizar todas las acciones
comentadas antes para insertar el cdigo en el ncleo. Haz, desde una consola:
# insmod ejemplo.o

2.4 Utilizacin de los mdulos

ESO/SOL. Prctica 2. Mdulos del ncleo


Acabamos de instalar ejemplo y ejecutar su funcin init_module(). Si se le pasa a insmod un nombre
de fichero sin ruta ni extensin, se busca en los directorios estndar (ver insmod(8)).
La orden lsmod permite listar los mdulos que en un momento dado tenemos instalados:
# lsmod
Y, finalmente, con rmmod podemos extraer del ncleo el mdulo (el nombre no incluye la extensin .o):
# rmmod ejemplo

Para pasar parmetros a un mdulo, no hay ms que asignar valores a las variables globales declaradas como
parmetros con la macro MODULE_PARM. Como hemos visto en el programa de ejemplo, MODULE_PARM
recibe como primer argumento el nombre de la variable y como segundo argumento, el tipo. Ms
concretamente:
El tipo debe ser una cadena con el formato [min[max]]{b,h,i,l,s}.
Si aparecen, min y max indican el mnimo y mximo nmero de elementos, del tipo indicado despus, que,
separados por comas, pueden asignarse a la variable (que ser entonces un vector). El carcter final indica el
tipo de la variable o vector segn la tabla:

b byte
h short
i int
l long
s string

La definicin de MODULE_PARM puede consultarse en el fichero


/usr/src/linux/include/linux/module.h.
La sintaxis es muy sencilla, ya que basta con escribir la asignacin como parmetro de insmod.
Por ejemplo (prubalo mejor desde una consola):
# insmod ejemplo.o n=4
Con modinfo p ejemplo.o podemos averiguar qu parmetros puede recibir el mdulo.
Se ha mostrado una perspectiva global de la constrcuccin y uso de los mdulos en Linux. Se puede encontrar
ms informacin, por ejemplo, en http://www.ddj.com/articles/1995/9505/9505a/9505a.htm

2.5 Tarea a realizar

2.5 Tarea a realizar

ESO/SOL. Prctica 2. Mdulos del ncleo


El objetivo de la prctica consiste en la implementacin de dos mdulos cargables en el ncleo de Linux.
Estos mdulos, acumulador y cliente, debern comportarse segn los criterios siguientes:
Cada uno de ellos ha de mostrar cuando lo insertemos o extraigamos un mensaje informativo indicando el
instante de insercin y de extraccin (en nmero de segundos desde el uno de enero de 1970).
Podemos obtener el instante actual consultando la variable xtime, declarada en kernel/sched.h. El tipo
de esta variable es struct timeval y est definido en include/linux/time.h (luego debes incluir
este fichero).
Recuerda declarar esta variable como externa para que el compilador sepa su tamao y estructura.
extern tipo variable;

El mdulo acumulador debe definir una funcin void acumular(int i), que reciba un parmetro
entero y vaya sumando su valor a una variable global. Esta funcin debe ser exportable (en C, toda funcin no
static es exportable).
El mdulo acumulador tambin debe ofrecer una funcin int llevamos(void), que devuelva cunto
lleva acumulado.
El mdulo cliente, al ser insertado, debe llamar a la funcin acumular() del mdulo acumulador
con un valor a acumular igual al parmetro que le pasemos al mdulo cliente al insertarlo.
El mdulo cliente, al ser extraido, debe llamar a la funcin llevamos() del mdulo acumulador e
imprimir el resultado en su mensaje de salida.
El mdulo acumulador, al ser extraido, tambin debe imprimir el resultado final de la suma en su mensaje
de salida.

2.6 Comprobacin del funcionamiento


Comprueba que los mdulos implementados se compilan correctamente. Despus inserta el mdulo
acumulador y comprueba que imprime el mensaje inicial.
Extrae el mdulo acumulador y comprueba el mensaje. Despus intenta insertar el cliente sin que est
el acumulador insertado.
Comprueba el funcionamiento del conjunto acumulando una serie de valores y extrayendo finalmente el
mdulo acumulador para ver el resultado.
Usa lsmod cada vez que insertes y extraigas los mdulos, para asegurarte de que todo funciona. Trabaja en
una consola de texto para ver los mensajes. Imprime stos con nivel de prioridad menor que 6.

2.6 Comprobacin del funcionamiento

Вам также может понравиться