martes, 30 de marzo de 2010

Ya, ya ya?

Hasta el momento he recibido muy pocos proyectos!!!


Ya, ya, ya???


Atentamente,
rdvarela

Ah, si...

Felices Vacaciones... (pero ya, ya, ya?)

lunes, 22 de marzo de 2010

Extensión de entrega del proyecto.

Recibí un correo de su compañero Julio, a nombre de todos ustedes, pidiendo extensión de tiempo para la entrega del proyecto...

"De cualquier forma, lo van a entregar después... :P"

... Así que,

Si... si extiendo la fecha de entrega, no mas no se tarden mucho, que empezaré a bajar puntos, a partir del viernes... :P

Salu2!
rdvarela

viernes, 12 de marzo de 2010

Agregar modulo al kernel 2.6.33

8. Agregando un modulo de Kernel
Para cargar un modulo de kernel es necesario realizar lo siguiente:
ls –l /lib/modules/`uname -r`
El resultado que se necesita seria uno como lo que a continuación se muestra:
lrwxrwxrwx 1 root root 07 mar 10 10:24 build -> /usr/src/linux-2.6.33
Esto es porque apunta a la raiz del código de nuestro kernel.
Ahora se mostrara un ejemplo con un archivo .c con el clásico Hola Mundo.
#include
#include
#include

static int hola_start(void)
{
printk(KERN_INFO "Cargando el modulo ...\n");
printk(KERN_INFO "Hola mundo!!\n");
return 0;
}

static void hola_end(void)
{
printk(KERN_INFO "Adios modulo!!\n");
}

module_init(hola_start);
modulo_exit(hola_end);
MODULE_DESCRIPTION("Prueba para cargar un modulo.");
MODULE_DESCRIPTION("Perla Diaz");
MODULE_DESCRIPTION("Edgar Garcia");
MODULE_DESCRIPTION("Dante Ramirez");

Después se requiere compilar y para esto se requiere el Makefile. Lo que se hará al compilar será detectar la ruta del directorio de los módulos, dirigirse a ese directorio y compilar el modulo desde ahí.
ifeq ($(KERNELRELEASE),)

KERNELDIR ?= /lib/modules/$(shell uname -r)/build
PWD := $(shell pwd)

.PHONY: build clean

build:
$(MAKE) -C $(KERNELDIR) M=$(PWD) modules

clean:
rm -rf *.o *~ core .depend .*.cmd *.ko *.mod.c
else

$(info Building with KERNELRELEASE = ${KERNELRELEASE})
obj-m := hola.o

endif

Una vez compilado el kernel se obtendrá un archivo con la extensión .ko
Con modinfo hola.ko se obtiene la información de nuestro modulo.

9. Cargar y remover el modulo
Cargar el modulo:
insmod hola.ko
Mostrar los modulos:
lsmod
Para ver la información que debió imprimir nuestro modulo:
dmesg | tail
Para remover el modulo:
rmmod hola

Compilar Kernel

Resumen de los pasos a seguir para compilar Kernel

  1. Instalar paquetes necesarios y sus dependencias.

a) apt-get update

b) apt-get install manpages

c) apt-get install make

d) apt-get install gcc

e) apt-get install automake

f) apt-get install autoconf

g) apt-get install libc6-dev

h) apt-get install debianutils

i) apt-get install binutils

j) apt-get install libc6

k) apt-get install apt-utils

l) apt-get install kernel-package

m) apt-get install libncurses5-dev

n) apt-get install dphys-kernel-packages

o) apt-get install kernel-package ncurses-dev

p) apt-get install fakeroot wget bzip2

q) apt-get install initrd-tools

  1. Descargar el kernel, desempaquetar

a) cp Desktop/linux-2.6.33.tar.bz2 /usr/src/

b) cd /usr/src/

c) tar -xjvf /usr/src/linux-2.6.33.tar.bz2

d) ln -s /usr/src/linux-2.6.33/ /usr/src/linux

e) cd linux

  1. Configurar el kernel.
    1. Cargar fichero de opciones (.config) anterior si está disponible.
    2. make menuconfig
    3. Guardar fichero de configuración en algún otro lugar para utilizarlo como base en nuevas compilaciones.

  1. Crear la imagen del kernel, con el paso a o con el paso b y c.
    1. Creación de la imagen

· cd linux

· make menuconfig

· make dep

· make clean

· make bzImage

· make modules

· make modules_install

· make install

    1. Si esta es una recopilación del mismo kernel compruebe el número de revisión y haga

make-kpkg clean.

    1. Crear la imagen del Kernel.

make-kpkg --revision=custom.X.X kernel_image

  1. Una vez instalado el siguiente paso es el siguiente.

a. cd /boot

b. mkinitrd -o /boot/initrd.img-2.6.33

  1. Ahora se tiene que modificar el siguiente archivo para que se agregue la información para arrancar con el nuevo kernel instalado.

a. vi /boot/grub/menu.lst

title Ubuntu, kernel 2.6.33

root (hd0,0)

kernel /boot/vmlinuz-2.6.33 root=/dev/hda1 ro

initrd /boot/initrd.img-2.6.33


  1. Ahora se actualiza el grub con los siguientes archivos.

a. update-initramfs -c -k 2.6.33

b. dpkg-reconfigure grub

c. reboot

miércoles, 10 de marzo de 2010

SIGNAL

La llamada al sistema signal() es utilizada para establecer un manejador de señales para un
determinado tipo de señal. signal() acepta un numero de señal y un apuntdor a la función
manejadora de señales, y prepara la manejador para aceptar la señal dada.

Si hay un manipulador de señal para una señal dada se invoca y, si no lo hay, se usa el
manipulador por defecto. El proceso puede especificar también dos comportamientos por
defecto sin necesidad de crear un manipulador: ignorar la señal (SIG_IGN) y usar el
manipulador por defecto (SIG_DFL). Hay dos señales que no pueden ser interceptadas ni
manipuladas: SIGKILL y SIGSTOP.

NOMBRE
signal - manejo de señales en ANSI C

SINOPSIS
#include
typedef void (*sighandler_t)(int);
sighandler_t signal(int signum, sighandler_t handler);

DESCRIPCIÓN
La llamada al sistema signal() instala un nuevo manejador de señales para la señal
con número signum. El manejador de señales queda establecido a sighandler que
puede ser una función especificada por el usuario o bien SIG_IGN o SIG_DFL.
Cuando llega una señal con número signum ocurre lo siguiente.
· Si el manejador correspondiente está establecido a SIG_IGN, la señal es ignorada.
· Si el manejador está establecido a SIG_DFL, se realiza la acción por defecto
asociada a la señal.
· Si el manejador está establecido a una función sighandler lo primero que se hace
es o bien restablecer el manejador a SIG_DFL o un bloqueo de la señal que
depende de la implementación, invocando después a sighandler con el argumento
signum.

LISTA DE SEÑALES
La Single Unix Specification especifica las siguientes señales, definidas en :
· SIGABRT - Proceso abortado.
· SIGALRM - Señal de alarma, salta al expirar el timer. Reprogramable.
· SIGBUS - Error en el bus "access to undefined portion of memory object"(SUS).
· SIGCHLD - Proceso hijo terminado, detenido (*o que continúa). Tratamiento por
defecto: ignorar. Reporgramable.
· SIGCONT - Continúa si estaba parado.Tratamiento por defecto: continuar.
Reprogramable.
· SIGFPE - Excepción de coma flotante -- "erroneous arithmetic operation"(SUS).
· SIGHUP - Hangup, al salir de la sessión se envía a los processos en Background.
Tratamiento por defecto: exit. Reprogramable.
· SIGILL - Instrucción ilegal.
· SIGINT - Interrupción, se genera al pulsar "^c" durante la ejecución. Tratamiento
por defecto:exit. Reprogramable.
· SIGKILL - Destrucción inmediata del proceso.Tratamiento:exit. No reprogramable,
no ignorable.
· SIGPIPE - Se genera al escribir sobre la pipe sin lector. Tratamiento por
defecto:exit. Reprogramable.
· SIGQUIT - Terminar.
· SIGSEGV - segmentation violation.Salta con dirección de memoria ilegal.
Tratamiento por defecto:exit + volcado de memoria. Reprogramable.
· SIGSTOP - Detiene el proceso. Se genera al pulsar "^z" durante la ejecución. No
reprogramable, no ignorable.
· SIGTERM - Terminación. Tratamiento por defecto:exit. Reprogramable.
· SIGTSTP - Parada de terminal.
· SIGTTIN - Proceso en segundo plano intentando leer ("in").
· SIGTTOU - Proceso en segundo plano intentando escribir ("out").
· SIGUSR1 - User defined 1. Signal definido por el usuario.Tratamiento por defecto:
exit. Reprogramable.
· SIGUSR2 - User defined 2. Signal definido por el usuario.Tratamiento por defecto:
exit. Reprogramable.
· *SIGPOLL - Pollable event.
· *SIGPROF - El temporizador copiador expiró.
· *SIGSYS - Mala llamada al sistema.
· *SIGTRAP - Trace/breakpoint trap.
· SIGURG - datos importantes disponibles en socket
· *SIGVTALRM - "virtual timer expired"(SUS)
· *SIGXCPU - excedido límite de tiempo de CPU
· *SIGXFSZ - excedido límite de tamaño de fichero
Nota: el asterisco significa que es una extensión de X/Open System Interfaces (XSI). Las
frases entre comillas y seguidas de (SUS) son la forma de escribirlas del SUS[1].

EJEMPLO
#include /* standard I/O functions */
#include /* standard unix functions, like getpid() */
#include /* signal name macros, and the signal() prototype */

/* first, here is the signal handler */
void catch_int(int sig_num)
{
/* re-set the signal handler again to catch_int, for next time */
signal(SIGINT, catch_int);
printf("Don't do that\n");
fflush(stdout);
}

int main(int argc, char* argv[])
{
/* set the INT (Ctrl-C) signal handler to 'catch_int' */
signal(SIGINT, catch_int);

/* now, lets get into an infinite loop of doing nothing. */
for ( ;; )
pause();
}


PIPE

Una tubería (pipe) proporciona una interfase entre dos procesos. Es un par de
descriptores de archivos especial que en lugar de estar conectado con un archivo, está
conectado a otro proceso. Así, cuando un proceso A escribe a su tubería, el proceso B
puede leer esos datos desde su descriptor de archivo de tubería. Existe la posibilidad
también de que cuando el proceso B escriba a su tubería, el proceso A pueda leer los
datos también desde su tubería. Una tubería proporciona un medio de comunicación
unidireccional para dos procesos.

Una vez que se crea una tubería, hay muy pocas diferencias entre un descriptor de archivo
de una tubería y un descriptor de archivo regular. De hecho, a menos que un programa
haga algo especial para saberlo, no sabrá que está escribiendo o leyendo una tubería en
lugar de un archivo.

NOMBRE
pipe - crea una tubería o interconexión

SINOPSIS
#include
int pipe(int descf[2]);

DESCRIPCIÓN
pipe crea un par de descriptores de archivos, que apuntan a un nodo de una tubería, y
los pone en el vector de dos elementos apuntado por descf. descf[0] es para lectura,
descf[1] es para escritura.

VALOR DEVUELTO
En caso de éxito, se devuelve cero. En caso de error se devuelve -1 y se pone un valor
apropiado en errno.

ERRORES
EMFILE El proceso tiene en uso demasiados descriptores de ficheros.
ENFILE La tabla de ficheros del sistema está llena.
EFAULT descf no es válido.

EJEMPLO
#include
#include
#include

int main(void)
{
int fd[2], nbytes;
pid_t childpid;
char string[] = "Hello, world!\n";
char readbuffer[80];

pipe(fd);

if((childpid = fork()) == -1)
{
perror("fork");
exit(1);
}

if(childpid == 0)
{
/* Child process closes up input side of pipe */
close(fd[0]);

/* Send "string" through the output side of pipe */
write(fd[1], string, (strlen(string)+1));
exit(0);
}
else
{
/* Parent process closes up output side of pipe */
close(fd[1]);

/* Read in a string from the pipe */
nbytes = read(fd[0], readbuffer, sizeof(readbuffer));
printf("Received string: %s", readbuffer);
}

return(0);
}

Uname & Select

UNAME(2)

NOMBRE uname - obtiene el nombre e información del núcleo actual

SINOPSIS #include %lt;sys/utsname.h%gt;

int uname(struct utsname *buf);

DESCRIPCIÓN uname devuelve información del sistema en la estructura apuntada por

buf. La estructura utsname se define en %lt;sys/utsname.h%gt;:

struct utsname {

char sysname[]; //Nombre del Sistema

char nodename[]; //Nombre de la maquina en la(s) red(es) *

char release[];

char version[]; Version del Kernel

char machine[];

#ifdef _GNU_SOURCE

char domainname[]; //Nombre del Dominio

#endif

};

La longitud de los vectores de la estructura utsname es indefinida; los campos terminan en NUL.

VALOR DEVUELTO Éxito à cero. Error à -1 y se establece el errno apropiado.

ERRORES EFAULT à buf no es válido.

CONFORME A

No hay ninguna llamada uname en BSD 4.3.

El miembro domainname (el nombre de dominio NIS o YP) es una extensión de GNU.

OBSERVACIONES

Cuatro de los campos de la estructura son relevantes (sysname, relase, versión y machine). Por otra parte, el campo nodename carece de importancia: da el nombre de la máquina actual en alguna red indefinida, pero normalmente las máquinas se encuentran en más de una red y tienen muchos nombres.

Además, el núcleo no tiene manera de conocer estas situaciones, por lo que hay que decirle cómo actuar en este caso. Lo mismo vale para el campo adicional domainname. Para este propósito Linux utiliza las llamadas al sistema sethostname(2) y setdomainname(2).

La longitud de los campos en la estructura varía. Algunos sistemas operativos o bibliotecas usan valores fijos como 9, 33, 65 o 257. Otros sistemas usan SYS_NMLN o _SYS_NMLN o UTSLEN o _UTSNAME_LENGTH. Claramente, es una mala idea usar cualquiera de estas constantes - tan sólo utilice sizeof(...). A menudo se elige 257 con el fin de tener espacio para un nombre de host en internet.

Ha habido tres llamadas al sistema uname() en Linux. La primera usaba longitud 9, la segunda usaba 65, la tercera también usa 65 pero añade el campo domainname.

Parte de la información de utsname también puede ser accedida vía sysctl y vía /proc/sys/kernel/{ostype, hostname, osrelease, version, domainname}.

SELECT(2)

NOMBRE select, pselect, FD_CLR, FD_ISSET, FD_SET, FD_ZERO - multiplexación de E/S síncrona

SINOPSIS /* Según POSIX 1003.1-2001 */

#include %lt;sys/select.h%gt;

/* Según estándares anteriores */

#include %lt;sys/time.h%gt;

#include %lt;sys/types.h%gt;

#include %lt;unistd.h%gt;

int select(int n, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout);

FD_CLR(int fd, fd_set *set);

FD_ISSET(int fd, fd_set *set);

FD_SET(int fd, fd_set *set);

FD_ZERO(fd_set *set);

DESCRIPCIÓN

Las funciones select espera a que un número de descriptores de fichero cambien de estado.

Usa un plazo de espera (timeout) que es de tipo struct timeval (con segundos y microsegundos).

Puede actualizar el parámetro timeout para indicar el tiempo sobrante.

Se miran tres conjuntos independientes de descriptores. Aquéllos listados en readfds serán observados para ver si hay caracteres que llegan a estar disponibles para lectura, aquéllos en writefds serán observados para ver si una operación de escritura no se bloqueará, y aquéllos en exceptfds serán observados para ver si ocurren excepciones. En caso de Éxito, los conjuntos se modifican en marcha para indicar qué descriptores cambiaron realmente su estado.

Cuatro macros para manipular los conjuntos. FD_ZERO limpiará un conjunto. FD_SET y FD_CLR añaden o borran un descriptor dado a o de un conjunto. FD_ISSET mira a ver si un descriptor es parte del conjunto; esto es útil después de que select regrese.

n es el descriptor con el número más alto en cualquiera de los tres conjuntos, más 1.

timeout es un límite superior de la cantidad de tiempo transcurrida antes de que select regrese. Puede ser cero. Si timeout es NULL (no hay tiempo de espera), select puede bloquear indefinidamente.

El plazo de espera o timeout tiene el siguiente aspecto

struct timeval {

long tv_sec; /* segundos */

long tv_usec; /* microsegundos */

};

VALOR DEVUELTO

Éxito à número de descriptores contenidos en los conjuntos de descriptores, que puede ser cero si el tiempo de espera expira antes de que ocurra algo interesante.

Error à -1, y se pone un valor apropiado en errno; los conjuntos y timeout estarán indefinidos, así que no confié en sus contenidos tras un error.

ERRORES

EBADF Se ha dado un descriptor de fichero inválido en uno de los conjuntos.

EINTR Se ha capturado una señal no bloqueante.

EINVAL n es negativo o el valor contenido en timeout no es válido.

ENOMEM select no ha sido capaz de reservar memoria para las tablas internas.

EJEMPLO

#include %lt;stdio.h%gt;

#include %lt;sys/time.h%gt;

#include %lt;sys/types.h%gt;

#include %lt;unistd.h%gt;

int

main(void) {

fd_set rfds;

struct timeval tv;

int valret;

/* Mirar stdin (df 0) para ver si tiene entrada */

FD_ZERO(&rfds);

FD_SET(0, &rfds);

/* Esperar hasta 5 s */

tv.tv_sec = 5;

tv.tv_usec = 0;

valret = select(1, &rfds, NULL, NULL, &tv);

/* ¡No confiar ahora en el valor de tv! */

if (valret)

write(1,"Los datos ya están disponibles.\n", 33);

/* FD_ISSET(0, &rfds) será verdadero */

else

write(1,"Ningún dato en 5 segundos.\n", 27);

return 0;

}

OBSERVACIONES

fd_set es un buffer de tamaño fijo. Ejecutar FD_CLR o FD_SET con un valor de fd que sea negativo o igual o mayor que FD_SETSIZE tendrá un comportamiento indefinido.

Referencia

Manuales: https://launchpad.net/ubuntu/hardy/+package/manpages-es