1 / 35

I/O Subsystem

I/O Subsystem. CS 105 “ Tour of the Black Holes of Computing ”. Overview of I/O Hardware Access Device Independent Routines Device Dependent Routines Device. io.ppt. I/O: A Typical Hardware System. CPU chip. register file. ALU. system bus. memory bus. main memory. bus interface.

rossa
Download Presentation

I/O Subsystem

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. I/O Subsystem CS 105“Tour of the Black Holes of Computing” Overview of I/O Hardware Access Device Independent Routines Device Dependent Routines Device io.ppt

  2. I/O: A Typical Hardware System CPU chip register file ALU system bus memory bus main memory bus interface I/O bridge I/O bus Expansion slots for other devices such as network adapters. USB controller graphics adapter disk controller mouse keyboard monitor disk

  3. Reading a Disk Sector: Step 1 CPU chip CPU initiates a disk read by writing a command, logical block number, and destination memory address to a port (address) associated with disk controller. register file ALU main memory bus interface I/O bus USB controller graphics adapter disk controller mouse keyboard monitor disk

  4. Reading a Disk Sector: Step 2 CPU chip Disk controller reads the sector and performs a direct memory access (DMA) transfer into main memory. register file ALU main memory bus interface I/O bus USB controller graphics adapter disk controller mouse keyboard monitor disk

  5. Reading a Disk Sector: Step 3 CPU chip When the DMA transfer completes, the disk controller notifies the CPU with an interrupt (i.e., asserts a special “interrupt” pin on the CPU) register file ALU main memory bus interface I/O bus USB controller graphics adapter disk controller mouse keyboard monitor disk

  6. Abstracting I/O • Low level requires complex device commands • Vary from device to device • Device models can be very different • Tape: read or write sequentially, or rewind • Disk: “random” access at block level • Terminal: sequential, no rewind, must echo and allow editing • Video: write-only, with 2-dimensional structure • Operating system should hide these differences • “read” and “write” should work regardless of device • OS builds table of specific driver routines for each device • Sometimes impossible to generalize (e.g., video) • Still need access to full power of hardware

  7. Layers of I/O System • User Level – processes • make I/O call, format I/O, spooling • Device-Independent software • naming, protection blocking, buffering, allocation • perform I/O functions common to all devices • provide uniform interface to the user level software • buffering, block sizes, etc. • e.g., map symbolic device names onto driver • Device-Dependent software • setup device registers, check status • specific code for device operations, i.e., driver routines for read, write, etc. • accept abstract requests, e.g., open, and execute • Hardware • controller, map I/O ops to device ops, e.g., print, • Interrupts

  8. UNIX I/O • Derived from Multics and earlier systems, the Unix I/O primitives follow a paradigm referred as “open-read-write-close”. Before a user process can perform I/O ops, it calls ‘open’ to specify the file to be used and obtains permission. The call to ‘open’ returns a small integer, ‘file descriptor’ that the process uses when performing I/O ops on the opened file or device. Once an object has been opened, the user process makes one or more ‘read’ or ‘write’ calls to read or write data. Both ‘read’ and ‘write’ take 3 arguments that specify the file descriptor, address of a buffer, and count of bytes to be transferred. After all transfer operations are complete, the user process calls ‘close’ to inform the OS that the process is finished with the object.

  9. Layers of I/O System • User Level – processes • make I/O call, format I/O, spooling • Device-Independent software • naming, protection blocking, buffering, allocation • perform I/O functions common to all devices • provide uniform interface to the user level software • buffering, block sizes, etc. • e.g., map symbolic device names onto driver • Device-Dependent software • setup device registers, check status • specific code for device operations, i.e., driver • accept abstract requests, e.g., open, and execute • Hardware • controller, map I/O ops to device ops, e.g., print, • Interrupts

  10. Device Independent: Dev Table • struct dvtype { • char *dvname; /* device name */ • char *dvtname; /* type name */ • int dvtnum; /* symbol table index of type */ • char *dvdevice; /* device name */ • int dvcsr; /* Control Status Register addr */ • int dvivec; /* input interrupt vector */ • int dvovec; /* Output interrupt vector */ • char dviint[20]; /* input interrupt routine */ • char dvoint[20]; /* output interrupt routine */ • char dvinit[20]; /* init routine name */ • char dvopen[20]; /* open routine name */ • char dvclose[20]; /* close routine name */ • char dvread[20]; /* read routine name */ • char dvwrite[20]; /* write routine name */ • char dvcntl[20]; /* control routine name */ • char dvseek[20]; /* seek routine name */ • char dvgetc[20]; /* getc routine name */ • char dvputc[20]; /* putc routine name */ • int dvminor; /* device number 0,1,... */ • struct dvtype *dvnext; /* next node on the list */ • }; typedef struct dvtype *dvptr; dvptr ftypes = NIL; /* linked list of device types */ dvptr devs = NIL; /* linked list of device decls. */ dvptr lastdv = NIL; dvptr currtype = NIL; • struct dvtype is common to all devices • uses linked list of dytype • allows dynamic creation of new dvtype(device)

  11. Device Independent: init.c • /* init.c - init */ /*include files do not appear in following modules */ • #include <conf.h> • #include <kernel.h> • #include <io.h> • /*------------------------------------------------------------------------ • * init - initialize a device • could be done by the OS, system level setup of the device • done at boot time or when first accessed • *------------------------------------------------------------------------ • */ • init(descrp) • int descrp; • { • struct devsw *devptr; • if (isbaddev(descrp) ) • return(SYSERR); • devptr = &devtab[descrp]; // get pointer to device struct • return( (*devptr->dvinit)(devptr) ); // run device’s init routine • }

  12. Device Independent: control.c • /* control.c - control */ • /*------------------------------------------------------------------------ • * control - control a device (e.g., set the mode) • * OS level operation, • *------------------------------------------------------------------------ • */ • SYSCALL control(descrp, func, addr, addr2) • int descrp, func; • char *addr,*addr2; • { • struct devsw *devptr; • if (isbaddev(descrp) ) • return(SYSERR); • devptr = &devtab[descrp]; • return( (*devptr->dvcntl)(devptr, func, addr, addr2) ); //’ run device’s cntl routine passing parms • }

  13. Device Independent: open.c /* open.c - open */ /*------------------------------------------------------------------------ * open - open a connection to a device/file (parms 2 &3 are optional) *------------------------------------------------------------------------ */ SYSCALL open(descrp, nam, mode) intdescrp; char *nam; char *mode; { structdevsw *devptr; if ( isbaddev(descrp) ) return(SYSERR); devptr = &devtab[descrp]; //get a pointer to the appropriate device structure in device table return( (*devptr->dvopen)(devptr, nam, mode) ); // use device pointer to call device specific open }

  14. Device Independent: getc.c • /* getc.c - getc */ • /*------------------------------------------------------------------------ • * getc - get one character from a device • *------------------------------------------------------------------------ • */ • SYSCALL getc(descrp) • int descrp; • { • struct devsw *devptr; • if (isbaddev(descrp) ) • return(SYSERR); • devptr = &devtab[descrp]; // get pointer to device structure • return( (*devptr->dvgetc)(devptr) ); // run device’s getc • }

  15. Device Independent: putc.c /* putc.c - putc */ /*------------------------------------------------------------------------ * putc - write a single character to a device *------------------------------------------------------------------------ */ SYSCALL putc(descrp, ch) intdescrp; char ch; { structdevsw *devptr; if (isbaddev (descrp) ) return(SYSERR); devptr = &devtab[descrp]; return( (*devptr->dvputc)(devptr,ch) ); }

  16. Device Independent: seek.c • /* seek.c seek */ • /* seek -- position a device (very common special case of control) */ • SYSCALL seek(descrp, pos) • int descrp; • long pos; • { • struct devsw *devptr; • if (isbaddev(descrp) ) • return(SYSERR); • devptr = &devtab[descrp]; // get pointer to devices structure • return( (*devptr->dvseek)(devptr,pos) ); // run device’s seek function, which may be a noop • }

  17. Device Dependent: ionull.c /* ionull.c - ionull */ /*------------------------------------------------------------------------ * ionull - do nothing (used for "don't care" entries in devtab) *------------------------------------------------------------------------ */ ionull() { return(OK); }

  18. Device Independent: read.c • /* read.c - read */ • /* read - read one or more bytes from a device */ • SYSCALL read(descrp, buff, count) • int descrp, count; • char *buff; • { • struct devsw *devptr; • if (isbaddev(descrp) ) • return(SYSERR); • devptr = &devtab[descrp]; // get pointer to device’s IO structure • return( (*devptr->dvread)(devptr,buff,count) ); // device’s read may be an ‘error’, e.g., on keyboard • }

  19. Device Independent: write.c /* write.c - write */ /*------------------------------------------------------------------------ * write - write 1 or more bytes to a device *------------------------------------------------------------------------ */ SYSCALL write(descrp, buff, count) intdescrp, count; char *buff; { structdevsw *devptr; if (isbaddev(descrp) ) return(SYSERR); devptr = &devtab[descrp]; return( (*devptr->dvwrite)(devptr,buff,count) ); }

  20. Device Independent: close /* close.c - close */ /*------------------------------------------------------------------------ * close - close a device *------------------------------------------------------------------------ */ SYSCALL close(descrp) intdescrp; { structdevsw *devptr; if (isbaddev(descrp) ) return(SYSERR); devptr = &devtab[descrp]; return( (*devptr->dvclose)(devptr)); }

  21. Layers of I/O System • User Level – processes • make I/O call, format I/O, spooling • Device-Independent software • naming, protection blocking, buffering, allocation • perform I/O functions common to all devices • provide uniform interface to the user level software • buffering, block sizes, etc. • e.g., map symbolic device names onto driver • Device-Dependent software • setup device registers, check status • specific code for device operations, i.e., driver • accept abstract requests, e.g., open, and execute • Hardware • Controller. map I/O ops to device ops, e.g., print, • Interrupts

  22. Device Dependent: slu.h /* slu.h- standard serial line unit device constants */ #define SLUENABLE 0100 /* device interrupt enable bit */ #define SLUREADY 0200 /* device ready bit */ #define SLUDISABLE 0000 /* device interrupt disable mask*/ #define SLUTBREAK 0001 /* transmitter break-mode bit */ #define SLUERMASK 0170000 /* mask for error flags on input*/ #define SLUCHMASK 0377 /* mask for input character */ /* SLU device register layout and correspondence to vendor's names */ structcsr { intcrstat; /* receiver control and status (RCSR) */ intcrbuf; /* receiver data buffer (RBUF) */ intctstat; /* transmitter control & status (XCSR) */ intctbuf; /* transmitter data buffer (XBUF) */ }; // memory mapped IO // real registers

  23. Layers of I/O System • User Level – processes • make I/O call, format I/O, spooling • Device-Independent software • naming, protection blocking, buffering, allocation • perform I/O functions common to all devices • provide uniform interface to the user level software • buffering, block sizes, etc. • e.g., map symbolic device names onto driver • Device-Dependent software • setup device registers, check status • specific code for device operations, i.e., driver • accept abstract requests, e.g., open, and execute • Hardware • controller, map I/O ops to device ops, e.g., print, • Interrupts

  24. Device Dependent: tty ttycntl.c ttyiin.c ttyoin.c ttyputc.c ttywrite.c ttygetc.c ttyinit.c ttyopen.c ttyread.c

  25. Device Dependent: tty struct • struct tty { /* tty line control block */ • // set up input queue • int ihead; /* head of input queue */ • int itail; /* tail of input queue */ • char ibuff[IBUFLEN]; /* input buffer for this line */ • int isem; /* input semaphore */ • // set up output queue • int ohead; /* head of output queue */ • int otail; /* tail of output queue */ • char obuff[OBUFLEN]; /* output buffer for this line */ • int osem; /* output semaphore */ • int odsend; /* sends delayed for space */ • ……

  26. Device Dependent: tty struct • ……. • /// set up echo queue • int ehead; /* head of echo queue */ • int etail; /* tail of echo queue */ • char ebuff[EBUFLEN]; /* echo queue */ • char imode; /* IMRAW, IMCBREAK, IMCOOKED */ • Bool iecho; /* is input echoed? */ • Bool ieback; /* do erasing backspace on echo?*/ • Bool evis; /* echo control chars as ^X ? */ • Bool ecrlf; /* echo CR-LF for newline? */ • Bool icrlf; /* map '\r' to '\n' on input? */ • Bool ierase; /* honor erase character? */ • …. RAW – puts characters into ibuff without processing ignores all user editing CBREAK – honors all control characters except those related to line editing COOKED – character echo, honors suspend or restart gets complete lines

  27. Device Dependent: tty struct cont. /* structcontinuid char ierasec; /* erase character (backspace) */ Boolikill; /* honor line kill character? */ char ikillc; /* line kill character */ Booliintr; /* is interrupt char honored? */ char iintrc; /* interrupt character */ intiintpid; /* interrupt process id */ Boolieof; /* honor end-of-file char? */ char ieofc; /* end-of-file character */ inticursor; /* current cursor position */ Booloflow; /* honor ostop/ostart? */ Booloheld; /* output currently being held? */ char ostop; /* character that stops output */ char ostart; /* character that starts output */ Boolocrlf; /* echo CR/LF for LF ? */ char ifullc; /* char to send when input full */ structcsr *ioaddr; /* device address of this unit */ }; extern structttytty[];

  28. Device Dependent: tty.h • #define BACKSP '\b' /* backspace one character pos. */ • #define BELL '\007' /* usually an audiable tone */ • #define BLANK ' ' /* used to print a "space" */ • #define EOFC '\004' /* end-of-file character (^D) */ • #define KILLCH '\025' /* line kill character (^U) */ • #define NEWLINE '\n' /* line feed */ • #define RETURN '\r' /* carriage return */ • #define STOPCH '\023' /* control-S stops output */ • #define STRTCH '\021' /* control-Q restarts output */ • #define INTRCH '\002' /* control-B is interrupt */ • #define UPARROW '^' /* usually for visuals like ^X */ • ……..

  29. Device Dependent: tty.h • …….. • /* ttycontrol function codes */ • #define TCSETBRK 1 /* turn on BREAK in transmitter */ • #define TCRSTBRK 2 /* turn off BREAK " " */ • #define TCNEXTC 3 /* look ahead 1 character */ • #define TCMODER 4 /* set input mode to raw */ • #define TCMODEC 5 /* set input mode to cooked */ • #define TCMODEK 6 /* set input mode to cbreak */ • #define TCICHARS 8 /* return number of input chars */ • #define TCECHO 9 /* turn on echo */ • #define TCNOECHO 10 /* turn off echo */ • #define TCINT 11 /* set input interrupt pid */ • #define TCINTCH 12 /* set input interrupt char */ • #define TCNOINT 13 /* turn off input interrupt */ • #define TFULLC BELL /* char to echo when buffer full*/

  30. Device Dependent: tty init • /* ttyinit.c – ttyinit - initialize buffers and modes for a tty line */ • ttyinit(devptr) • struct devsw *devptr; • { • register struct tty *iptr; • register struct csr *cptr; //pointer to actual i/o registers • int junk, isconsole; • /* set up interrupt vector and interrupt dispatch table */ • iptr = &tty[devptr->dvminor]; • iosetvec(devptr->dvnum, (int)iptr, (int)iptr); • devptr->dvioblk = (char *)iptr /* fill tty control blk */ • isconsole = (devptr->dvnum == CONSOLE) /* make console cooked */ • iptr->ioaddr = (struct csr *)devptr->dvcsr;/* copy in csr addr. */ • iptr->ihead = iptr->itail = 0; /* empty input queue */ • iptr->isem = screate(0); /* chars. read so far=0 */ • iptr->osem = screate(OBUFLEN); /* buffer available=al, create semaphorne and initialize */ • iptr->odsend = 0;/* sends delayed so far */ • iptr->ohead = iptr->otail = 0; /* output queue empty, buffer pointer*/

  31. Device Dependent: tty init, cont iptr->ehead = iptr->etail = 0; /* echo queue empty */ iptr->imode = (isconsole ? IMCOOKED : IMRAW); iptr->iecho = iptr->evis = isconsole; /* echo console input */ iptr->ierase = iptr->ieback = isconsole;/* console honors erase */ iptr->ierasec = BACKSP; /* using ^h */ iptr->ecrlf = iptr->icrlf = isconsole; /* map RETURN on input */ iptr->ocrlf = iptr->oflow = isconsole; /* map RETURN on output */ iptr->ieof = iptr->ikill = isconsole; /* set line kill == @ */ iptr->iintr = FALSE; iptr->iintrc = INTRCH; iptr->iintpid = BADPID; iptr->ikillc = KILLCH; iptr->ieofc = EOFC; iptr->oheld = FALSE; iptr->ostart = STRTCH; iptr->ostop = STOPCH; iptr->icursor = 0; iptr->ifullc = TFULLC; cptr = (structcsr *)devptr->dvcsr; junk = cptr->crbuf; /* clear receiver and */ cptr->crstat = SLUENABE; /* enable in. interrupts*/ cptr->ctstat = SLUDISABL E;/* disable out. " */ }

  32. Device Dependent: tty open • /* ttyopen.c – ttyopen * ttyopen - open tty device and return descriptor (for namespace) */ • ttyopen(devptr, nam, mode) • struct devsw *devptr; • char *nam; • char *mode; • { • /* This routine is not usually used to open tty devices, */ • /* but is provided so that automatic calls to open do not */ • /* fail. It returns SYSERR unless called with a null name */ • if (*nam == '\0') • return( devptr->dvnum ); • else • return(SYSERR); • }

  33. Device Dependent: tty getc • /* ttygetc.c – ttygetc * ttygetc - read one character from a tty device */ • ttygetc(devptr) • struct devsw *devptr; • { char ps; • int ch; • struct tty *iptr; • disable(ps); // disable interrupts so I can mess with OS tables • iptr = &tty[devptr->dvminor]; // get moinor device # from device table • wait(iptr->isem); /* wait for a character in buff by waiting fro semaphone */ • ch = LOWBYTE & iptr->ibuff[iptr->itail++]; // get character and update tail • if (iptr->itail >= IBUFLEN) • iptr->itail = 0; // circular buffer mod operation • if (iptr->ieof && (iptr->ieofc == ch) ) • ch = EOF; • restore(ps); • return(ch); • }

  34. Device Dependent: tty putc • /* ttyputc.c – ttyputc * ttyputc - write one character to a tty device */ • ttyputc(devptr, ch ) • struct devsw *devptr; • char ch; • { • struct tty *iptr; • char ps; • iptr = &tty[devptr->dvminor]; // get pointer to control block, i.e., this tty • if ( ch==NEWLINE && iptr->ocrlf ) • ttyputc(devptr,RETURN); //convert newline to REturn, NEWLINE • disable(ps); • wait(iptr->osem); /* wait for space in queue */ • iptr->obuff[iptr->ohead++] = ch; //put char into output buffer • if (iptr->ohead >= OBUFLEN) //buffer pointer mod • iptr->ohead = 0; • (iptr->ioaddr)->ctstat = SLUENABLE;// turn on transmit interupt • restore(ps); • return(OK); • }

  35. Layers of I/O System • User Level – processes • make I/O call, format I/O, spooling • Device-Independent software • naming, protection blocking, buffering, allocation • perform I/O functions common to all devices • provide uniform interface to the user level software • buffering, block sizes, etc. • e.g., map symbolic device names onto driver • Device-Dependent software • setup device registers, check status • specific code for device operations, i.e., driver • accept abstract requests, e.g., open, and execute • Hardware • controller, map I/O ops to device ops, e.g., print, • Interrupts

More Related