L1. OS overview (Chapter 1,2, and 3 from Lion's) o Goal of course - design and implement miminal OS - "new" course (not taught since 1968) o What is an operating system? - a piece of software that turns the hardware into something useful - picture: hardware, OS, applications o Two main functions abstract hardware manage hardware o Examples: - OSX, Windows, Linux, *BSD, ... (desktop, server) - PalmOS Windows/CE (PDA) - VxWorks (real-time) - ... o Abstractions processes fork, wait, exec, exit, kill, getpid, brk, nice, sleep, trace files open, close, read, write, lseek, stat directories etc. mkdir, rmdir, link, unlink, mount, umount, chdir, sync users + security chown, chmod, getuid, setuid, interprocess communication signals, pipe networking socket, accept, snd, recv, connect time time, .. o Main organization trust and nontrusted code (kernel) Conflict between extensibilty and enforced modularity o Lab - minimal OS x86 exokernel (interface, interrupts, etc.) libOS (fork, exec, pipe, ...) - development environment gcc, bochs o Lecture structure - 45min lecture - 45min case study (v6 source code or paper) o First case study: UNIX 6th edition (for first half of the term) - Multi-user time-sharing operating system for PDP11 - PDP-11 (1972): - 16-bit processor, 18-bit physical (40) - UNIBUS - memory-mapped I/O - performance: less than 1MIPS - register-to-register transfer: 0.9 usec - 56k-228k (40) - no paging, but some segmentation support - interrupts, traps - about $10K - with cabinet 11/40 is 400lbs - UNIX v6 - 1976; first widely available UNIX outside Bell labs - R&T - simplicity (reaction to MULTICS) - complete (used for real work) - small (43 system calls) - modular (composition through pipes; one had to split programs!!) - advanced UI (shell) - compactly written (2 programmers, 9,000 lines of code) - newer UNIXs have inherited many of the conceptual ideas even though they added paging, networking, graphics, etc. - introduced C (derived from B) - distributed with source - V7 was sold by Microsoft for a couple years under the name Xenix - Lion's commentary - surpressed because of copyright issue - resurfaced in 1996 o the shell (simplified) - structure while (1) { printf ("$"); readcommand (command, args); if ((pid = fork ()) == 0) { // child? exec (command, args, 0); } else if (pid > 0) { // parent? wait (pid); } else { printf ("Unable to fork\n"); } } $ ls - why call "wait" if child finishes, it becomes a zombie - I/O: file descriptors - every process starts with: file descriptor 0 for input (e.g., keyboard) read_command: read (1, buf, bufsize) file descriptor 1 for output (e.g., terminal) file descriptor 2 for error (e.g., terminal) - how does the shell implement $ls > tmp1 - just before exec insert: close (1); fd = open ("tmp1", O_CREAT|O_WRONLY); // fd will be 1! - how does the shell implement $ls 2> tmp1 (sharing an output file) - replace last code with: close (1); close (2); fd1 = open ("tmp1", O_CREAT|O_WRONLY); // fd will be 1! fd2 = dup (fd); both file descriptors share offset - how do programs communicate? $ sort file.txt | uniq | wc or $ sort file.txt > tmp1 $ uniq tmp1 > tmp2 $ wc tmp2 $ rm tmp1 tmp2 or $ kill signal - pipe example: int fd[2]; if (pipe(fd) < 0) panic ("error"); if ((pid = fork()) < 0) panic ("error"); else if (pid > 0) { close(fd[0]); write(fd[1], "hello world\n", 12); } else { close(fd[1]); n = read (fd[0], buf, MAXBUF); write (1, buf, n); } - how does the shell implement pipelines? int fd[2]; if (pipe(fd) < 0) panic ("error"); if ((pid = fork ()) == 0) { close (1); tmp = dup (fd[1]); // 1 is the write end close (0); exec (command1, args1, 0); } else if (pid > 0) { close (0); tmp = dup (fd[0]); // 0 is the read end close (fd[1]); // close write end exec (command2, args2, 0); } else { printf ("Unable to fork\n"); } - why close read-end and write-end? multiple reasons: maintain that every process starts with 3 file descriptors reading from an empty pipe blocks reader - how do you background jobs? $ compute & - how does the shell implement "&"