Dispositivi di I/O Gestione dell’ I/O e del Discohomes.di.unimi.it/.../SOLez20DiskDevx4.pdf ·...

19
Operating Systems and Distributed Systems Gestione dell’ I/O e del Disco Operating Systems and Distributed Systems 2 Dispositivi di I/O Operating Systems and Distributed Systems Caratteristiche degli I/O Devices Operating Systems and Distributed Systems 4 Dispositivi di I/O: la vista hardware

Transcript of Dispositivi di I/O Gestione dell’ I/O e del Discohomes.di.unimi.it/.../SOLez20DiskDevx4.pdf ·...

Operating Systems and Distributed Systems

Gestione dell’ I/O e del Disco

Operating Systems and Distributed Systems 2

Dispositivi di I/O

Operating Systems and Distributed Systems

Caratteristiche degli I/O Devices

Operating Systems and Distributed Systems 4

Dispositivi di I/O: la vista hardware

Operating Systems and Distributed Systems

Perchè funziona su svariati dispositivi?

Dispositivi di I/O: la vista del processo

int main(){

! int fd;

! char buf[512];

!

! fd = open("/dev/hda", O_RDONLY);

! if (fd >= 0)

! ! read(fd, buf, sizeof(buf));

! return 0;

}

Programma CopyFile.c

Operating Systems and Distributed Systems

Application I/O Interface

Operating Systems and Distributed Systems

Application I/O Interface

Operating Systems and Distributed Systems

void run_new_thread() {

! newThread = Schedule();

! Switch(curThread, newThread);

! ThreadHouseKeeping();

}

void Switch(tCur,tNew) {

! /* Unload old thread */

! TCB[tCur].regs.r7 = CPU.r7;

! …

! TCB[tCur].regs.r0 = CPU.r0;

! TCB[tCur].regs.sp = CPU.sp;

! TCB[tCur].regs.retpc = CPU.retpc; /*return addr*/

! /* Load and execute new thread */

! CPU.r7 = TCB[tNew].regs.r7;

! …

! CPU.r0 = TCB[tNew].regs.r0;

! CPU.sp = TCB[tNew].regs.sp;

! CPU.retpc = TCB[tNew].regs.retpc;

! return; /* Return to CPU.retpc */

}

int main(){

! int fd;

! char buf[512];

!

! fd = open("/dev/hda", O_RDONLY);

! if (fd >= 0)

! ! read(fd, buf, sizeof(buf));

! return 0;

}

Programma CopyFile.c

void kernel_read {

! ........;

}

Dispositivi di I/O: la vista del SO

#include <sys/process.h >

void main(){

! ...

! read(fd, buf, sizeof(buf))

! ...

}

extern int! read(int, char *, int);

syscall.h

;;; Stub functions for traps.

.proc _Kernel_Read

.global _Kernel_Read

_Read:! !

! trap! #0x210

! jr! r31

! nop

.endproc _Kernel_Read

#define TRAP_READ! 0x210

traps.h

.proc _intrhandler

.global _intrhandler

_intrhandler:

........

sw! 0(r29),r6! ; push CAUSE

! sw! 4(r29),r4! ; push IAR

! sw! 8(r29),r5! ; push ISR

;; push regs on stack

j! _dointerrupt!

.endproc _intrhandler

void dointerrupt (unsigned int cause,

unsigned int iar, unsigned int isr,

! uint32 *trapArgs)

{

// TRAP_INSTR bit is set: trap instruction.

// bit isn't set:system interrupt.

if (cause & TRAP_TRAP_INSTR) {

.....

switch (cause) {

case TRAP_READ:

............

break;.....

intrreturn ();

}

.proc! _intrreturn

! .global!_intrreturn

_intrreturn:

! ;; Disable interrupts

....;; Reload the regs for new process.

.endproc _intrreturnOperating Systems and Distributed Systems

CAUSE registerSTATUS register

CPU

(1)

(2)

(3)

(4)

Operating Systems and Distributed Systems10

I/O handling: requisiti• Uniform naming

• Device independence

• Error handling and protection

• Synchronous vs. asynchronous transfers

• Buffering

• Sharable vs. dedicated devices

Operating Systems and Distributed Systems11

I/O handling: requisiti Uniform Naming

• Unix: device indirizzati con path names ordinari nel file system.

/dev/tty* terminals

/dev/fd* floppy fisk

/dev/mt* magnetic tape

/dev/st* streaming tape

/dev/mouse mouse

int main(){

! int fd;

! char buf[512];

!

! fd = open("/dev/hda", O_RDONLY);

! if (fd >= 0)

! ! read(fd, buf, sizeof(buf));

! return 0;

}

Operating Systems and Distributed Systems

ApplicationProcess

FileManager

Device Controller

Command Status Data

Hardware Interface

System Interface

Device-Independent

Device-Dependent

Principio dei Livelli + Meccanismo di astrazione

ABSTRACTION LAYERS

I/O handling: requisiti Device independence

Operating Systems and Distributed Systems

– Tutte le istruzioni di I/O sono privilegiate

– I/O via system calls• Memory-mapped e I/O port memory sono anche

protette

I/O handling: requisitiProtezione

Operating Systems and Distributed Systems

I/O via system calls

I/O handling: requisitiProtezione

Operating Systems and Distributed Systems

Classificazione dei device

Operating Systems and Distributed Systems

Blk0 Blk1 Blkk-1

Blkk Blkk+1 Blk2k-1

Track 0, Cylinder 0

Track 0, Cylinder 1

Blk Blk Blk Track 1, Cylinder 0

Blk Blk Blk Track N-1, Cylinder 0

Blk Blk Blk Track N-1, Cylinder M-1

Boot Sector Volume Directory

Classificazione dei device: a blocchi

Operating Systems and Distributed Systems

• Tastiere, porte seriali, ecc

• Deliver/accept stream di caratteri (bytes) – get, put

Classificazione dei device: a caratteri

Operating Systems and Distributed Systems

• Ridurre context switch

• Ridurre data copying

• Ridurre interrupt usando trasferimenti ampi, smart controllers, polling

• Usare DMA

• Bilanciare la performance di CPU, memoria, bus, I/O per max throughput

Il problema dell’ I/O Performance

Operating Systems and Distributed Systems19

Port-mapped IO (PMIO)

I/O & memory

space

Separati

0xFFF…

0

Memory

I/O ports

Memory-mapped I/O

(MMIO)

Hybrid: entrambi

MMIO &

PMIO

MMIO vs PMIO• I dispositivi hanno indirizzi

Operating Systems and Distributed Systems

CPU/Controller communication: MMIO vs PMIO

! more /proc/iomem00000000-0009b7ff : System RAM

0009b800-0009ffff : reserved

000a0000-000bffff : Video RAM area

000c0000-000c7fff : Video ROM

000c8000-000c8fff : Adapter ROM

000f0000-000fffff : System ROM

00100000-7ff6ffff : System RAM

00100000-002c7f2f : Kernel code

002c7f30-003822ff : Kernel data

7ff70000-7ff77fff : ACPI Tables

7ff78000-7ff7ffff : ACPI Non-volatile Storage

Operating Systems and Distributed Systems

CPU/Controller communication: MMIO vs PMIO

– Macro per memory-mapped I/O

unsigned int ioread8(void *addr);

unsigned int ioread16(void *addr);

unsigned int ioread32(void *addr);

void iowrite8(u8 value, void *addr);

void iowrite16(u16 value, void *addr);

void iowrite32(u32 value, void *addr);

Operating Systems and Distributed Systems

Esempio: memory mapped video

Operating Systems and Distributed Systems

• /proc/ioports

MMIO vs PMIO

0000-001f : dma1

0020-0021 : pic1

0040-0043 : timer0

0050-0053 : timer1

0060-006f : keyboard

0070-0077 : rtc

0080-008f : dma page reg

00a0-00a1 : pic2

00c0-00df : dma2

00f0-00ff : fpu

0170-0177 : ide1

Operating Systems and Distributed Systems

• Read e write

• Si distingue fra porte a 8-bit, 16-bit, 32-bit

MMIO vs PMIO

#include <asm/io.h>

/* 8-bit functions */

unsigned inb(unsigned port);

void outb(unsigned char byte, unsigned port);

/* 16-bit functions */

unsigned inw(unsigned port);

void outw(unsigned short word, unsigned port);

/* 32-bit functions */

unsigned inl(unsigned port);

void outl(unsigned longword, unsigned port);

Operating Systems and Distributed Systems

MMIO: vantaggi

• CPU richiede meno logica interna;

– RISC

– embedded systems.

• Uso di istruzioni generali per gestire memoria.

Operating Systems and Distributed Systems

PMIO: vantaggi

• Utile su CPUs con addressing limitato

– port-mapped I/O separa I/O access da memory access, tutto l’

address space può essere utilizzato per la memoria.

• Facile da gestire in assembler.• IN!!!!! REG, PORT

• OUT! PORT, REG

• Le operazioni di I/O possono rallentare il memory access

– periferiche più lente della memoria

• Il port-mapped I/O può usare un I/O bus dedicato

Operating Systems and Distributed Systems

CPU/Controller communication: programmazione dell’I/O

• Spostare l’intelligenza dalla CPU al device

– Polling

• CPU fa la query

– Interrupts

• Device informa la CPU

– DMA

• Device controlla il trasferimento dati da/a memoria; richiede interrupt quando ha finito

– IO Controllers

• Controlla IO senza interventi, richiede interrupt quando ha finito

– IO coprocessors

CPU

DeviceOperating Systems and Distributed Systems28

CPU/Controller communication: Vista HW degli interrupt

Bus

CPU

Interruptcontroller

1. Device finishes

2. Controller issues interrupt

3. CPU acks interrupt

Operating Systems and Distributed Systems29

User processes

Device-independent

code

Device drivers

Interrupt handlers

Hardware

Request

Reply

I/O call; format I/O; spooling

Naming, protection

blocking / buffering / allocation

Gestione dei device registers & status

Segnala i device driver quando I/O

completato

Effettua realmente I/O (in hardware)

CPU/Controller communication: Vista SW degli interrupt

Operating Systems and Distributed Systems

Interrupt-Driven I/O Cycle

Operating Systems and Distributed Systems31

Direct Memory Access (DMA)

CPU

DMA

controller

Disk

controllerMain

memoryAddress

Count

Control

1: CPU programs

the DMA controller

2: DMA controller requests

transfer to memory

Buffer

3: Data is transferred

4: ACK

5: Interrupt

when done

Operating Systems and Distributed Systems

Direct Memory Access• DMA channels.

• Device: segnalano il DMA controller per un DMA transfer asserendo un hardware DMA request signal.

• Il DMA request signal è indirizzato (routed) verso il DMA controller.

– DMA controller risponde: data transfer da I/O device verso RAM o viceversa

DMA! Function!! Physical Line! ISA Bus! ! Channel Width

DMA0! Available!! Yes! ! 16 bit! ! 8 bits

DMA1! Sound! ! Yes! ! 8 bit! ! 8 bits

DMA2! Floppy Disk controller! Yes! 8 bit! ! 8 bits

DMA3! ECP Parallel Port! Yes! ! 8 bit! ! 8 bits

DMA4! * - Not used! ! No! -! ! 16 bit

DMA5! Sound! ! ! Yes! 16 bit! ! 16 bit

DMA6! SCSI! ! ! Yes! 16 bit! ! 16 bit

DMA7! Available!! Yes! ! 16 bit! ! 16 bit

Operating Systems and Distributed Systems

Direct Memory Access

Operating Systems and Distributed Systems

Direct Memory Access: flyby

Operating Systems and Distributed Systems

Direct Memory Access: F&D

Operating Systems and Distributed Systems

Disk drive: struttura

sector

cylinder

platter

spindle

track

head

actuator

surfaces

Operating Systems and Distributed Systems

Dispositivi a blocchi: Memorizzazione di massa– Drive ruota da 60 a 200 volte per secondo (o 3600 RPM, revolutions Per

Minute)

– Transfer rate : data flow tra drive e computer

• TR = MB/sec

– Positioning time: muovere il braccio al cilindro (seek time, ST) + rotazione settore sotto testina (rotational latency, RL)

– Overhead: dovuta al controller (senza waiting queues)

<Tacc>= <ST> + <RL> + TR + Toverhead

• Seek time dominaOperating Systems and Distributed Systems

Mass storage: astrazioni del sistema operativo

• Hard disk abstraction:– Raw device – un array di data blocks.

– File system – il SO mette in coda e schedula le richieste delle varie applicazioni.

Operating Systems and Distributed Systems39

Disk “addressing”

• Due possibilità:

– Cylinder/track/sector

– Sequential numbering

Operating Systems and Distributed Systems40

Costruire “dischi” migliori• Dischi limitati dalla meccanica

• Affidabilità

• Soluzione: distribuire i dati su più dischi:

– Data stored across drives (striping)

Operating Systems and Distributed Systems41

RAIDs, RAIDs, e RAIDs

strip stripStripe

RAID 0

(Redudant Array of Inexpensive Disks

RAID 1

(Mirrored copies)

RAID 2

(Striped with parity)

RAID 3

(Parity rotates through disks)

Operating Systems and Distributed Systems42

Struttura di un disk sector

• Preamble: informazione sul settore

– Sector number & location information

• Dati: 256, 512, or 1024 bytes

• ECC (Error Correcting Code)

Preamble Data ECC

Operating Systems and Distributed Systems

Device-status Table

Che cosa c’e’ in una disk request?

Operating Systems and Distributed Systems44

Che cosa c’è in una disk request?

Operating Systems and Distributed Systems45

Disk request scheduling

• Goal: efficienza

– Bandwidth elevata

– Trasferimento elevato e minimo seeking

• Ovvero

– Minimo disk seek time (track -> track)

– Minima rotational latency (rotazione del settore sotto la testina)

byte totali trasferiti

Tempo per servire la richiesta

Disk bandwith =

Operating Systems and Distributed Systems46

175

read/write head positiondisk requests

(cilindro in cui risiede il blocco)

Outside edge Inside edge

140

133

10073

77

8 51

Algoritmi di schedulazione del disco

• Minimizzazione seek time– Seek time proporzionale alla distanza

– Minimizzazione seek distance -> Minimizzazione seek time

• Si assume una request queue e una posizione della testina (Head position). Disco di 200 cylinders– Coda = 100, 175, 51, 133, 8, 140, 73, 77

– Head position = 63

Operating Systems and Distributed Systems47

175

Outside edge Inside edge

140

133

100

73

77

8

51

First-Come-First Served (FCFS)• Richieste servite nell’ordine di arrivo

– Facile!

– Seek distance può essere elevata

• Coda = 100, 175, 51, 133, 8, 140, 73, 77

• Seek order = 100, 175, 51, 133, 8, 140, 73, 77

• Seek distance = (100-63) + (175-100) + (175-51) + (133-51) +(133-8) + (140-8) + (140-73) + (77-73) = 646 cilindri

Operating Systems and Distributed Systems48

175

Outside edge Inside edge

140

133100

73

77

851

Shortest Seek Time First (SSTF)• Servire la richiesta con seek time più breve dalla posizione corrente

– Assomiglia al SJF scheduling

– Potrebbe causare starvation

• Coda = 100, 175, 51, 133, 8, 140, 73, 77

• Seek order = 73, 77, 51, 8, 100, 133, 140, 175

• Seek distance = 10 + 4 + 26 + 43 + 92 + 33 + 7 + 35 = 250 cilindri

Operating Systems and Distributed Systems49

175

Outside edge Inside edge

140

133100

73

77

851

SCAN (algoritmo dell’ascensore)• Servire la richiesta da un edge all’altro raccogliendo via via le richieste

– Inversione alla fine del disco

• Coda = 100, 175, 51, 133, 8, 140, 73, 77

• Seek order = 51, 8, 0 , 73, 77, 100, 133, 140, 175

• Seek distance = 12 + 43 + 8 + 73 + 4 + 23 + 33 + 7 + 35 = 238 cyls

Operating Systems and Distributed Systems50

175

Outside edge Inside edge

140

133100

73

77

851

C-SCAN• Come SCAN, ma ritorna al cilindro 0 quando arriva alla fine del disco

– Lista dei cilindri = lista circolare

– Waiting time uniform per cilindri agli edge del disco

• Coda = 100, 175, 51, 133, 8, 140, 73, 77

• Seek order = 73, 77, 100, 133, 140, 175, 199, 0, 8, 51

• Distance = 10 + 4 + 23 + 33 + 7 + 35 + 24 + 199 + 8 + 43 = 386 cyls

Operating Systems and Distributed Systems51

175

Outside edge Inside edge

140

133100

73

77

851

C-LOOK• Come C-SCAN, ma si ferma all’ultima richiesta in ciascuna

direzione

– Ottimizza la distanza

• Coda = 100, 175, 51, 133, 8, 140, 73, 77

• Seek order = 73, 77, 100, 133, 140, 175, 8, 51

• Distance = 10 + 4 + 23 + 33 + 7 + 35 + 167 + 43 = 322 cilindri

Operating Systems and Distributed Systems52

Criteri di scelta

• SSTF facile da implementare e OK se non ci sono troppe richieste in coda

• SCAN-type: meglio per systemi sotto heavy load– Più equo di SSTF

– LOOK meglio di SCAN per ottimizzare

• Seeks lunghi poco costosi: meglio C-LOOK di LOOK per response time uniforme

• Quindi

– SSTF per sistemi lightly loaded

– C-LOOK per sistemi heavily loaded

Operating Systems and Distributed Systems

Strutture del kernel per l’ I/O

Operating Systems and Distributed Systems

UNIX Kernel

Operating Systems and Distributed Systems

• Device = file speciale

• Software device independent: mappa device name simbolici ai driver correspondenti– /dev/hda

Entry /hda nella directory /dev identifica l’ i-node del file speciale che contiene major and minor device number.

• Major DN identifica il driver,

• Minor DN parametro utilizzato dal driver per identificare un dispositivo fra gli altri dello stesso tipo

UNIX Kernel

int main(){

! int fd;

! char buf[512];

!

! fd = open("/dev/hda", O_RDONLY);

! if (fd >= 0)

! ! read(fd, buf, sizeof(buf));

! return 0;

}

Operating Systems and Distributed Systems

UNIX I/O Kernel Structure

Operating Systems and Distributed Systems

Unix Kernel I/O Structure

Operating Systems and Distributed Systems

Strutture dati del Kernel: buffer cache

•Software cache,.•Un pool di internal data buffers, che contiene blocchi di dischi usati recentemente.•Ciascun buffer

• Buffer header: •!!!Device number (file system number) e block number

per identificare i dati su disco.•!!!Pointer al data array.•!!!Status : stato del buffer.

•Memory Array.

Operating Systems and Distributed SystemsEach time the buffer cache wishes to read or write a block of data to or from a registered device it adds a

request data structure onto its blk_dev_struct.

each request has a pointer to one or more buffer_head data structures, each one a request to read or write a

block of data. The buffer_head structures are locked (by the buffer cache) and there may be a process waiting

on the block operation to this buffer to complete. Each request structure is allocated from a static list, the

all_requests list. If the request is being added to an empty request list, the driver's request function is called to

start processing the request queue. Otherwise the driver will simply process every request on the request list.

Once the device driver has completed a request it must remove each of the buffer_head structures from the

request structure, mark them as up to date and unlock them. This unlocking of the buffer_head will wake up

any process that has been sleeping waiting for the block operation to complete.

Strutture dati del Kernel: buffer cache

Operating Systems and Distributed Systems

Read e write di blocchi• Ricerca nella buffer cache:

– se presente, • il kernel ritorna il buffer

– assente • kernel chiama il disk driver per “schedulare” una

read request e va in sleep aspettando il completamento dell’ I/O

bread(int dev, int block_number )

{

! buffer= getblk(dev, block_number); //get buffer for block! if( buffer_status==VALID)

! ! return buffer;

!

! disk_read(dev); //calls the driver

! sleep( disk_read_complete);

! return buffer;

! !

}

Operating Systems and Distributed Systems

Strutture dati del Kernel: buffer cache getblk(dev, block_number)

{

! while(buffer not found){

! ! if(block in hash queue){

! ! ! if(buffer busy/locked){

! ! ! ! sleep(buffer becomes free)

! ! ! ! continue

! ! ! }

! ! ! mark buffer busy/locked

! ! ! remove buffer from free list

! ! ! return buffer

! ! }

! ! else{

! ! ! if(no buffers on free list){

! ! ! ! sleep(any buffer becomes free)

! ! ! ! continue;

! ! ! }

! ! ! remove buffer from free list

! ! ! if(delayed write buffer){

! ! ! ! write buffer to disc (asynchronously)

! ! ! ! continue

! ! ! }

! ! ! remove buffer from old hash queue

! ! ! put buffer on new hash queue

! ! ! return buffer

! ! }

! }

} Operating Systems and Distributed Systems

Buffer cache: ottenere un blocco

Operating Systems and Distributed Systems

Strutture dati del Kernel:Block device handling

Each time the buffer cache wishes to read or write a block of data to or from a registered device it adds a request data structure onto its blk_dev_struct.

the driver will simply process every request on the request list. Once the device driver has completed a request it must remove each of the buffer_head structures from the request structure, mark them as up to date and unlock them

Operating Systems and Distributed Systems

Come funziona?

Dispositivi di I/O: caso reale

int main(){

! int fd;

! char buf[512];

!

! fd = open("/dev/hda", O_RDONLY);

! if (fd >= 0)

! ! read(fd, buf, sizeof(buf));

! return 0;

}

Operating Systems and Distributed Systems

Come funziona?

Dispositivi di I/O: caso reale

int main(){

! int fd;

! char buf[512];

!

! fd = open("/dev/hda", O_RDONLY);

! if (fd >= 0)

! ! read(fd, buf, sizeof(buf));

! return 0;

}

sys_read(unsigned int fd, char *buf, size_t count) {! struct file *file = fget(fd);

! return file->f_op->read(file, buf, count, &file->f_pos);}

sys_read(unsigned int fd, char *buf, size_t count) {! struct file *file = fget(fd);

! return file->f_op->read(file, buf, count, &file->f_pos);}

block_read(struct file *filp, char *buf, size_t count, loff_t *ppos) {! struct inode *inode = filp->f_dentry->d_inode;

! kdev_t dev = inode->i_rdev;

! ssize_t blocksize = blksize_size[MAJOR(dev)][MINOR(dev)];

! ......

! getblk(dev, block++, blocksize);! ! !

ll_rw_block(READ, bhrequest, bhreq);! ! /* wait for I/O to complete,

! ! copy result to user space,

! ! increment read and *ppos, decrement left */

!

}

Operating Systems and Distributed Systems

Caso reale(1)

getblk(kdev_t dev, int block, int size) {

! //finds the buffer that already

contains the required data if we are

lucky,

! //and otherwise a buffer that is

going to be used.

}

ll_rw_block(int rw, int nr, struct buffer_head * bhs[]) {

! //real I/O is started

! ! for (i = 0; i < nr; i++) {

! ! struct buffer_head *bh = bhs[i];

! !

! ! bh->b_end_io = end_buffer_io_sync;//specifies

what to do when I/O is finished

! !

! ! submit_bh(rw, bh);! }

}

submit_bh(int rw, struct buffer_head *bh) {

! .....

! generic_make_request(rw, bh);}

generic_make_request (int rw, struct buffer_head *bh) {

! //finds the right queue and calls the request function

for that queue

! request_queue_t *q;

!

! q = blk_get_queue(bh->b_rdev);

! q->make_request_fn(q, rw, bh);}

ide_do_request(ide_hwgroup_t *hwgroup, int masked_irq) {

! ide_startstop_t startstop;

!

! while (!hwgroup->busy) {

! ! hwgroup->busy = 1;

! ! drive = choose_drive(hwgroup);

! ! startstop = start_request(drive);

! ! if (startstop == ide_stopped)

! ! ! hwgroup->busy = 0;

! }

}Operating Systems and Distributed Systems

Caso reale(2)ll_rw_block(int rw, int nr, struct buffer_head * bhs[]) {! //real I/O is started

! ! for (i = 0; i < nr; i++) {

! ! struct buffer_head *bh = bhs[i];

! !

! ! bh->b_end_io = end_buffer_io_sync;//specifies what to do when I/O is finished

! ! submit_bh(rw, bh);! }

}

start_request (ide_drive_t *drive) {! .......

! rq = blkdev_entry_next_request(&drive-

>queue.queue_head);

! block = rq->sector;

! block += drive->part[minor & PARTN_MASK].start_sect;

! SELECT_DRIVE(hwif, drive);

! return (DRIVER(drive)->do_request(drive, rq, block));}

ide_startstop_t do_rw_disk (ide_drive_t *drive, struct request *rq, unsigned long block) {! ......

! track = block / drive->sect;

! sect = block % drive->sect + 1;

! OUT_BYTE(sect,IDE_SECTOR_REG);

! head = track % drive->head;

! cyl = track / drive->head;

! .................

! if (rq->cmd == READ) {

! !

! ! //sets up read_intr() to be called when we get an interrupt

! ! ide_set_handler(drive, &read_intr, WAIT_CMD, NULL); ! !

! ! OUT_BYTE(WIN_READ, IDE_COMMAND_REG);

! ! return ide_started;

! }

! ...

}

Operating Systems and Distributed Systems

Caso reale(3)ide_do_request(ide_hwgroup_t *hwgroup, int masked_irq) {

! ide_startstop_t startstop;

!

! while (!hwgroup->busy) {

! ! hwgroup->busy = 1;

! ! drive = choose_drive(hwgroup);

! ! startstop = start_request(drive);

! ! if (startstop == ide_stopped)

! ! ! hwgroup->busy = 0;

! }

}

Operating Systems and Distributed Systems

Kernel structures

Operating Systems and Distributed Systems

Kernel I/O Subsystem• Scheduling

– per-device queue

– fairness

• Buffering -– ridurre device speed mismatch

– ridurre device transfer size mismatch

– Preservare la “copy semantics”

Operating Systems and Distributed Systems

Application I/O Interface

Operating Systems and Distributed Systems

Application I/O Interface

Operating Systems and Distributed Systems

Esempio: controllo del Terminale

Operating Systems and Distributed Systems

• Unix: funzione ``ioctl'' per cambiare il terminal driver behaviour.

– Input speed

– Output speed

– Echo or non-echo

– Mode - raw, cooked, rare

int ioctl(int fd, u_long request, char *arg)

open file descriptor request code number pointer to data

Esempio: controllo del Terminale

#define LINE_MAX 128

int main(void)

{

struct sgttyb tty_params;

short flags;

char buff[LINE_MAX];!

! /* get terminal parameters */

ioctl(0, TIOCGETP, &tty_params);!

/* save echo and other state */

flags = tty_params.sg_flags;!

/* turn off echoing */

tty_params.sg_flags &= ~ECHO;

ioctl(0, TIOCSETP, &tty_params);!

printf("Enter password\n");

! fgets(buff, LINE_MAX, stdin);

printf("Secret password was %s\n", buff);!

/* restore previous state */

tty_params.sg_flags = flags;

ioctl(0, TIOCSETP, &tty_params);!

exit(0);

}

Operating Systems and Distributed Systems

• Controla l’echoing dei caratteri.

Esempio: controllo del Terminale