UNIX-Schnittstelle ================== 6. E/A-Geräte unter UNIX ======================== Alle Beispiel-Quellen mittels SVN unter: https://svn.informatik.hu-berlin.de/svn/unix-2014/File |
next | back | 2017 - 1 |
6.1 Vorbemerkung ---------------- a) Hardware E/A-Geräte Blockorientierte Geräte - Medium hat feste physische Blocklänge (128..4096 Byte, üblich 512/1024) - Direktzugriff und sequentieller Zugriff - Seekoperationen möglich Beispiele: Festplatten, CD's, Floppy, Magnetband Zeichenorientierte Geräte - Ströme von Zeichen, sequentieller Zugriff - keine feste Satzstruktur - keine Seekoperationen Beispiele: Terminal, Drucker, Modem Sondergeräte - nicht zum direkten Datenaustausch Beispiele: Uhren, Hauptspeicher |
next | back | 2017 - 2 |
Controller Geräte haben Standardschnittstellen (RS232, SCSI, SCSI2, IDE, Centronics,...) Prozessoren realisieren unterschiedliche Busstrukturen. Controller stellen die Verbindung zwischen den hersteller- spezifischen Buststrukturen und den standardisierten Geräte- schnittstellen her. Aufgaben der Controller: - Wandlung von Bitströmen in Byte-/Wortströme - Geräteauswahl - Prüfsummenberechnung - Fehlerkorrektur - Erzeugung von gerätespezifischen Steuersignalen (Synchronsignale) - Interrupterzeugung - Ausführung von Steueroperationen Controller belegen in der Regel mehrere E/A-Adressen und ein Interruptvektor |
next | back | 2017 - 3 |
Struktur eines Rechners (Busstruktur) ============================================================ Bus | | | | | +---+ +--------+ +----------+ +----------+ +----------+ |CPU| |Speicher| |Platten- | |Drucker- | |andere | | | | | |kontroller| |kontroller| |Kontroller| +---+ +--------+ +----------+ +----------+ +----------+ | | | | | P1 P2 Drucker G1 Gn Struktur eines Rechners (Switch-Struktur) +---+ +----------+ |CPU|-------------+ +---------|Platten- |--P1 +---+ | | |kontroller|--P2 | | +----------+ | | +--------+ | SWITCH | +--------+ | | +--------+ | | +----------+ |Speicher|--------+ +---------|Drucker- |--Drucker | | |kontroller| +--------+ +----------+ |
next | back | 2017 - 4 |
b) Software Grundforderungen: - Gerätunabhängigkeit der Nutzersoftware - Einheitliche Namensgebung von Geräten und Dateien - Einheitliche Fehlerbehandlung für den Nutzer, d.h. E/A- Software muss gerätspezifische Fehlerbehandlung realisieren. - synchrone und asynchrone E/A-Operationen - Syncronisation und Organisation des Zugriffs zu E/A-Geräten a) gleichzeitiger Zugriff mehrerer Nutzer auf ein Gerät (Platte - Filesystem) b) Einzelzugriff auf ein Gerät (Magnetband) Günstige Struktur des IO-Systems: 5. nutzerorientierte Software (Nutzer) 4. gerätunabhängige Systemsoftware (System - Kern) 3. Gerätetreiber (System - Hardwareentwickler) 2. Interrupthandler (System - Kern) 1. Hardware |
next | back | 2017 - 5 |
E/A-Anforderung Schicht E/A-Rückmeldung | +--------------------------+ ^ | | | | +------->| * Benutzerprozess * |-+ Spooling, E/A-Aufrufe | | ^ | E/A-Formatierung +-|----------------------|-+ | | | | | V Gräteunabhängige | Namensgebung, schützen | Software ^ | puffern, blocken +-|----------------------|-+ | | | | | V Gerätetreiber | Gerätesteuerung | ^ | Statusabfragen +-|----------------------|-+ | | | | | V Unterbrechungs- | Gerätetreiber aktivieren | routine ^ | nach E/A-Unterbrechung +-|----------------------|-+ | | | | | V Hardware | | E/A-Operation | * .................. * | ausführen +--------------------------+ |
next | back | 2017 - 6 |
Aufgaben der Schichten im Detail: Hardware: Realisierung der E/A-Operation Interrupthandler: Assemblerroutine des Kerns - Retten des aktuellen Prozessorzustandes - Memmorymanagment (ausblenden des aktuellen Prozesses, einblenden der Gerätetreiber) - aktivieren des Gerätetreibers zur I/O-Ende-Behandlung - aktivieren eines Prozesses nach Interruptbehandlung Gerätetreiber C-Routine zur Steuerung einer Gerätefamilie. Es werden folgende gerätunabhängige Funktionen zur Verfügung gestellt: xx_open - eröffnen eines Gerätes xx_close - abschliessen eines Gerätes xx_read - lesen (Zeichen) xx_write - schreiben (Zeichen) xx_ioctl - gerätspezifische Steueroperationen (Zeichen) xx_intr - Interruptroutine (Eintritt für Interrupthandler) xx_strategy - lesen/schreiben (blockorientiert) |
next | back | 2017 - 7 |
Geräteunabhängige Systemsoftware Einheitliche Schnittstellen für Gerätetreiber Einheitliche Schnittstellen zum Nutzer Einheitliche Namensgebung für Geräte und Files Schutz der Geräte Geräteunabhängige Blockgrösse Pufferung Speicherzuordnung auf blockorientierten Geräten (Filesystem) Ver- und Freigabe von exklusiv genutzten Geräten Fehlerstatistik Nutzerorietierte Software - basierend auf "low level I/O" : open, close, read, write, lseek, ioctl, ... - basierend auf "high level I/O" : fopen, fclose, fprintf, fscanf, ... - Spoolsysteme: lp, uucp |
next | back | 2017 - 8 |
6.2 Systemrufe des Nutzers für E/A ----------------------------------- Nutzbar für E/A-Operationen über Geräte und über Files (später). open - Eröffnen von (bestehenden) Files close - Abschliessen von Files ioctl - Ausführen von Steueroperationen für Geräte (nur bedingt für Files nutzbar) read - Lesen von Daten write - Schreiben von Daten |
next | back | 2017 - 9 |
#include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> int open(const char *pathname, int oflag,.../*, mode_t mode */ ); open eröffnet ein File unter dem angegeben Namen *pathname für den angegeben Modus oflag . mode spezifiziert die Zugriffsrechte, falls das File neu erzeugt wird. oflag: O_RDONLY - nur lesen O_WRONLY - nur schreiben O_RDWR - lesen und schreiben O_APPEND - Anfügen O_CREAT - Erzeugen eines neuen Files O_EXCL - Erzeugt Fehler, wenn O_CREAT und File existiert O_TRUNC - Wenn File zum Schreiben eröffnet, dann kürze die Länge des Files auf 0 O_NONBLOCK - nonblocking Mode für FIFO, block special file oder character special file O_SYNC - warten auf physisches E/A-Ende bei Schreiboperationen Filenamenlänge: alt: 14, neu: 256 Pathnamelänge: 4095 Anzahl der eröffneten Files: alt 20 neu: 256 (OPEN_MAX in sys/limits.h) |
next | back | 2017 - 10 |
mode: sys/stat.h S_IRUSR user-read S_IRGRP group-read S_IWUSR user-write S_IWGRP group-write S_IXUSR user-execute S_IXGRP group-execute S_IROTH other-read S_IWOTH other-write S_IXOTH other-execute S_ISUID set-user-ID on execution S_ISGID set-group-ID on execution S_ISVTX sticky bit (textsegment in swap, Directory: Schreibzugriff für Files nur für Eigentümer und su) Rückkehrkode: >=0 - Filedescriptor für das eröffnete File < 0 - Fehler EACCESS - no search access, O_TRUNC and no write-permission, no permission EDQUOT - file not exist, no quota EEXIST - O_EXCL and O_CREAT and file exist EFAULT - wrong address EINTR - signal EISDIR - file is directory and write ELOOP - too many symbolic links EMFILE - no filedescriptor ENAMETOOLONG- path to long (PAH_MAX) ENFILE - system file table full ENOENT - file not exist and no O_CREAT ENOSPC - no space in directory, no inode ENOTDIR - component in the path is not a directory EROFS - O_CREAT and read only file system |
next | back | 2017 - 11 |
Kerneldatenstrukturen nach Open ein Prozess mit Zugriff auf zwei Files IO4 zwei unabhängige Prozesse mit Zugriff auf ein File IO5 Vater- und Kindprozess mit Zugriff auf drei Files IO6 |
next | back | 2017 - 12 |
#include <unistd.h> int close(int filedes); Schliessen eines Files. Freigabe aller Ressourcen einschliesslich "gelockter" Bereiche des Prozesses. filedes - Filedescriptor Rückkehrwert: 0 - ok <0 - Fehler EBADF - fieldes ist kein eröffnetes File EINTR - Signal aufgetreten |
next | back | 2017 - 13 |
#include <unistd.h> ssize_t read(int filedes, void *buff, size_t nbytes); read liest die Anzahl von nbytes Bytes des eröffneten Files filedes in den Puffer *buff. Der Rückkehrwert gibt die Anzahl der gelesenen Bytes an. Die Anzahl der gelesenen Bytes kann von der geforderten Zahl von Bytes abweichen wenn: - Fileende - wenn von einem Terminal gelesen wird - wenn von einem Socket gelesen wird - Blockorientierte Geräte können nur Blöcke liefern Rückkehrwert: > 0 - Anzahl der gelesenen Bytes 0 - Fileende (EOF) <0 - Fehler EAGAIN - non-blocking File ohne Daten EBADF - Filedes ist kein eröffnetes File EFAULT - *buff nicht im Adressraum EINTR - Signal EINVAL - negativer Filedescriptor EIO - E/A-Fehler |
next | back | 2017 - 14 |
#include <unistd.h> ssiz_t write(int filedes, const void *buff, size_t nbytes); write schreibt die in nbytes spezifizierte Anzahl von Bytes aus dem Puffer *buff in das File filedes. Rückkehrwert: >=0 - Anzahl der geschriebenen Bytes < 0 - Fehler EBADF - filedes ist kein eröffnetes File EDQUOT - Quotafehler EFAULT - *buff nicht im Adressraum EFBIG - Filegrösse zu gross EINTR - Signal EINVAL - negativer Filedescriptor EIO - E/A-Fehler ENOSPC - Filesystem ist voll |
next | back | 2017 - 15 |
Einfaches Beispiel: Kopieren von Standardeingabe nach Standardausgabe: ./copy <Eingabefile >Ausgabefile Kopieren mit unterschiedlichen Blockgrößen ./copy1 blocksize <Eingabefile >Ausgabefile |
next | back | 2017 - 16 |
#include <unistd.h> #include <sys/ioctl.h> int ioctl(int filedes, int request, ...); ioctl erlaubt die Ausführung von Steueroperationen uber dem File filedes. request spezifiziert die Art der Steueroperation. Ein weiterer Parameter (int-Wert oder Adresse eines Feldes) sind zu- lässig. Rückkehrwert: >=0 - ok <0 - Fehler EBADF - filedes ist kein erööffnetes File EFAULT - Falsche Parameterkombination EINVAL - request nicht unterstützt ENOTTY - request passt nicht zum File |
next | back | 2017 - 17 |
/* @(#)mtio.h 2.24 91/06/26 SMI; from UCB 4.10 83/01/17 */ /* * Structures and definitions for mag tape io control commands */ /* structure for MTIOCTOP - mag tape op command */ struct mtop { short mt_op; /* operations defined below */ daddr_t mt_count; /* how many of them */ }; /* operations */ #define MTWEOF 0 /* write an end-of-file record */ #define MTFSF 1 /* forward space over file mark */ #define MTBSF 2 /* backward space over file mark (1/2" only) */ #define MTFSR 3 /* forward space to inter-record gap */ #define MTBSR 4 /* backward space to inter-record gap */ #define MTREW 5 /* rewind */ #define MTOFFL 6 /* rewind and put the drive offline */ #define MTNOP 7 /* no operation, sets status only */ #define MTRETEN 8 /* retension the tape (cartridge tape only) */ #define MTERASE 9 /* erase the entire tape */ #define MTEOM 10 /* position to end of media */ #define MTNBSF 11 /* backward space file to BOF */ /* @(#)ttycom.h 1.10 89/06/23 SMI */ #define TIOCGWINSZ _IOR(t, 104, struct winsize) /* get window size */ #define TIOCSWINSZ _IOW(t, 103, struct winsize) /* set window size */ #define TIOCSSIZE _IOW(t,37,struct ttysize)/* set tty size */ #define TIOCGSIZE _IOR(t,38,struct ttysize)/* get tty size */ |
next | back | 2017 - 18 |
/* * 4.3BSD and SunOS terminal "ioctl"s with no "termios" equivalents. * This file is included by <sys/termios.h> and indirectly by <sys/ioctl.h>> * so that programs that include either one have these "ioctl"s defined. */ #define TIOCSCTTY _IO(t, 132) /* get a ctty */ #define TIOCGPGRP _IOR(t, 119, int) /* get pgrp of tty */ #define TIOCGETPGRP _IOR(t, 131, int) /* get pgrp of tty (posix) */ #define TIOCSPGRP _IOW(t, 118, int) /* set pgrp of tty */ #define TIOCSETPGRP _IOW(t, 130, int) /* set pgrp of tty (posix) */ #define TIOCOUTQ _IOR(t, 115, int) /* output queue size */ #define TIOCSTI _IOW(t, 114, char) /* simulate terminal input */ #define TIOCNOTTY _IO(t, 113) /* void tty association */ #define TIOCPKT _IOW(t, 112, int) /* pty: set/clear packet mode */ #define TIOCPKT_DATA 0x00 /* data packet */ #define TIOCPKT_FLUSHREAD 0x01 /* flush data not yet written to controller */ #define TIOCPKT_FLUSHWRITE 0x02 /* flush data read from controller but not yet processed */ #define TIOCPKT_STOP 0x04 /* stop output */ #define TIOCPKT_START 0x08 /* start output */ #define TIOCPKT_NOSTOP 0x10 /* no more ^S, ^Q */ #define TIOCPKT_DOSTOP 0x20 /* now do ^S, ^Q */ #define TIOCPKT_IOCTL 0x40 /* "ioctl" packet */ #define TIOCMSET _IOW(t, 109, int) /* set all modem bits */ #define TIOCMBIS _IOW(t, 108, int) /* bis modem bits */ #define TIOCMBIC _IOW(t, 107, int) /* bic modem bits */ #define TIOCMGET _IOR(t, 106, int) /* get all modem bits */ #define TIOCM_LE 0001 /* line enable */ #define TIOCM_DTR 0002 /* data terminal ready */ #define TIOCM_RTS 0004 /* request to send */ #define TIOCM_ST 0010 /* secondary transmit */ |
next | back | 2017 - 19 |
#define TIOCM_SR 0020 /* secondary receive */ #define TIOCM_CTS 0040 /* clear to send */ #define TIOCM_CAR 0100 /* carrier detect */ #define TIOCM_CD TIOCM_CAR #define TIOCM_RNG 0200 /* ring */ #define TIOCM_RI TIOCM_RNG #define TIOCM_DSR 0400 /* data set ready */ #define TIOCREMOTE _IOW(t, 105, int) /* remote input editing */ #define TIOCUCNTL _IOW(t, 102, int) /* pty: set/clr usr cntl mode */ |
next | back | 2017 - 20 |
/* * Sun-specific ioctls with no "termios" equivalents. */ #define TIOCTCNTL _IOW(t, 32, int) /* pty: set/clr intercept ioctl mode */ #define TIOCSIGNAL _IOW(t, 33, int) /* pty: send signal to slave */ #define TIOCCONS _IO(t, 36) /* get console I/O */ #define TIOCSSOFTCAR _IOW(t, 101, int) /* set soft carrier flag */ #define TIOCGSOFTCAR _IOR(t, 100, int) /* get soft carrier flag */ #define TIOCISPACE _IOR(t, 128, int) /* space left in input queue */ #define TIOCISIZE _IOR(t, 129, int) /* size of input queue */ #define TIOCSINTR _IOW(t, 99, int) /* set DOS interrupt number */ #define TCXONC _IO(T, 6) #define TCFLSH _IO(T, 7) #define TCGETS _IOR(T, 8, struct termios) #define TCSETS _IOW(T, 9, struct termios) #define TCSETSW _IOW(T, 10, struct termios) #define TCSETSF _IOW(T, 11, struct termios) #define TCOOFF 0 /* arg to TCXONC & tcflow() */ #define TCOON 1 /* arg to TCXONC & tcflow() */ #define TCIOFF 2 /* arg to TCXONC & tcflow() */ #define TCION 3 /* arg to TCXONC & tcflow() */ #define TCIFLUSH 0 /* arg to TCFLSH & tcflush() */ #define TCOFLUSH 1 /* arg to TCFLSH & tcflush() */ #define TCIOFLUSH 2 /* arg to TCFLSH & tcflush() */ #define TCSANOW 0 /* arg to tcsetattr() */ #define TCSADRAIN 1 /* arg to tcsetattr() */ #define TCSAFLUSH 2 /* arg to tcsetattr() */ #define TCGETA _IOR(T, 1, struct termio) #define TCSETA _IOW(T, 2, struct termio) #define TCSBRK _IO(T, 5) |
next | back | 2017 - 21 |
/* @(#)sockio.h 1.7 88/12/06 SMI; from UCB ioctl.h 7.1 6/4/86 */ /* * General socket ioctl definitions. */ /* socket i/o controls */ #define SIOCSHIWAT _IOW(s, 0, int) /* set high watermark */ #define SIOCGHIWAT _IOR(s, 1, int) /* get high watermark */ #define SIOCSLOWAT _IOW(s, 2, int) /* set low watermark */ #define SIOCGLOWAT _IOR(s, 3, int) /* get low watermark */ #define SIOCATMARK _IOR(s, 7, int) /* at oob mark? */ #define SIOCSPGRP _IOW(s, 8, int) /* set process group */ #define SIOCGPGRP _IOR(s, 9, int) /* get process group */ #define SIOCADDRT _IOW(r, 10, struct rtentry) /* add route */ #define SIOCDELRT _IOW(r, 11, struct rtentry) /* delete route */ #define SIOCSIFADDR _IOW(i, 12, struct ifreq) /* set ifnet address */ #define SIOCGIFADDR _IOWR(i,13, struct ifreq) /* get ifnet address */ #define SIOCSIFDSTADDR _IOW(i, 14, struct ifreq) /* set p-p address */ #define SIOCGIFDSTADDR _IOWR(i,15, struct ifreq) /* get p-p address */ #define SIOCSIFFLAGS _IOW(i, 16, struct ifreq) /* set ifnet flags */ #define SIOCGIFFLAGS _IOWR(i,17, struct ifreq) /* get ifnet flags */ #define SIOCSIFMEM _IOW(i, 18, struct ifreq) /* set interface mem */ #define SIOCGIFMEM _IOWR(i,19, struct ifreq) /* get interface mem */ #define SIOCGIFCONF _IOWR(i,20, struct ifconf) /* get ifnet list */ #define SIOCSIFMTU _IOW(i, 21, struct ifreq) /* set if_mtu */ #define SIOCGIFMTU _IOWR(i,22, struct ifreq) /* get if_mtu */ |
next | back | 2017 - 22 |
/* from 4.3BSD */ #define SIOCGIFBRDADDR _IOWR(i,23, struct ifreq) /* get broadcast addr */ #define SIOCSIFBRDADDR _IOW(i,24, struct ifreq) /* set broadcast addr */ #define SIOCGIFNETMASK _IOWR(i,25, struct ifreq) /* get net addr mask */ #define SIOCSIFNETMASK _IOW(i,26, struct ifreq) /* set net addr mask */ #define SIOCGIFMETRIC _IOWR(i,27, struct ifreq) /* get IF metric */ #define SIOCSIFMETRIC _IOW(i,28, struct ifreq) /* set IF metric */ #define SIOCSARP _IOW(i, 30, struct arpreq) /* set arp entry */ #define SIOCGARP _IOWR(i,31, struct arpreq) /* get arp entry */ #define SIOCDARP _IOW(i, 32, struct arpreq) /* delete arp entry */ #define SIOCUPPER _IOW(i, 40, struct ifreq) /* attach upper layer */ #define SIOCLOWER _IOW(i, 41, struct ifreq) /* attach lower layer */ #define SIOCSETSYNC _IOW(i, 44, struct ifreq) /* set syncmode */ #define SIOCGETSYNC _IOWR(i, 45, struct ifreq) /* get syncmode */ #define SIOCSSDSTATS _IOWR(i, 46, struct ifreq) /* sync data stats */ #define SIOCSSESTATS _IOWR(i, 47, struct ifreq) /* sync error stats */ #define SIOCSPROMISC _IOW(i, 48, int) /* request promisc mode #define SIOCADDMULTI _IOW(i, 49, struct ifreq) /* set m/c address */ #define SIOCDELMULTI _IOW(i, 50, struct ifreq) /* clr m/c address */ /* FDDI controls */ #define SIOCFDRESET _IOW(i, 51, struct ifreq) /* Reset FDDI */ #define SIOCFDSLEEP _IOW(i, 52, struct ifreq) /* Sleep until next dnld req */ #define SIOCSTRTFMWAR _IOW(i, 53, struct ifreq) /* Start FW at an addr */ #define SIOCLDNSTRTFW _IOW(i, 54, struct ifreq) /* Load the shared memory */ #define SIOCGETFDSTAT _IOW(i, 55, struct ifreq) /* Get FDDI stats */ #define SIOCFDNMIINT _IOW(i, 56, struct ifreq) /* NMI to fddi */ #define SIOCFDEXUSER _IOW(i, 57, struct ifreq) /* Exec in user mode */ #define SIOCFDGNETMAP _IOW(i, 58, struct ifreq) /* Get a netmap entry */ #define SIOCFDGIOCTL _IOW(i, 59, struct ifreq) /* Generic ioctl for fddi */ |
next | back | 2017 - 23 |
/* @(#)filio.h 1.5 91/06/18 SMI; from UCB ioctl.h 7.1 6/4/86 */ /* * General file ioctl definitions. */ #define FIOCLEX _IO(f, 1) /* set exclusive use on fd */ #define FIONCLEX _IO(f, 2) /* remove exclusive use */ /* another local */ #define FIONREAD _IOR(f, 127, int) /* get # bytes to read */ #define FIONBIO _IOW(f, 126, int) /* set/clear non-blocking i/o */ #define FIOASYNC _IOW(f, 125, int) /* set/clear async i/o */ #define FIOSETOWN _IOW(f, 124, int) /* set owner */ #define FIOGETOWN _IOR(f, 123, int) /* get owner */ /* file system locking */ #define FIOLFS _IO(f, 64) /* file system lock */ #define FIOLFSS _IO(f, 65) /* file system lock status */ #define FIOFFS _IO(f, 66) /* file system flush */ /* short term backup */ #define FIOAI _IO(f, 67) /* allocation information */ #define FIODUTIMES _IO(f, 68) /* delay update access time */ #define FIODIO _IO(f, 69) /* delay write all data */ #define FIODIOS _IO(f, 70) /* status of FIODIO */ |
next | back | 2017 - 24 |
|
back | 2017 - 25 |