Publicado el 14 de Enero del 2017
794 visualizaciones desde el 14 de Enero del 2017
380,1 KB
50 paginas
Creado hace 16a (03/03/2009)
Periféricos Interfaces y Buses
UNIVERSIDAD
DE CANTABRIA
I. Arquitectura de E/S
II. Programación de E/S
Aspectos básicos de la programación de E/S. Arquitectura y
programación de la E/S en el sistema operativo. Manejadores de
dispositivos (drivers) y su programación (interrupciones).
III. Interfaces de E/S de datos
IV. Dispositivos de E/S de datos
V. Buses
VI. Controladores e interfaces de dispositivos de almacenamiento
VII. Sistemas de almacenamiento
GRUPO DE COMPUTADORES Y TIEMPO REAL
FACULTAD DE CIENCIAS
8
© J. Javier Gutiérrez, Michael González
3/mar/09
1
UNIVERSIDAD
DE CANTABRIA
II. Programación de E/S
Bloque II
• Operaciones de control en el driver
• Sincronización
• Temporización
• Acceso al hardware
• Interrupciones
• Threads del kernel
GRUPO DE COMPUTADORES Y TIEMPO REAL
FACULTAD DE CIENCIAS
© J. Javier Gutiérrez, Michael González
3/mar/09
2
Operaciones de control en el driver
UNIVERSIDAD
DE CANTABRIA
Las operaciones de control sobre el dispositivo se hacen a través
del punto de entrada ioctl:
• establecer ciertos parámetros del dispositivo
• obtener información sobre el estado del mismo
La orden de control al dispositivo consta de dos parámetros:
• cmd es la orden
• arg es un argumento para ejecutar la orden
En Linux los comandos se pueden definir de acuerdo a unos
criterios que codifican los números mágicos:
• cuatro grupos de bits: tipo, número, dirección y tamaño
• una serie de macros para construirlos y consultarlos
GRUPO DE COMPUTADORES Y TIEMPO REAL
FACULTAD DE CIENCIAS
© J. Javier Gutiérrez, Michael González
3/mar/09
3
Operaciones de control en el driver
(cont.)
UNIVERSIDAD
DE CANTABRIA
En cualquier caso los comandos y los argumentos que éstos
necesitan son un compromiso entre el driver y el programa de
aplicación
La implementación del ioctl es normalmente una instrucción
switch basada en el número del comando
El valor de retorno:
• si el número de comando no es válido algunas funciones
devuelven -EINVAL (argumento inválido)
• POSIX establece que se devuelva -ENOTTY (comando
inapropiado para dispositivo)
GRUPO DE COMPUTADORES Y TIEMPO REAL
FACULTAD DE CIENCIAS
© J. Javier Gutiérrez, Michael González
3/mar/09
4
Acceso al argumento del ioctl
UNIVERSIDAD
DE CANTABRIA
Como para las operaciones de lectura y escritura es necesario
intercambiar infomación con la memoria de usuario
• se pueden utilizar copy_from_user y copy_to_user
• para intercambio de datos pequeños (uno, dos, cuatro y ocho
bytes) se pueden utilizar otras macros definidas en <asm/
uaccess.h>:
put_user(dato, puntero);
get_user(local, puntero);
- escribe el dato al puntero del espacio de usuario y viceversa
- el tamaño del dato depende del tipo del puntero
- devuelve un cero si va bien o -EFAULT si falla; se llama
internamente a access_ok que chequea si el puntero es válido
GRUPO DE COMPUTADORES Y TIEMPO REAL
FACULTAD DE CIENCIAS
© J. Javier Gutiérrez, Michael González
3/mar/09
5
UNIVERSIDAD
DE CANTABRIA
Ejemplo: iocontrol
Definición de las constantes de control
// ioconst.h
// comandos de ioctl
#define CAMBIAR_MODO 10
#define LEER_MODO 100
// modos de operación para el argumento
#define IO_MODO1 1
#define IO_MODO2 2
GRUPO DE COMPUTADORES Y TIEMPO REAL
FACULTAD DE CIENCIAS
© J. Javier Gutiérrez, Michael González
3/mar/09
6
Ejemplo: iocontrol (cont.)
UNIVERSIDAD
DE CANTABRIA
// iocontrol.h
int iocontrol_open(struct inode *inodep, struct file *filp);
int iocontrol_release(struct inode *inodep, struct file *filp);
ssize_t iocontrol_read (struct file *filp, char *buff,
size_t count, loff_t *offp);
ssize_t iocontrol_write (struct file *filp, const char *buff,
size_t count, loff_t *offp);
int iocontrol_ioctl(struct inode *inodep, struct file *filp,
unsigned int cmd, unsigned long arg);
GRUPO DE COMPUTADORES Y TIEMPO REAL
FACULTAD DE CIENCIAS
© J. Javier Gutiérrez, Michael González
3/mar/09
7
Iocontrol: includes y variables globales
UNIVERSIDAD
DE CANTABRIA
#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/cdev.h>
#include <asm/uaccess.h>
#include "iocontrol.h"
#include "ioconst.h"
MODULE_LICENSE("GPL");
struct iodatos {
struct cdev *cdev; // Character device structure
dev_t dev; // informacion con el numero mayor y menor
int modo; // registro del modo de operación
};
static struct iodatos datos;
GRUPO DE COMPUTADORES Y TIEMPO REAL
FACULTAD DE CIENCIAS
© J. Javier Gutiérrez, Michael González
3/mar/09
8
Iocontrol: inicialización de puntos de
entrada y modo
UNIVERSIDAD
DE CANTABRIA
static struct file_operations iocontrol_fops = {
THIS_MODULE, // owner
..., // todo nulos
};
static int modulo_instalacion(void) {
...
// ponemos los puntos de entrada y el modo
iocontrol_fops.open=iocontrol_open;
iocontrol_fops.release=iocontrol_release;
iocontrol_fops.write=iocontrol_write;
iocontrol_fops.read=iocontrol_read;
iocontrol_fops.ioctl=iocontrol_ioctl;
datos.modo = IO_MODO1;
...
}
GRUPO DE COMPUTADORES Y TIEMPO REAL
FACULTAD DE CIENCIAS
© J. Javier Gutiérrez, Michael González
3/mar/09
9
Iocontrol: operaciones de lectura
UNIVERSIDAD
DE CANTABRIA
Solamente informan del estado que implementan
ssize_t iocontrol_read (struct file *filp, char *buff,
size_t count, loff_t *offp)
{
printk(KERN_INFO "iocontrol> (read) estoy en MODO 1\n");
return 0;
}
ssize_t iocontrol_read2 (struct file *filp, char *buff,
size_t count, loff_t *offp)
{
printk(KERN_INFO "iocontrol> (read) estoy en MODO 2\n");
return 0;
}
GRUPO DE COMPUTADORES Y TIEMPO REAL
FACULTAD DE CIENCIAS
© J. Javier Gutiérrez, Michael González
3/mar/09
10
Iocontrol: operaciones de escritura
UNIVERSIDAD
DE CANTABRIA
Solamente informan del estado que implementan
ssize_t iocontrol_write (struct file *filp, const char *buff,
size_t count, loff_t *offp)
{
printk(KERN_INFO "iocontrol> (write) estoy en MODO 1\n");
return count;
}
ssize_t iocontrol_write2 (struct file *filp, const char *buff,
size_t count, loff_t *offp)
{
printk(KERN_INFO "iocontrol> (write) estoy en MODO 2\n");
return count;
}
GRUPO DE COMPUTADORES Y TIEMPO REAL
FACULTAD DE CIENCIAS
© J. Javier Gutiérrez, Michael González
3/mar/09
11
Iocontrol: ioctl
UNIVERSIDAD
DE CANTABRIA
int iocontrol_ioctl (struct inode *inodep, struct file *filp,
unsigned int cmd, unsigned long arg)
{
int modo;
switch (cmd) {
case CAMBIAR_MODO:
// capturamos el modo que llega en arg
if (get_user(modo,(int *)arg)) {
printk(KERN_ERR "iocontrol> (ioctl) puntero erroneo\n");
return -EFAULT;
}
printk(KERN_INFO "iocontrol> (ioctl) el modo es =%d\n",modo);
GRUPO DE COMPUTADORES Y TIEMPO REAL
FACULTAD DE CIENCIAS
© J. Javier Gutiérrez, Michael González
3/mar/09
12
Iocontrol: ioctl (cont.)
UNIVERSIDAD
DE CANTABRIA
// cambiamos de modo
switch (modo) {
case IO_MODO1:
filp->f_op->read=iocontrol_read;
filp->f_op->write=iocontrol_write;
datos.modo=modo;
break;
case IO_MODO2:
filp->f_op->read=iocontrol_read2;
filp->f_op->write=iocontrol_write2;
datos.modo=modo;
break;
default:
printk(KERN_ERR "iocontrol> (ioctl) modo %d no valido\n",modo);
return -EINVAL;
}
break; // fin de CAMBIAR_MODO
GRUPO DE COMPUTADORES Y TIEMPO REAL
FACULTAD DE CIENCIAS
© J. Javier Gutiérrez, Michael González
3/mar/09
13
Iocontrol: ioctl (cont.)
UNIVERSIDAD
DE CANTABRIA
case LEER_MODO:
if (put_user(datos.modo,(int *)arg)) {
printk(KERN_ERR "iocontrol> (ioctl) puntero erroneo\n");
return -EFAULT;
}
break;
default:
printk(KERN_ERR "iocontrol> (ioctl) comando %d no valido\n",cmd);
return -EINVAL;
}
printk(KERN_INFO "iocontrol> (ioctl) nuevo modo =%d\n",datos.modo);
return 0;
}
GRUPO DE COMPUTADORES Y TIEMPO REAL
FACULTAD DE CIENCIAS
© J. Javier Gutiérrez, Michael González
3/mar/09
14
Prueba de iocontrol
UNIVERSIDAD
DE CANTABRIA
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>
#include <stdlib.h>
#include <sys/ioctl.h>
#include "ioconst.h"
int main() {
int fd;
int modo;
char *mistring="Hola yo soy un mensaje";
char strleido[100];
ssize_t leidos, escritos;
GRUPO DE COMPUTADORES Y TIEMPO REAL
FACULTAD DE CIENCIAS
© J. Javier Gutiérrez, Michael González
3/mar/09
15
Prueba de iocontrol (cont.)
UNIVERSIDAD
DE CANTABRIA
//Primer uso dejado con el modo cambiado
fd=open("/dev/ioctl0", O_RDWR);
if (fd==-1) { perror("Error al abrir el fichero");
exit(1);}
printf("Fichero abierto\n");
escritos=write(fd,mistring,strlen(mistring)+1);
printf("Escrito en modo 1\n");
//cambio a modo 2
modo=IO_MODO2;
ioctl(fd,CAMBIAR_MODO,&modo);
leidos=read(fd,&strleido,100);
printf("Leido en modo 2\n");
//cambio de nuevo a modo 1
modo=IO_MODO1;
ioctl(fd,CAMBIAR_MODO,&modo);
leidos=read(fd,&strleido,100);
printf("Leido en modo 1\n");
GRUPO DE COMPUTADORES Y TIEMPO REAL
FACULTAD DE CIENCIAS
© J. Javier Gutiérrez, Michael González
3/mar/09
16
Prueba de iocontrol (cont.)
UNIVERSIDAD
DE CANTABRIA
// cambio final a modo 2
modo=IO_MODO2;
ioctl(fd,CAMBIAR_MODO,&modo);
escritos=write(fd,mistring,strlen(mistring)+1);
printf("Escrito en modo 2\n");
if (close(fd)==-1) {perror("Error al cerrar el fichero");
exit(1);}
printf("Fichero cerrado\n");
//Segundo uso
fd=open("/dev/ioctl0", O_RDWR);
if (fd==-1) {perror("Error al abrir el fichero");
exit(1);}
printf("Fichero abierto\n");
GRUPO DE COMPUTADORES Y TIEMPO REAL
FACULTAD DE CIENCIAS
© J. Javier Gutiérrez, Michael González
3/mar/09
17
Prueba de iocontrol (cont.)
UNIVE
Comentarios de: Periféricos Interfaces y Buses - II. Programación de E/S Aspectos básicos de la programación de E/S (0)
No hay comentarios