* Name, room number, name of class, class time, office hours * "Advanced" Operating Systems * Class goal - Demystify the operating system - Understand conventional operating systems in detail by designing and implementing a minimal OS - Seminal operating systems papers, historical and some recent - For you and for me! * Centerpiece: JOS Kernel - Build a minimal OS for PC hardware - Bootstrap code, memory management, processes, IPC, networking - OS will run on a standard PC: x86 architecture, IDE disk, standard console - C with some assembly language - bochs: a faithful PC hardware simulator - need a GNU binutils/GCC/Bochs toolchain - easiest with UNIX - working on SEASnet * Class organization - Mixed lecture/discussion - Based on papers and freely available documentation - Read papers before class - Class website - Class mailing list * Approximate grading - Lab assignments 50% - Midterm & final exam 40% - Class participation 10% - Note: subjective - Late policy on labs: 3 free days; if you use them up, 1 letter grade per day * What is an OS? - Makes HW useful to the programmer 1: - Provides abstractions for applications - Provides protection 2: - Fault isolate applications - Abstract hardware - Manage hardware 3: - Make it easier to write applications - Reduce impact of bugs - Sharing * Fundamental OS choices - What functionality is provided? - What programming failures or mistakes are tolerated, and how robustly? - What hardware failures or mistakes are tolerated, and how robustly? * Before UNIX, CTSS - IBM 7094, from the early 1960s: 32K 36-bit words of memory, $3.5M (~$20M now) - batch mode: one job at a time - Fortran Monitor System - job + libraries + monitor routine that killed jobs > time estimate - MIT thought they'd get a whole machine; instead, they got one 8-hour shift a day. All other New England colleges and universities got another shift, and IBM got the remaining shift. - "One use IBM made of it was yacht handicapping: the president of IBM raced big yachts on Long Island Sound, and these boats were assigned handicap points by a complicated formula. There was a special job deck kept at the MIT Computation Center, and if a request came in to run it, operators were to stop whatever was running on the machine and do the yacht handicapping job immediately." - CTSS, developed in early 1960s - compatible: FMS could run in B-core; Time Sharing System - one early mention: 1959, John McCarthy, interactive time-shared debugging - "sequence break mode": an important professor's job can interrupt a running job, roll its core image to tape, make a quick run, and restore the interrupted job - How'd it work? - IBM hardware RPQs: Request Price Quotation (special!) - Add several instructions, memory boundary register, two 32K core memory banks - B-core: instrs forbidden; if executed, trap to A-core: supervisor mode * Unix v6 - 1976: first widely available UNIX outside Bell Labs - Ritchie & Thompson - 43 system calls; 9000 LOC - introduced C * JOS Kernel - Asynchronous "exokernel-like" interface - No kernel threads - Only one kernel stack - Interrupts always disabled (except in idle loop); kernel never sleeps (except in idle loop) - "Manual stack ripping" - Simulate traditional synchronous interface at user level * TinyOS - Asynchronous "exokernel-like" interface - No protection - Hardware sharing possible, but difficult - Some language support to make it harder to shoot yourself - Wave of the future? * Shell while (1) { printf("$"); readcommand(command, args); if ((pid = fork()) == 0) exec(command, args, 0); else if (pid > 0) wait(0); else perror("failed to fork"); } * System calls - int gettimeofday(struct timeval*) - int read(int fd, void*, int) - int write(int fd, void*, int) - off_t lseek(int fd, off_t, int [012]) - int close(int fd) - int fsync(int fd) - int open(const char*, int flags [, int mode]) - O_RDONLY, O_WRONLY, O_RDWR, O_CREAT - int rename(const char*, const char*) [?] - int fork() - returns childPID in parent, 0 in child; only difference - int waitpid(int pid, int* stat, int opt) - pid==-1: any; opt==0||WNOHANG - returns pid or error - void exit(int status) - int kill(int pid, int signal) - int execve(char* prog, char** argv, char** envp) - int dup2(int oldfd, int newfd) - int fcntl(int fd, F_SETFD, int val) // close-on-exec - int pipe(int fds[2]) - writes on fds[1] will be read on fds[0] - when last fds[1] closed, read fds[0] retursn EOF - when last fds[0] closed, write fds[1] kills SIGPIPE/fails EPIPE - int fchown(int fd, uind_t owner, gid_t group) - int fchmod(int fd, mode_t mode) - int socket(int domain, int type, int protocol) - int accept(int socket_fd, struct sockaddr*, int* namelen) - returns new fd - int listen(int fd, int backlog) - int connect(int fd, const struct sockaddr*, int namelen) - void* mmap(void* addr, size_t len, int prot, int flags, int fd, off_t offset) - int munmap(void* addr, size_t len) -- not reached -- * Unix contexts - User-level - Kernel 'top half' - Kernel 'bottom half' - Software/device/timer interrupt - Context switch code - User > top half syscall/page fault - User/top half > dev/timer intr hardware - Top half > user/ctx sw return - Top half > ctx sw sleep - Ctx sw > user/top half - Synchronization: int x = splhigh(); ... splx(x);