16.05.2015 Views

Working with the Unix OS

Working with the Unix OS

Working with the Unix OS

SHOW MORE
SHOW LESS

Create successful ePaper yourself

Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.

145<br />

I/O Subsystem<br />

Close only for <strong>the</strong> last close of <strong>the</strong> device<br />

- kernel searches <strong>the</strong> file table to make sure that no o<strong>the</strong>r processes still have <strong>the</strong> device open<br />

- several process may access <strong>the</strong> device via different file table entry<br />

- several device files may specify <strong>the</strong> same device different inodes but same device<br />

- for block devices, kernel searches <strong>the</strong> mount table to make sure that <strong>the</strong> device does not contain a mounted file<br />

system<br />

- <strong>the</strong> kernel searches <strong>the</strong> buffer cache for blocks marked "delayed write" and writes <strong>the</strong>m before<br />

invoking <strong>the</strong> device close procedure.<br />

- kernel releases inode of <strong>the</strong> device file<br />

Kernel algorithms for read and write are similar to those of a regular file.<br />

The kernel can transmit data directly between address space and <strong>the</strong> device, or device drivers may buffer data<br />

internally e.g. terminal drivers use clist to buffer data.<br />

- memory mapped - status registers<br />

- programmed I/O - execute instructions<br />

- direct memory access (DMA) - used for bulk data transfer in parallel to CPU operations.<br />

- transfer data between device and user's address space faster (one less copy, no kernel buffers).<br />

! Strategy interface<br />

To transmit data between <strong>the</strong> buffer cache and a device. The process must be locked in memory until <strong>the</strong> I/O<br />

transfer is complete.<br />

! ioctl(fd, command, arg)<br />

Device specific<br />

! Interrupt handlers<br />

Many physical devices can be associated <strong>with</strong> one interrupt vector entry, <strong>the</strong> driver must be able to resolve which<br />

device caused <strong>the</strong> interrupt.<br />

Disk Drivers<br />

Partitioning <strong>the</strong> disk into sections, means that some<br />

sections can be read-only, some read-write, and some<br />

unmounted (no access)<br />

Section Name Start Length<br />

Block in Blocks<br />

0 0s0 0 64000<br />

1 0s1 64000 192000<br />

2 0s2 256000 256000<br />

3 0s3 0 512000<br />

Sections may overlap, but file systems must not.<br />

$ ls -1 Idev/dsk15 Idev/rdsk15<br />

br------- 2 root root 0,21 Feb 12 15:40<br />

/dev/dsk15<br />

crw-rw--- 2 root root 7,21 May 7 09:29<br />

/dev/rdsk15<br />

The kernel loops internally 4 times to read 4096 bytes<br />

Programs that read and write <strong>the</strong> disk directly can<br />

destroy <strong>the</strong> consistency of <strong>the</strong> file system data.<br />

Therefore "fsck" should not run on active file system.<br />

Figure 31. Reading Disk Data - block & raw interface<br />

#include "fcntl.h" #include <br />

main()<br />

{<br />

char buf1[4096], buf2[4096];<br />

int fdl, fd2, i;<br />

}<br />

if (((fdl =open("/dev/dsk5", O_RDONLY)) == -1) ||<br />

((fd2=open("/dev/rdsk5", O_RDONLY)) == -1))<br />

{<br />

printf("failure on open\n");<br />

exit();<br />

}<br />

lseek(fdl, 8192L, 0);<br />

lseek(fd2, 8l92L, 0);<br />

if ((read(fdl, bufl, sizeof(buf1)) == -1) ||<br />

(read(fd2, buf2, sizeof(buf2)) == -1))<br />

{<br />

printf("failure on read\n");<br />

exit(0);<br />

}<br />

for (i = 0; i < sizeof(buf1); i++)<br />

if (buf[I] != buf2[i])<br />

{<br />

printf("different at offset %d\n", i);<br />

exit(0);<br />

}<br />

printf("reads match\n");

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!