{ "query": "Please summarize the whole context. It is important that you include a summary for each file. All files should be included, so please make sure to go through the entire context", "namespace": "45f3201e-c91d-402e-b952-e79e52c0df94", "messages": [], "stream": false, "language_level": "", "chat_channel": "", "language": "German", "tone": "neutral", "writing_style": "standard", "model": "gemini-1.5-flash", "knowledgebase": "ki-dev-large", "seed": 0, "client_id": 0, "all_context": true, "follow_up_for": null, "knowledgebase_files_count": 0, "override_command": "", "disable_clarity_check": true, "custom_primer": "", "logging": true, "query_route": "" } INITIALIZATION Knowledgebase: ki-dev-large Base Query: Please summarize the whole context. It is important that you include a summary for each file. All files should be included, so please make sure to go through the entire context Model: gemini-1.5-flash Use Curl?: ================================================== **Elapsed Time: 0.00 seconds** ================================================== ROUTING Query type: summary ================================================== **Elapsed Time: 2.66 seconds** ================================================== PRIMER Primer: You are Simon, a highly intelligent personal assistant in a system called KIOS. You are a chatbot that can read knowledgebases through the "CONTEXT" that is included in the user's chat message. Your role is to act as an expert at summarization and analysis. In your responses to enterprise users, prioritize clarity, trustworthiness, and appropriate formality. Be honest by admitting when a topic falls outside your scope of knowledge, and suggest alternative avenues for obtaining information when necessary. Make effective use of chat history to avoid redundancy and enhance response relevance, continuously adapting to integrate all necessary details in your interactions. Use as much tokens as possible to provide a detailed response. ================================================== **Elapsed Time: 0.34 seconds** ================================================== FINAL QUERY Final Query: CONTEXT: ########## File: 1%20A%20short%20introduction%20to%20operating%20systems%20%282001%29%20-%20Mark%20Burgess%20%28PDF%29.pdf Page: 1 Context: # A short introduction to operating systems Mark Burgess October 3, 2001 #################### File: 1%20A%20short%20introduction%20to%20operating%20systems%20%282001%29%20-%20Mark%20Burgess%20%28PDF%29.pdf Page: 2 Context: # Contents 1. **What is an operating system?** .......................................... 5 1.1 Key concepts .................................................... 8 1.1.1 Hierarchies and black boxes .................................. 8 1.1.2 Resources and sharing ....................................... 9 1.1.3 Communication, protocols, data types ........................ 9 1.1.4 System overhead ............................................ 10 1.1.5 Caching .................................................... 11 1.2 Hardware ........................................................ 11 1.2.1 The CPU .................................................... 11 1.2.2 Memory ...................................................... 11 1.2.3 Devices ...................................................... 12 1.2.4 Interrupts, traps, exceptions ................................ 12 1.3 Software ........................................................ 13 1.3.1 Resource management ......................................... 13 1.3.2 Spooling ..................................................... 13 1.3.3 System calls .................................................. 13 1.3.4 Basic command language ...................................... 14 1.3.5 Filesystem .................................................... 15 1.3.6 Multiple windows and screens ................................ 15 2. **Single-task OS** ...................................................... 17 2.1 Memory map and registers .......................................... 17 2.2 Stack ............................................................ 19 2.3 Input/Output .................................................... 23 2.3.1 Interrupts .................................................... 23 2.3.2 Buffers ....................................................... 24 2.3.3 Synchronous and asynchronous I/O ............................. 24 2.3.4 DMA - Direct Memory Access .................................. 24 3. **Multi-tasking and multi-user OS** .................................... 26 3.1 Competition for resources .......................................... 26 3.1.1 Users - authentication ....................................... 26 3.1.2 Privileges and security ....................................... 26 #################### File: 1%20A%20short%20introduction%20to%20operating%20systems%20%282001%29%20-%20Mark%20Burgess%20%28PDF%29.pdf Page: 3 Context: # Table of Contents ## 3 System Mechanics ### 3.1 Processes #### 3.1.1 Tasks - Two-Mode Operation .................................. 27 #### 3.1.2 I/O and Memory Protection ................................... 27 #### 3.1.3 Time Sharing ............................................... 28 ### 3.2 Memory Map .................................................. 28 ### 3.3 Kernel and Shells - Layers of Software ........................ 30 ### 3.4 Services: Daemons ........................................... 30 ### 3.5 Multiprocessors – Parallelism ................................ 31 ## 4 Processes and Threads ### 4.1 Key Concepts ................................................. 32 #### 4.1.1 Naming Conventions ......................................... 32 #### 4.1.2 Scheduling ................................................ 33 #### 4.1.3 Scheduling Hierarchy ...................................... 33 #### 4.1.4 Run Levels - Priority ..................................... 35 #### 4.1.5 Context Switching ......................................... 36 #### 4.1.6 Interprocess Communication ................................ 37 ### 4.2 Creation and Scheduling ...................................... 38 #### 4.2.1 Creating Processes ........................................ 38 #### 4.2.2 Process Hierarchy: Children and Parent Processes ......... 39 #### 4.2.3 Unix: `fork()` and `wait()` ................................ 39 #### 4.2.4 Process States ............................................ 41 #### 4.2.5 Queue Scheduling ......................................... 42 #### 4.2.6 Round-Robin Scheduling ................................... 44 #### 4.2.7 CPU Quotas and Accounting ................................ 45 ### 4.3 Threads ...................................................... 45 #### 4.3.1 Heavy and Lightweight Processes ........................... 47 #### 4.3.2 Why Use Threads? .......................................... 47 #### 4.3.3 Levels of Threads ......................................... 47 #### 4.3.4 Symmetric and Asymmetric Multiprocessing ................ 48 #### 4.3.5 Example: POSIX Pthreads .................................. 49 #### 4.3.6 Example: LWPs in Solaris ................................. 52 ### 4.4 Synchronization of Processes and Threads ...................... 54 #### 4.4.1 Problems with Sharing for Processes ....................... 54 #### 4.4.2 Serialization ............................................ 55 #### 4.4.3 Mutexes: Mutual Exclusion ................................ 56 #### 4.4.4 User Synchronization: File Locks .......................... 57 #### 4.4.5 Exclusive and Non-Exclusive Locks ......................... 58 #### 4.4.6 Critical Sections: The Mutex Solution ..................... 58 #### 4.4.7 Flags and Semaphores ...................................... 59 #### 4.4.8 Monitors .................................................. 60 ### 4.5 Deadlock .................................................... 61 #### 4.5.1 Cause ..................................................... 61 #### 4.5.2 Prevention ................................................ 62 #################### File: 1%20A%20short%20introduction%20to%20operating%20systems%20%282001%29%20-%20Mark%20Burgess%20%28PDF%29.pdf Page: 4 Context: # 4.5.3 Detection ................................................. 62 # 4.5.4 Recovery .................................................. 62 # 4.6 Summary ..................................................... 63 # 5 Memory and Storage .......................................... 65 ## 5.1 Logical and Physical Memory ................................ 65 ### 5.1.1 Physical Address Space ................................... 65 ### 5.1.2 Word Size ............................................... 65 ### 5.1.3 Paged RAM/ROM ......................................... 66 ### 5.1.4 Address Binding - Coexistence in Memory ............... 66 ### 5.1.5 Shared Libraries ........................................ 67 ### 5.1.6 Runtime Binding ......................................... 69 ### 5.1.7 Segmentation - Sharing .................................. 72 ### 5.1.8 The malloc() Function ................................... 72 ### 5.1.9 Page Size, Fragmentation and Alignment .................. 74 ### 5.1.10 Reclaiming Fragmented Memory (Tetris) ................. 76 ## 5.2 Virtual Memory ............................................. 76 ### 5.2.1 Paging and Swapping ...................................... 76 ### 5.2.2 Demand Paging - Lazy Evaluation ........................ 77 ### 5.2.3 Swapping and Paging Algorithms ......................... 78 ### 5.2.4 Thrashing ............................................... 82 ## 5.3 Disks: Secondary Storage .................................. 82 ### 5.3.1 Physical Structure ....................................... 83 ### 5.3.2 Device Drivers and IDs .................................. 84 ### 5.3.3 Checking Data Consistency and Formatting ............... 85 ### 5.3.4 Scheduling .............................................. 86 ### 5.3.5 Partitions ............................................... 87 ### 5.3.6 Stripes .................................................. 89 ## 5.4 Disk Filesystems ............................................ 90 ### 5.4.1 Hierarchical Filesystems and Links ....................... 90 ### 5.4.2 File Types and Device Nodes .............................. 91 ### 5.4.3 Permissions and Access .................................. 92 ### 5.4.4 File System Protocols .................................... 93 ### 5.4.5 Filesystem Implementation and Storage .................... 94 ### 5.4.6 The UNIX UFS Filesystem ................................ 95 # 6 Networks: Services and Protocols .............................. 100 ## 6.1 Services: The Client-Server Model .......................... 101 ## 6.2 Communication and Protocol ................................ 102 ## 6.3 Services and Ports .......................................... 103 ## 6.4 UNIX Client-Server Implementation ........................... 103 ### 6.4.1 Socket Based Communication ............................... 103 ### 6.4.2 RPC Services ............................................. 105 #################### File: 1%20A%20short%20introduction%20to%20operating%20systems%20%282001%29%20-%20Mark%20Burgess%20%28PDF%29.pdf Page: 5 Context: ``` # 6 TCP/IP Networks ## 6.5 The telnet command ..................................... 106 ## 6.6 X11 .................................................... 107 ## 6.7 HTML: Hypertext Markup Language ........................ 107 # 7 TCP/IP Networks ........................................... 109 ## 7.1 The protocol hierarchy .................................. 109 ### 7.1.1 The OSI model ....................................... 109 ### 7.1.2 Data encapsulation .................................. 111 ## 7.2 The Internet Protocol Family ............................ 111 ### 7.2.1 UDP ................................................. 112 ### 7.2.2 TCP ................................................. 113 ## 7.3 The Physical Layer ..................................... 114 ### 7.3.1 Network Connectivity ................................ 114 ### 7.3.2 Ethernet Addresses .................................. 116 ## 7.4 Internet Addresses and Routing .......................... 116 ### 7.4.1 IP Addresses, Networks and Domain Names ............. 116 ### 7.4.2 Netmask and Broadcast Address ........................ 117 ### 7.4.3 Routers and Gateways ................................ 118 ## 7.5 Network Naming Services ................................. 119 ### 7.5.1 The Domain Name Service ............................. 119 ### 7.5.2 Network Information Service .......................... 120 ## 7.6 Distributed File Systems ................................ 121 ### 7.6.1 NFS - The Network File System ....................... 121 ### 7.6.2 AFS - The Andrew File System ........................ 122 ### 7.6.3 DCE - The Distributed Computing Environment .......... 122 # 8 Security: Design Considerations ........................... 123 ## 8.1 Who is Responsible? .................................... 124 ## 8.2 Passwords and Encryption ............................... 124 ### 8.2.1 UNIX Passwords ...................................... 124 ### 8.2.2 Bad Passwords ....................................... 125 ## 8.3 Super-user or System Administrator ...................... 126 ### 8.3.1 Network Administration .............................. 126 ### 8.3.2 Setuid Programs in UNIX ............................. 127 ## 8.4 Backups ................................................ 128 ## 8.5 Intruders: Worms and Viruses ........................... 129 ### 8.5.1 Back Doors .......................................... 129 ## 8.6 Firewall ................................................ 130 ## 8.7 Public and Private Keys ................................ 131 ``` #################### File: 1%20A%20short%20introduction%20to%20operating%20systems%20%282001%29%20-%20Mark%20Burgess%20%28PDF%29.pdf Page: 6 Context: # Chapter 1 ## What is an operating system? An operating system is a layer of software which takes care of technical aspects of a computer's operation. It shields the user of the machine from the low-level details of the machine's operation and provides frequently needed facilities. There is no universal definition of what an operating system consists of. You can think of it as being the software which is already installed on a machine, before you add anything of your own. Normally, the operating system has a number of key elements: 1. **A technical layer of software** for driving the hardware of the computer, like disk drives, the keyboard, and the screen. 2. **A filesystem** which provides a way of organizing files logically. 3. **A simple command language** which enables users to run their own programs and to manipulate their files in a simple way. Some operating systems also provide text editors, compilers, debuggers, and a variety of other tools. Since the operating system (OS) is in charge of a computer, all requests to use its resources and devices need to go through the OS. An OS therefore provides: 4. **Legal entry points** into its code for performing basic operations like writing to devices. Operating systems may be classified by both how many tasks they can perform "simultaneously" and by how many users can be using the system "simultaneously". That is: - **Single-user** or **multi-user** - **Single-task** or **multi-tasking** A multi-user system must clearly be multi-tasking. The table below shows some examples. | System Type | Examples | |----------------|---------------------------| | Single-user, single-task | MS-DOS | | Single-user, multi-task | Windows (single user mode) | | Multi-user, multi-task | UNIX, Linux | Image Analysis: ### Image Analysis #### 1. Localization and Attribution - **Image 1**: - Located in the center of a text document, occupying most of the page. #### 4. Text Analysis - **Image 1**: - The text is a description of what an operating system is. - **Detected Text**: - "Chapter 1" - "What is an operating system?" - An operating system is a layer of software which takes care of technical aspects of a computer's operation. It shields the user of the machine from the low- level details of the machine's operation and provides frequently needed facilities. There is no universal definition of what an operating system consists of. You can think of it as being the software which is already installed on a machine, before you add anything of your own. Normally the operating system has a number of key elements: (i) a technical layer of software for driving the hardware of the computer, like disk drives, the keyboard and the screen; (ii) a filesystem which provides a way of organizing files logically, and (iii) a simple command language which enables users to run their own programs and to manipulate their files in a simple way. Some operating systems also provide text editors, compilers, debuggers and a variety of other tools. Since the operating system (OS) is in charge of a computer, all requests to use its resources and devices need to go through the OS. An OS therefore provides (iv) legal entry points into its code for performing basic operations like writing to devices. Operating systems may be classified by both how many tasks they can perform "simultaneously' and by how many users can be using the system "simultaneously'. That is: single-user or multi-user and single-task or multi-tasking. A multi-user system must clearly be multi-tasking. The table below shows some examples. - **Significance**: - The text introduces the concept of an operating system (OS), describing its fundamental components, roles, and functions. It highlights the essential elements such as technical layers for hardware control, file systems, and command languages. Additionally, it points out the classification of operating systems based on the number of simultaneous tasks and users they can handle, differentiating between single-user/multiple users and single-task/multi-tasking abilities. This foundational information is crucial for readers to understand the broader chapters likely to follow. #### 9. Perspective and Composition - **Image 1**: - The text layout uses clear headings and subheadings which offer a structured and readable format, helping the reader navigate through the content easily. The title "Chapter 1" and "What is an operating system?" are prominently positioned at the top and middle, respectively, followed by a block of explanatory text. #### 10. Contextual Significance - **Image 1**: - This image is likely a page from a textbook or educational document designed to introduce readers to the basics of operating systems. It lays the groundwork for further detailed discussions and chapters on operating systems, helping readers build a foundational understanding before moving onto more complex topics. ### Overall Summary: The image presents the first chapter of a text about operating systems. It defines the operating system, discusses its components, and briefly introduces the concept of classifying operating systems based on the number of users and tasks they handle. The organized layout and structured headings make it easy to follow, setting a clear introducion for readers. #################### File: 1%20A%20short%20introduction%20to%20operating%20systems%20%282001%29%20-%20Mark%20Burgess%20%28PDF%29.pdf Page: 7 Context: OS | Users | Tasks | Processors ---|---|---|--- MS/PC DOS | S | S | 1 Windows 3x | S | QM | 1 Macintosh System 7.¹ | S | QM | 1 Windows 9x | S | M* | 1 AmigaDOS | S | M | 1 inline MTS | M | M | 1 UNIX | M | M | n VMS | M | M | 1 NT | S/M | M | n Windows 2000 | M | M | n BeOS (Haiku?) | S | M | n The first of these (MS/PC DOS/Windows 3x) are single user, single-task systems which build on a ROM based library of basic functions called the BIOS. These are system calls which write to the screen or to disk etc. Although all the operating systems can service interrupts, and therefore simulate the appearance of multitasking in some situations, the older PC environments cannot be thought of as multi-tasking systems in any sense. Only a single user application could be open at any time. Windows 95 replaced the old coroutine approach of quasi-multitasking with a true context switching approach, but only a single user system, without proper memory protection. Windows NT added a proper kernel with memory protection, based on the VMS system, originally written for the DEC/Vax. Later versions of Windows NT and Windows 2000 added security and kernel enhanced version of NT) allow multiple logins also through a terminal server. Windows 2000 thus has comparable functionality to Unix in this respect. The Macintosh System 7 can be classified as single-user, quasi-multitasking¹. That means that it is possible to use several user applications simultaneously. A window manager can simulate the appearance of several programs running simultaneously, but this relies on each program obeying specific rules in order to achieve the illusion. The Macintosh not a true multitasking system in the sense that, if one program crashes, the whole system crashes. Windows 9x is purported to be preemptive multitasking but most program crashes also crash the entire system. This might be due to the lack of proper memory protection. AmigaDOS is an operating system for the Commodore Amiga computer. It is based on the UNIX model and is a fully multi-tasking, single-user system. Several programs may be actively running at any time. The operating system includes a window environment which means that each independent program ¹At the present, Apple are preparing a new operating system called NeXTStep or Rhapsody or Mac OS Server X which is based on BSD 4.4 Unix running on a Mach microkernel and will run old Macintosh software under emulation. #################### File: 1%20A%20short%20introduction%20to%20operating%20systems%20%282001%29%20-%20Mark%20Burgess%20%28PDF%29.pdf Page: 8 Context: # Operating Systems Overview Unix has a 'screen' of its own and does not therefore have to compete for the screen with other programs. This has been a major limitation on multi-tasking operating systems in the past. MTS (Michigan timesharing system) was the first time-sharing multi-user system. It supports only simple single-screen terminal based input/output and has no hierarchical file system. Unix is arguably the most important operating system today, and one which we shall frequently refer to below. It comes in many forms, developed by different manufacturers. Originally designed at AT&T, UNIX split into two camps early on: BSD (Berkeley software distribution) and system 5 (AT&T license). The BSD version was developed as a research project at the University of Berkeley, California. Many of the networking and user-friendly features originate from these modifications. With time these two versions have been merged back together and most systems are now a mixture of both worlds. Historically, BSD Unix has been most prevalent in universities, while system 5 has been dominant in business environments. The trend during the last three years by Sun Microsystems and Hewlett-Packard amongst others has been to move towards system 5, keeping only the most important features of the BSD system. A standardization committee for Unix called POSIX, formed by the major vendors, attempts to bring compatibility to the Unix world. Here are some common versions of UNIX. | Unix | Manufacturer | Mainly BSD / Sys 5 | |-----------------------|---------------------|-----------------------| | BSD | Berkeley | BSD | | SunOS (solaris 1) | Sun Microsystems | BSD/sys 5 | | Solaris 2 | Sun Microsystems | Sys 5 | | Ultrix | DEC/Compaq | BSD | | OSF 1 / Digital Unix | DEC/Compaq | BSD/sys 5 | | HPUX | Hewlett-Packard | Sys 5 | | AIX | IBM | Sys 5 / BSD | | IRIX | Silicon Graphics | Sys 5 | | GNU/Linux | Public Domain | Posix (Sys 5/BSD) | | SCO Unix | Novell | Sys 5 | Note that the original BSD source code is now in the public domain. Unix is generally regarded as the most portable and powerful operating system available today by impartial judges, but NT is improving quickly. Unix runs on everything from laptop computers to CRAY mainframes. It is particularly good at managing large database applications and can run on systems with hundreds of processors. Most Unix types support symmetric multi-threaded processing and all support simultaneous logins by multiple users. ¹ In Manitoba, Canada, the telephone system is also called MTS. The telephone system is probably more advanced than the original MTS, and certainly faster! #################### File: 1%20A%20short%20introduction%20to%20operating%20systems%20%282001%29%20-%20Mark%20Burgess%20%28PDF%29.pdf Page: 9 Context: # NT Operating System NT is a 'new' operating system from Microsoft based on the old VAX/VMS kernel from the Digital Equipment Corporation (VMS's inventor moved to Microsoft) and the Windows32 API. Initially, it reinvented many existing systems, but it is gradually being forced to adopt many open standards from the Unix world. It is fully multitasking and can support multiple users (but only one at a time—multiple logins by different users is not possible). It has virtual memory and multithreaded support for several processors. NT has a built-in object model and security framework which is amongst the most modern in use. The Be operating system, originally developed for a new multimedia computer called the BeBox, is also new and is a fully multitasking OS. It is optimized for multimedia and is now a saleable software developed by Be.Com after the new computer concept failed due to lack of financial backing. BeOS has proper memory protection but allows direct access to video memory (required for fast video games). It also has virtual memory, is pre-emptive multitasking, and is based on a microkernel design. It shares little with Unix except for a Bash shell, a POSIX programming interface, and about 150 Unix commands (including Perl). ## 1.1 Key Concepts Before discussing more of the details, let’s review some key ideas which lie behind the whole OS idea. Although these ideas may seem simple, you will do well to keep them in mind later. Simple ideas often get lost amongst distracting details, but it is important to remember that the ideas are simple. ### 1.1.1 Hierarchies and Black Boxes A hierarchy is a way of organizing information using levels of detail. The phrase **high-level** implies few details, whereas **low-level** implies a lot of detail, down in the guts of things. A hierarchy usually has the form of a tree, which branches from the highest level to the lowest, since each high-level object is composed of several lower-level objects. The key to making large computer programs and solving difficult problems is to create a hierarchical structure, in which large high-level problems are gradually broken up into manageable low-level problems. Each level works by using a series of "black boxes" (e.g., subroutines) whose inner details are not directly visible. This allows us to hide details and remain sane as the complexity builds up. This is the single most important concept in computing! It is used repeatedly to organize complex problems. #################### File: 1%20A%20short%20introduction%20to%20operating%20systems%20%282001%29%20-%20Mark%20Burgess%20%28PDF%29.pdf Page: 10 Context: # 1.1 Introduction ## 1.1.2 Resources and Sharing A computer is not just a box which adds numbers together. It has resources like the keyboard and the screen, the disk drives, and the memory. In a multi-tasking system, there may be several programs that need to receive input or write output simultaneously; thus, the operating system may have to share these resources between several running programs. If the system has two keyboards (or terminals) connected to it, the OS can allocate both to different programs. If only a single keyboard is connected, then competing programs must wait for the resources to become free. Most multi-tasking systems have only a single central processor unit, and yet this is the most precious resource a computer has. An multi-tasking operating system must therefore share CPU time between programs. That is, it must work for a time on one program, then work a while on the next program, and so on. If the first program was left unfinished, it must then return to work more on it, in a systematic way. The way an OS decides to share its time between different tasks is called **scheduling**. ## 1.1.3 Communication, Protocols, Data Types The exchange of information is an essential part of computing. Suppose computer A sends a message to computer B reporting on the names of all the users and how long they have been working. To do this, it sends a stream of bits across a network. When computer B receives a stream of bits, it doesn’t automatically know what they mean. It must decide if these bits represent numbers or characters, integers or floating point numbers, or a mixture of all of them. These different types of data are all stored as binary information—the only difference between them is the way one chooses to interpret them. The resolution to this problem is to define a **protocol**. This is a convention or agreement between the operating systems of two machines on what messages are being sent and how to interpret them. --- ![](image.png) *Figure 1.1: The hierarchy is the most important concept in computing.* ### Hierarchy ``` Level 0: Root Node Level 1: - Child #1 - Child #2 - Child #3 Level 2: ``` #################### File: 1%20A%20short%20introduction%20to%20operating%20systems%20%282001%29%20-%20Mark%20Burgess%20%28PDF%29.pdf Page: 12 Context: # 1.1.5 Caching Caching is a technique used to speed up communication with slow devices. Usually, the CPU can read data much faster from memory than it can from a disk or network connection, so it would like to keep an up-to-date copy of frequently used information in memory. The memory area used to do this is called a cache. You can think of the whole of the primary memory as being a cache for the secondary memory (disk). Sometimes caching is used more generally to mean 'keeping a local copy of data for convenience'. ## 1.2 Hardware Here we list the main hardware concepts. ### 1.2.1 The CPU The CPU, or central processor unit, is the heart and soul of every computer. This is the part that does the work of executing machine instructions. Traditionally, it is just one microprocessor with lots of pins to connect to memory and devices – usually identifiable by being the largest chip. On modern machines, there may be several CPUs which can work in parallel. Also, VLSI or very large scale integration technology has made it possible to put very many separate processors and memory into a single package, so the physical distinction between the CPU and its support chips is getting blurred. Nevertheless, the CPU is still logically separate from the memory and devices. The CPU is driven by a 'clock' or pulse generator. Each instruction completes in a certain number of 'clock cycles'. Traditionally, CPUs are based on CISC (Complex Instruction Set Computing) architecture, where a single instruction takes one or more clock cycles to complete. A new trend is to build RISC (Reduced Instruction Set Computing) processors which aim to be more efficient for a subset of instructions by using redundancy. These have simpler instructions but can execute much more quickly, sometimes with several instructions per clock cycle. ### 1.2.2 Memory The primary memory is the most important resource a computer has. Since CPUs are only made with instructions for reading and writing to memory, no programs would be able to run without it. There are two types of memory: RAM - random access memory, or read/write memory, which loses its contents when the machine is switched off, and ROM - read-only memory, which never loses its contents unless destroyed. ROM is normally used for storing those. #################### File: 1%20A%20short%20introduction%20to%20operating%20systems%20%282001%29%20-%20Mark%20Burgess%20%28PDF%29.pdf Page: 13 Context: # 1.2.3 Devices The concepts of a device really have two parts. There is the hardware unit which is connected to the machine, and there is the logical device which is a name given by the OS to a legal entry point for talking to a hardware device. When a user writes to a logical device, the OS invokes a device driver which performs the physical operations of controlling the hardware. For example, when writing to a disk, the OS must control the movement of the read-write heads. When writing to a printer, the OS places the information in a queue and services the request when the printer becomes free. Some common logical devices are: - The system disks - The keyboard - The screen - The printer - The audio device Disks and tapes are often called **secondary memory** or **secondary storage**. # 1.2.4 Interrupts, Traps, Exceptions Interrupts are hardware signals which are sent to the CPU by the devices it is connected to. These signals literally interrupt the CPU from what it is doing and demand that it spend a few clock cycles servicing a request. For example, interrupts may come from the keyboard because a user pressed a key. Then the CPU must stop what it is doing and read the keyboard, place the key value into a buffer for later reading, and return to what it was doing. Other 'events' generate interrupts: the system clock sends interrupts at periodic intervals, disk devices generate interrupts when they have finished an I/O task and interrupts can be used to allow computers to monitor sensors and detectors. User programs can also generate 'software interrupts' in order to handle special situations like a 'division by zero' error. These are often called traps or exceptions on some systems. Interrupts are graded in levels. **Low level** interrupts have a low priority, whereas **high level** interrupts have a high priority. A high level interrupt can interrupt a low level interrupt, so that the CPU must be able to recover from several 'layers' of interruption and end up doing what it was originally doing. This is accomplished by means of a stack or heap. Moreover, programs can often choose whether or not they wish to be interrupted by setting an interrupt mask which masks out the interrupts it does not want to hear about. Masking interrupts can be dangerous, since data can be lost. All systems therefore have **non-maskable interrupts** for the most crucial operations. *This is described more fully in the next chapter.* #################### File: 1%20A%20short%20introduction%20to%20operating%20systems%20%282001%29%20-%20Mark%20Burgess%20%28PDF%29.pdf Page: 14 Context: # 1.3 Software ## 1.3.1 Resource management In order to keep track of how the system resources are being used, an OS must keep tables or lists telling it what is free and what is not. For example, data cannot be stored neatly on a disk. As files become deleted, holes appear and the data becomes scattered randomly over the disk surface. ## 1.3.2 Spooling Spooling is a way of processing data serially. Print jobs are spooled to the printer, because they must be printed in the right order (it would not help the user if the lines of his/her file were liberally mixed together with parts of someone else's file). During a spooling operation, only one job is performed at a time and other jobs wait in a queue to be processed. Spooling is a form of batch processing. Spooling comes from the need to copy data onto a spool of tape for storage. It has since been dubbed Simultaneous Peripheral Operation On-Line, which is a pretty lousy attempt to make something more meaningful out of the word 'spool'! ## 1.3.3 System calls An important task of an operating system is to provide black-box functions for the most frequently needed operations, so that users do not have to waste their time programming very low-level code which is irrelevant to their purpose. These ready-made functions comprise frequently used code and are called system calls. For example, controlling devices requires very careful and complex programming. Users should not have to write code to position the head of the disk drive at the right place just to save a file to the disk. This is a very basic operation which everyone requires and it becomes the responsibility of the OS. Another example is mathematical functions or graphics primitives. System calls can be thought of as a very simple protocol – an agreed way of asking the OS to perform a service. Some typical OS calls are: - `read` (to screen, disk, printer etc.) - `write` (to screen, disk, printer etc.) - `stat` (get the status of a file: its size and type) - `malloc` (request for memory allocation). On older microcomputers, where high-level languages are uncommon, system calls are often available only through assembler or machine code. On modern systems and integrated systems like UNIX, they are available as functions in a high-level language like C. #################### File: 1%20A%20short%20introduction%20to%20operating%20systems%20%282001%29%20-%20Mark%20Burgess%20%28PDF%29.pdf Page: 15 Context: # 1.3.4 Basic Command Language Commands like: - `dir` ; list files (DOS) - `ls` ; list files (UNIX) - `cd` ; change directory - `copy file prn` ; copy file to printer - `myprog` ; execute program ‘myprog’ constitute a basic command language. Every computer must have such a language (except perhaps the Macintosh - yawn!). In microcomputer operating systems, the command language is often built into the system code, whereas on larger systems (UNIX), the commands are just executable programs like the last example above. The command language deals typically with: **file management**, **process management**, and **text editing**. # 1.3.5 Filesystem In creating a system to store files, we must answer some basic questions. - Should the filesystem distinguish between types of files e.g., executable files, text files, scripts? If so how? One way is to use file extensions, or a naming convention to identify files, like `myprog.exe`, `SCRIPT.BAT`, `file.txt`. The problem with this is that the names can be abused by users. If one tries to execute a file which is not meant to be executed, the result would be nonsense and might even be dangerous to the point of crashing the system. One way around this problem is to introduce a protocol or standard format for executable files, so that when the OS opens a file for execution, it first checks to see whether the file obeys the protocol. This method is used for binary files in UNIX, for instance. - **Protection.** If several users will be storing files together on the same disk, should each user’s files be exclusive to him or her? - Is a mechanism required for sharing files between several users? - A hierarchical filesystem is a good starting point for organizing files, but it can be too restrictive. Sometimes it is useful to have a file appear in several places at one time. This can be accomplished with links. A link is not a copy of a file, but a pointer to where a file really is. By making links to other places in a hierarchical filesystem, its flexibility is increased considerably. #################### File: 1%20A%20short%20introduction%20to%20operating%20systems%20%282001%29%20-%20Mark%20Burgess%20%28PDF%29.pdf Page: 18 Context: # Chapter 2 ## Single-task OS Before tackling the complexities of multi-tasking, it is useful to think about the operation of a single-task OS without all the clutter that multi-tasking entails. In a multi-task OS, the features we shall discuss below have to be reproduced N-times and then augmented by extra control structures. ### 2.1 Memory map and registers The key elements of a single-task computer are shown in Figure 2.1. Roughly speaking, at the hardware level, a computer consists of a CPU, memory, and a number of peripheral devices. The CPU contains registers or 'internal variables' which control its operation. The CPU can store information only in the memory it can address and in the registers of other microprocessors it is connected to. The CPU reads machine code instructions, one at a time, from the memory and executes them forever without stopping. Here is a brief summary of the types of register a CPU has. Some microprocessors have several of each type. | Register | Purpose | |-------------------------|--------------------------------------------------------------------| | Accumulator | Holds the data currently being worked on. | | Program counter | Holds the address of the next instruction to be executed. | | Index (addressing) registers | Used to specify the address of data to be loaded into or saved from the accumulator, or operated on in some way. | | Stack pointer | Points to the top of the CPU's own hardware controlled stack. | | Status register | Contains status information after each instruction which can be tested for to detect errors, etc. | The memory, as seen by the CPU, is a large string of bytes starting with. #################### File: 1%20A%20short%20introduction%20to%20operating%20systems%20%282001%29%20-%20Mark%20Burgess%20%28PDF%29.pdf Page: 19 Context: # Memory Overview Address space starts at address 0 and increases up to the maximum address. Physically, it is made up like a jigsaw puzzle of many memory chips and control chips, mapped into the diagram shown. Normally, because of the hardware design of the CPU, not all of the memory is available to the user of the machine. Some of it is required for the operation of the CPU. The roughly distinguished areas in figure 2.1 are: - **Zero page:** The first 'page' of the memory is often reserved for a special purpose. It is often faster to write to the zero page because you don’t have to code the leading zero for the address—special instructions for the zero page can leave the 'zero' implicit. - **Stack:** Every CPU needs a stack for executing subroutines. The stack is explained in more detail below. - **User programs:** Space the user programs can 'grow into'. - **Screen memory:** What you see on the screen of a computer is the image of an area of memory, converted into colors and positions by a hardware video controller. The screen memory is the area of memory needed to define the color of every 'point' or 'unit' on the screen. Depending on what kind of visual system a computer uses, this might be one byte per character, and it might be four bytes per pixel! - **Memory mapped I/O:** Hardware devices like disks and video controllers contain smaller microprocessors of their own. The CPU gives them instructions by placing numbers into their registers. To make this process simpler, these device registers (only a few bytes per device, perhaps) are 'wired' into the main memory map, so that writing to the device is the same as writing to the rest of the memory. - **Operating system:** The operating system itself is a large program that often takes up a large part of the available memory. > Note that this figure is very simplified. It does not show, for instance, special memory which might be located inside the devices or CPU. Such memory is often used for caching. Also, it does not show how the various components are connected together by means of a high speed data bus. #################### File: 1%20A%20short%20introduction%20to%20operating%20systems%20%282001%29%20-%20Mark%20Burgess%20%28PDF%29.pdf Page: 20 Context: # Operating System Memory Map | Segment | Description | |--------------------------|-------------------------------------------------------------------------| | Operating system | System-level software managing hardware and software resources | | Memory mapped I/O | Interface mapping input/output devices into the memory space | | Screen/display memory | Video memory holding data to be displayed on the screen | | User programs | Programs executed by the user | | Stack | Temporary storage for data, used in function calls | | Zero pages | Memory pages that do not contain any data, usually reserved for special use| **Figure 2.1**: A simple schematic memory map of a microcomputer. The order of the different segments of memory can vary depending on the system. ## 2.2 Stack A stack is a so-called last-in first-out (LIFO) data structure. That is to say – the last thing to be placed on top of a stack, when making it, is the first item which gets removed when un-making it. Stacks are used by the CPU to store the current position within a program before jumping to subroutines, so that they remember where to return to after the subroutine is finished. Because of the nature of the stack, the CPU can simply deposit the address of the next instruction to be executed (after the subroutine is finished) on top of the stack. When the subroutine is finished, the CPU pulls the first address it finds off the top of the stack and jumps to that location. Notice that the stack mechanism will continue to work even if the subroutine itself calls another subroutine, since the second subroutine causes another stack frame to be created. #################### File: 1%20A%20short%20introduction%20to%20operating%20systems%20%282001%29%20-%20Mark%20Burgess%20%28PDF%29.pdf Page: 21 Context: # A Simple Stack Handler Use the commands `push` and `pop` to push onto the stack and to pop "off" the stack. The allocated stack size is very small, so that an overflow can occur if you push too far! e.g., input 1. `push 4` 2. `pop` 3. `push 678` 4. `quit` In a real stack handler, the numbers would be the address of the next instruction to return to after completing a subroutine. The program is compiled with: ``` g++ stack.C ``` **MB 1994** ```cpp #include #include #include // Include file const int forever = 1; const int stacksize = 10; const int minsize = 20; class Stack { public: int stack[stacksize]; Stack(); void ShowStack(); void Push(int); int Pop(); private: int stackpointer; }; ``` #################### File: 1%20A%20short%20introduction%20to%20operating%20systems%20%282001%29%20-%20Mark%20Burgess%20%28PDF%29.pdf Page: 22 Context: ```markdown #include #include #include using namespace std; //*********************************************************** // Level 0 //*********************************************************** int main() { char input[256]; char command[21]; int number, newnumber; Stack s; cout << "Stack demo:\n"; s.ShowStack(); while (true) { cout << "Enter command: "; // Extract command cin.getline(input, sizeof(input)); istringstream(input) >> command >> number; // Interpret command if (strcmp(command, "push") == 0) { s.Push(number); } else if (strcmp(command, "pop") == 0) { newnumber = s.Pop(); } else if (strcmp(command, "quit") == 0) { break; } else { number = 0; cout << "Bad command\n"; } s.ShowStack(); } return 0; } //*********************************************************** // Class Stack //*********************************************************** class Stack { int i; }; ``` #################### File: 1%20A%20short%20introduction%20to%20operating%20systems%20%282001%29%20-%20Mark%20Burgess%20%28PDF%29.pdf Page: 23 Context: ``` stackpointer = 0; for (int i = 0; i < stacksize; i++) { stack[i] = 0; } /****************************************************************************** * Stack::Push ******************************************************************************/ void Stack::Push(int n) { cout << "Pushing " << n << " on the stack!"; if (stackpointer >= stacksize) { cerr << "Stack overflow!\n"; return; } stack[stackpointer] = n; stackpointer++; } /****************************************************************************** * Stack::Pop ******************************************************************************/ int Stack::Pop() { if (stackpointer == 0) { cerr << "Stack underflow!\n"; return 0; } stackpointer--; cout << "Popped " << stack[stackpointer] << " from stack\n"; return stack[stackpointer]; } /****************************************************************************** * Stack::ShowStack ******************************************************************************/ void Stack::ShowStack() { for (int i = stacksize - 1; i >= 0; i--) { cout << "stack[" << i << "] = " << stack[i]; if (i == stackpointer) { cout << " <-- Pointer\n"; } else { cout << endl; } } } ``` #################### File: 1%20A%20short%20introduction%20to%20operating%20systems%20%282001%29%20-%20Mark%20Burgess%20%28PDF%29.pdf Page: 24 Context: ```markdown ## 2.3 Input/Output Input arrives at the computer at unpredictable intervals. The system must be able to detect its arrival and respond to it. ### 2.3.1 Interrupts Interrupts are hardware triggered signals which cause the CPU to stop what it is doing and jump to a special subroutine. Interrupts normally arrive from hardware devices, such as when the user presses a key on the keyboard, or the disk device has fetched some data from the disk. They can also be generated in software by errors like division by zero or illegal memory address. When the CPU receives an interrupt, it saves the contents of its registers on the hardware stack and jumps to a special routine which will determine the cause of the interrupt and respond to it appropriately. Interrupts occur at different levels. Low-level interrupts can be interrupted by high-level interrupts. Interrupt handling routines have to work quickly, or the computer will be drowned in the business of servicing interrupts. For certain critical operations, low-level interrupts can be ignored by setting a mask (See also the generalization of this for multiprocessor systems in chapter 4). There is no logical difference between what happens during the execution of an interrupt routine and a subroutine. The difference is that interrupt routines are triggered by events, whereas software subroutines follow a prearranged plan. An important area is the interrupt vector. This is a region of memory reserved by the hardware for servicing interrupts. Each interrupt has a number from zero to the maximum number of interrupts supported on the CPU; for each interrupt, the interrupt vector must be programmed with the address of a routine which is to be executed when the interrupt occurs, i.e., when an interrupt occurs, the system examines the address in the interrupt vector for that interrupt and jumps to that location. The routine exits when it meets an RTI (return from interrupt) instruction. ``` #################### File: 1%20A%20short%20introduction%20to%20operating%20systems%20%282001%29%20-%20Mark%20Burgess%20%28PDF%29.pdf Page: 25 Context: ## 2.3.2 Buffers The CPU and the devices attached to it do not work at the same speed. Buffers are therefore needed to store incoming or outgoing information temporarily while it is waiting to be picked up by the other party. A buffer is simply an area of memory which works as a waiting area. It is a first-in first-out (FIFO) data structure or queue. ## 2.3.3 Synchronous and Asynchronous I/O To start an I/O operation, the CPU writes appropriate values into the registers of the device controller. The device controller acts on the values it finds in its registers. For example, if the operation is to read from a disk, the device controller fetches data from the disk and places it in its local buffer. It then signals the CPU by generating an interrupt. While the CPU is waiting for the I/O to complete, it may do one of two things. It can do nothing or idle until the device returns with the data (synchronous I/O), or it can continue doing something else until the completion interrupt arrives (asynchronous I/O). The second of these possibilities is clearly much more efficient. ## 2.3.4 DMA - Direct Memory Access Very high-speed devices could place heavy demands on the CPU for I/O servicing if they relied on the CPU to copy data word by word. The DMA controller is a device which copies blocks of data at a time from one place to the other, without the intervention of the CPU. To use it, its registers must be loaded with the information about what it should copy and where it should copy to. Once this is done, it generates an interrupt to signal the completion of the task. The advantage of the DMA is that it transfers large amounts of data before generating an interrupt. Without it, the CPU would have to copy the data one register-full at a time, using up hundreds or even thousands of interrupts and possibly bringing a halt to the machine! ## Exercises 1. What is the program counter? 2. Explain why a stack is used to store local variables. 3. Some microprocessors (68000/Intel 386 upward) support multitasking internally. A separate stack is then needed for each process. How can this be achieved? #################### File: 1%20A%20short%20introduction%20to%20operating%20systems%20%282001%29%20-%20Mark%20Burgess%20%28PDF%29.pdf Page: 26 Context: 4. Write a program to create a stack (LIFO) which can store any number of local variables for each subroutine. Hint: use a linked list for the stack and for the variables. 5. Write a program to implement a buffer (FIFO). 6. When a computer is first switched on, it executes a program called a bootstrap program. This comes from the expression ‘to lift oneself by one’s own bootstraps’. The computer must begin to execute instructions and ‘get going’. Find out for yourself, or speculate on how this takes place. 7. What is a stack frame? 8. What is memory mapped I/O? #################### File: 1%20A%20short%20introduction%20to%20operating%20systems%20%282001%29%20-%20Mark%20Burgess%20%28PDF%29.pdf Page: 27 Context: # Chapter 3 ## Multi-tasking and multi-user OS To make a multi-tasking OS, we need loosely to reproduce all of the features discussed in the last chapter for each task or process which runs. It is not necessary for each task to have its own set of devices. The basic hardware resources of the system are shared between the tasks. The operating system must therefore have a ‘manager’ which shares resources at all times. This manager is called the **kernel** and it constitutes the main difference between single and multitasking operating systems. ### 3.1 Competition for resources #### 3.1.1 Users - authentication If a system supports several users, then each user must have his or her own place on the system disk, where files can be stored. Since each user's files may be private, the file system should record the owner of each file. For this to be possible, all users must have a user identity or login name and must supply a password which prevents others from impersonating them. Passwords are stored in a cryptographic (coded) form. When a user logs in, the OS encrypts the typed password and compares it to the stored version. Stored passwords are never decrypted for comparison. #### 3.1.2 Privileges and security On a multi-user system, it is important that one user should not be able to interfere with another user’s activities, either purposefully or accidentally. Certain commands and system calls are therefore not available to normal users directly. #################### File: 1%20A%20short%20introduction%20to%20operating%20systems%20%282001%29%20-%20Mark%20Burgess%20%28PDF%29.pdf Page: 28 Context: The super-user is a privileged user (normally the system operator) who has permission to do anything, but normal users have restrictions placed on them in the interest of system safety. For example: normal users should not be able to halt the system; nor should they be able to control the devices connected to the computer, or write directly into memory without making a formal request of the OS. One of the tasks of the OS is to prevent collisions between users. ## 3.1.3 Tasks - two-mode operation It is crucial for the security of the system that different tasks, working side by side, should not be allowed to interfere with one another (although this occasionally happens in microcomputer operating systems, like the Macintosh, which allow several programs to be resident in memory simultaneously). Protection mechanisms are needed to deal with this problem. The way this is normally done is to make the operating system all-powerful and allow no user to access the system resources without going via the OS. To prevent users from tricking the OS, multiuser systems are based on hardware which supports two-mode operation: **privileged mode** for executing OS instructions and **user mode** for working on user programs. When running in user mode, a task has no special privileges and must ask the OS for resources through system calls. When I/O or resource management is performed, the OS takes over and switches to privileged mode. The OS switches between these modes personally, so provided it starts off in control of the system, it will always remain in control. - At boot-time, the system starts in privileged mode. - During user execution, it is switched to user mode. - When interrupts occur, the OS takes over and it is switched back to privileged mode. Other names for privileged mode are **monitor mode** or **supervisor mode**. ## 3.1.4 I/O and Memory protection To prevent users from gaining control of devices, by tricking the OS, a mechanism is required to prevent them from writing to an arbitrary address in the memory. For example, if the user could modify the OS program, then it would clearly be possible to gain control of the entire system in privileged mode. All a user would have to do would be to change the addresses in the interrupt vector to point to a routine of their own making. This routine would then be executed when an interrupt was received in privileged mode. The solution to this problem is to let the OS define a segment of memory for each user process and to check, when running in user mode, every address that #################### File: 1%20A%20short%20introduction%20to%20operating%20systems%20%282001%29%20-%20Mark%20Burgess%20%28PDF%29.pdf Page: 29 Context: ``` the user program refers to. If the user attempts to read or write outside this allowed segment, a segmentation fault is generated and control returns to the OS. This checking is normally hard-wired into the hardware of the computer so that it cannot be switched off. No checking is required in privileged mode. //*************************************************************** // Example of a segmentation fault in user mode //*************************************************************** main() // When we start, we are by definition in user mode. { int *ptr; ptr = 0; // An address guaranteed to NOT be in our segment. cout << *ptr; } ## 3.1.5 Time sharing There is always the problem in a multi-tasking system that a user program will go into an infinite loop, so that control never returns to the OS and the whole system stops. We have to make sure that the OS always remains in control by some method. Here are two possibilities: - The operating system fetches each instruction from the user program and executes it personally, never giving it directly to the CPU. The OS software switches between different processes by fetching the instructions it decides to execute. This is a kind of software emulation. This method works, but it is extremely inefficient because the OS and the user program are always running together. The full speed of the CPU is not realized. This method is often used to make simulators and debuggers. - A more common method is to switch off the OS while the user program is executing and switch off the user process while the OS is executing. The switching is achieved by hardware rather than software, as follows. When handing control to a user program, the OS uses a hardware timer to ensure that control will return after a certain time. The OS loads a fixed time interval into the timer's control registers and gives control to the user process. The timer then counts down to zero and when it reaches zero it generates a non-maskable interrupt, whereupon control returns to the OS. ## 3.2 Memory map We can represent a multi-tasking system schematically as in figure 3.1. Clearly the memory map of a computer does not look like this figure. It looks like the following: ``` #################### File: 1%20A%20short%20introduction%20to%20operating%20systems%20%282001%29%20-%20Mark%20Burgess%20%28PDF%29.pdf Page: 30 Context: # Schematic Diagram of a Multitasking System Figures in the previous chapter show that the OS has to simulate behavior using software. The point of this diagram is to illustrate the elements required by each process executing on the system. Each program must have a memory area to work in and a stack to keep track of subroutine calls and local variables. ## Components - **Input/Output** - **Screen Memory** ## Programs | Virtual I/O | Program | Stack | |-------------|---------|-------| | | Program #1 | Stack | | | Program #2 | Stack | | | Program #3 | Stack | Each program must have its own input/output sources. These cannot be the actual resources of the system; instead, each program has a **virtual I/O** stream. The operating system arranges things so that the virtual I/O looks to the user program as though it is just normal I/O. In reality, the OS controls all the I/O itself and arranges the sharing of resources transparently. The virtual output stream for a program might be a **window** on the real screen, for instance. The virtual printer is really a print queue. The keyboard is only ‘connected’ to one task at a time, but the OS can share this too. For example, in a window environment, this happens when a user clicks in a particular window. #################### File: 1%20A%20short%20introduction%20to%20operating%20systems%20%282001%29%20-%20Mark%20Burgess%20%28PDF%29.pdf Page: 31 Context: ## 3.3 Kernel and Shells - Layers of Software So far we have talked about the OS almost as though it were a living thing. In a multitasking, multi-user OS like UNIX, this is not a bad approximation to the truth! In what follows, we make use of UNIX terminology, and all of the examples we shall cover later will refer to versions of the UNIX operating system. The part of the OS which handles all of the details of sharing and device handling is called the **kernel** or **core**. The kernel is not something which can be used directly, although its services can be accessed through system calls. What is needed is a user interface or command line interface (CLI) which allows users to log onto the machine and manipulate files, compile programs, and execute them using simple commands. Since this is a layer of software which wraps the kernel in more acceptable clothes, it is called a **shell** around the kernel. It is only by making layers of software, in a hierarchy, that very complex programs can be written and maintained. The idea of layers and hierarchies returns again and again. ## 3.4 Services: Daemons The UNIX kernel is a very large program, but it does not perform all of the services required in an OS. To keep the size of the kernel to a minimum, it only deals with the sharing of resources. Other jobs for the operating system (which we can call services) are implemented by writing programs which run alongside user programs. Indeed, they are just **user programs**—the only difference is that they are owned by the system. These programs are called **daemons**. Here are some examples from UNIX: - **mountd**: Deals with requests for 'mounting' this machine's disks on other machines, i.e., requests to access the disk on this machine from another machine on the network. - **rlogind**: Handles requests to login from remote terminals. - **keyserv**: A server which stores public and private keys. Part of a network security system. - **syslogd**: Records information about important events in a log file. - **named**: Converts machine names into their network addresses and vice versa. #################### File: 1%20A%20short%20introduction%20to%20operating%20systems%20%282001%29%20-%20Mark%20Burgess%20%28PDF%29.pdf Page: 32 Context: # 3.5 Multiprocessors – Parallelism The idea of constructing computers with more than one CPU has become more popular recently. On a system with several CPUs, it is not just a virtual fact that several tasks can be performed simultaneously – it is a reality. This introduces a number of complications in OS design. For example, how can we stop two independent processors from altering some memory location which they both share simultaneously (so that neither of them can detect the collision)? This is a problem in process synchronization. The solution to this problem is much simpler in a single CPU system since no two things ever happen truly simultaneously. We shall consider this in more detail in later chapters. For now, it is useful to keep in mind that multiprocessors are an important element of modern OS design. ## Exercises 1. Write a program to manage an array of many stacks. 2. Describe the difference between the kernel and daemons in UNIX. What is the point of making this distinction? 3. What is two-mode operation? 4. What is the difference between an emulator or simulator and true multitasking? 5. To prepare for the project suggestion in the next chapter, write a program which reads fictitious commands in from a file. The commands should be of the form: ``` operator operand load 12 add 23 store 1334 jsr 5678 wait 1 fork 0 ``` etc. Read in the commands and print out a log of what the commands are, in the form "Executing (operator) on (operand)". You should be able to recognize the commands 'wait' and 'fork' specially, but the other commands may be anything you like. The aim is to simulate the type of commands a real program has to execute. 31 #################### File: 1%20A%20short%20introduction%20to%20operating%20systems%20%282001%29%20-%20Mark%20Burgess%20%28PDF%29.pdf Page: 33 Context: # Chapter 4 ## Processes and Threads ### 4.1 Key Concepts Multitasking and multi-user systems need to distinguish between the different programs being executed by the system. This is accomplished with the concept of a **process**. #### 4.1.1 Naming Conventions Before talking about process management, we shall introduce some of the names which are in common use. Not all operating systems or books agree on the definitions of these names. In this chapter, we shall take a liberal attitude—after all, it is the ideas rather than the names which count. Try to remember the different terms—they will be used repeatedly. - **Process:** This is a general term for a program which is being executed. All work done by the CPU contributes to the execution of processes. Each process has a descriptive information structure associated with it (normally held by the kernel) called a **process control block**, which keeps track of how the execution has progressed and what resources the process holds. - **Task:** On some systems, processes are called tasks. - **Job:** Some systems distinguish between batch execution and interactive execution. Batch (or queued) processes are often called jobs. They are like production line processes which start, do something, and quit, without stopping to ask for input from a user. They are non-interactive processes. - **Thread:** (Sometimes called a **lightweight process**) is different from process or task in that a thread is not enough to get a whole program executed. A thread is a kind of stripped-down process—it is just one 'active hand' in a program—something which the CPU is doing on behalf of a program. #################### File: 1%20A%20short%20introduction%20to%20operating%20systems%20%282001%29%20-%20Mark%20Burgess%20%28PDF%29.pdf Page: 34 Context: but not enough to be called a complete process. Threads remember what they have done separately, but they share the information about what resources a program is using, and what state the program is in. A thread is only a CPU assignment. Several threads can contribute to a single task. When this happens, the information about one process or task is used by many threads. Each task must have at least one thread in order to do any work. - **CPU burst**: A period of uninterrupted CPU activity. - **I/O burst**: A period of uninterrupted input/output activity. ## 4.1.2 Scheduling On most multitasking systems, only one process can truly be active at a time—the system must therefore share its time between the execution of many processes. This sharing is called scheduling. (Scheduling = time management.) Different methods of scheduling are appropriate for different kinds of execution. A queue is one form of scheduling in which each program waits its turn and is executed serially. This is not very useful for handling multitasking, but it is necessary for scheduling devices which cannot be shared by nature. An example of the latter is the printer. Each print job has to be completed before the next one can begin; otherwise, all the print jobs would be mixed up and interleaved resulting in nonsense. We shall make a broad distinction between two types of scheduling: - **Queueing**. This is appropriate for serial or batch jobs like print spooling and requests from a server. There are two main ways of giving priority to the jobs in a queue. One is a first-come first-served (FCFS) basis, also referred to as first-in first-out (FIFO); the other is to process the shortest job first (SJF). - **Round-robin**. This is the time-sharing approach in which several tasks can coexist. The scheduler gives a short time-slice to each job before moving on to the next job, polling each task round and round. This way, all the tasks advance, little by little, on a controlled basis. These two categories are also referred to as non-preemptive and preemptive respectively, but there is a grey area. - **Strictly non-preemptive**. Each program continues executing until it has finished, or until it must wait for an event (e.g., I/O or another task). This is like Windows 95 and Macintosh system 7. - **Strictly preemptive**. The system decides how time is to be shared between the tasks and interrupts each process after its time-slice whether. #################### File: 1%20A%20short%20introduction%20to%20operating%20systems%20%282001%29%20-%20Mark%20Burgess%20%28PDF%29.pdf Page: 35 Context: # Scheduling Basics To choose an algorithm for scheduling tasks, we must understand what we are trying to achieve. What are the criteria for scheduling? - **Efficiency:** We want to maximize the efficiency of the machine. We would like all the resources of the machine to be doing useful work all of the time—i.e., not be idling during one process when another process could be using them. The key to organizing the resources is to get the CPU time-sharing right, as this is the central "organ" in any computer, through which almost everything must happen. However, this cannot be achieved without also considering how the I/O devices must be shared, since the I/O devices communicate by interrupting the CPU from what it is doing. (Most workstations spend most of their time idling. There are enormous amounts of untapped CPU power going to waste all over the world each day.) - **Job Completion:** We would like as many jobs to get finished as quickly as possible. - **User Interaction:** Interactive users get irritated if the machine's performance seems slow. We would like the machine to appear fast for interactive users or have a fast response time. Some of these criteria cannot be met simultaneously, and we must make compromises. In particular, what is good for batch jobs is often not good for interactive processes and vice versa, as we remark under *Run Levels - Priority* below. ## 4.1.3 Scheduling Hierarchy Complex scheduling algorithms distinguish between short-term and long-term scheduling. This helps to deal with tasks which fall into two kinds: those which are active continuously and must therefore be serviced regularly, and those which sleep for long periods. For example, in UNIX, the long-term scheduler moves processes which have been sleeping for more than a certain time out of memory and onto disk, to make space for those which are active. Sleeping jobs are moved back into memory only when they wake up (for whatever reason). This is called swapping. #################### File: 1%20A%20short%20introduction%20to%20operating%20systems%20%282001%29%20-%20Mark%20Burgess%20%28PDF%29.pdf Page: 36 Context: The most complex systems have several levels of scheduling and exercise different scheduling policies for processes with different priorities. Jobs can even move from level to level if the circumstances change. ``` HIGH - System processes - Interactive user processes - Batch scheduling - Mostly sleeping processes LOW ``` Figure 4.1: Multi-level scheduling. ## 4.1.4 Runs levels - priority Rather than giving all programs equal shares of CPU time, most systems have priorities. Processes with higher priorities are either serviced more often than processes with lower priorities, or they get longer time-slices of the CPU. Priorities are not normally fixed but vary according to the performance of the system and the amount of CPU time a process has already used up in the recent past. For example, processes which have used a lot of CPU time in the recent past often have their priority reduced. This tends to favor iterative processes which wait often for I/O and makes the response time of the system seem faster for interactive users. In addition, processes may be reduced in priority if their total accumulated CPU usage becomes very large. (This occurs, for example in UNIX.) The wisdom of this approach is arguable, since programs which take a long time to complete tend to be penalized. Indeed, they take much longer to complete because their priority is reduced. If the priority continued to be lowered, long jobs would never get finished. This is called process starvation and must be avoided. Scheduling algorithms have to work without knowing how long processes will run. #################### File: 1%20A%20short%20introduction%20to%20operating%20systems%20%282001%29%20-%20Mark%20Burgess%20%28PDF%29.pdf Page: 37 Context: # 4.1.5 Context Switching Switching from one running process to another running process incurs a cost to the system. The values of all the registers must be saved in the present state, the status of all open files must be recorded, and the present position in the program must be recorded. Then the contents of the MMU must be stored for the process (see next chapter). All those things must be read in for the next process, so that the state of the system is exactly as it was when the scheduler last interrupted the process. This is called a **context switch**. Context switching is a system overhead. It costs real time and CPU cycles, so we don’t want to context switch too often, or a lot of time will be wasted. The state of each process is saved to a data structure in the kernel called a **process control block (PCB)**. Here is an example PCB from Mach OS: ```c typedef struct machpcb { char mpcb_frame[REG064]; /* user’s saved registers */ struct regs mpcb_regs; /* user window save area */ struct window mpcb_vwbuf[MAxWIN]; /* sp’s for each subroutine */ char mpcb_spbuf[MAXWIN]; /* sp’s for each sub */ int mpbc_vcnt; /* number of saved windows in pcb_vwbuf */ struct vfp *mpcb_fpu; /* fpu state */ struct fq mpcb_fpu_q[MAXFPU]; /* fpu exception queue */ int mpcb_flags; /* various state flags */ int mpcb_vwcnt; /* window overflow count */ int mpcb_uccnt; /* window underflow count */ kthread_t mpcb_thread; /* associated thread */ } machpcb_t; ``` Below is a kernel process structure for a UNIX system: ```c struct proc { struct proc *p_link; /* linked list of running processes */ struct proc *p_qlink; /* linked list of scheduled processes */ struct proc *p_uptr; /* user’s process structure */ char *p_y; /* size index, for user’s proc */ }; ``` #################### File: 1%20A%20short%20introduction%20to%20operating%20systems%20%282001%29%20-%20Mark%20Burgess%20%28PDF%29.pdf Page: 38 Context: ```markdown struct u_area { /* user area description */ char u_comm[8]; /* name of the user process */ int u_uid; /* user id of the process */ int u_gid; /* group id of the process */ char u_rport; /* (DEBUG) entry to entry for something */ int u_procp; /* pointer to the process structure */ int u_pgid; /* process group id */ int u_pgrp; /* current process group id */ char *u_textp; /* pointer to the current text */ int u_ttyp; /* terminal being used by user */ int u_ttyi; /* state of tty input */ int u_ttyo; /* state of tty output */ int u_ttyd; /* (effective) device id in use */ int u_sig; /* signal pending */ int u_sigmask; /* signals not delivered */ int u_sigcatch; /* signals user wants to catch */ int u_error; /* last error code */ int u_acflag; /* accounting flags */ struct proc *u_procp; /* pointer to process structure */ struct proc *u_cursig; /* pointer to current signal */ struct proc *u_psig; /* pointer to process siblings */ struct proc *u_zsig; /* signal the process is to be killed */ char *u_argv; /* pointer to user’s argv block */ char *u_envp; /* pointer to user’s envp block */ short u_bsize; /* size of buffer being used */ int u_pcb; /* processor control block */ int u_pjid; /* process id of job controlling */ int u_jpid; /* process id */ }; /* -------------------------------- */ /* UNIX also uses a 'user' structure to keep auxiliary information which is only needed when jobs are not 'swapped out' (see next chapter). */ ### 4.1.6 Interprocess Communication One of the benefits of multitasking is that several processes can be made to cooperate in order to achieve their ends. To do this, they must do one of the following. - **Communicate.** Interprocess communication (IPC) involves sending information from one process to another. This can be achieved using a 'mailbox' system, a socket (Berkeley) which behaves like a virtual communications network (loopback), or through the use of 'pipes'. Pipes are a system construction which enables one process to open another process as if it were a file for writing or reading. ``` #################### File: 1%20A%20short%20introduction%20to%20operating%20systems%20%282001%29%20-%20Mark%20Burgess%20%28PDF%29.pdf Page: 39 Context: # 4.2 Creation and scheduling ## 4.2.1 Creating processes The creation of a process requires the following steps. The order in which they are carried out is not necessarily the same in all cases. 1. **Name.** The name of the program which is to run as the new process must be known. 2. **Process ID and Process Control Block.** The system creates a new process control block or locates an unused block in an array. This block is used to follow the execution of the program through its course, keeping track of its resources and priority. Each process control block is labelled by its PID or process identifier. 3. **Locate the program** to be executed on disk and allocate memory for the code segment in RAM. 4. **Load the program** into the code segment and initialize the registers of the PCB with the start address of the program and appropriate starting values for resources. 5. **Priority.** A priority must be computed for the process, using a default for the type of process and any value which the user specified as a 'nice' value (see Run levels – priorities above). 6. **Schedule the process for execution.** - **Share data.** A segment of memory must be available to both processes. (Most memory is locked to a single process). - **Waiting.** Some processes wait for other processes to give a signal before continuing. This is an issue of synchronization. As soon as we open the door to co-operation there is a problem of how to synchronize cooperating processes. For example, suppose two processes modify the same file. If both processes tried to write simultaneously the result would be a nonsensical mixture. We must have a way of synchronizing processes, so that even concurrent processes must stand in line to access shared data serially. Synchronization is a tricky problem in multiprocessor systems, but it can be achieved with the help of critical sections and semaphores/locks. We shall return to these below. #################### File: 1%20A%20short%20introduction%20to%20operating%20systems%20%282001%29%20-%20Mark%20Burgess%20%28PDF%29.pdf Page: 40 Context: # 4.2.2 Process hierarchy: children and parent processes In a democratic system, anyone can choose to start a new process, but it is never users which create processes but other processes! That is because anyone using the system must already be running a shell or command interpreter in order to be able to talk to the system, and the command interpreter is itself a process. When a user creates a process using the command interpreter, the new process becomes a child of the command interpreter. Similarly, the command interpreter process becomes the parent for the child. Processes therefore form a hierarchy. ```plaintext Level 0 Root Node / | \ Level 1 Child #1 Child #2 Child #3 \ Level 2 ``` *Figure 4.2: Process hierarchies* The processes are linked by a tree structure. If a parent is signalled or killed, usually all its children receive the same signal or are destroyed with the parent. This doesn't have to be the case—it is possible to detach children from their parents—but in many cases it is useful for processes to be linked in this way. When a child is created, it may do one of two things: - Duplicate the parent process. - Load a completely new program. Similarly, the parent may do one of two things: - Continue executing alongside its children. - Wait for some or all of its children to finish before proceeding. ## 4.2.3 Unix: `fork()` and `wait()` As an example of process creation, we shall consider UNIX. The following example program is written in C++ and makes use of the standard library function `fork()`. The syntax of `fork()` is: ```cpp returncode = fork(); ``` 39 #################### File: 1%20A%20short%20introduction%20to%20operating%20systems%20%282001%29%20-%20Mark%20Burgess%20%28PDF%29.pdf Page: 43 Context: ``` ### 4.2.5 Queue Scheduling The basis of all scheduling is the queue structure. A round-robin scheduler uses a queue but moves cyclically through the queue at its own speed, instead of waiting for each task in the queue to complete. Queue scheduling is primarily used for serial execution. There are two main types of queue: - **First-come first-server (FCFS)**, also called first-in first-out (FIFO). - **Sorted queue**, in which the elements are regularly ordered according to some rule. The most prevalent example of this is the shortest job first (SJF) rule. #### Process State Diagram ``` From state | Event | To state -----------|-------------------------------|----------- New | Accepted | Ready Ready | Scheduled / Dispatch | Running Running | Need I/O | Waiting Running | Scheduler timeout | Ready Running | Completion / Error / Killed | Terminated Waiting | I/O completed or wakeup event | Ready ``` Figure 4.3: Process state diagram. 42 ``` #################### File: 1%20A%20short%20introduction%20to%20operating%20systems%20%282001%29%20-%20Mark%20Burgess%20%28PDF%29.pdf Page: 47 Context: # Kitchen Threads **Figure 4.4:** System and user-level threads: suppose we think of a household kitchen as being a process; then each electrical appliance which contributes to the work of the kitchen is like a thread. In order to work, a thread needs power. The power sockets are like kernel threads or CPUs. A job like making a cake or tidying up might involve several threads (powered machinery), which might run in parallel or one after the other. Since there are more appliances than power points, we have to schedule the time each appliance gets power so as to share between all of them. Threads need to communicate. When one part of the program needs to send data to the other part, two independent pieces must be synchronized, or be made to wait for one another. But what is the point of this? We can always run independent procedures in a program as separate programs, using the process mechanisms we have already introduced. They could communicate using normal interprocess communication. ### Why Introduce Another New Concept? Why do we need threads? The point is that threads are cheaper than normal processes, and that they can be scheduled for execution in a user-dependent way, with less overhead. Threads are cheaper than a whole process because they do not have a full set of resources each. Whenever the process control block for a heavyweight process is large and costly to context switch, the PCBs for threads are much smaller, since each thread has only a stack and some registers to manage. It has no open file lists or resource lists, no accounting structures to update. All of these resources are shared by all threads within the process. Threads can be assigned priorities—a higher priority thread will get put to the front of the queue. #################### File: 1%20A%20short%20introduction%20to%20operating%20systems%20%282001%29%20-%20Mark%20Burgess%20%28PDF%29.pdf Page: 48 Context: In other words, threads are processes within processes! Threads can only run inside a normal process. Let's define heavy and lightweight processes with the help of a table. | Object | Resources | |-----------------------|-----------------------------------------------------| | Thread (LWP) | Stack + set of CPU registers + CPU time. | | Task (HWP) | 1 thread + process control block, | | | program code, memory segment, etc. | | Multithreaded task | n-threads + process control block, | | | program code, memory segment, etc. | ### 4.3.2 Why use threads? From our discussion of scheduling, we can see that the sharing of resources could have been made more effective if the scheduler had known exactly what each program was going to do in advance. Of course, the scheduling algorithm can never know this—but the programmer who wrote the program does know. Using threads, it is possible to organize the execution of a program in such a way that something is always being done, even when the scheduler gives the heavyweight process CPU time. - Threads allow a programmer to switch between lightweight processes when it is best for the program. (The programmer has control.) - A process which uses threads does not get more CPU time than an ordinary process—but the CPU time it gets is used to do work on the threads. It is possible to write a more efficient program by making use of threads. - Inside a heavyweight process, threads are scheduled on a FCFS basis, unless the program decides to force certain threads to wait for other threads. If there is only one CPU, then only one thread can be running at a time. - Threads context switch without needing to involve the kernel—the switching is performed by a user-level library, so time is saved because the kernel doesn't need to know about the threads. ### 4.3.3 Levels of threads In modern operating systems, there are two levels at which threads operate: system or kernel threads and user-level threads. If the kernel itself is multithreaded, the scheduler assigns CPU time on a thread basis rather than on a #################### File: 1%20A%20short%20introduction%20to%20operating%20systems%20%282001%29%20-%20Mark%20Burgess%20%28PDF%29.pdf Page: 52 Context: ```markdown /*****************************************************************************************/ #include #include #include #include using namespace std; const int maxfiles = 10; const int buffersize = 256; int LINECOUNT = 0; void *ParseFile(char *filename); int main() { pthread_t tid[maxfiles]; int i, ret; // Create a thread for each file ret = pthread_create(&tid[0], NULL, ParseFile, "file1.txt"); ret = pthread_create(&tid[1], NULL, ParseFile, "file2.txt"); ret = pthread_create(&tid[2], NULL, ParseFile, "file3.txt"); ret = pthread_create(&tid[3], NULL, ParseFile, "file4.txt"); cout << "Parent thread waiting...\n"; // We don’t wait for the threads, they will be killed // before they can start... for (i = 0; i < maxfiles; i++) { ret = pthread_join(tid[i], (void**)NULL); } cout << "Parent thread continuing\n"; cout << "Number of lines = " << LINECOUNT << endl; } /*****************************************************************************************/ void *ParseFile(char *filename) { ifstream file; char buffer[buffersize]; int ret; cout << "Trying to open " << filename << endl; file.open(filename); if (!file) { cerr << "Couldn't open file" << endl; return NULL; } while (file) { file.getline(buffer, buffersize); cout << filename << ": " << buffer << endl; // Critical section LINECOUNT++; } // Try uncommenting this .... // Yield the process to allow next thread to be run return NULL; } ``` #################### File: 1%20A%20short%20introduction%20to%20operating%20systems%20%282001%29%20-%20Mark%20Burgess%20%28PDF%29.pdf Page: 53 Context: In this version of the program, a separate thread is spawned for each file. First, we call the function `pthread_create()` for each file we encounter. A new thread is spawned with a pointer to the function the thread should execute (in this case the same function for all threads), called `ParseFile()`, which reads lines from the respective files and increments the global variable `LINECOUNT`. Several things are important here. The main program is itself a thread. It is essential that we tell the main program to wait for the additional threads to `join` the main program before exiting, otherwise the main program will exit and kill all of the child threads immediately. Thread join-semantics are like wait-semantics for normal processes. Each of the threads updates the same global variable. Suppose now that two threads are running on different CPUs. It is possible that both threads would try to alter the value of the variable `LINECOUNT` simultaneously. This is called a race condition and can lead to unpredictable results. For this reason, we use a mutex to lock the variable while it is being updated. We shall discuss this more in the next section. A final point to note is the commented-out lines in the `ParseFile()` function. The call `sched_yield()` tells a running thread to give itself up to the scheduler, so that the next thread to be scheduled can run instead. This function can be used to switch between several threads. By calling this function after each line is read from the files, we can spread the CPU time evenly between each thread. Actually, it is difficult to predict precisely which threads will be scheduled and when, because the threads in our program here are only a small number compared to the total number of threads waiting to be scheduled by the system. The interaction with disk I/O can also have a complicated effect on the scheduling. On a single CPU system, threads are usually scheduled using PCFS in a queue. If we yield after every instruction, it has the effect of simulating round-robin scheduling. ### 4.3.6 Example: LWPs in Solaris 1 Early Solaris systems had user-level threads only, which were called light weight processes. Since the kernel was single threaded, only one user-level thread could run at any given time. To create a threaded process in Solaris 1, one simply has to execute a LWP system call. The "lightweight processes library" then converts the normal process into a process descriptor plus a thread. Here is the simplest example: --- 52 #################### File: 1%20A%20short%20introduction%20to%20operating%20systems%20%282001%29%20-%20Mark%20Burgess%20%28PDF%29.pdf Page: 56 Context: # Process Synchronization is read in line by line. During the execution of the script, the user adds four lines to the beginning of the file and saves the file. Suddenly, when the next line of the executing script gets read, the pointer to the next line points to the wrong location and it reads in the same line it already read in four lines ago! Everything in the program is suddenly shifted by four lines, without the process executing the script knowing about it. This example (which can actually happen in the UNIX shell) may or may not turn out to be serious - clearly, in general, it can be quite catastrophic. It is a problem of synchronization on the part of the user and the filesystem[^1]. We must consider programs which share data. 1. **When do we need to prevent programs from accessing data simultaneously?** If there are 100 processes which want to read from a file, this will cause no problems because the data themselves are not changed by a read operation. A problem only arises if more than one of the parties wants to modify the data. 2. **Is it even sensible for two programs to want to modify data simultaneously?** Or is it simply a stupid thing to do? We must be clear about whether such collisions can be avoided, or whether they are a necessary part of a program. For instance, if two independent processes want to add entries to a database, this is a reasonable thing to do. If two unrelated processes want to write a log of their activities to the same file, it is probably not sensible; a better solution would be to use two separate files. 3. **How should we handle a collision between processes?** Should we signal an error, or try to make the processes wait in turn? There is no universal answer to this question - in some cases it might be logically incorrect for two processes to change data at the same time: if two processes try to change one numerical value then one of them has to win - which one? On the other hand, if two processes try to add something to a list, that makes sense, but we have to be sure that they do not write their data on top of each other. The writing must happen serially, not in parallel. ## 4.4.2 Serialization The key idea in process synchronization is serialization. This means that we have to go to some pains to undo the work we have put into making an operating system perform several tasks in parallel. As we mentioned, in the case of print queues, parallelism is not always appropriate. Synchronization is a large and difficult topic, so we shall only undertake to describe the problem and some of the principles involved here. [^1]: Experts might say that this has purely to do with filesystem semantics (see chapter 5) but given the filesystem, this becomes a synchronization problem. #################### File: 1%20A%20short%20introduction%20to%20operating%20systems%20%282001%29%20-%20Mark%20Burgess%20%28PDF%29.pdf Page: 60 Context: # 4.4.7 Flags and Semaphores Flags are similar in concept to locks. The idea is that two cooperating processes can synchronize their execution by sending very simple messages to each other. A typical behavior is that one process decides to stop and wait until another process signals that it has arrived at a certain place. ## Mutex Implementation The modern way of implementing a critical section is to use mutexes as we have described above. In 1981, G.L. Peterson discovered a simple algorithm for achieving mutual exclusion between two processes with PID equal to 0 or 1. The code goes like this: ```c int turn; int interested[2]; void Get_Mutex(int pid) { int other; other = 1 - pid; interested[pid] = true; turn = pid; while (turn == pid && interested[other]) { // Loop until no one // else is interested } } void Release_Mutex(int pid) { interested[pid] = false; } ``` Where more processes are involved, some modifications are necessary to this algorithm. The key to serialization here is that, if a second process tries to obtain the mutex when another already has it, it will get caught in a loop, which does not terminate until the other process has released the mutex. This solution is said to involve busy waiting—i.e., the program actively executes an empty loop, wasting CPU cycles, rather than moving the process out of the scheduling queue. This is also called a spin lock since the system "spins" on the loop while waiting. #################### File: 1%20A%20short%20introduction%20to%20operating%20systems%20%282001%29%20-%20Mark%20Burgess%20%28PDF%29.pdf Page: 61 Context: For example, suppose we want to ensure that `procedure1()` in process 1 gets executed before `procedure2()` in process 2. ```plaintext // Process 1 // Process 2 procedure1(); | wait(mysignal); signal(mysignal); | procedure2(); ... | ... ``` These operations are a special case of **interprocess communication**. A semaphore is a flag which can have a more general value than just true or false. A semaphore is an integer counting variable and is used to solve problems where there is competition between processes. The idea is that one part of a program tends to increment the semaphore while another part tends to decrement the semaphore. The value of the flag variable dictates whether a program will wait or continue, or whether something special will occur. There are many uses for semaphores and we shall not go into them here. A simple example is reading and writing via buffers, where we count how many items are in the buffer. When the buffer becomes full, the process which is filling it must be made to wait until space in the buffer is made available. ### 4.4.8 Monitors Some languages (like Modula) have special language class-environments for dealing with mutual exclusion. Such an environment is called a monitor. - A monitor is a language device which removes some of the pain from synchronization. Only one process can be ‘inside’ a monitor at a time – users don’t need to code this themselves, they only have to create a monitor. - A procedure or function defined under the umbrella of a monitor can only access those shared memory locations declared within that monitor and vice-versa. - Wait and signal operations can be defined to wait for specific condition variables. A process can thus wait until another process sends a signal or semaphore which changes the condition variable. #################### File: 1%20A%20short%20introduction%20to%20operating%20systems%20%282001%29%20-%20Mark%20Burgess%20%28PDF%29.pdf Page: 62 Context: # 4.5 Deadlock Waiting and synchronization is not all sweetness and roses. Consider the European road rule which says: on minor roads, one should always wait for traffic coming from the right. If four cars arrive simultaneously at a crossroads (see figure), then, according to the rule, all of them must wait for each other, and none of them can ever move. This situation is called **deadlock**. It is the **stale-mate** of the operating system world. ![Figure 4.5: Deadlock in the European suburbs.](#) ## 4.5.1 Cause Deadlock occurs when a number of processes are waiting for an event which can only be caused by another of the waiting processes. These are the essential requirements for a deadlock: 1. **Circular waiting.** There must be a set of processes \(P_1, P_2, \ldots, P_n\) where \(P_1\) is waiting for a resource or signal from \(P_2\), \(P_2\) is waiting for \(P_3\), and \(P_n\) is waiting for \(P_1\). 2. **Non-sharable resources.** It is not possible to share the resources or signals which are being waited for. If the resource can be shared, there is no reason to wait. 3. **No preemption.** The processes cannot be forced to give up the resources they are holding. There are likewise three methods for handling deadlock situations: #################### File: 1%20A%20short%20introduction%20to%20operating%20systems%20%282001%29%20-%20Mark%20Burgess%20%28PDF%29.pdf Page: 63 Context: # Deadlock Management 1. **Prevention.** We can try to design a protocol which ensures that deadlock never occurs. 2. **Recovery.** We can allow the system to enter a deadlock state and then recover. 3. **Ostrich method.** We can pretend that deadlocks will never occur and live happily in our ignorance. This is the method used by most operating systems. User programs are expected to behave properly. The system does not interfere. This is understandable: it is very hard to make general rules for every situation which might arise. ## 4.5.2 Prevention Deadlock prevention requires a system overhead. The simplest possibility for avoidance of deadlock is to introduce an extra layer of software for requesting resources in addition to a certain amount of accounting. Each time a new request is made, the system analyzes the allocation of resources before granting or refusing the resource. The same applies for wait conditions. The problem with this approach is that, if a process is not permitted to wait for another process—what should it do instead? At best, the system would have to reject or terminate programs which could enter deadlock, returning an error condition. Another method is the following: One might demand that all programs declare what resources they will need in advance. Similarly, all wait conditions should be declared. The system could then analyze (and re-analyze each time a new process arrives) the resource allocation and pinpoint possible problems. ## 4.5.3 Detection The detection of deadlock conditions is also a system overhead. At regular intervals, the system is required to examine the state of all processes and determine the interrelations between them. Since this is quite a performance burden, it is not surprising that most systems ignore deadlocks and expect users to write careful programs. ## 4.5.4 Recovery To recover from a deadlock, the system must either terminate one of the participants, and go on terminating them until the deadlock is cured, or reprocess the resources which are causing the deadlock from some processes until the deadlock is cured. The latter method is somewhat dangerous since it can lead to incorrect program execution. Processes usually wait for a good reason, and any #################### File: 1%20A%20short%20introduction%20to%20operating%20systems%20%282001%29%20-%20Mark%20Burgess%20%28PDF%29.pdf Page: 64 Context: # 4.6 Summary In this chapter, we have considered the creation and scheduling of processes. Each process may be described by: - A process identifier. - A process control block which contains status information about the scheduled processes. - A private stack for that process. The scheduling of processes takes place by a variety of methods. The aim is to maximize the use of CPU time and spread the load for the devices. Processes can be synchronized using semaphores or flags. Protocol constructions such as critical sections and monitors guarantee that shared data are not modified by more than one process at a time. If a process has to wait for a condition which can never arise until it has finished waiting, then a **deadlock** is said to arise. The cause of deadlock waiting is often a resource which cannot be shared. Most operating systems do not try to prevent deadlocks, but leave the problem to user programs. ## Exercises 1. Explain the difference between a lightweight process and a normal process. 2. What is meant by the critical section of a program? 3. What is meant by deadlock? 4. Explain why round-robin scheduling would not be appropriate for managing a print queue. 5. Devise a combination of first-come-first-serve (FCFS) and shortest-job-first (SJF) scheduling which would be the 'fairest' solution to scheduling a print queue. ## Project You can learn a lot by solving the following problem. The idea is to make a time-sharing system of your own. #################### File: 1%20A%20short%20introduction%20to%20operating%20systems%20%282001%29%20-%20Mark%20Burgess%20%28PDF%29.pdf Page: 65 Context: (a) Make a fake kernel simulator, which, instead of executing processes in memory, reads instructions from a number of files. You should aim to share the time spent reading each `process` equally between all tasks. The output of your kernel should show clearly what is being executed and when. You should give each process a process identifier (pid). The `command language` you are reading in contains instructions like `abed 3`, `wait 4`, etc., i.e., four letters followed by a number. (b) Add process priorities to each task. You can decide how these are assigned yourself. Keep a record of how long each process takes to complete and print status information when each process finishes. You can either call the real system clock to do this, or increment a counter each time an instruction is read. This is like counting `fake CPU cycles`. (c) The input files contain `wait ` instructions. Modify your program so that when one of the tasks reads an instruction `wait 5`, for instance, it waits for process number 5 to finish before it continues. The output of the kernel should show this clearly. Hint: use a status variable which indicates whether the process is `ready` or `waiting`. (d) Copy and modify the input files so that a deadlock can occur. Explain carefully how it occurs. For example, make two processes wait for each other. Add to your kernel a simple test to detect such deadlock situations. Decide for yourself how you wish to handle this situation. Explain what you have chosen to do in your solution. (e) Some of the input files contain `fork` instructions. Modify your code so that when such an instruction is detected, the current process spawns a new copy of itself which begins executing from the instruction after the fork command. The new process should have a different pid and should have the same priority as the old one. Try to make your program as structured as possible. The aim is to write the clearest program, rather than the most efficient one. When presenting your results, give a listing of the output of each part and explain the main features briefly. #################### File: 1%20A%20short%20introduction%20to%20operating%20systems%20%282001%29%20-%20Mark%20Burgess%20%28PDF%29.pdf Page: 66 Context: # Chapter 5 ## Memory and Storage Together with the CPU, the physical memory (RAM) is the most important resource a computer has. The CPU chip has instructions to manipulate data only directly in memory, so all arithmetic and logic operations must take place in RAM. ### 5.1 Logical and Physical Memory #### 5.1.1 Physical Address Space Every byte in the memory has an address which ranges from zero up to a limit which is determined by the hardware (see below). Although bytes are numbered from zero upward, not every address is necessarily wired up to a memory chip. Some addresses may be reserved for: - **Memory mapped I/O** – individual registers belonging to other chips and hardware devices. - **The interrupt vector** – the CPU itself requires some workspace. Usually the interrupt vector and sometimes the processor stack occupy fixed locations. - **The operating system itself** – this takes up a fair chunk of memory. On most microcomputers, this is located in ROM. On multiuser systems upgrades are much more frequent and it is always loaded from disk into RAM. The physical address space consists of every possible address to which memory chips are connected. #### 5.1.2 Word Size A word is a small unit of memory, normally just a few bytes. The size of a word on any system is defined by the size of the registers in the CPU. #################### File: 1%20A%20short%20introduction%20to%20operating%20systems%20%282001%29%20-%20Mark%20Burgess%20%28PDF%29.pdf Page: 67 Context: # 5.1.3 Paged RAM/ROM The size of the physical address space is limited by the size of the address registers in the CPU. On early machines, this memory was soon exceeded and it was necessary to resort to tricks to add more memory. Since it was not possible to address any more than the limit, these machines temporarily switched out one bank of memory with another. The new memory bank used the same addresses as the old, but only one could be accessed at a time. This operation is called **paging**. A special hardware paging chip was used to switch between banks, containing a register which could choose between N banks of memory. Paging has obvious disadvantages— not all memory can be used at once and the method is seldom used nowadays since modern CPUs can address much larger memory spaces. As we shall see later, multi-user systems use paging to disk. Instead of switching between hardware banks of memory, they copy the old contents to disk and reuse the memory which is already there for something else. # 5.1.4 Address Binding – Coexistence in Memory When a high-level language program is compiled, it gets converted into machine code. In machine code there are no procedure names, or variable names. All references to data or program code are made by specifying the address at which they are to be found. This immediately begs the question: how do we know what the addresses will be? How do we know where the program is going to be located in memory? On microcomputers, this is very straightforward. A program is compiled to run starting from some fixed address. The system defines a certain range of addresses which can be used by user programs (See Figure 2.1). Whenever the program is loaded from disk, it is loaded into memory at the same address. #################### File: 1%20A%20short%20introduction%20to%20operating%20systems%20%282001%29%20-%20Mark%20Burgess%20%28PDF%29.pdf Page: 68 Context: so that all of the addresses referred to in the program are correct every time. A problem arises if the system supports several programs resident in memory simultaneously. Then it is possible that the addresses coded into one program will already be in use by another. In that case, there are three possible options: 1. **Demand** that programs which can coexist be compiled to run at different addresses. *(This means that every program which is to be able to coexist must know about every other!)* 2. **Relative addressing.** Machine code uses addresses relative to the start address at which the program was loaded. The CPU must then add the start address to every relative address to get the true address. This incurs a performance penalty. Also, on some microprocessors (e.g., Intel 6502), the relative addressing instructions available are limited to fairly small relative ranges, due to the size of the CPU registers. 3. **Use address binding.** Here the idea is that “dummy” addresses are used when code is generated. When a program is loaded in, the true addresses are computed relative to the start of the program and replaced before execution begins. This requires a special program called a *loader*. Needless to say, it is the last of these methods which is used in modern systems. It introduces an important distinction between *logical* and *physical* addresses. A user program writes only to logical addresses, not knowing where the program will end up in the physical address space. The addresses are converted to physical addresses automatically. Again there is a choice. **When should this conversion take place?** 1. When the program is loaded into memory, once and for all? 2. While the program is being executed? Initially it would seem that 1. is the better alternative, since 2 incurs a runtime overhead. In fact 2. is the more flexible option for reasons which will become more apparent when we consider paging to disk. By performing the distinction at runtime, we have the freedom to completely reorganize the use of physical memory dynamically at any time. This freedom is very important in a multitasking operating system where memory has to be shared continually. ### 5.1.5 Shared Libraries The concept of shared libraries lies somewhere in the grey zone between compiling and linking of programs and memory binding. We introduce it here for want of a better place. The advantages of shared libraries should be clearly apparent by the end of this section. On Windows systems, shared libraries are called dynamically loaded libraries or DLLs. #################### File: 1%20A%20short%20introduction%20to%20operating%20systems%20%282001%29%20-%20Mark%20Burgess%20%28PDF%29.pdf Page: 69 Context: # Figure 5.1 If a program hard codes addresses, there will be collisions when we try to load a second program into memory. It is therefore important to have a way of allocating addresses dynamically. On older systems, when you compile a program, the **linker** attaches a copy of standard libraries to each program. Because of the nature of the linker, the whole library has to be copied even though perhaps only one function is required. Thus a simple program to print “hello” could be hundreds or thousands of kilobytes long! This wastes considerable amounts of disk space, copying the same code for every program. When the program is loaded into memory, the whole library is loaded too, so it is also a waste of RAM. The solution is to use a **run-time linker**, which only loads the shared library into RAM when one of the functions the library is needed. The advantages and disadvantages of this scheme are the following: 1. Considerable savings in disk space are made, because the standard library code is never joined to the executable file which is stored on disk, thus there’s only one copy of the shared library on the system. 2. A saving of RAM can also be made since the library, once loaded into RAM can often be shared by several programs. See under **segmentation** below. 68 #################### File: 1%20A%20short%20introduction%20to%20operating%20systems%20%282001%29%20-%20Mark%20Burgess%20%28PDF%29.pdf Page: 70 Context: 3. A performance penalty is transferred from load-time to run-time the first time a function is accessed: the library must be loaded from disk during the execution of the program. In the long run, this might be outweighed by the time it would otherwise have taken to load the library for `n` programs, which now can share it. Also, the amount of RAM needed to support `n` programs is now considerably less. ``` | | Static Link | Dynamic Link | |--------------|-------------|--------------| | | | Dynamic Link | | | | ShareLib | ``` **Figure 5.2:** Statically linked files append the entire library to each compiled program. With shared libraries, we can save disk and memory by linking a program dynamically with a single copy of the library. ### 5.1.6 Runtime Binding Keeping physical and logical addresses completely separate introduces a new level of abstraction to the memory concept. User programs know only about logical addresses. Logical addresses are mapped into real physical addresses, at some location which is completely transparent to the user, by means of a conversion table. The conversion can be assisted by hardware processors which are specially designed to deal with address mapping. This is much faster than a purely software solution (since the CPU itself must do the conversion work). The conversion is, at any rate, performed by the system and the user need know nothing about it. The part of the system which performs the conversion (be it hardware or software) is called the **memory management unit (MMU)**. The conversion table of addresses is kept for each process in its process control block (PCB) and #################### File: 1%20A%20short%20introduction%20to%20operating%20systems%20%282001%29%20-%20Mark%20Burgess%20%28PDF%29.pdf Page: 71 Context: # Memory Management Logical addresses must be downloaded into the MMU during context switching (this is one reason why context switching is expensive!). Each logical address sent to the MMU is checked in the following way: 1. **Does the logical address belong to the process?** If not, generate an ownership error (often called a segmentation fault, as we shall see below). 2. **Translate the logical address into a physical address.** The ownership checking is performed at the logical level rather than the physical level because we want to be able to use the physical memory in the most general possible way. If we bind physical addresses to a special user, it means that we cannot later reorganize the physical memory, and part of the point of the exercise is lost. On the other hand, if users are only bound to logical addresses, we can fiddle as much as we like with the physical memory, and the user will never know. One more question must be added to the above: - **Are the data we want to access actually in the physical memory?** As we shall see later in this chapter, many systems (the most immediate example of which is UNIX) allow paging to disk. We shall return to this in the next section. ## Conversion of Logical Addresses into Physical Addresses The conversion of logical addresses into physical addresses is familiar in many programming languages and is achieved by the use of pointers. Instead of referring to data directly, one uses a pointer variable which holds the true address at which the data are kept. In machine language, the same scheme is called **“indirect addressing.”** The difference between logical addresses and pointers is that all pointers are user objects, and thus pointers only point from one place in logical memory to another place in logical memory. The mapping from logical to physical is only visible to the designer of the system. ## Translation in Practice How is the translation performed in practice? To make the translation of logical to physical addresses practical, it is necessary to coarse grain the memory. If every single byte address were independently converted, then two 32-bit addresses would be required for each byte address in the table, and the storage space for the conversion table would be seven times bigger than the memory of the system! To get around this problem, we have to break up the memory into chunks of a certain size. Then we only need to map the start address of each block, which is much cheaper if the blocks are big enough. There are two schemes for coarse graining the memory in this way: #################### File: 1%20A%20short%20introduction%20to%20operating%20systems%20%282001%29%20-%20Mark%20Burgess%20%28PDF%29.pdf Page: 72 Context: 1. Give each process/task a fixed amount of workspace (a fixed size vector) which is estimated to be large enough to meet its needs. Only the base address of the workspace and the size need to be stored; i.e., the whole vector in logical memory is mapped into a corresponding vector in physical memory. We don’t know where it lies in the physical memory, but the mapping is one-to-one. The disadvantage with this scheme is that either too much or too little memory might be allocated for the tasks. Moreover, if only a small part of the program is actually required in practice, then a large amount of memory is wasted and cannot be reused. 2. Coarse grain or “quantize” the memory in smallish pieces, called pages. Each page is chosen to have the same fixed size (generally 2-4kB on modern systems), given by some power of 2 bits (this varies from system to system). The base address of each page is then stored in the conversion table (the length is known, since it is fixed). A unit of logical memory is called a page, whereas a unit of physical memory is called a frame. Apart from the difference in names, they must of course have the same size. The second of these possibilities is an attractive proposition for a number of reasons. By breaking up the memory into smaller pieces, we have the possibility of reorganizing (reusing) each piece separately. Large programs need not be entirely in memory if they are not needed. Also, if two programs use the same code, they can share pages, so two logical pages map into the same physical frame. This is advantageous for shared libraries. # Page numbers and addresses Page addressing is a simple matter if the size of one page is a power of 2ⁿ. Since addresses are stored in bits, page numbers can be assigned by simply throwing away the lower bits from every address. It is analogous to counting in blocks of a thousand, in regular base 10. To number blocks of size 1000 in base 10, one simply has to drop the lowest three digits. Thus, to store the mapping from logical to physical here, we must cover all addresses from 0000 to 9999. Without paging, we would require 9999 addresses. With paging we need only 9 addresses, since 7123 and 7663 are both in page 7, for instance. An important consequence of the mapping of pages is that what appears to the user as 10MB of sequential memory may in reality be spread in some random order just about anywhere in physical memory. The tables which map logical to physical memory are called the page table and the frame table, and are stored per process and loaded as a part of context switching. #################### File: 1%20A%20short%20introduction%20to%20operating%20systems%20%282001%29%20-%20Mark%20Burgess%20%28PDF%29.pdf Page: 73 Context: # 5.1.7 Segmentation - Sharing From the point of view of the system: sharing, process management, and efficiency, it is highly convenient to view the memory for different processes as being segmented. A segment is a convenient block of logical memory that is assigned to a process when it is executed. The memory given to any process is divided up into one or more segments, which then belong to that process. The purpose of segments is to help the system administer the needs of all processes according to a simple paradigm. Each segment of memory is administered separately, and all of the checks on valid addressing are made on each segment. It is therefore convenient to use separate segments for logically separate parts of a program/process. - **Code segment** - program code - **Data segment** - the program stack and dynamically allocated data. - Arrays can conveniently be placed in a segment of their own— that way, array bound-checking will be performed automatically by the hardware of the system. The segment idea can all be built on top of the page/frame concept above by demanding that segments be a whole number of pages. That way, we retain the advantages of the page system. Segmentation is an additional overhead which relates to the sharing of logical memory between processes. The page overhead relates to the mapping of logical to physical addresses. Memory addressing with segments is like plotting points in a plane with coordinates (segment, offset). Addresses are written as `(segment, offset)`. # 5.1.8 The malloc() Function The C + operator new, which dynamically allocates memory, is a wrapper function for the C library function `malloc()`. When we use `new`, the compiler translates this into a call to `malloc()`. As an example, let's ask what happens when we call the function `malloc()`. `malloc()` is part of the standard C library on any system, but we shall only be concerned with how it is implemented in BSD UNIX. The function is used to obtain a pointer to the address of a block of memory n bytes long. For example, ```c pointer = malloc(n); ``` Since `malloc` is a user-level command, it obtains logical memory for the caller. The acquisition of physical memory is taken care of by the system on behalf of `malloc`, by deeper level kernel commands. In order to obtain n bytes of memory, `malloc` must normally acquire too much memory. This is because the smallest unit of memory is a page. #################### File: 1%20A%20short%20introduction%20to%20operating%20systems%20%282001%29%20-%20Mark%20Burgess%20%28PDF%29.pdf Page: 74 Context: # Figure 5.3: The UNIX Process Model The UNIX process model shows the various segments used by each process. The stack contains all local (automatic) variables and the heap is allocated by `malloc()`. ``` HIGH ADDRESS +-------------------+ | arg[ ] and env[ ] | +-------------------+ | Stack | | | | Heap | +-------------------+ | Uninitialized data | +-------------------+ | Initialized data | | (static) | +-------------------+ | Text / Code | +-------------------+ LOW ADDRESS ``` When `malloc()` is called, it checks to see if the data segment of the current process has free bytes. If the space already exists within the pages allocated to the process, `malloc()` uses this space and updates the free-memory list. If there is not sufficient space, `malloc()` makes a call to the `brk()` function, which tries to extend the size of the data segment. In most cases, not all the memory obtained is required. The most extreme example would be the allocation of one char variable (one single byte). Then the remainder of the page is free and is added to the free memory list. The next time `malloc()` is called, it tries to use the remainder of the last allocated page, or any memory in the same segment which it allocated earlier, but has since been freed. The fact that `malloc()` divides up pages of logical memory is of no consequence to the memory management system, since each process maintains its own free memory list for the data segment. Since the segment always consists of a whole page, the division is a matter of internal bookkeeping. #################### File: 1%20A%20short%20introduction%20to%20operating%20systems%20%282001%29%20-%20Mark%20Burgess%20%28PDF%29.pdf Page: 75 Context: ```markdown # 5.1.9 Page size, fragmentation and alignment The process of allocating memory is really only half the story of memory management. We must also be able to de-allocate or free memory. When memory is freed from a segment, it leaves a hole of a certain size, which is added to the free-list. Eventually, the number of these holes grows quite large and the memory is said to become **fragmented**. Fragmentation can lead to wasted resources. We would clearly like to re-use freed memory as far as possible, but if the holes are not big enough to fit the data we need to allocate then this is not possible. Another technical problem which leads to fragmentation and wastage is **alignment**. Alignment is a technical problem associated with the word-size and design of the CPU. Certain memory objects (variables) have to be stored starting from a particular (usually even) address. This is because the multiple-byte registers of the CPU need to align their “footprints” to the addresses of the memory. Or, by virtue of the word-size of the system, the CPU regards the addresses as being effectively multiples of the word-size. In order to meet this requirement, memory sometimes has to be ‘padded’ out with empty bytes — which are therefore wasted. Fragmentation occurs at two levels: - **Internal fragmentation**. This is space wasted by `malloc` in trying to fit data into a segment (logical memory). - **External fragmentation**. This is space lying between segments in the physical memory. (There are never holes between segments in logical memory since we can always just renumber the logical addresses to remove them — they are not real anyway.) See the figure below. ![Mapping from user allocation to physical memory](path/to/your/figure.png) Figure 5.4: Levels of mapping from user allocation to physical memory. ``` #################### File: 1%20A%20short%20introduction%20to%20operating%20systems%20%282001%29%20-%20Mark%20Burgess%20%28PDF%29.pdf Page: 76 Context: # Figure 5.5 Fragmentation occurs because we allocate memory in blocks of different sizes and then free the blocks. Fragments are shown as the white gaps between allocated objects. Internal fragmentation happens inside segments of logical memory when programs like `malloc` divide up the segment space. External fragmentation occurs in the mapping of logical segments to physical segments when there are gaps between the segments in physical memory. External fragmentation is cured by only mapping **pages** as in figure 5.4. Note that external fragmentation is formally eliminated by the page concept. With pages, every object in physical memory is always the size of a page or frame; every hole must also be the size of a page, and thus one is guaranteed to be able to fit a page block into a page hole. To some extent, this is a cheat though, because the problem is only transferred from external to internal fragmentation – but such is the nature of definitions. Internal fragmentation can be minimized by choosing a smaller page size for the system. That means that, on average, fewer bytes will be wasted per page. Of course, the system overhead grows larger as the page size is reduced, so as usual the size of pages is a tradeoff between two competing requirements. At the user level, it is possible to avoid the fragmentation problem when writing programs. For example, if a program allocates and frees memory objects of random sizes, it will be a random issue whether or not the holes left over can be used again. If, on the other hand, a program only allocates memory in fixed size structures (like C’s `struct` and union variable types), then every hole will be the same size as every new object created and (with pages) it will always be possible to fit new data into old holes. This is a program design consideration. Unions were designed for precisely this kind of purpose. #################### File: 1%20A%20short%20introduction%20to%20operating%20systems%20%282001%29%20-%20Mark%20Burgess%20%28PDF%29.pdf Page: 77 Context: # 5.1.10 Reclaiming Fragmented Memory (Tetris!) There are two strategies for reclaiming fragmented memory: 1. Try to fit data into the holes that already exist. 2. Reorganize the data so that all the holes are regrouped into one large hole. The second alternative clearly represents a large system overhead and is seldom used. The first method can be implemented in one of three ways. Given a free-list of available holes, one may choose a space on the basis of: - **First fit:** Choose the first hole which will do. - **Best fit:** Choose the smallest hole that will do. - **Worst fit:** Choose the largest hole (which in some screw sense leaves the biggest remainder – for what it's worth). The first two are preferable, but neither works best in all cases. The criteria are i) minimization of fragmentation and ii) minimization of the allocation overhead. The first is perhaps preferable, since it is fastest. ## 5.2 Virtual Memory ### 5.2.1 Paging and Swapping Virtual memory is a way of making the physical memory of a computer system effectively larger than it really is. Rather than using mirrors, the system does this by determining which parts of its memory are often sitting idle, and then makes a command decision to empty their contents onto a disk, thereby freeing up useful RAM. As we noted earlier, it is quite seldom that every byte of every program is in use all of the time. More often, programs are large and contain sections of code which are visited rarely if ever at all by the majority of users – so if they are not used, why keep them in RAM? Virtual memory uses two methods to free up RAM when needed: - **Swapping:** An entire process, including code segment and data segments is expunged from the system memory. - **Paging:** Only single pages are swapped out. Of course, the simplest way to clear a space in RAM is to terminate some processes, but virtual memory is more subtle than that. The idea is to free up memory efficiently. #################### File: 1%20A%20short%20introduction%20to%20operating%20systems%20%282001%29%20-%20Mark%20Burgess%20%28PDF%29.pdf Page: 78 Context: # 5.2.2 Demand Paging - Lazy Evaluation You might ask – if a program has a lot of pages which do not get used, what is the purpose of loading them in the first place and then swapping them out? One could simply make a rule that no page should be brought into memory until it is needed. Such a scheme is possible, but few systems allow a program to run if it cannot be loaded fully into memory on start-up. One argument against this extreme form of paging is that it could be dangerous to start a program which was unable to complete because it was too large to run on the system, under the conditions of the moment. If it started to run and then crashed or exited, it could compromise important data. (The BSD UNIX system allocates sufficient space in its swap area to swap or page out each entire process as it begins. That way, none of them will ever run out of swap during execution.) On the other hand, if a program can be loaded in, it is most likely safe – so if we then discover that large parts of the program are never used, we can page them out and never bother to page them in again. This is an example of what is called **lazy evaluation**. A lazy pager never brings a page back into memory until it has to, i.e., until someone wants to use it. This can save a considerable amount of I/O time. Another name for this is... #################### File: 1%20A%20short%20introduction%20to%20operating%20systems%20%282001%29%20-%20Mark%20Burgess%20%28PDF%29.pdf Page: 79 Context: # 5.2.3 Swapping and Paging Algorithms How does the system decide what pages or processes to swap out? This is another problem in scheduling. A multitude of schemes is available. Here we shall only consider some examples. Consider the UNIX system a moment. Before paging was introduced, the only way that memory segments could increase their size was to: 1. Try to look for free memory at the end of the current segment and add it to the current segment. 2. Try to allocate a new, larger segment, copy the data to the new segment and deallocate the old one. 3. Swap out the process, reallocates, and swap in again. In this use of swap space, it is clear that a process is swapped out while it is waiting for a suitable hole to appear in the memory. This might take a long time and it might be immediate. Another case for swapping out a job is if it has been idle (sleeping) for a long time. On a BSD-like UNIX system, the first three processes to be started are: 1. The swapper, 2. init, and 3. the pagedaemon. The pagedaemon is responsible for examining the state of the page table and deciding which pages are to be moved to disk. Normally the swapper will not swap out processes unless they have been sleeping for a long time, because the pagedaemon will first strip them of their inactive pages. It will begin to swap out processes however, if the average load on the system is very high. (The load average is a number based on demand paging, since it only occurs on demand from user processes.) It is now easy to see how the paging concept goes hand in hand with the logical memory concept: each time the system pages out a frame of physical memory, it sets a flag in the page table next to the logical page that was removed. If a process attempts to read from that page of logical memory, the system first examines the flag to see if the page is available and, if it is not, a page fault occurs. A page fault is a hardware or software interrupt (depending on implementation) which passes control to the operating system. The OS proceeds to locate the missing page in the swap area and move it back into a free frame of physical memory. It then binds the addresses by updating the paging table and, when control returns to the waiting process, the missing page is automatically restored, as if it had never been gone. Notice that the location of the physical frame is completely irrelevant to the user process. A frame does not have to be moved back into the same place that it was removed from because the runtime binding of addresses takes care of its relocation. #################### File: 1%20A%20short%20introduction%20to%20operating%20systems%20%282001%29%20-%20Mark%20Burgess%20%28PDF%29.pdf Page: 80 Context: on the kernel's own internal accounting and is supposed to reflect the state of system activity. This gives 'cheap' processes a chance to establish themselves. It is the pagedaemon which makes the paging decisions. By copying read-only segments to the swap area at load time, the running overhead of paging out read-only data is removed, since the data are always where we need them in swap space and never change. In modernized versions of UNIX, such as the Solaris systems by Sun Microsystems, read-only pages from the code segment are thrown away when they are selected for swap out and then read in from the filesystem if needed again. Moreover, data pages are only allocated swap space when they are forced out of physical memory. These optimizations reflect the fact that modern systems have more physical memory than previously; also, disks are getting faster. ## Paging Decisions Let us now look more generally at how paging decisions are made. The most important aspect of paging is that pages can still be accessed even though they are physically in secondary storage (the disk). Suppose a page fault occurs and there are no free frames into which the relevant data can be loaded. Then the OS must select a **victim**: it must choose a frame and free it so that the new faulted page can be read in. This is called (obviously) **page replacement**. The success or failure of virtual memory rests on its ability to make page replacement decisions. Certain facts might influence these algorithms. For instance, if a process is receiving I/O from a device, it would be foolish to page it out – so it would probably **I/O locked into RAM**. Here are some viable alternatives for page replacement: ### FIFO - First In First Out Consider the figure below. Here we see the frames in the physical memory of a paging system. The memory is rather small so that we can illustrate the principles of contention for pages most clearly. The simplest way of replacing frames is to keep track of their age (by storing their age in the frame table). This could either be the data, as recorded by the system clock, or a sequential counter. When a new page fault occurs, we can load in pages until the physical memory is full; thereafter, we have to move out pages. The page which has been in memory longest is then selected as the first to go. This algorithm has the advantage of being very straightforward, but its performance can suffer if a page is in heavy use for a long period of time. Such a page would be selected even though it was still in heavy use. ### Second Chance A simple optimization we can add to the FIFO algorithm is the following. Suppose we keep a reference bit for each page in the page table. Every time the #################### File: 1%20A%20short%20introduction%20to%20operating%20systems%20%282001%29%20-%20Mark%20Burgess%20%28PDF%29.pdf Page: 81 Context: # Figure 5.6: Illustration of the FIFO page replacement scheme. | Frame table | Page fault | |-------------|------------| | 1 | 1 | | 1 | 2 | | 1 | 3 | | 4 | 4 | | 4 | 3 | | 4 | 5 | When the memory management unit accesses a page, it sets that bit to 1. When a page fault occurs, the page replacement algorithm looks at that bit and – if it is set to 1 – sets the bit to 0 but jumps over it and looks for another page. The idea is that pages which are frequently used will have their bits set often and will therefore not get paged out. Of course, this testing incurs an overhead. In the extreme case that all pages are in heavy use, the page algorithm must cycle through all the pages, setting their bits to zero before finding the original page again. Even then, it might not find a page to replace if the bit was set again while it was looking through the others. In such a case, the paging system simply fails. ## LRU - Least Recently Used The best possible solution to paging would be to replace the page that will not be used for the longest period of time – but unfortunately, the system has no way of knowing what that is. A kind of compromise solution is to replace the page which has not been used for the longest period (see the figure below). This does not require a crystal ball, but it does require some appropriate hardware support to make it worthwhile. As with all good ideas, it costs the system quite a lot to implement it. Two possibilities for such an implementation are the following: - We record the time at which each page was last referenced. Unlike the #################### File: 1%20A%20short%20introduction%20to%20operating%20systems%20%282001%29%20-%20Mark%20Burgess%20%28PDF%29.pdf Page: 82 Context: # LRU Page Replacement Algorithm ## Figure 5.7 ### LRU page replacement algorithm. When there is a tie, the algorithm uses FIFO. | Frame Table | Page Fault | Pages Used | |-------------|------------|------------| | time | | | | 1 | 2 | 3 | 4 | | 1 | 4 | 3 | 5 | | 1 | 4 | 5 | 2 | | 2 | 4 | 5 | 1 | | (FIFO) | 2 | 1 | 5 | 7 | | 2 | 7 | 5 | | *Pages Used:* - 1, 3 - 1, 4 - 4, 2 - 2, 4, 5 - 1 FIFO scheme above means that we have to update the time-stamp every time memory is referenced, instead of only when a page is replaced. If the copying operation takes, say, five CPU instructions (jump to update routine, locate page table entry, load system clock time, store system clock time, return), this means—roughly speaking—that the system is slowed down by a factor of around five. This is an unacceptable loss, so unless the memory management unit can do something fancy in hardware, this scheme is not worth the system's time. - We keep a stack of page addresses so that the page number of the most recently accessed page is always on the top of the stack. Although this sounds cheaper in principle, since the page replacement algorithm never has to search for a replacement—it just looks on top of the stack—it still results in a large system overhead to maintain the stack. We must update a data structure which requires process synchronization and therefore waiting. Again, without special hardware, this is not economical. In practice, many systems use something like the second-chance algorithm above. The UNIX `pagedaemon` uses this approach. #################### File: 1%20A%20short%20introduction%20to%20operating%20systems%20%282001%29%20-%20Mark%20Burgess%20%28PDF%29.pdf Page: 83 Context: # 5.2.4 Thrashing Swapping and paging can lead to quite a large system overhead. Compared to memory speeds, disk access is quite slow—and, in spite of optimized disk access for the swap area, these operations delay the system markedly. Consider the sequence of events which takes place when a page fault occurs: 1. Interrupt / trap and pass control to the system interrupt handler. 2. Save the process control block. 3. Determine cause of interrupt – a page fault. 4. Consult MMU – is the logical address given inside the process’ segment i.e. legal? 5. Look for a free frame in the frame table. If none is found, free one. 6. Schedule the disk operation to copy the required page and put the process into the waiting state. 7. Interrupt from disk signals end of waiting. 8. Update the page table and schedule the process for running. 9. (On scheduling) restore the process control block and resume executing the instruction that was interrupted. Such a sequence of operations could take of the order of milliseconds under favorable conditions (although technology is rapidly reducing the timescale for everything). It is possible for the system to get into a state where there are so many processes competing for limited resources that it spends more time servicing page faults and swapping in and out processes than it does executing the processes. This sorry state is called **thrashing**. Thrashing can occur when there are too many active processes for the available memory. It can be alleviated in certain cases by making the system page at an earlier threshold of memory usage than normal. In most cases, the best way to recover from thrashing is to suspend processes and forbid new ones, to try to clear some of the others by allowing them to execute. The interplay between swapping and paging is important here too, since swapping effectively suspends jobs. # 5.3 Disks: secondary storage The physical memory, as we have already seen, is not large enough to accommodate all of the needs of a computer system. Also, it is not permanent. Secondary storage consists of disk units and tape drives onto which data can be moved for storage. #################### File: 1%20A%20short%20introduction%20to%20operating%20systems%20%282001%29%20-%20Mark%20Burgess%20%28PDF%29.pdf Page: 84 Context: # 5.3.1 Physical Structure Even disks come in different shapes and sizes. The most obvious distinction is between floppy disks, diskettes, and hard disks. Floppy disks and diskettes consist of a single disk of magnetic material, while hard disks normally consist of several stacked on top of one another. Hard disks are totally enclosed devices which are much more finely engineered and therefore require protection from dust. A hard disk spins at a constant speed, while the rotation of floppy drives is switched on and off. On the Macintosh floppy drives have a variable speed operation, whereas most floppy drives have only a single speed of rotation. As hard drives and tape units become more efficient and cheaper to produce, the role of the floppy disk is diminishing. We look therefore mainly at hard drives. ![Figure 5.8: Hard disks and floppy disks.](#) Looking at the figure, we see that a hard disk is composed of several physical disks stacked on top of each other. A separate read head is provided for each surface. Although the disks are made of continuous magnetic material, there is a limit to the density of information which can be stored on the disk. The heads are controlled by a stepper motor which moves them in fixed-distance intervals across each surface, i.e. there is a fixed number of tracks on each surface. The tracks on all the surfaces are aligned, and the sum of all the tracks at a fixed distance from the edge of the disk is called a cylinder. To make the disk access quicker, tracks are usually divided up into sectors – or fixed size regions which lie along tracks. When writing to a disk, data are written in units of a whole number of sectors. (In this respect, they are) Image Analysis: 1. **Localization and Attribution:** - There is one image on the page. - Image number: **Image 1**. 2. **Object Detection and Classification:** - **Image 1** contains the following objects: 1. A **floppy disk** illustration. 2. A **hard disk** illustration with components labeled such as "Heads", "Tracks", and "Sectors." 3. **Scene and Activity Analysis:** - **Image 1** features labeled diagrams showing the internal structure and components of floppy disks and hard disks. - The diagrams illustrate the differences in the construction and functioning of these storage devices. 4. **Text Analysis:** - The page includes headers and body text discussing the physical structure of storage disks, specifically differentiating between floppy disks and hard disks. - The notable text sections are: 1. **Header:** "5.3.1 Physical structure" 2. **Figure description:** "Figure 5.8: Hard disks and floppy disks." - The text explains physical differences and operation principles of floppy disks and hard disks, with emphasis on their structural components like heads, tracks, and cylinders. 5. **Diagram and Chart Analysis:** - **Image 1** can be analyzed as a diagram showing the cross-sectional view and components of floppy disks and hard disks. - Key insights from the diagrams include: - Hard disks consist of multiple magnetic disks (platters) stacked together, while floppy disks consist of a single disk. - Hard disks are more complex and enclosed for protection from dust. - The illustration of hard disks shows a more intricate internal structure involving a stepper motor for head movement and fixed tracks and sectors for data storage. 7. **Anomaly Detection:** - No noticeable anomalies in **Image 1**. Both diagrams accurately represent the typical internal structures of floppy disks and hard disks. 8. **Color Analysis:** - The color scheme in **Image 1** is grayscale, providing a clear and simple representation focused on structural components without the use of color for emphasis. 9. **Perspective and Composition:** - **Image 1** uses a side view perspective to illustrate the internal components and cross-sectional layout of the storage devices. - The composition is straightforward, with clear labeling of key parts to facilitate understanding of the structure and function of each device. 10. **Contextual Significance:** - **Image 1** contributes significantly to the educational content of the document, providing visual support to the text that explains the physical structure and operational characteristics of floppy disks and hard disks. - It aids in conveying the technical details described in the text, thereby enhancing comprehension of the storage device concepts. 13. **Graph Numbers:** - There are no specific numbers in the diagrams. **Additional Aspects:** - **Ablaufprozesse (Process Flows):** - The image describes the process flow of data read/write operations in hard disks, referring to the role of the stepper motor, head positioning, and data organization in tracks and sectors. - **Prozessbeschreibungen (Process Descriptions):** - The document describes the process of data storage and retrieval in hard disks, explaining how the stepper motor aligns the heads over tracks and sectors for accessing data. - **Typen Bezeichnung (Type Designations):** - The types of disks depicted in the images are labeled as "Floppy" and "Hard disk." - **Trend and Interpretation:** - An interpretation of the provided information suggests a shift towards hard disks due to their higher efficiency and capacity compared to floppy disks. - **Tables:** - There are no tables on the page. In summary, the image and accompanying text provide a detailed explanation of the physical structure and operation of floppy disks and hard disks. The diagrams help visualize the internal components, playing an educational role in understanding these storage devices. #################### File: 1%20A%20short%20introduction%20to%20operating%20systems%20%282001%29%20-%20Mark%20Burgess%20%28PDF%29.pdf Page: 85 Context: # 5.3.2 Device Drivers and IDs A hard disk is a device, and as such, an operating system must use a device controller to talk to it. Some device controllers are simple microprocessors which translate numerical addresses into head motor movements, while others contain small decision-making computers of their own. The most popular type of drive for larger personal computers and workstations is the SCSI drive. SCSI (pronounced scuzzy) (Small Computer System Interface) is a protocol and now exists in four variants: SCSI I, SCSI II, and fast SCSI 2, SCSI 3. SCSI disks live on a data bus which is a fast parallel data link to the CPU and memory, rather like a very short network. Each drive coupled to the bus identifies itself by a SCSI address (0.6) and each SCSI controller can address up to seven units. If more disks are required, a second controller must be added. SCSI is more efficient at multiple access sharing than other disk types for microcomputers. To address any portion of a disk, we need a three-component address consisting of (surface, track, sector). When a disk is supplied by a manufacturer, the physical properties of the disk (number of tracks, number of heads, sectors per track, speed of revolution) are provided with the disk. An operating system must be able to adjust to different types of disk. Clearly, sectors per track is not a constant, nor is necessarily the number of tracks. The numbers given are just a convention used to work out a consistent set of addresses on a disk and may not have anything to do with the hard and fast physical limits of the disk. Because the heads of the disk move together on all surfaces, we can increase read-write efficiency by allocating blocks in parallel across all surfaces. Thus, if a file is stored in consecutive blocks on a disk with n surfaces and n heads, it could read in sectors x sectors-per-track without any head movement. In order to talk to a SCSI disk, an operating system must have a SCSI device driver. This is a layer of software which translates disk requests from the operating system's abstract command layer into the language of signals which the SCSI controller understands. The operating system generally provides two logical devices for each SCSI address: a raw device and a buffered device. On BSD UNIX systems these are referred to as `/dev/?` and `/dev/??`. #################### File: 1%20A%20short%20introduction%20to%20operating%20systems%20%282001%29%20-%20Mark%20Burgess%20%28PDF%29.pdf Page: 86 Context: # 5.3.3 Checking Data Consistency and Formatting Hard drives are not perfect; they develop defects due to magnetic dropout and imperfect manufacturing. On more primitive disks, this is checked when the disk is formatted and these damaged sectors are avoided. If a sector becomes damaged under operation, the structure of the disk must be patched up by some repair program. Usually, the data are lost. On more intelligent drives, like the SCSI drives, the disk itself keeps a defect list which contains a list of all bad sectors. A new disk from the manufacturer contains a starting list and this is updated as time goes by if more defects occur. Formatting is a process by which the sectors of the disk are: 1. (if necessary) created by setting out ‘signposts’ along the tracks, 2. labeled with an address, so that the disk controller knows when it has found the correct sector. On simple disks used by microcomputers, formatting is done manually. On other types, like SCSI drives, there is a low-level formatting already on the disk when it comes from the manufacturer. This is part of the SCSI protocol, in a sense. High-level formatting on top of this is not necessary, since an advanced enough filesystem will be able to manage the hardware sectors. Data consistency is checked by writing to disk and reading back the result. If there is disagreement, an error occurs. This procedure can best be implemented inside the hardware of the disk—modern disk drives are small computers in their own right. Another, cheaper way of checking data consistency is to calculate a number for each sector, based on what data are in the sector and store it in the sector. When the data are read back, the number is recalculated and if there is disagreement then an error is signaled. This is called a cyclic redundancy check (CRC) or error correcting code. Some device controllers are intelligent enough to be able to detect bad sectors and move data to a spare ‘good’ sector if there is an error. Disk design is still a subject of considerable research and disks are improving both in speed and reliability by leaps and bounds. # 5.3.4 Scheduling The disk is a resource which has to be shared. It therefore has to be scheduled for use, according to some kind of queue system. If a disk only had one customer at a time, a first-come first-served (FCFS) policy would be adequate. However, requests both to read and to write may come randomly from any user process or from the system on a multitasking system and so we must think carefully about how to serve them. Since a disk is hardware and involves mechanical movement, it can literally be destroyed by asking it to do too much. One of the aims of scheduling a disk is to avoid overloading it. #################### File: 1%20A%20short%20introduction%20to%20operating%20systems%20%282001%29%20-%20Mark%20Burgess%20%28PDF%29.pdf Page: 87 Context: # FCFS As always, the simplest option for scheduling is the first-come first-served method. This can be thought of in two ways: 1. The first user to obtain the disk gets to use it uninterrupted until his or her file access is finished, or 2. Every individual disk access can be scheduled on a FCFS basis. On a busy system, this can lead to wild thrashing of the disk heads as different processes first try to move them one way and then another. The AmigaDOS system (at least up to 1.3) suffered from this problem even if there were only two processes. The system tried to time-share the disk which resulted in a more than fifty percent loss in performance. The user could wait for minutes while the system tried to thrash out a job which could have taken seconds if one job had been allowed to complete first without interruption. # SSTF - Shortest Seek Time First To get the fastest response (ignoring mechanical restrictions), we could try to sort disk requests according to those which will cause the smallest movements of the disk head. Again, this does not protect the head from direction reversals, only from large movements. Also, like all priority scheduling, it could lead to starvation of some requests. # SCAN, C-SCAN and LOOK The scanning method is to order requests so that we only move the disk head in one direction at a time. Since the disk heads only move if we need to change tracks, all requests are ordered according to which track they lie on. The heads start at the first track and move unidirectionally to the next request and then the next etc. When they reach the inside of the disk, they reverse direction and come back again. This is also called the elevator or lift algorithm since this is the way many elevators are scheduled. The C-SCAN or circular scan is a slight variant: when the heads hit the end track, they come immediately back to the beginning and start again, so that they always move in the same direction. #################### File: 1%20A%20short%20introduction%20to%20operating%20systems%20%282001%29%20-%20Mark%20Burgess%20%28PDF%29.pdf Page: 88 Context: Of course, neither algorithm needs to go as far as the last track if there are no requests for data there. The LOOK algorithm is the same as SCAN or C-SCAN but does not move into areas of the disk where no requests are waiting. ![SCAN Diagram](path/to/scan_image.png) *Figure 5.9: Scanning disk scheduling algorithms.* ![C-SCAN Diagram](path/to/c-scan_image.png) *Figure 5.9: Scanning disk scheduling algorithms.* ![LOOK Diagram](path/to/look_image.png) *Figure 5.9: Scanning disk scheduling algorithms.* ### Which method? The choice of scheduling algorithm depends on the nature of disk usage. For heavily used disks, the SCAN and LOOK algorithms are well suited because they take care of the hardware and access requests in a reasonable order. There is no real danger of starvation, especially in the C-SCAN case. The arrangement of data on a disk plays an important role in deciding the efficiency of data retrieval. In the next section, we shall look at the high-level structures that the operating system places on top of sectors. This determines the level at which we are most used to seeing the disk. ### 5.3.5 Partitions For the purposes of isolating special areas of the disk, most operating systems allow the disk surface to be divided into partitions. A partition (also called a... #################### File: 1%20A%20short%20introduction%20to%20operating%20systems%20%282001%29%20-%20Mark%20Burgess%20%28PDF%29.pdf Page: 89 Context: # Partitioning and Filesystems A **cylinder group** is just that: a group of cylinders which lie next to each other. By defining partitions, we divide up the storage of data into special areas for convenience. For instance, it is quite normal to keep the system software in one partition and user data in another partition. That way, when one makes a backup of the disk, user data can easily be kept separate from system data. The separation becomes a hardware matter. Partitions are supported on MS-DOS, Macintosh, BSD UNIX, AmigaDOS, etc. Remarkably, there are versions of System V UNIX which do not support partitions. BSD UNIX partitions are a good example, and since we are focusing on UNIX, we shall discuss its partitions in more detail. BSD UNIX uses a special convention for the partitions on each disk. Each disk may have up to eight logical partitions which are labelled from a to h. | Partition | Usage | |-----------|----------------------------| | a | root and boot partition | | b | swap partition | | c | the whole disk | | d | anything | | e | anything | | f | anything | | g | anything | | h | anything | Each partition is assigned a separate logical device and each device can only write to the cylinders which are defined as being its own. Partitions can overlap because they are just limits. Thus, if we read from logical device `c`, which is defined as the whole disk, we could, in principle, read from the whole disk, whereas if we use logical device `b`, we may only read from the swap partition. To use a partition, we have to create a filesystem on it. This involves reserving space workspace for the operating system and suitable markers for navigating over the surface of the disk. Since partitions are defined for convenience, it does not matter that they overlap. What is important is that the filesystems on two partitions do not overlap! This is extremely important. If two filesystems overlap, they will destroy each other! In BSD UNIX, partitions are created by editing a table which is downloaded into the device driver. In Sun's SunOS and Solaris operating systems, a special command format is used to make partitions. The `newfs` command is used to create a filesystem. Once a partition has been created, it has to be mounted in order to be reachable from the directory structure of the filesystem. The mount action is analogous to the opening of a file. On the Macintosh and Amiga operating systems, #################### File: 1%20A%20short%20introduction%20to%20operating%20systems%20%282001%29%20-%20Mark%20Burgess%20%28PDF%29.pdf Page: 90 Context: # 5.3.6 Stripes In recent years, some UNIX systems (particularly Hewlett Packard) have experimented with **disk striping**. Disk striping is a way of increasing the disk transfer rate up to a factor of N, by splitting files across N different disks. Instead of saving all the data from a given file on one disk, it is split across many. Since the N heads can now search independently, the speed of transfer is, in principle, increased manifold. The disadvantage with disk striping is that, if one of the N disks becomes damaged, then the data on all N disks is lost. Thus, striping needs to be combined with a reliable form of backup in order to be successful. **Example of mounting a partition in UNIX:** ```bash mount /dev/sd0g /user-data ``` would mount partition g on disk number zero onto the directory `/user-data`. The result would be that all files on that partition would appear under the directory `/user-data`. A prerequisite for mounting a UNIX partition is that the partition must contain a filesystem. ![Figure 5.10: Disk striping: files are spread in parallel over several disks.](link_to_image) **Figure 5.10**: Disk striping: files are spread in parallel over several disks. #################### File: 1%20A%20short%20introduction%20to%20operating%20systems%20%282001%29%20-%20Mark%20Burgess%20%28PDF%29.pdf Page: 91 Context: # 5.4 Disk Filesystems A filesystem is a high-level interface to the disk, which allows users of a system to give names to files, organize files in directories, and separate special areas using partitions. A filesystem is said to be created on a disk by running a special program. On many systems, this is identified with formatting the disk and involves writing address data to the surface as well as reserving system workspace on the disk. ## 5.4.1 Hierarchical Filesystems and Links The most popular type of filesystem interface is the hierarchical one. Earlier operating systems like MTS did not have a directory structure. Each user had a separate login area, but the login area was not able to hold subdirectories. The hierarchical file structure is a very convenient way of organizing data in directories, sub-directories, and so on. But this rigid preoccupation with a hierarchical ordering is not always the most appropriate one. Look at the diagram below. Suppose we are in the directory `/usr/local/mysoftware`, which contains a complete package of software that we have obtained in all of its sub-directories. Since the package is a unit, we would like to keep all of its files together and preserve that unity—but it might also be necessary for some of the files in the package to be installed in special places, elsewhere in the file tree. For example, the executable binaries might have to be placed in `/usr/local/bin`, and some configuration files for the system might have to be placed in a special directory where the operating system can find them. The conflict of interest can be solved by introducing links. Links are pointers to other files which appear in the file system and look just like files. In fact, they are pointers to other files which are elsewhere in the strict hierarchy. Links enable one file to appear to exist at two or more places at the same time. A link is not a copy of a file; it is an alias for the true route to the file through the hierarchical system. The Macintosh filesystem refers to such links as "aliases." The UNIX file system makes a distinction between hard links and symbolic links. A symbolic link is literally just a small file which contains the name of the true file. We can create a symbolic link to a file which does not exist, and delete the file to which a symbolic link points. A hard link is more permanent however. In order to delete a file with hard links, all of the hard links must be removed. This requires a list of links to be associated with each file. The special files `.` and `..` are hard links to their parent directories. When links jump across different branches of the file tree, the directory structure is sometimes called an acyclic graph. #################### File: 1%20A%20short%20introduction%20to%20operating%20systems%20%282001%29%20-%20Mark%20Burgess%20%28PDF%29.pdf Page: 92 Context: # 5.4.2 File types and device nodes Extremely elaborate filesystem interfaces can be made, which distinguish between different types of file and which permit or disallow certain operations on the basis of file type. The Macintosh operating system determines whether files are executable or text files. Clicking on an executable file loads and runs the program, whilst clicking on an application file loads the application which created it and then tells the program to load that file. MS-DOS distinguishes file types by using filename extensions like `.EXE`, `.COM`, `.TXT` for executable files, relocatable executables and textfiles. The UNIX system does not make any particular distinction on the basis of filenames. Instead, it keeps a flag to say whether a file is executable or not. If a file is not marked as executable, UNIX will not try to run it. If it is marked executable, it will try to execute the file. If the file is not a valid binary program, it will fail. Executable binary files must conform to a certain protocol structure. ## Figure 5.11: Links - deviations from a strict hierarchical filesystem. - `/usr/local/bin/prog.exe` is a link to `/usr/local/mysoftware/prog.exe` - `/local` is a link to `/usr/local` ```plaintext / / \ local /ar / \ /usr/local / \ /local/bin /local/mysoftware prog.exe prog.exe ``` #################### File: 1%20A%20short%20introduction%20to%20operating%20systems%20%282001%29%20-%20Mark%20Burgess%20%28PDF%29.pdf Page: 93 Context: # 5.4.3 Permissions and Access On multi-user systems we must have a mechanism to prevent one user from freely modifying the files of another user—while at the same time, keeping enough flexibility to enable groups of users to share certain files. It is also advantageous to be able to lock files so that they cannot be deleted—even by their owner. This is normally done by giving files **permissions** or **protection bits**. Files must be **readable** and/or **writable** only to very specific users. In some operating systems, like the Apollo Domain OS and the Andrew File System, there are very intricate schemes for protecting files, consisting of lists of users who are allowed or disallowed access to them. Here we shall briefly sketch out the simple system used by UNIX as an example. Each file has an **owner** and belongs to one **group**. The owner of the file is the only one (apart from the system administrator) who can decide whether others can read or write to the file and to which group it belongs. If the owner wishes, he or she may open the file for reading or writing to i) the other members of the group to which the file belongs, or ii) anyone. Since only the system administrator can add users to a group, the file is secure, provided the user sets the correct protection bits. - When a new file is created by a given user, that user is automatically the owner of the file. The group ownership is determined differently for BSD and System 5 UNIX. In BSD, the group is normally set to a default group for that user, called the **login group**. In System 5, the file inherits the group ownership from the directory it is created in. (This can also be arranged in BSD by setting the **sticky bit**.) More modern UNIX systems and other operating systems now provide **access control lists** (ACLs). This generalizes the notion of file owner and group by allowing a file to be accessible to a named list of users and a named list of groups, rather than just a single user or a single group. ACLs were first introduced in the DOMAIN operating system by Apollo and were later adopted by HPUX and then Solaris. Novell systems (based on Apollo NCS) also provide ACLs. #################### File: 1%20A%20short%20introduction%20to%20operating%20systems%20%282001%29%20-%20Mark%20Burgess%20%28PDF%29.pdf Page: 94 Context: Modern filesystems like NFS 3, AFS, and DFS also provide ACL support, but there is currently no standard implementation and the different systems are not compatible. ## 5.4.4 File System Protocols To read or write to a file, all operating systems require that users formally **open** the file. When finished, they must **close** the file. This formal procedure has several purposes. It allows us to: 1. See whether the file is inaccessible because we do not have permission to open it. 2. See whether the file is inaccessible because it is being used by another user. When we open a file for writing, a lock is placed on the file to prevent others from writing to it simultaneously. This lock is removed by the **close** operation. 3. Obtain pointers to where the file exists physically within the secondary storage and set up a data structure called a **filehandle** which the system will use to describe the state of the file as we use it. 4. Set up any cached data which might be used by the OS. Once a file is open, the system must present the user with a consistent picture of the filesystem. When a user program reads lines from a file, a pointer should be advanced so that every line is read exactly once. An end-of-file condition should be signaled when the file is read (this is usually achieved by storing an EOF character at the end of the file). These are all aspects of an agreed protocol defined by the filesystem. A more complex situation is the following. Suppose one user is reading a file and another user wants to write to it. 1. Should the user be allowed to write to the file while someone is reading it? 2. If so, should the user be able to see the changes made to the file until after they have closed it? There are two possibilities—either all users see changes immediately or only users opening files after the changes were made see the changes. Both versions of this are in use by different filesystem implementations. In the latter case, the OS has to keep several copies of the file until all file handles are released and everyone agrees about the contents of the file. It is difficult to say that one or the other type of behavior is more correct. This is largely a subjective issue. What is important is that the filesystem defines its behavior and sticks to it consistently. The behavior of the filesystem is often called **filesystem semantics**. #################### File: 1%20A%20short%20introduction%20to%20operating%20systems%20%282001%29%20-%20Mark%20Burgess%20%28PDF%29.pdf Page: 95 Context: # 5.4.5 Filesystem Implementation and Storage Although a sector is the smallest unit of allocation for the physical disk, most filesystems create logical structures on top of sectors in order to optimize disk access. These are called **blocks**. A block can in principle be any size. Usually, they are from 512 bytes (the same size as a sector) up to 8 KB. The larger the block size, the more efficient file transfers will be. If we want to save a file that is only three bytes long, we normally have to allocate a whole block and the remainder of the block is wasted. Some systems, notably BSD UNIX's ufs filesystem, from release 4.2, solve this problem by using two block sizes: major blocks and fragments. A file is allocated in large blocks except for the last one, which is allocated as a fragment. Typical sizes for large blocks are 4 KB to 8 KB, and a typical size for fragments is from 512 bytes to 1 KB (eighths). ![Blocks and Fragments](path/to/image) **Figure 5.12:** Blocks and fragments We must now address the issue of how the blocks are allocated. This is analogous to the problem of memory allocation in RAM. The principal difference is that disk memory is considerably larger than primary memory, so problems can be encountered addressing all of the blocks on the disk. We shall briefly mention some general strategies below and then look more closely. #################### File: 1%20A%20short%20introduction%20to%20operating%20systems%20%282001%29%20-%20Mark%20Burgess%20%28PDF%29.pdf Page: 96 Context: # The UNIX ufs filesystem To use the space on a disk, we must make a choice about whether we wish files to be stored contiguous ly, or whether we wish to use a scheme of logical and physical addresses, as we did in primary memory and allow files to be spread liberally any on the disk. The problem with contiguous allocation is, of course, fragmentation. We have a much better chance of being able to fit files into the spaces on a disk if we can allocate space in small blocks. On the other hand, we know that large blocks are more efficient, since we can read or write a file in fewer operations in the block size is large. Contiguous allocation is seldom used (except in the swap area) for filesystems because of the fragmentation problem. Instead files are divided up into blocks and each file consists of a list of blocks which may be scattered anywhere on the disk. Our problem is then to identify files amongst all of the blocks. There are three ways of doing this: 1. **Linked lists.** Each block of data includes a pointer to the next block of data in a linked list. The difficulty with this method is that each block must be read in the correct order and the blocks might be spread randomly over the disk. Thus the retrieval of a file could require a lot of disk head movement which is slow. 2. **Linked table.** A linked list of blocks for each file is stored in a *file allocation table*. All of the pointers for every file are collected together in one place. This table could also be cached in RAM for faster access. This method is used by MS-DOS and a number of other microcomputer operating systems. 3. **Indexing.** Each file has an index containing a list of blocks which contain the file itself. This index might be stored anywhere in principle. Space for it is normally allocated on the disk itself, inside reserved disk blocks, and partly inside an index table which is built when the filesystem is created. The index blocks are grouped in one place for convenient access. This system is used in UNIX. Since the index table must contain pointers to disk blocks, a way of storing the pointers must be found. If the list is small and is held in a filesystem block, then most of the block will be wasted. This is a drawback of the index method, but the main advantage of this method is that it has few limitations. #################### File: 1%20A%20short%20introduction%20to%20operating%20systems%20%282001%29%20-%20Mark%20Burgess%20%28PDF%29.pdf Page: 97 Context: Two structures are created when a file system is created: inodes and superblocks. These are the most important objects in the filesystem. Both of these objects are information structures, in the sense of the C language, and they are defined under your `/usr/include/ufs` directory in files `h` and `inode.h`. It is instructive to look at these files. This is where the default blocksize etc. will be defined on your system! The blocksize is variable, but a minimum block size of 4096 bytes i.e. 4kB is stipulated so that the system can address \(2^{32}\) bytes of memory without using three level indirection (see below). Also, the last block of a file can be allocated as a fragment of a block whose size is recorded in the inode. (It might be a half, a quarter or an eighth of a block.) A superblock contains the information on the boundaries of the partition (cylinder groups) and information about where the inode table is and where databloks start. If the superblock is lost or damaged, the whole filesystem would be unreadable. It is so important that, when a file system is created, superblock backups are made at regular intervals throughout a partition. Thus, if one block is destroyed, another can be used to repair the damage. The UNIX filesystem check program `fsck` can do this. `fsck` is run automatically on every boot of the system in case the system went down uncleanly. (UNIX uses buffered and cached I/O so data are not always written to the filesystem immediately.) The program is run the OS at regular intervals in order to synchronize the disk structure with the present state of the cache. If the system crashes or goes down without synchronizing the filesystem, the superblock will be invalid and will have to be repaired. Partition `a` on disk zero is special. This is the default boot device. On power up, the boot program (in ROM) looks to the first sectors of this partition for a boot block. Sectors 0.15 contain the boot-block. Sector 16 marks the start of the superblock. An inode or index node is the data structure which holds the specific data about a particular file. Regardless of how large a file is, there is exactly one inode per file. The elements of an inode are drawn in the figure below. When a file system is created, it creates a fixed number of inodes. It is not possible to create more files on the system than the number of inodes, so a limit is built into each file system. Usually the limit is no problem in practice—and anyway, it can always be changed by changing the parameters given to `newfs`. Inodes which are not in use are kept in a doubly linked list called the free list. Filenames are stored in a directory structure, not in the inodes themselves, with pointers to the appropriate inodes for the start of the file. Each inode contains a plethora of information about the file: the device on which the file resides, the type of file and its protection bits, the user id and group id of the owner, timestamps indicating the last time the file was written to, the size of the file and of course pointers to the actual blocks of data. #################### File: 1%20A%20short%20introduction%20to%20operating%20systems%20%282001%29%20-%20Mark%20Burgess%20%28PDF%29.pdf Page: 98 Context: # UNIX Inodes ## Figure 5.13: UNIX inodes Data blocks are (of course) addressed by indexing. As an attempt at optimizing the index, inodes use three separate ways of addressing data on the disk (in fact, four different ways are built into the inodes, but only three are used). The inode contains a list of twelve 32-bit pointers to blocks on the disk. For small files, this would be enough. Since the minimum block size is 4KB, these pointers can address up to 12 × 4096 bytes, i.e., 48KB. For larger files, a system of indirect addressing is used. There are three levels of indirect addressing, though only two are used currently. In single-indirect addressing, the inode has a pointer which points to a file block (not another inode). This file block has room for 4KB at least. Those 4KB are used to store a sequential array of 32-bit pointers to other data blocks which contain the true data. Using this method, we have space for 4096 / 4-byte pointers in the address block—and each pointer can point to 4096 bytes (4KB), thus we have space for 4096 × 4096 = 4194304 bytes per file. This must then be added to the 48KB of direct pointers. In double-indirect addressing, the inode pointer points to a block of pointers (as before), but now these pointers point to blocks which also contain pointers—i.e., the pointers to the real data. The total space accessible per file is now multiplied by 1024—i.e., the number of 32-bit pointers which will fit into the minimum block size, since every fourth byte of the single-indirect memory above now forms a pointer to a block of 4KB. The total size is 4294967296 bytes, which is roughly 4 gigabytes. This should, again, be added to the single-indirect and direct memory above. Although the inodes can span an address space which is larger than 2²³ bytes, internal pointers in the file structures are still 32-bit (except in OSF/1). Image Analysis: 1. **Localization and Attribution:** - The page contains a single image located at the top-center of the page. - This is referred to as **Image 1**. 2. **Object Detection and Classification:** - **Image 1** shows a diagram consisting of several text labels and arrows. It depicts parts of an inode structure in a UNIX file system. 3. **Scene and Activity Analysis:** - **Image 1** represents a technical diagram explaining how UNIX inodes manage data storage within a filesystem. The diagram outlines the structure and flow of data pointers. 4. **Text Analysis:** - **Extracted Text from Image 1:** - "INODE" - "Device" - "Owner" - "Mode" - "Timestamp" - "12 x pointers to blocks" - "True data" - "1 pointer (indirect)" - "1 pointer (double)" - "1 pointer (triple)" - **Significance:** - The text explains the specific components of a UNIX inode, which includes metadata such as ownership, permissions, and timestamps, as well as pointers that address the actual data blocks. 5. **Diagram and Chart Analysis:** - **Image 1** illustrates the inode structure in UNIX. This includes direct pointers and various levels of indirect pointers (single, double, and triple) to manage data storage efficiently. - **Description:** - Direct pointers allow direct access to data blocks. - Single indirect pointers point to a block that further points to data blocks. - Double indirect pointers achieve another level of pointer indirection. - Triple indirect pointers add yet another layer to the same pattern. 8. **Color Analysis:** - The diagram in **Image 1** is monochromatic, primarily utilizing black text and lines on a white background. This clear contrast ensures readability and focus on the technical content. 9. **Perspective and Composition:** - **Image 1** is rendered from a straight-on, minimal perspective to clearly detail the relationships between inode components. The elements are neatly organized, starting from the inode and branching out to various data blocks via direct and indirect pointers. 10. **Contextual Significance:** - The diagram and accompanying text form part of an instructional or academic document discussing UNIX file system architecture. The image supports a more detailed explanation provided in the surrounding text. 13. **Graph Numbers:** - Although no specific numeric data points or statistical graphs are presented, the diagram indirectly references numbers related to inode pointers and data block sizes, contributing to understanding the potential storage capabilities and structure management within a UNIX file system. --- **Ablaufprozesse (Process Flows):** - The diagram outlines a clear inode process flow within the UNIX file system, emphasizing the hierarchical structure of data pointer management for efficient data storage and retrieval. **Prozessbeschreibungen (Process Descriptions):** - The text explains the indirect addressing process and the method by which UNIX manages large files through single, double, and triple indirect pointers. **Typen Bezeichnung (Type Designations):** - The types designated in **Image 1** include "direct," "indirect," "double," and "triple" pointers, each adding layers of indirection in data storage. **Trend and Interpretation:** - The trend illustrated by the inode structure points toward scalability and efficient data management as files grow larger, using progressively complex pointer systems. This method aids in handling vast amounts of data efficiently within the constraints of a file system's architecture. **Tables:** - No tables are present in the image. #################### File: 1%20A%20short%20introduction%20to%20operating%20systems%20%282001%29%20-%20Mark%20Burgess%20%28PDF%29.pdf Page: 100 Context: # Track -> ``` 1 2 3 4 5 6 7 8 9 ... * * * * * * * * ``` Time is measured in units of one head movement – one click of the stepper motor. Show how the head moves when you save and retrieve your files. > **Hint:** Use separate output files to print the result of the head movement and the result of retrieving a file. Note that you will have to design a ‘protocol’ for saving the data into the array. The disk array is just an array of characters; if you want to save a file, you need to know what data corresponds to which file. > **Hint:** You might want to limit the filename size to, say, eight characters to make the problem easier, like in DOS. Explain carefully how you locate files on your disk and what scheme your filesystem uses to recover files in the correct order. #################### File: 1%20A%20short%20introduction%20to%20operating%20systems%20%282001%29%20-%20Mark%20Burgess%20%28PDF%29.pdf Page: 101 Context: # Chapter 6 ## Networks: Services and Protocols In this section, we shall consider how to use the concepts we have considered so far to make the task of implementing network communication as straightforward as possible. Consider a large company or a university with thousands of users, many of whom have workstations or terminals on their desks—all of whom are connected to a network. In this situation, it is natural to share certain resources so that they can be accessed from anywhere on the network, without having to be reproduced on every machine: - The printer - User authentication data (password database) - Disks holding user data - A reference clock which can be used to set the local clocks on all systems - Addresses and telephone numbers To some extent, this idea of sharing was the idea behind multi-user systems. Not everyone can afford their own, so we share. What big multiuser mainframe machines have taught us, however, is that a single monolithic computer with \( n \) terminals is not a good solution. - Users demand more and more CPU power every day. - Scheduling the CPU, even if efficient on paper, can be spoiled in practice for most users by a few greedy users. Everyone wants their own private CPU. - Interactive I/O places a big load, proportional to the number of users. A large machine with a hundred keyboards attached to it can quickly become unmanageable. #################### File: 1%20A%20short%20introduction%20to%20operating%20systems%20%282001%29%20-%20Mark%20Burgess%20%28PDF%29.pdf Page: 103 Context: # Client-Server Model ``` Figure 6.1: The client-server model. The client and the server need not be on the same machine when there is a network present. ``` - Network services need to be **multi-threaded**, since several clients might request services simultaneously. We don't want to keep clients waiting. ## 6.2 Communication and Protocol There are two ways of making a client-server pair. One is to use Berkeley **sockets** directly and the other is to use RPC – or **Remote Procedure Call** software package. A **socket** is a communications link from one process to another. Sockets work over a network using the internet protocol set (see next chapter). Opening a **socket** to another machine is like opening a file to read from or write to. Data are transferred as streams or packets of raw, non-interpreted bytes. The interpretation of the data once they arrive at their destination is a problem for the user to deal with. RPC, on the other hand, is a high-level software package that works on top of sockets and allows programs to send **typed data** using a protocol known as **XDR** – external data representation. It also has high-level tools called **protocol compilers** which help programmers to write the code to interpret data at both ends of a client-server connection. There are two main implementations of this software: - Sun Microsystems' RPC - Apollo's NCS system Most of the software was developed for the UNIX-like operating systems, but has since been adapted to all the popular systems in use. All of the software #################### File: 1%20A%20short%20introduction%20to%20operating%20systems%20%282001%29%20-%20Mark%20Burgess%20%28PDF%29.pdf Page: 104 Context: # 6.3 Services and Ports Services are a **high-level concept**. When we ask for a service, we are not interested in how the message gets to the server over a network. We just want to be able to call some function `DoService(myservice)` and have the result performed by some invisible part of the system. To make this happen, a system of ‘handles’ is used. It is rather like opening a file — but now we want to open a service. The terminology is also different. To obtain a service, we do not request a file handle but a **port**. A port is a software concept—it should not be confused with the hardware connector which couples your machine to the network (which is also called a port on some systems). It is a number that an operating system uses to figure out which service a client wants. We say that a particular service lives at port `xxx`. Here is some important terminology: - **Well-known ports.** Every computer, all over the world, has to agree on the port numbers for different services. A well-known port is a port number (< 256) which is reserved for a well-known service like `ftp` or `telnet`. It has been registered in a world-wide register. - **RPC program numbers.** Historically, we distinguish between services and RPC, although the effect of the two is the same. The system of calling RPC services is different from normal services—it uses program numbers first and works out port numbers for itself. # 6.4 UNIX Client-Server Implementation It is useful to describe how UNIX deals with services, since this is the model that has been adapted for other systems. ## 6.4.1 Socket Based Communication To send data to a server using sockets, we need to know the **port number** at which the server lives. Port numbers are listed in the file `/etc/services`, which looks like this: ``` # Network services, Internet style # This file is never consulted when the NTS are running ``` #################### File: 1%20A%20short%20introduction%20to%20operating%20systems%20%282001%29%20-%20Mark%20Burgess%20%28PDF%29.pdf Page: 105 Context: ``` # Services ``` tcp 21/tcp ftp 21/tcp smtp 25/tcp mail time 37/tcp timer tftp 69/tcp timer name 42/udp nameserver whois 43/tcp # usually to sri-nic domain 53/tcp domain 53/udp hostname 101/tcp # usually to sri-nic murp 111/tcp ... login 513/tcp shell 514/tcp # no passwords used printer 515/tcp spooler # line Printer Spooler courier 530/tcp # experimental rpc 10000/tcp # udp daemon biff 512/tcp # comsat who 513/udp wchd syslog 514/udp talk 517/udp route 520/udp router routed igmp 1542/tcp bootpc 68/udp # boot program client bootp 67/udp bootp # boot program server The file maps named services into port numbers and protocol type. The protocol type is also an agreed standard which is defined in the file `/etc/protocols`, which looks like this: # Internet (IP) protocols # This file is server consulted when the NIS are running | Protocol Number | Protocol Name | |------------------|---------------------------------------------------| | 0 | IP 0 Internet protocol, pseudo protocol number | | icmp | ICMP Internet control message Protocol | | igmp | IGMP Internet group multicast protocol | | ggp | GGP Gateway-gateway protocol | | tcp | TCP Transmission control protocol | | pup | PUP PARC universal packet protocol | | udp | UDP User datagram protocol | | hmp | HMP Host monitoring protocol | | xns-idp | 22 XNS-IDP Xerox NS IDP | | rdp | 37 RDP "Reliable datagram" protocol | In order to open a socket, we must know the name of the host on which the server lives. If we don’t know this information in advance, we can send a broadcast request to all hosts, hoping that one of them will reply with their correct address (see next chapter). Also, when the message arrives at a host which runs the server process, there are two possibilities. ``` #################### File: 1%20A%20short%20introduction%20to%20operating%20systems%20%282001%29%20-%20Mark%20Burgess%20%28PDF%29.pdf Page: 107 Context: When an RPC client wants a service, it sends a request to the portmapper on the server host asking for a server which can deal with program number (service) `xxx`. The portmapper replies by giving the port on which the RPC server is listening. The advantage of this scheme is that RPC applications do not have to run on well-known ports. A suitable free port can be found at start-up. On the other hand, each type of server program must have a unique program number, which must be obtained from Sun Microsystems. The program numbers are stored in `/etc/rpc`. The real benefit of the RPC packages is the high-level concepts which they handle on behalf of the programmer. The protocol compilers and XDR protocols provide a set of "frequently used subroutines" which enhance the system of communication across a network. ## 6.5 The telnet command The `telnet` command, as opposed to the `telnet` service, does not only contact the well-known port number 23, but can also be used to send a message to any port. For example, instead of the command ``` finger mark@mymachine ``` to get information on user `mark` from the `finger` database, we could contact the well-known port on host `mymachine` as follows: ``` anyone$ telnet anyone finger Trying 129.240.22.14 ... Connected to anyone. Escape character is `^]`. mark Login name: mark In real life: Mark Burgess Directory: /mm/anyon/u2/mark Shell: /local/bin/tcsh On since Aug 14 11:59:39 on ttyp1 from :0.0 17 minutes Idle Time Mail last read Sun Aug 14 14:27:02 1994 No Plan. ``` Or had `finger` not been in `/etc/services`, we could have written ``` telnet hostname 79 ``` Not all services accept textual input in this way, but `telnet` will try to contact their ports nevertheless. #################### File: 1%20A%20short%20introduction%20to%20operating%20systems%20%282001%29%20-%20Mark%20Burgess%20%28PDF%29.pdf Page: 108 Context: # 6.6 X11 The X11 window system, used by Unix, is a client-server based application. A user's workstation runs a server process called `X`, whose job it is to display windows on the user's display. Each application the user wishes to run is a client, which must contact the server in order to have its output displayed on the X-display. ![Figure 6.2: The X windowing system.](image-url) By making this simple client-server abstraction, it makes no difference whether applications are running on the same host as the X-display, or whether they are running over the network. `X` uses its own system of protocols which is layered on top of socket communication. Strangely, `X` and Sun's variant `News` are the only window systems which have understood the point of networking. All other window systems require you to run programs on the computer at which you are sitting. ## 6.7 HTML: Hypertext Markup Language A further example of a protocol is the world wide web hypertext markup (formatting) language (HTML). This insists upon simple rules for formatting pages and references. ## Exercises 1. Explain what "protocol" means. 2. Describe briefly the client-server model. 3. What role do daemons play in respect to the Unix kernel? Why are servers daemons? #################### File: 1%20A%20short%20introduction%20to%20operating%20systems%20%282001%29%20-%20Mark%20Burgess%20%28PDF%29.pdf Page: 110 Context: # Chapter 7 ## TCP/IP Networks In the last chapter we looked at some of the high level considerations for enabling transparent communication over a network. The next thing to look at is how such a scheme of protocols is achieved in practice. ### 7.1 The protocol hierarchy #### 7.1.1 The OSI model We begin by returning to the ‘most important idea in computing’ – namely hierarchies. As we have noted before, the most practical way of solving complicated problems is to create ‘layers of detail’. At any level in a hierarchy, the details of the lower levels are invisible – so we never see the irrelevant pieces of the computing puzzle we are trying to solve. The International Standards Organization (ISO) has defined a standard model for describing communications across a network, called the OSI model, for Open Systems Interconnect (reference model). The OSI model is a seven-layered structure. It does not have to be taken literally – it might not be natural to separate all of these parts in every single program – but it is useful as a way of discussing the logically distinct parts of network communication. The layers are described as follows: | Layer Number | Layer Name | Description | |--------------|-------------------|-----------------------------------| | 7 | Application layer | Program which sends data | | 6 | Presentation layer | XDR or user routines | | 5 | Session layer | RPC / sockets | | 4 | Transport layer | TCP or UDP | | 3 | Network layer | IP internet protocol | | 2 | Data link layer | Ethernet (protocols) | | 1 | Physical layer | Ethernet (electronics) | At the lowest level, the sending of data between two machines takes place. #################### File: 1%20A%20short%20introduction%20to%20operating%20systems%20%282001%29%20-%20Mark%20Burgess%20%28PDF%29.pdf Page: 111 Context: # Networking Layers Networking involves sending data by manipulating voltages along wires. This means we need a device driver for the signal and something to receive the data at the other end—a way of converting the signals into bytes. We then need a way of structuring the data so that they make sense. Each of these elements is achieved by a different level of abstraction. ## 1. Physical layer This is the problem of sending a signal along a wire, amplifying it if it gets weak, and removing noise. If the type of cable changes (we might want to reflect signals off a satellite or use fibre optics), we need to convert one kind of signal into another. Each type of transmission might have its own accepted ways of sending data (i.e., protocols). ## 2. Data link layer This is a layer of checking which makes sure that what is sent from one end of a cable to the other actually arrived. This is sometimes called handshaking. ## 3. Network layer This is the layer of software which remembers which machines are talking to other machines. It establishes connections and handles the delivery of data by manipulating the physical layer. The network layer needs to know something about addresses—i.e., where the data are going, since data might flow along many cables and connections to arrive where they are going. ## 4. Transport layer We shall concentrate on this layer for much of what follows. The transport layer builds ‘packets’ or ‘datagrams’ so that the network layer knows what is data and how to get the data to their destination. Because many machines could be talking on the same network all at the same time, data are broken up into short ‘bursts’. Only one machine can talk over a cable at a time, so we must have sharing. It is easy to share if the signals are sent in short bursts. This is analogous to the sharing of CPU time by use of time-slots. ## 5. Session layer This is the part of a host’s operating system which helps a user program to set up a connection. This is typically done with sockets or the RPC. ## 6. Presentation layer How are the data to be sent by the sender and interpreted by the receiver, so there is no doubt about their contents? This is the role played by the external data representation (XDR) in the RPC system. ## 7. Application layer The program which wants to send data. As always, the advantage of using a layered structure is that we can change the details of the lower layers without having to change the higher layers. Layers 1 to 4 are those which involve the transport of data across a network. #################### File: 1%20A%20short%20introduction%20to%20operating%20systems%20%282001%29%20-%20Mark%20Burgess%20%28PDF%29.pdf Page: 112 Context: # 7.1.2 Data Encapsulation Each time we introduce a new layer of protocol into network transport, we need to *package* the information in some agreed format. This is called **data encapsulation**. Often when data are encapsulated, each *packet* (to use the word loosely) is given a few bytes of *header information*. This is information which includes, for example, what the information is for, where it is going, and which piece of the total information the current packet represents. At the level of the network layer, data might be divided up into numbered packets, each of which contains the address of the sender and receiver, the length of the packet, and so on. Suppose now that we were to ‘unpack’ these data, removing their headers and reassembling the data. We might find that the data are structured at a higher level, namely the transport layer. The form of the data might be a sequence of messages, each of which has a header of its own containing a **port number** or **RPC program number** of the recipient application program, the length of the message, and so on. Notice the parallels between this and the system of segments and pages in the virtual memory concept of chapter 5. Each layer of abstraction we introduce requires a small overhead (the header) which gets added to the data so that the receiver can make sense of them. This is the essence of implementing a protocol in practice. # 7.2 The Internet Protocol Family The set of protocols currently used on most networks is called the **internet protocol family**. This is divided into four layers which correspond roughly to a coarse OSI model. | Layer Number | Layer Name | Description | Reference | |--------------|----------------------|-------------------------------------------|-----------| | 4 | Application Layer | User program | 6.7 | | 3 | Host to Host Transport | Higher level data encapsulation | 3, 4, 5 | | 2 | Internet Layer | Lower level datagram transport | 2 | | 1 | Physical Layer | Network | 1 | At the internet layer, we have the IP or **internet protocol** which includes a specification of addresses and basic units of data transmission. The official name for the lowest level data *packages* in the internet protocol is **datagrams**. #################### File: 1%20A%20short%20introduction%20to%20operating%20systems%20%282001%29%20-%20Mark%20Burgess%20%28PDF%29.pdf Page: 113 Context: Each datagram consists of a number of 32-bit words. The first six of these words consist of the IP header. | Version | IHL | Service | Total length | |---------|-----|---------|--------------| | Identifier | Flags | Fragmentation offset | | | Lifetime | Protocol | Header checksum | | | Sender's address | Destination address | Options | Padding | | DATA .... | | | | Figure 7.1: IP datagram format The size of datagrams may be altered by the transport agents during the process of being sent. If a router transmits datagrams from one physical network to another, and the second network uses a smaller packet size, it will divide datagrams up into smaller datagrams called fragments. The above header is then reproduced in each fragment together with a 'fragment offset' which determines the order in which the fragments should be reconstructed at their final destination. The packet size on different physical networks is part of the low-level protocol definition. This is chosen when the physical layer is designed, based on the efficiency and speed of the network. On a slow network, a small packet size would be used so that the multiuser sharing of network time is more equitable, i.e., a greater number of packets per unit time can be sent if the packets are smaller. On the other hand, if the packet size is too small, the overhead becomes a significant portion of the total packet size and the transfer is inefficient. At the next level (the transport layer), there are two standard protocol types provided. These are called TCP (transmission control protocol) and UDP (user datagram protocol). They are sometimes called connection-oriented and connectionless protocols respectively, or reliable and unreliable. We shall explain these names below. ## 7.2.1 UDP The user datagram protocol is called unreliable because when an application chooses this protocol, the best it can do is to "throw its data out to the wind" and hope that it will arrive. When we use UDP transport, there is no guarantee that data will arrive at the destination and no confirmation of receipt is sent. #################### File: 1%20A%20short%20introduction%20to%20operating%20systems%20%282001%29%20-%20Mark%20Burgess%20%28PDF%29.pdf Page: 116 Context: # Ethernet Modern Ethernet uses neither method. Instead, it uses a combination of two solutions. A basic Ethernet network consists of a single cable or bus. Every machine listens into the same cable with one interface connector (see figure). ![Figure 7.5: Ethernet](#) Since all machines share the same cable, only one machine can be talking at once. Each machine waits its turn to transmit data. Each host flashes its signals to all the hosts on the cable like sending Morse code with a torch. Every host sees every message but only the host with the destination address bothers to accept the message. Ethernet comes in three flavours: 1. **Thick Ethernet** - a fat yellow cable with black markings. 2. **Thin Ethernet** - a coaxial (usually black) cable a few millimeters thick. 3. **Twisted Pair Ethernet** - comes out of an ISDN telephone connector, whereas the older types use coaxial and D-sub connectors. Twisted pair Ethernet is usually structured in star formation. That is, at strategic places on a master cable (usually thick Ethernet) a 'hub' is attached. This is a device which converts one connection into many. From the hub there is one twisted pair wire to each machine. If there are many machines, we require many hubs, since the number of connections is limited to ten or so. A similar arrangement can be achieved with thin Ethernet using a multipoint repeater, rather than a hub. A repeater is simply an amplifier, which is used over long stretches of cable. A multipoint repeater combines amplification with dividing up a thin Ethernet cable into n branches. The twisted pair solution is the most modern of these solutions. #################### File: 1%20A%20short%20introduction%20to%20operating%20systems%20%282001%29%20-%20Mark%20Burgess%20%28PDF%29.pdf Page: 119 Context: # 7.4.3 Routers and Gateways A router is a device which connects two physically different segments of a network. A router can be an ordinary workstation, or it can be a dedicated piece of machinery. If a router joins in different networks, it has different network interfaces and forwards datagrams between them. The router must be able to understand internet addresses in order to do this—since it must know where packets want to go. --- ## The Netmask The netmask only has a meaning as a binary number. When you look at the netmask, you have to ask yourself— which bits are ones and which are zeros? The bits which are ones decide which bits can be used to specify the domain and the subnets within the domain. The bits which are zeros decide which are hostnames on each subnet. The local network administrator decides how the netmask is to be used. ``` 11111111.11111111.11111111.11111111.00000000 255 255 255 248 Network Host ``` ### Figure 7.7 The netmask sets the division between network address and host address in the 4-byte IP address. The most common situation is that the first three numbers `xxx.yyy.zzz` represent the domain and the last number `mmm` represents the machine. In this case, the netmask is `255.255.255.0`, leaving the last byte for machine addresses. It is only possible to have 254 different machines in the domain with address `xxx.yyy.zzz` with this netmask. If we wanted more, we would have to introduce a different domain name for the extra hosts! If we wanted more machines on each subnet, we would have to change the netmask and the definitions of the domain address. By making the netmask `255.255.248.0`, as in the figure above, we add an extra bit to the host part. Thus a total of ``` 2^11 - 2 ``` hosts could use the same domain name. One address is always reserved by the internet protocol, namely the **broadcast address**. This is an address which is used like a wildcard—to refer to all machines in a given domain simultaneously. Another address is reserved as an address for the **network itself**. Usually `xxx.yyy.zzz.0` is the network address, and `xxx.yyy.zzz.255` is the broadcast address, but on older networks the address `xxx.yyy.zzz.0` was used for both of these. #################### File: 1%20A%20short%20introduction%20to%20operating%20systems%20%282001%29%20-%20Mark%20Burgess%20%28PDF%29.pdf Page: 120 Context: ``` A gateway is another name for a router. Some authors distinguish between gateways which forward packets with different network protocols, and routers which just isolate different segments of the network of the same type. Roughly speaking, the network on the short end of a router is called a **local area network** (LAN) and the greater network on the long end is a **wide area network** (WAN), though these names are normally used as it suits. # 7.5 Network Naming Services ## 7.5.1 The Domain Name Service Although the system of textual internet addresses is very convenient from a user point of view, it creates a problem. Users, on the one hand, would like to use names rather than numbers to talk about network hosts, but the name form is not sufficient in itself as an exact specification of a network and host addresses. The solution to this problem is the **domain name service** or **DNS**. This is a service which takes a textual internet address of the form: `host.domain` and returns the numerical form of the IP address for that host. This is called **resolving the name**. Notice that no two machines in the same domain may have the same name; otherwise, the DNS would not be able to resolve the IP address from the textual form. The DNS also performs the reverse service, converting numbers into names and stores extra information about which hosts are mail-exchangers etc. The UNIX program `nslookup` can be used to browse the Domain Name Service. The domain name service is a daemon, called a **nameserver**, which runs on some chosen host (usually a UNIX machine, since the software was written for UNIX) and looks up names in a database. The host on which the nameserver runs is often called a **nameserver** too. Each **server** covers only the list of hosts in its local domain, not those of other domains—but it has a knowledge of other nameservers which can answer queries in other domains. If a nameserver receives a request to resolve a name which is not in its own domain, it **forwards** the request to the official nameserver for that domain. Nameservers update each other’s information constantly about what official nameservers’ addresses are so that the data are always up to date. Each new network which is set up on the internet has to register its nameserver centrally so that this information is complete. Every host on a network must know the name of its local nameserver in order to send requests for name resolution. ``` #################### File: 1%20A%20short%20introduction%20to%20operating%20systems%20%282001%29%20-%20Mark%20Burgess%20%28PDF%29.pdf Page: 122 Context: # 7.6 Distributed Filesystems Probably the first thing we are interested in doing with a network is making our files available to all hosts, so that – no matter where in our corporate empire we happen to be sitting – we always have access to our files. The concept of a **distributed filesystem** is about sharing disks across a network. Many operating systems have. There are three main contenders for such a system in the UNIX world. Only one of these is in widespread use. ## 7.6.1 NFS - the network filesystem NFS was historically the first distributed filesystem to be implemented by Sun Microsystems. All manufacturers now support Sun's NFS. NFS is based on Sun's own RPC system (Remote Procedure Call). The idea behind NFS is to imitate UNIX filesystem semantics as closely as possible from across a network. NFS works by implementing a number of servers which run on UNIX machines. One problem with a network file system is what to do about machine crashes. Suppose we are in the middle of writing or retrieving a file and the server machine supplying the file crashes. We need some way of remembering where we were, so that when the machine comes back up, the operation can continue where it left off. In fact, this is almost impossible to achieve in practice – NFS's solution works in many cases, but not in all. In the UNIX filesystem, a user must obtain a **lock** on a file in order to read or write to it. In NFS, the same system applies. A lock is obtained from a lock server on the host where the real disk filesystem lies and the state of the filesystem is communicated by a **state server**. NFS is sometimes called a **stateless protocol**, but this is a misleading title. The state of the filesystem on the server is maintained on the server which owns the filesystem. If there is a crash, the server tries to reestablish the locks it held before the crash. If this is not possible because the filesystem has changed in the meantime or due to unfortunate timing, the result is a *stale NFS filehandle* – an unrecoverable error. The state information has to be cleared and restarted. NFS is called stateless because the server does not record the requests which the client makes (except for locks). The server processes requests without caring about which client it is serving, or about what it has done in previous requests. It doesn't know how much of a file the client has read. In other words, it is the client's responsibility to keep track of what requests it sends to the server and whether or not it gets a reply. NFS version 3 is now in use by some vendors and includes a number of improvements (and a few new bugs) over NFS. These include better caching, access control lists (ACLs), etc. #################### File: 1%20A%20short%20introduction%20to%20operating%20systems%20%282001%29%20-%20Mark%20Burgess%20%28PDF%29.pdf Page: 124 Context: # Chapter 8 ## Security: Design Considerations System security can mean several things. To have system security, we need to protect the system from corruption and the data on the system. There are many reasons why these need not be secure: - Malicious users may try to hack into the system to destroy it. - Power failure might bring the system down. - A badly designed system may allow a user to accidentally destroy important data. - A system may not be able to function any longer because one user fills up the entire disk with garbage. Although discussions of security usually concentrate on the first of these possibilities, the latter two can be equally damaging to the system in practice. One can protect against power failure by using uninterruptible power supplies (UPS). These are units which detect quickly when the power falls below a certain threshold and switch to a battery. Although the battery does not last forever, the UPS gives a system administrator a chance to halt the system by the proper route. The problem of malicious users has been heightened in recent years by the growth of international networks. Anyone connected to a network can try to log on to almost any machine. If a machine is very insecure, they may succeed. In other words, we are not only looking at local environment anymore; we must consider potential threats to system security to come from any source. The final point can be controlled by enforcing quotas on how much disk each user is allowed to use. #################### File: 1%20A%20short%20introduction%20to%20operating%20systems%20%282001%29%20-%20Mark%20Burgess%20%28PDF%29.pdf Page: 125 Context: # 8.1 Who is responsible? System security lies with: - The user. - The system administrator. - The system designer. Many would prefer to write this list upside down – but we must be practical. Usually, we are not in a position to ring to the system designer and say, “Hey, that system module you wrote is not secure, fix it.” The response would at any rate take some time. Rather, we have to learn to take the system as it comes (pending improvements in later releases) and make the best of it. All users of the system should be aware of security issues. Ideally, if all users were friendly and thoughtful, everyone would think about the welfare of the system and try to behave in a system-friendly way. Unfortunately, some users are not friendly, and accidents can happen even to friendly users. # 8.2 Passwords and encryption The first barrier to malicious users is the password. Every user on a multiuser system must have a password in order to log on. Passwords are stored in a coded or encrypted form so that other users cannot read them directly. Nevertheless, on very many systems, the coded passwords are readable to all users. Moreover, the algorithm which encrypts passwords is usable by all users. This means that anyone can try to crack the passwords by guessing. ## 8.2.1 UNIX passwords In most UNIX systems, passwords and login information are stored in the file `/etc/passwd`. This file looks something like: ``` root:90uPHtXn3uk:01:Operator:/bin/csh sundiag:*:0:1:System Diagnostic:/usr/diag/sundiag/sundiag sysdiag:*:0:0:0190 System Diagnostic:/usr/diag/sysdiag:/usr/diag/sysdiag/sysdiag daemon:*:1:1::/bin/sh sys:*:2:2::/bin/csh bin:*:3:3::/bin uucp:*:4:4:/var/spool/uucppublic news:*:6:6:/var/spool/news:/bin/csh audit:*:9:9:/etc/security/audit:/bin/csh nobody:*:65534:65534::: +NISgroup::0:0::: ``` #################### File: 1%20A%20short%20introduction%20to%20operating%20systems%20%282001%29%20-%20Mark%20Burgess%20%28PDF%29.pdf Page: 127 Context: 5. Your birthday. 6. Your car registration plate. 7. Any personal information which is easily obtained. 8. Your login name! 9. Any word in an English or foreign dictionary. 10. A keyboard sequence like qwerty. 11. Any of the above spelled backwards. Some enhanced systems take the view that users should not be able to choose an insecure password, and prevents them from doing so. Most commercial operating systems don’t care whether users have no passwords at all. ## 8.3 Super-user, or system administrator The super-user is a **trusted user**. The super-user has unlimited access to files on a system. He/she is the only user who can halt the system and is the only user who can make backups of system data. Clearly, such a user is required: - To maintain the system and deal with special circumstances which arise. - To create and destroy new and old users. - To make backups of the system. - To install software and system upgrades. Often, system administrators end up doing a lot more than this. What is important to understand is that the super-user has a highly responsible position which must not be compromised. The administrator's account must not be used by authorized users. The password is of crucial importance. The designer of an operating system must be acutely aware of the need to preserve the security of privileged access. Under the UNIX system, the super-user is called **root**. ### 8.3.1 Network administration Networks make it possible to link computer systems in an unprecedented way. We can `mount` (see chapter 5) filesystems from one computer onto another computer across a network and log in to systems all around the world (if we have an account!). We must ask: what is the role of the super-user in a networked environment? #################### File: 1%20A%20short%20introduction%20to%20operating%20systems%20%282001%29%20-%20Mark%20Burgess%20%28PDF%29.pdf Page: 130 Context: Larger systems may also use half-inch tape. Tape machines are becoming more intelligent and often include compression software in their device drivers which packs more information into the same space on the tape. An EXABYTE video tape with normal compression can hold up to 5GB of data. Newer drives support 10GB, but device drivers are not easy to come by. Depending on how often users actually use the system, it is worth considering making backups: - **Every night.** The most important data should be backed up at least as often as significant changes are made. - **Every week.** Less important data might only be worth backing up once a week. - **Every month.** For convenience you might want to record the setup of your system software once in a while – even though this can be loaded in again from source. Backup software is usually intelligent enough to be able to extract only files which have been modified since the last backup, so daily backups need not copy every file every night. How long should you keep a backup? It might take some time to discover that a file is gone. How long you keep backup tapes depends on how long you value your data. A year is not an unreasonable length of time. ## 8.5 Intruders: Worms and Viruses Worms and viruses are intruder programs which enter a system illegally and take hold of the system in some way. A virus is a piece of code which attaches itself to another program in order to get executed surreptitiously. A worm is a program which propagates from computer to computer, without necessarily changing anything. Other kinds of intruders are Trojan horses, i.e., programs which masquerade as something they are not, bacteria, which simply copy themselves in order to overwhelm the system and logic bombs which go off when some condition is met. Multiuser systems are generally harder to affect with intruders than microcomputers since the operating system exercises a much greater level of control. ### 8.5.1 Back Doors Back doors or Trojan horses are faults in the system software, which devious programs can use to gain access to the system from outside. In most cases, these #################### File: 1%20A%20short%20introduction%20to%20operating%20systems%20%282001%29%20-%20Mark%20Burgess%20%28PDF%29.pdf Page: 131 Context: # Active Internet Connections ## Active Internet Connections **Proto Recv-Q Send-Q Local Address Foreign Address (state)** tcp 0 0 saga.1147 xanto7-6000 ESTABLISHED tcp 0 0 saga.1146 xanto7-6000 ESTABLISHED tcp 0 0 saga.1145 xanto7-6000 ESTABLISHED tcp 0 0 saga.1144 njai.6000 ESTABLISHED tcp 0 0 saga.1143 njai.6000 ESTABLISHED tcp 0 0 saga.1138 xanto7-6000 ESTABLISHED tcp 0 0 saga.1132 xanto7-6000 ESTABLISHED tcp 0 0 saga.1130 xanto2-6000 ESTABLISHED tcp 0 0 saga.1125 128.39.84.2600 FIN_WAIT_1 tcp 0 0 saga.1120 128.39.84.2600 FIN_WAIT_1 tcp 0 0 saga.1022 anyon.sio.18.login ESTABLISHED tcp 0 0 saga.1004 xanto7-6000 ESTABLISHED tcp 0 0 saga.1068 xanto7-6000 ESTABLISHED tcp 0 0 saga.1023 anyon.sio.16.login ESTABLISHED tcp 0 0 saga.1080 xanto4-6000 ESTABLISHED This gives an indication of who is currently connected. Of course, intruders could connect when you are not watching, so another thing to do is to monitor all the connections made to your machine continuously and dump the result to a file. This requires a considerable amount of storage and some skill in interpreting the data. The program `tcpdump` will do this. Sun have their own version called `etherfind`. On the other hand, we cannot live in a perpetual state of paranoia, thinking that everyone is out to get us. A balance must be struck by taking all reasonable precautions and being aware of the problem. Finally, the super-user should never install software which is of suspicious or unknown origin. # 8.6 Firewall One way of designing a network to protect it from attack is to use a machine as a “firewall”. That is—a barrier to stop the spread of network threats. The idea is to isolate important machines by placing another highly secure machine between the outside world and the local network. The firewall is the only machine that is connected to a wide area network. It is also connected to the local network. #################### File: 1%20A%20short%20introduction%20to%20operating%20systems%20%282001%29%20-%20Mark%20Burgess%20%28PDF%29.pdf Page: 133 Context: # Where next? There are many topics which have only been covered superficially in this introduction. A deeper understanding of networks and system administration can be found in: [Lecture Notes](http://www.iu.hioslo.no/~mark/lectures) Image Analysis: ### Analysis of the Attached Visual Content #### 1. **Localization and Attribution** - **Image Numbering:** This document contains a single image and will be referenced as **Image 1**. #### 2. **Object Detection and Classification** - **Image 1:** - **Objects Detected:** - Textual content: Headings, paragraphs, and a hyperlink. #### 3. **Scene and Activity Analysis** - **Image 1:** - **Scene Description:** The image appears to be the final page of a document or presentation. It is white with black text provided in a structured, clear manner. - **Activities:** The primary activity is providing a closing note or conclusion along with directions for further reading or study. #### 4. **Text Analysis** - **Image 1:** - **Detected Text:** - **Title:** "Where next?" - **Paragraph:** "There are many topics which have only been covered superficially in this introduction. A deeper understanding of networks and system administration can be found in" - **Hyperlink:** "http://www.iu.hioslo.no/~mark/lectures" - **Analysis:** - **Contextual Significance:** The title "Where next?" suggests a concluding section or a prompt for further action. - **Paragraph:** It indicates that the preceding document was an introduction covering a broad range of topics superficially. - **Hyperlink:** This link redirects readers to a resource for deeper understanding of networks and system administration. #### 8. **Color Analysis** - **Image 1:** - **Dominant Colors:** The text is black against a white background, which provides high contrast for readability. #### 9. **Perspective and Composition** - **Image 1:** - **Perspective:** The content is displayed from a top-down perspective typical of a standard document page. - **Composition:** The text is centered and evenly spaced, enhancing clarity and readability. #### 10. **Contextual Significance** - **Image 1:** - **Overall Contribution:** This image serves as a final guidance for readers to further resources, indicating that the document has provided foundational information and encouraging further learning. #################### File: 1%20A%20short%20introduction%20to%20operating%20systems%20%282001%29%20-%20Mark%20Burgess%20%28PDF%29.pdf Page: 135 Context: # Glossary of Terms - **IPC**: Inter-process communication. A mechanism by which UNIX processes can exchange data with one another. See also RPC. - **Kernel**: The core of a multitasking operating system which deals with the basic system resources. The kernel drives physical devices and handles I/O, memory management, and process scheduling. - **Loopback**: The loopback device is a pseudo network device in the UNIX operating system which, rather than sending data out onto a physical network, sends packets straight back into the system. The protocols for talking to the loopback device are the same as those for the physical network, so programs employing interprocess communication have only to hold to a single standard, regardless of whether the processes are on the same machine or on different machines. - **Machine code**: The basic numerical language of codes which the CPU understands. Compilers and assemblers convert programs into machine code. - **Multiplex**: To switch between several activities or devices. - **Multi-user system**: An operating system where several users can use the system simultaneously. - **OS**: Operating system. - **Parallel**: Parallel processes are not merely timeshared (concurrent) but actually run simultaneously on different CPUs. - **Pixel**: A single dot on the screen. This is one "grain" or the object of maximum resolution. - **Primary memory**: RAM internal memory (see secondary memory). - **Primitive**: A very low level function or routine. A basic element in a library of functions. - **RISC**: Reduced instruction set chip. This is part of a new philosophy to make microprocessors faster by giving them fewer (less complicated) instructions which are optimized to run very fast. Usually, each instruction completes in a single clock cycle. - **RPC**: Remote Procedure Call. This is a mechanism for executing tasks on remote machines across the network. The RPC protocol makes use of the XDR (external data representation) protocol for passing data. It is a relatively high-level interface between networked machines. - **Secondary memory**: Disk or tape storage. #################### File: 1%20A%20short%20introduction%20to%20operating%20systems%20%282001%29%20-%20Mark%20Burgess%20%28PDF%29.pdf Page: 136 Context: # Terminology - **Semantics**: This term is used to describe the 'method of operation' of a particular system. The prescribed way in which a particular system is supposed to behave. The logic of operation of the system. - **Single-user system**: A system in which only one user can use the system at a time. - **Starvation**: A process is said to starve if it never gets a share of the CPU. This can occur if there are errors or deadlocks in scheduling. - **Transparency**: This word is often used to mean that something happens without anyone needing to know the details about **how** it happens. For example, the OS handles timesharing transparently—i.e., without users needing to know about how it happens. - **Vector**: An array of data or a segment of memory. - **Virtual**: Almost, a likeness of, simulated. #################### File: 1%20A%20short%20introduction%20to%20operating%20systems%20%282001%29%20-%20Mark%20Burgess%20%28PDF%29.pdf Page: 137 Context: # Index - `crypt()`, 124 - `fork()`, 38 - `malloc()`, 71 - `wait()`, 38 - Access control lists, 91 - Accounting, 44 - Accumulator, 16 - ACL, 91 - Address, 64 - Address binding, 65 - Address resolution, 118 - AFS, 121 - Alignment, 73 - AmigaDOS, 6, 85 - Andrew file system, 121 - Application layer, 109 - ARP, 115 - ASMP, 47 - Asynchronous I/O, 23 - AT&T, 7 - Authentication, 25 - Back door, 128 - Backups, 127 - Batch, 31 - Be Box, 8 - BIND, 116 - BIOS, 6 - Black boxes, 8 - Block allocation, 94 - Blocks, 93 - British Telecom, 119 - Broadcast address, 116, 119 - BSD unix, 7 - Buffer, 23 - Busy waiting, 58 - C-SCAN algorithm, 85 - C-shell resources, 10 - Caching, 10 - CISC, 11 - CLI, 29 - Client server model, 100 - Clock cycles, 11 - Command language, 5 - Communication, 9 - Connection oriented socket, 111 - Connectionless socket, 111 - Context switching, 35, 70 - Core, 29 - CPU, 11 - CPU burst, 32 - CRC, 84 - Critical sections, 57 - Cyclic redundancy check, 84 - Cylinder, 82 - Cylinder groups, 86 - Dæmons, 29 - Data links layer, 109 - Data types, 9 - Datagram, 111 - Deadlock, 60 - Deadlock prevention, 61 - Defect list, 84 - Demand paging, 76 - Device driver, 11 - Device ID's, 83 - Devices, 11 - DFS, 121 #################### File: 1%20A%20short%20introduction%20to%20operating%20systems%20%282001%29%20-%20Mark%20Burgess%20%28PDF%29.pdf Page: 138 Context: ``` # Table of Contents 1. Direct memory access, 23 2. Disk blocks, 93 3. Disk scheduling, 84 4. Disk surface, 82 5. Distributed file system (DFS), 121 6. Distributed file systems, 120 7. DLLs, 66 8. DMA, 23 9. DNS, 116, 118 10. Domain name service, 116, 118 11. DOS, 6 12. Encapsulation of data, 110 13. Encryption, 123 14. Entry points to OS code, 5 15. Exceptions, 12 16. FCFS, 32, 44, 84 17. FDDI, 113 18. FIFO, 23, 32, 44, 78 19. File locks, 56 20. File permissions, 91 21. File types, 90 22. Filename extensions, 90 23. Filesystem, 14, 84 24. Firewall, 129 25. First come first served, 32 26. First in first out, 23 27. Floppy disks, 85 28. Formatting, 83, 84 29. Fragmentation, 73 30. Fragments (network), 111 31. Frame table, 70 32. FTP, 102 33. Gateway, 117 34. Handshaking, 109 35. Hewlett Packard, 7 36. Hierarchical filesystems, 89 37. High level, 8 38. I/O burst, 32 39. I/O sharing, 8 40. Index nodes, 96 41. Index register, 16 42. Inodes, 96 43. Internet protocol, 110 44. Interprocess communication, 36 45. Interrupt vector, 22, 64 46. Interrupts, 6, 12, 22 47. IPC, 36 48. IPv4, 115 49. ISDN, 113 50. ISO, 108 51. Job, 31 52. Kernel, 29 53. Last in first out, 18 54. Lazy evaluation, 76 55. Least recently used algorithm, 79 56. LIFO, 18 57. Lightweight process, 31 58. Lightweight processes, 51 59. Linux, 7 60. Loader, 66 61. Locks, 37 62. Logical device, 11 63. Logical memory, 64 64. LOOK algorithm, 85 65. Low level, 8 66. LRU, 79 67. Mach, 35 68. Macintosh, 6 69. Memory management unit, 68 70. Memory map, 17 71. Memory-mapped I/O, 64 72. MMU, 35, 68 73. Monitor mode, 26 74. Monitors, 59 75. MTS, 6 76. Multi-tasking OS, 25 77. Multi-user mode, 5 78. Multiple processors, 30 ``` #################### File: 1%20A%20short%20introduction%20to%20operating%20systems%20%282001%29%20-%20Mark%20Burgess%20%28PDF%29.pdf Page: 139 Context: # Table of Contents - Multitasking system, 5 - Mutex, 55 - Mutual exclusion, 55 - Name server, 118 - Netmask, 116 - Network filesystem, 120 - Network information service, 119 - Network layer, 109 - NFS, 120 - NIS, 119 - NT, 8 - Object orientation, 44 - Operating system, 5 - OSI, 108 - Overhead, 10 - Page fault, 77 - Page table, 70 - Pages, 70 - Paging algorithms, 77 - Paging memory banks, 65 - Paging to disk, 75 - Parallelism, 30 - Partitions, 86 - Passwords, 123 - PCB, 35 - Permissions and access on files, 91 - Physical layer, 109 - Physical memory, 64 - Port number, 110 - Ports, 102 - Process control block, 35 - Process creation, 37 - Process hierarchy, 38 - Process states, 40 - Protocol, 10, 99 - Protocols, 9, 108 - Pthreads, 48 - Queue, 32 - Queue scheduling, 41 - Quotas, 44 - RAM, 11 - RARP, 115 - Register, 16 - Relative addressing, 66 - Reliable protocol, 111 - Resolving addresses, 118 - Resources, 8 - Response time, 33 - Rings, 114 - ROM, 11 - Round robin scheduling, 43 - Round-robin, 32 - Router, 111, 117 - RPC, 101, 104, 110, 120 - RR, 44 - SCAN algorithm, 85 - Scheduling criteria, 33 - Scheduling, 9, 32 - Screens, 14 - SCSI, 83 - Semaphores, 37 - Second chance algorithm, 78 - Secondary memory, 12 - Secondary storage, 81 - Sectors, 83 - Security, 122 - Segmentation, 27, 71 - Segmentation fault, 27 - Serialization, 37, 54 - Services, 29 - Session layer, 109 - Setuid programs, 126 - Shared data, 54 #################### File: 1%20A%20short%20introduction%20to%20operating%20systems%20%282001%29%20-%20Mark%20Burgess%20%28PDF%29.pdf Page: 140 Context: # Table of Contents - Shared libraries, 66 - Shortest job first, 32 - Shortest seek time first algorithm, 58 - Signals, 58 - Single task system, 5 - Single user mode, 5 - SJF, 32 - SMP, 47 - Socket, 101 - Sockets, 109 - Spin lock, 58 - Spooling, 12 - SSL, 130 - SSTF, 85 - Stack frame, 19 - Stack overflow, 19 - Stack pointer, 16 - Starvation, 85 - Status register, 16 - Sun Microsystems, 7, 119 - Super user, 26 - Supervisor, 26 - Supervisor mode, 26 - Swapping, 75 - Synchronization, 30 - Symmetric multiprocessing, 47 - Synchronous I/O, 23 - System 5/System V, 7 - System calls, 13 - System overhead, 10 - Task, 31 - TCP, 111 - TCP/IP, 108 - Telnet, 102, 105 - Tetris algorithm, 75 - Thrashing, 81 - Thread, 31 - Thread levels, 46 - Threads, 44 - Time sharing, 27 ## Additional Entries - Track, 82 - TransArc, 121 - Transport layer, 109 - Traps, 12 - Trojan horse, 128 - Two mode operation, 26 - UDP, 111 - UFS filesystem, 94 - UID, 25 - Unreliable protocol, 111 - User ID, 25 - User mode, 26 - Users, 25 - Virtual memory, 75 - Virus, 128 - VLSI, 11 - Waiting, 58 - Well known ports, 102 - Window system, 15 - Windows, 6, 14 - Word size, 65 - Worm, 128 - X windows, 106 - X11, 106 - XDR, 101 #################### File: 2%20Project%20Oberon%20The%20Design%20of%20an%20Operating%20System%2C%20a%20Compiler%2C%20and%20a%20Computer%20-%20Niklaus%20Wirth%2C%20J%C3%BCrg%20Gutknecht%20%28PDF%29%20%20UsingOberon.pdf Page: 2 Context: System.Close close the viewer Edit.Store store the text as a file Edit.Search search for the selected word from the position of the caret # Editing Texts The most frequent task is editing a text. For this case, some commands can be issued by simple mouse clicks alone rather than clicking the command name. When a text is to be entered, it is always **inserted** at the position of the **caret** displayed as a hook. The caret is positioned by pointing (with the cursor) at the desired position and clicking the left button (pointer button). Then the text is entered by simply typing it. A piece of text can be **selected** in order to be subjected to a subsequent command. This is done by moving the cursor over the piece of text while holding the right button (select button) pressed. Often it is only necessary to select the first character of a parameter. Selection can be turned into **deletion** by briefly clicking also the left button while holding the right button pressed. This is called **inter-clicking**. Similarly, a piece of text being selected can be copied-over to the caret position by inter-clicking the middle button. The functions of the mouse buttons are summarized by the following table: | inter-click: | left | middle | right | |---------------|---------------------|-------------|-------------------| | primary click:| | | | | left | set caret | - | copy | | middle | command | - | - | | right | select | delete | copy | The keyboard features two special keys, so-called **control keys**. The **Esc** key undoes selections. The **Backspace** key deletes the character left of the caret. Text viewers have a **scroll bar** at their left edge. While the cursor is in the scroll bar, it assumes the form of an up/down pointer in order to show its difference in functionality. Clicking a button then causes the text to scroll up or down. - **left button**: the current line moves up to the top of the viewer - **middle button**: show the section at the relative position given by the cursor - **right button**: the top line moves down to the current cursor position # Viewer Handling Viewers can be extended, moved, or copied. A viewer is enlarged or shrunk by clicking the left button, while the cursor is in the title bar, and then dragging the bar up or down. A viewer is moved to another location by also inter-clicking with the middle button. A duplicate of a viewer may be generated by activating the command **System.Copy** in the title bar. Note that in this case the old and the new viewer show the same text, and not a copy of the text. This facility comes in handy when a piece of text needs to #################### File: 2%20Project%20Oberon%20The%20Design%20of%20an%20Operating%20System%2C%20a%20Compiler%2C%20and%20a%20Computer%20-%20Niklaus%20Wirth%2C%20J%C3%BCrg%20Gutknecht%20%28PDF%29%20%20UsingOberon.pdf Page: 3 Context: # System Tool Documentation Be moved or copied into a position not visible in the same viewer (long distance move, or long-distance copy). The command `System.grow` in the title bar generates a copy extending over the entire column (or over the entire display). By closing the viewer (command `System.close` in the title bar), the original viewer reappears. We may imagine that `grow` lifts a viewer to an overlay in the third dimension. ## Commands The following commands appear in the standard tool `System.Tool`. The character `^` indicates that a name must be selected previously. The command then applies to that named text (file, as in the example above). The character `~` indicates that a list of names must be inserted before the `~` character, and the command will apply to all named objects. - `System.Open ^` - open viewer in the system track to the right - `System.Recall` - close the last viewer opened - `Edit.Open ^` - open viewer in the user track to the left - `Edit.Recall` - undo last editing operation - `Edit.ChangeFont` - applies to selected piece of text - `Edit.SetFont` - use specified font for subsequent input - `System.Directory ^` - search directory for specified file names - `System.Free ~` - remove specified modules from store - `System.CopyFiles ->` - e.g. `file1 => file2 file3 => file4` - `System.RenameFiles ->` - e.g. `file1 => file2 file3 => file4` - `System.DeleteFiles ~` - e.g. `file1 => file2 file3~` (from file directory) - `System.ShowModules` - `System.ShowCommands ^` - `ORP.Compile @` - compile selected text - `Hilbert.Draw` - draw Hilbert curve, as an example When clicking a command `M.P.`, module `M` is searched in the file store and, if found and not already present, loaded into main store. Then its command `P` is searched and executed (if found). A list of loaded modules can be generated by the command `System.ShowModules`, and a list of its commands is obtained by the command `System.ShowCommands`. Any parameter-less procedure in any (compiled) module is accessible as a command. Its parameters are accessed via a scanner. As an example, consider the following short program: ```pascal MODULE M0: IMPORT Texts, Oberon; VAR W: Texts.Writer; PROCEDURE P0; VAR sum: INTEGER; S: Texts.Scanner; BEGIN sum := 0; Texts.OpenScanner(S, Oberon.Par.text, Oberon.Par.pos); Texts.Scan(S); WHILE S.Class = Texts.Id DO Texts.WriteInt(W, S.i, 0); sum := sum + S.i; Texts.Scan(S); END; END M0; ``` #################### File: 2%20Project%20Oberon%20The%20Design%20of%20an%20Operating%20System%2C%20a%20Compiler%2C%20and%20a%20Computer%20-%20Niklaus%20Wirth%2C%20J%C3%BCrg%20Gutknecht%20%28PDF%29%20%20UsingOberon.pdf Page: 4 Context: ``` Texts.Write(W, sum, 8); Texts.WriteLn(W); Texts.Append(Oberon.Log, W.buf) END P0; BEGIN Texts.OpenWriter(W) END M0. After its successful compilation (ORP.Compile @), the command M0.P0 2 3 5 7 11~ causes these numbers and their sum to be output to the standard viewer System.Log. # The core of the Oberon System The system's core consists of a loop which continuously senses for a command. The command is identified, control is dispatched, and the command is executed. A command may stem from an explicit click (middle button) on a text of the form M.P, or it may be a click of the left or right mouse buttons (see editing commands). A further source of input is the keyboard. If any key is pressed, this is interpreted as a command to read that character. Exceptions are the esc, ctrl-z (or F1), and backspace keys. Esc is interpreted as a command to undo all selections, backspace to remove the character left of the caret, and ctrl-z to set the global marker. | yes | no | | ---------------- | ---------------- | | mouse key? | keyboard? | | | | | yes | no | The initially loaded system contains, apart from module Oberon, the command module System, a text system (modules TextFrames, MenuViewers, Texts, Fonts, Input), a viewer system (modules Viewers, Display), the loader and linker (module Modules), a file system (modules Files, FileDir), and the disk space manager and the garbage collector (module Kernel). The compiler is loaded on demand, like other application programs. [Project Oberon - ETH](https://www.inf.ethz.ch/personal/wirth/ProjectOberon/index.html) [Project Oberon](http://www.projectoberon.com/) ``` #################### File: 3%20BIOS%20Disassembly%20Ninjutsu%20Uncovered%201st%20Edition%20-%20Darmawan%20Salihun%20%28PDF%29%20POST_Memory_Manager_Specification.pdf Page: 1 Context: # POST Memory Manager Specification **Version 1.01** **November 21, 1997** This specification has been made available to the public. You are hereby granted the right to use, implement, reproduce, and distribute this specification with the foregoing rights at no charge. This specification is, and shall remain, the property of Phoenix Technologies Ltd. (“Phoenix”), and Intel Corporation (“Intel”). NEITHER PHOENIX NOR INTEL MAKE ANY REPRESENTATION OR WARRANTY REGARDING THIS SPECIFICATION OR ANY PRODUCT OR ITEM DEVELOPED BASED ON THIS SPECIFICATION. USE OF THIS SPECIFICATION FOR ANY PURPOSE IS AT THE RISK OF THE PERSON OR ENTITY USING IT. PHOENIX AND INTEL DISCLAIM ALL EXPRESS AND IMPLIED WARRANTIES, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND FREEDOM FROM INFRINGEMENT. WITHOUT LIMITING THE GENERALITY OF THE FOREGOING, NEITHER PHOENIX NOR INTEL MAKE ANY WARRANTY OF ANY KIND THAT ANY ITEM DEVELOPED BASED ON THIS SPECIFICATION, OR ANY PORTION OF IT, WILL NOT INFRINGE ANY COPYRIGHT, PATENT, TRADE SECRET OR OTHER INTELLECTUAL PROPERTY RIGHT OF ANY PERSON OR ENTITY IN ANY COUNTRY. #################### File: 3%20BIOS%20Disassembly%20Ninjutsu%20Uncovered%201st%20Edition%20-%20Darmawan%20Salihun%20%28PDF%29%20POST_Memory_Manager_Specification.pdf Page: 2 Context: # TABLE OF CONTENTS 1. INTRODUCTION...................................................................................................3 1.1 REVISION HISTORY....................................................................................3 1.1.1 Technical Editors.................................................................................3 1.2 RELATED DOCUMENTS.............................................................................3 1.3 TERMS.........................................................................................................4 2. FUNCTIONALITY.................................................................................................5 2.1 OVERVIEW.................................................................................................5 2.1.1 Why a PMM?....................................................................................5 2.1.2 PMM Model.....................................................................................5 2.2 CLIENTS.....................................................................................................5 3. PMM SERVICES INTERFACE............................................................................6 3.1 DETECTING PMM SERVICES......................................................................6 3.1.1 PMM Structure................................................................................6 3.1.2 Detection Algorithm.......................................................................6 3.2 PMM SERVICES.........................................................................................6 3.2.1 Interface Style................................................................................7 3.2.2 Stack Requirements......................................................................7 3.2.3 Memory Block Alignment.................................................................7 3.2.4 Accessing Extended Memory..........................................................7 3.3 PM_ALLOCATE - FUNCTION 0...................................................................7 3.3.1 Description.....................................................................................7 3.3.2 Function Prototype.........................................................................7 3.3.3 Parameters.......................................................................................8 3.4 PM_FIND - FUNCTION 1...........................................................................9 3.4.1 Description.....................................................................................9 3.4.2 Function Prototype.........................................................................9 3.4.3 Parameters.......................................................................................9 3.5 PM_DEALLOCATE - FUNCTION 2..............................................................9 3.5.1 Description.....................................................................................9 3.5.2 Function Prototype.......................................................................10 3.5.3 Parameters.....................................................................................10 3.6 C LANGUAGE CODING EXAMPLE...........................................................11 3.7 ASSEMBLY LANGUAGE CODING EXAMPLE..........................................13 4. CONVENTIONS FOR CREATING MEMORY BLOCK HANDLES........................14 4.1 NAME SELECTION.....................................................................................14 4.1.1 EISA Product Identifiers.................................................................14 4.1.2 Convention for Selecting Handle Values......................................14 4.2 RECOMMENDED METHOD FOR THE USE OF NAMED BLOCKS.................15 4.3 FINDING OTHER CARDS IN THE SYSTEM...............................................16 #################### File: 3%20BIOS%20Disassembly%20Ninjutsu%20Uncovered%201st%20Edition%20-%20Darmawan%20Salihun%20%28PDF%29%20POST_Memory_Manager_Specification.pdf Page: 3 Context: # 1 Introduction ## 1.1 Revision History | Revision | Date | Changes | |----------|-----------------|--------------------------------------------------------------------------------------------------| | 1.01 | November 21, 1997 | Included guidelines on using extended memory during POST.
Clarified the processor mode and the state of Gate A20 during POST.
Definitions for the terms: Big Real Mode, Extended Memory, and Gate A20 were added.
Changed to not clear the contents of memory blocks when they are deallocated.
Simplified the assembly language coding example by using 32-bit instructions and operands.
Clarified the 'C' language code example by adding a function to find the PMM structure.
Updated the contact information for the technical editors. | | 1.0 | September 20, 1996 | Approved for public release. | ### 1.1.1 Technical Editors **Scott Townsend** Phoenix Technologies Ltd. 135 Technology Drive Irvine, CA 92618 - phone: (714) 790-2125 - fax: (714) 790-2001 - email: [Scott.Townsend@Phoenix.com](mailto:Scott.Townsend@Phoenix.com) **Bob Hale** Intel Corporation 5200 N.E. Elam Young Parkway Hillsboro, OR 97124-6497 - phone: (503) 696-4249 - fax: (503) 648-6705 - email: [robert_p_hale@ccm2.hf.intel.com](mailto:robert_p_hale@ccm2.hf.intel.com) ## 1.2 Related Documents | Title | Author | Version | |-----------------------------------|-------------------------------|---------| | BIOS Boot Specification | Phoenix, Intel, Compaq | 1.01 | | Plug and Play BIOS Specification | Compaq, Phoenix, Intel | 1.0A | | EISA Specification | BCPR Services, Inc. | 3.12 | #################### File: 3%20BIOS%20Disassembly%20Ninjutsu%20Uncovered%201st%20Edition%20-%20Darmawan%20Salihun%20%28PDF%29%20POST_Memory_Manager_Specification.pdf Page: 7 Context: # 3.2.1 Interface Style The EntryPoint field in the PMM Structure points to the PMM Services interface. Clients call the PMM Services by executing a far call to the address specified in the EntryPoint field. PMM services return to the client via a far return. Values returned to the caller are placed in the DX:AX register pair. The flags and all registers, other than DX and AX, are preserved across calls to PMM services. ## 3.2.2 Stack Requirements PMM Services requires a minimum stack size of 256 bytes. BIOSes that support the PMM must provide a stack size of at least 1KB when calling an initialization vector, a Boot Connection Vector, or a Bootstrap Entry Vector of a PCI or PnP ISA Option ROM. ## 3.2.3 Memory Block Alignment The default alignment of memory blocks is on a paragraph boundary. Alignment of a memory block on a particular memory boundary (larger than a paragraph) is supported by specifying the desired alignment in the length parameter of the `pmnAllocate` function. ## 3.2.4 Accessing Extended Memory This section specifies how clients should access extended memory blocks allocated by the PMM. When control is passed to an option ROM from a BIOS that supports PMM, the processor will be in real mode, and Gate A20 will be disabled (segment wrap turned off). This allows access to extended memory blocks using real mode addressing. In big real mode, access to memory above 1MB can be accomplished by using a 32-bit extended index register (EDI, etc.) and setting the segment register to 0000h. The following code example assumes that the `pmnAllocate` function was just called to allocate a block of extended memory, and DX:AX returned the 32-bit buffer address. ```assembly ; Assume here that DX:AX contains the 32-bit address of our allocated buffer. ; Clear the DS segment register. push 0000h pop ds ; Put the DX:AX 32-bit buffer address into EDI. mov di, dx ; Get the upper word. shl di, 16 ; Shift it to upper EDI. mov di, ax ; Get the lower word. ; Example: clear the first four bytes of the extended memory buffer. mov [edi], 00000000h ; DS:EDI is used as the memory pointer. ``` In a similar way, the other segment registers and 32-bit index registers can be used for extended memory accessing. **WARNING:** Clients must not modify the state of Gate A20, put the processor in protected mode, or call BIOS Interrupt 15h, functions 87h or 89h. Any of these actions would alter the big real mode of the processor and could lead to a catastrophic system failure. # 3.3 pmnAllocate - Function 0 ## 3.3.1 Description The `pmnAllocate` function attempts to allocate a memory block of the specified type and size and returns the address of the memory block to the caller. The memory block is a contiguous array of paragraphs whose size is specified by the length parameter. The contents of the allocated memory block are undefined and must be initialized by the client. #################### File: 3%20BIOS%20Disassembly%20Ninjutsu%20Uncovered%201st%20Edition%20-%20Darmawan%20Salihun%20%28PDF%29%20POST_Memory_Manager_Specification.pdf Page: 8 Context: # 3.3.2 Function Prototype ```c unsigned long {entryPoint}( unsigned int function, // 0 for pmAllocate, unsigned long length, // in paragraphs unsigned long handle, // handle to assign to memory block unsigned int flags // bit flags specifying options ); ``` ## 3.3.3 Parameters ### function 0 for pmAllocate. Invalid values for the function parameter (0x0003...0xFFFF) cause an error value of 0xFFFFFFFF to be returned, signaling that the function is not supported. ### length The size of the requested memory block in paragraphs, or if it is `0x00000000`, no memory is allocated and the value returned is the size of the largest memory block available for the memory type specified in the flags parameter. The alignment bit in the flags register is ignored when calculating the largest memory block available. ### handle A client-specified identifier to be associated with the allocated memory block. A handle of 0xFFFFFFFF indicates that no identifier should be associated with the block. Such a memory block is known as an “anonymous” memory block and cannot be found using the pmnFind function (see below). If a specified handle for a requested memory block is already used in a currently allocated memory block, the error value of 0x00000000 is returned. ### flags A bitmap used by the client to designate options regarding memory allocation. | Bits | Field | Value | Description | |------|--------------|-------|-----------------------------------------| | 1.0 | MemoryType | 1.3 | 0 = Invalid
1 = Requesting conventional memory block (0 to 1MB)
2 = Requesting extended memory block (1MB to 4GB)
3 = Requesting either a conventional or an extended memory block, whichever is available. | | 2 | Alignment | 0.1 | 0 = No alignment
1 = Use alignment from the length parameter. | | 15.3 | Reserved | 0 | Reserved for future expansion, must all be zero. | ### flags.MemoryType Specifies whether the requested memory block should be allocated from conventional memory, extended memory, or from either conventional or extended memory. At least one of the bits in this field must be set. If bit 0 is set, the PMM will attempt to allocate only from conventional memory. If bit 1 is set, the PMM will attempt to allocate only from extended memory. If both bits 0 and 1 are set, the PMM will attempt to allocate from either source. #################### File: 3%20BIOS%20Disassembly%20Ninjutsu%20Uncovered%201st%20Edition%20-%20Darmawan%20Salihun%20%28PDF%29%20POST_Memory_Manager_Specification.pdf Page: 9 Context: # Memory Management Functions Documentation ## 3.4 pmmFind - Function 1 ### 3.4.1 Description The `pmmFind` function returns the address of the memory block associated with the specified handle. The `entryPoint` identifier is of type function pointer and is a far address. It must be assigned the value of the `EntryPoint` field in the PMM structure before it can be called. The return value is of type `unsigned long` and represents the 32-bit physical memory address of the memory block that is associated with the handle. A return value of `0x00000000` indicates that the handle does not correspond to a currently allocated memory block. ### 3.4.2 Function Prototype ```c unsigned long (*entryPoint)( unsigned int function, // 1 for pmmFind unsigned long handle // handle assigned to memory block ); ``` ### 3.4.3 Parameters - **function** 1 for `pmmFind`. Invalid values for the function parameter (`0x0003...0xFFFF`) cause an error value of `0xFFFFFFFF` to be returned, signaling that the function is not supported. - **handle** An identifier specified by the client that was assigned to a memory block when the `pmmAllocate` function was called. If called with an anonymous handle (`0xFFFFFFFF`) or a currently undefined handle, a value of `0x00000000` will be returned indicating that no associated memory block was found. ## 3.5 pmmDeallocate - Function 2 ### 3.5.1 Description The `pmmDeallocate` function frees the specified memory block that was previously allocated by `pmmAllocate`. Memory blocks are not cleared to all zeros by the PMM before being deallocated. Memory below 1MB is cleared by the BIOS before the OS boot, but deallocated extended memory blocks in particular will not explicitly be cleared. Clients of the PMM should not rely on the contents of deallocated memory blocks. #################### File: 3%20BIOS%20Disassembly%20Ninjutsu%20Uncovered%201st%20Edition%20-%20Darmawan%20Salihun%20%28PDF%29%20POST_Memory_Manager_Specification.pdf Page: 16 Context: # Support of Multiple Structures With One Named Block ## XYZ0000 ### Dir ``` Buffer ``` ``` BootStruct ``` ``` BootStruct ``` ### Key - **Anonymous Block** - **Named Block** - **Null Pointer** ## 4.3 Finding Other Cards in the System The use of PnP IDs for named handles has another consequence: it makes it possible to perform a simplified search for other similar cards in the system. Assume that XYZ's Option ROMs always attempt to allocate a block of memory named "XYZ0000". If two of XYZ's Option ROMs exist in the same system, the second request to allocate will fail. If the company's Option ROMs instead do a `pnmFind` for the handle XYZ0000 prior to attempting to allocate memory with the same handle, the Option ROM can use the previously initialized allocation. In companies with more complex product lines, each set of products may need to use a different "family" ID (e.g., XYZ0000 for one family, XYZ0100 for another, etc.). Pseudocode implementing multiple card support is shown below. ```c #define NoId 0xFFFFFFFF #define XYZ0000 ((*(Y->A+1) << 26) | \ ((*(Y->A+1) << 21) | \ ((*(Y->A+1) << 16)) struct dir { struct dir *nextcard; // point to next directory byte *buffer; struct BootStruct *boot; int cardsCs; }; // ... struct dir *base, *t; // pnmAllocate is assumed to be defined as above. if ((base = (*(entryPoint)(PMM_FIND, XYZ0000) != 0) { t = pnmAllocate(NoId, (sizeof(dir) + 15) / 16); t->nextcard = base->nextcard; base = t; } ``` #################### File: 3%20BIOS%20Disassembly%20Ninjutsu%20Uncovered%201st%20Edition%20-%20Darmawan%20Salihun%20%28PDF%29%20POST_Memory_Manager_Specification.pdf Page: 17 Context: ```markdown ) else { base = pmAlloc(XYZ0000, (sizeof(dir) + 15) / 16); base->nextcard = NULL; } // ... base->buffer = pmAlloc(NoId, (BufLen + 15) / 16); base->cardsCS = GetOurCodeSegment(); // ... base->boot = NULL; for each device i { // do stuff if (device is bootable) { t = pmAlloc(NoId, (sizeof(BootStruct) + 15) / 16); t->next = base->boot; base->boot = t; } } Visually, the resulting data structure looks like this: # Support of Multiple Cards With One Named Block ``` XYZ0000 ├── Dir │ ├── 0D000h │ │ └── (Card 1) └── Dir ├── 0D800h │ └── (Card 2) │ ├── Buffer │ └── Buffer └── BootStruct ├── BootStruct └── BootStruct ``` ## Key - ☐ Anonymous Block - ── Named Block - -- Null Pointer [ End of Specification ] ``` ########## """QUERY: Please summarize the whole context. It is important that you include a summary for each file. All files should be included, so please make sure to go through the entire context""" Consider the chat history for relevant information. Use all information included. Use as much tokens as needed. Important: If you find information separated by a | in the context, it is a table formatted in Markdown. Final Files Sources: 1%20A%20short%20introduction%20to%20operating%20systems%20%282001%29%20-%20Mark%20Burgess%20%28PDF%29.pdf - Page 1, 1%20A%20short%20introduction%20to%20operating%20systems%20%282001%29%20-%20Mark%20Burgess%20%28PDF%29.pdf - Page 2, 1%20A%20short%20introduction%20to%20operating%20systems%20%282001%29%20-%20Mark%20Burgess%20%28PDF%29.pdf - Page 3, 1%20A%20short%20introduction%20to%20operating%20systems%20%282001%29%20-%20Mark%20Burgess%20%28PDF%29.pdf - Page 4, 1%20A%20short%20introduction%20to%20operating%20systems%20%282001%29%20-%20Mark%20Burgess%20%28PDF%29.pdf - Page 5, 1%20A%20short%20introduction%20to%20operating%20systems%20%282001%29%20-%20Mark%20Burgess%20%28PDF%29.pdf - Page 6, 1%20A%20short%20introduction%20to%20operating%20systems%20%282001%29%20-%20Mark%20Burgess%20%28PDF%29.pdf - Page 7, 1%20A%20short%20introduction%20to%20operating%20systems%20%282001%29%20-%20Mark%20Burgess%20%28PDF%29.pdf - Page 8, 1%20A%20short%20introduction%20to%20operating%20systems%20%282001%29%20-%20Mark%20Burgess%20%28PDF%29.pdf - Page 9, 1%20A%20short%20introduction%20to%20operating%20systems%20%282001%29%20-%20Mark%20Burgess%20%28PDF%29.pdf - Page 10, 1%20A%20short%20introduction%20to%20operating%20systems%20%282001%29%20-%20Mark%20Burgess%20%28PDF%29.pdf - Page 12, 1%20A%20short%20introduction%20to%20operating%20systems%20%282001%29%20-%20Mark%20Burgess%20%28PDF%29.pdf - Page 13, 1%20A%20short%20introduction%20to%20operating%20systems%20%282001%29%20-%20Mark%20Burgess%20%28PDF%29.pdf - Page 14, 1%20A%20short%20introduction%20to%20operating%20systems%20%282001%29%20-%20Mark%20Burgess%20%28PDF%29.pdf - Page 15, 1%20A%20short%20introduction%20to%20operating%20systems%20%282001%29%20-%20Mark%20Burgess%20%28PDF%29.pdf - Page 18, 1%20A%20short%20introduction%20to%20operating%20systems%20%282001%29%20-%20Mark%20Burgess%20%28PDF%29.pdf - Page 19, 1%20A%20short%20introduction%20to%20operating%20systems%20%282001%29%20-%20Mark%20Burgess%20%28PDF%29.pdf - Page 20, 1%20A%20short%20introduction%20to%20operating%20systems%20%282001%29%20-%20Mark%20Burgess%20%28PDF%29.pdf - Page 21, 1%20A%20short%20introduction%20to%20operating%20systems%20%282001%29%20-%20Mark%20Burgess%20%28PDF%29.pdf - Page 22, 1%20A%20short%20introduction%20to%20operating%20systems%20%282001%29%20-%20Mark%20Burgess%20%28PDF%29.pdf - Page 23, 1%20A%20short%20introduction%20to%20operating%20systems%20%282001%29%20-%20Mark%20Burgess%20%28PDF%29.pdf - Page 24, 1%20A%20short%20introduction%20to%20operating%20systems%20%282001%29%20-%20Mark%20Burgess%20%28PDF%29.pdf - Page 25, 1%20A%20short%20introduction%20to%20operating%20systems%20%282001%29%20-%20Mark%20Burgess%20%28PDF%29.pdf - Page 26, 1%20A%20short%20introduction%20to%20operating%20systems%20%282001%29%20-%20Mark%20Burgess%20%28PDF%29.pdf - Page 27, 1%20A%20short%20introduction%20to%20operating%20systems%20%282001%29%20-%20Mark%20Burgess%20%28PDF%29.pdf - Page 28, 1%20A%20short%20introduction%20to%20operating%20systems%20%282001%29%20-%20Mark%20Burgess%20%28PDF%29.pdf - Page 29, 1%20A%20short%20introduction%20to%20operating%20systems%20%282001%29%20-%20Mark%20Burgess%20%28PDF%29.pdf - Page 30, 1%20A%20short%20introduction%20to%20operating%20systems%20%282001%29%20-%20Mark%20Burgess%20%28PDF%29.pdf - Page 31, 1%20A%20short%20introduction%20to%20operating%20systems%20%282001%29%20-%20Mark%20Burgess%20%28PDF%29.pdf - Page 32, 1%20A%20short%20introduction%20to%20operating%20systems%20%282001%29%20-%20Mark%20Burgess%20%28PDF%29.pdf - Page 33, 1%20A%20short%20introduction%20to%20operating%20systems%20%282001%29%20-%20Mark%20Burgess%20%28PDF%29.pdf - Page 34, 1%20A%20short%20introduction%20to%20operating%20systems%20%282001%29%20-%20Mark%20Burgess%20%28PDF%29.pdf - Page 35, 1%20A%20short%20introduction%20to%20operating%20systems%20%282001%29%20-%20Mark%20Burgess%20%28PDF%29.pdf - Page 36, 1%20A%20short%20introduction%20to%20operating%20systems%20%282001%29%20-%20Mark%20Burgess%20%28PDF%29.pdf - Page 37, 1%20A%20short%20introduction%20to%20operating%20systems%20%282001%29%20-%20Mark%20Burgess%20%28PDF%29.pdf - Page 38, 1%20A%20short%20introduction%20to%20operating%20systems%20%282001%29%20-%20Mark%20Burgess%20%28PDF%29.pdf - Page 39, 1%20A%20short%20introduction%20to%20operating%20systems%20%282001%29%20-%20Mark%20Burgess%20%28PDF%29.pdf - Page 40, 1%20A%20short%20introduction%20to%20operating%20systems%20%282001%29%20-%20Mark%20Burgess%20%28PDF%29.pdf - Page 43, 1%20A%20short%20introduction%20to%20operating%20systems%20%282001%29%20-%20Mark%20Burgess%20%28PDF%29.pdf - Page 47, 1%20A%20short%20introduction%20to%20operating%20systems%20%282001%29%20-%20Mark%20Burgess%20%28PDF%29.pdf - Page 48, 1%20A%20short%20introduction%20to%20operating%20systems%20%282001%29%20-%20Mark%20Burgess%20%28PDF%29.pdf - Page 52, 1%20A%20short%20introduction%20to%20operating%20systems%20%282001%29%20-%20Mark%20Burgess%20%28PDF%29.pdf - Page 53, 1%20A%20short%20introduction%20to%20operating%20systems%20%282001%29%20-%20Mark%20Burgess%20%28PDF%29.pdf - Page 56, 1%20A%20short%20introduction%20to%20operating%20systems%20%282001%29%20-%20Mark%20Burgess%20%28PDF%29.pdf - Page 60, 1%20A%20short%20introduction%20to%20operating%20systems%20%282001%29%20-%20Mark%20Burgess%20%28PDF%29.pdf - Page 61, 1%20A%20short%20introduction%20to%20operating%20systems%20%282001%29%20-%20Mark%20Burgess%20%28PDF%29.pdf - Page 62, 1%20A%20short%20introduction%20to%20operating%20systems%20%282001%29%20-%20Mark%20Burgess%20%28PDF%29.pdf - Page 63, 1%20A%20short%20introduction%20to%20operating%20systems%20%282001%29%20-%20Mark%20Burgess%20%28PDF%29.pdf - Page 64, 1%20A%20short%20introduction%20to%20operating%20systems%20%282001%29%20-%20Mark%20Burgess%20%28PDF%29.pdf - Page 65, 1%20A%20short%20introduction%20to%20operating%20systems%20%282001%29%20-%20Mark%20Burgess%20%28PDF%29.pdf - Page 66, 1%20A%20short%20introduction%20to%20operating%20systems%20%282001%29%20-%20Mark%20Burgess%20%28PDF%29.pdf - Page 67, 1%20A%20short%20introduction%20to%20operating%20systems%20%282001%29%20-%20Mark%20Burgess%20%28PDF%29.pdf - Page 68, 1%20A%20short%20introduction%20to%20operating%20systems%20%282001%29%20-%20Mark%20Burgess%20%28PDF%29.pdf - Page 69, 1%20A%20short%20introduction%20to%20operating%20systems%20%282001%29%20-%20Mark%20Burgess%20%28PDF%29.pdf - Page 70, 1%20A%20short%20introduction%20to%20operating%20systems%20%282001%29%20-%20Mark%20Burgess%20%28PDF%29.pdf - Page 71, 1%20A%20short%20introduction%20to%20operating%20systems%20%282001%29%20-%20Mark%20Burgess%20%28PDF%29.pdf - Page 72, 1%20A%20short%20introduction%20to%20operating%20systems%20%282001%29%20-%20Mark%20Burgess%20%28PDF%29.pdf - Page 73, 1%20A%20short%20introduction%20to%20operating%20systems%20%282001%29%20-%20Mark%20Burgess%20%28PDF%29.pdf - Page 74, 1%20A%20short%20introduction%20to%20operating%20systems%20%282001%29%20-%20Mark%20Burgess%20%28PDF%29.pdf - Page 75, 1%20A%20short%20introduction%20to%20operating%20systems%20%282001%29%20-%20Mark%20Burgess%20%28PDF%29.pdf - Page 76, 1%20A%20short%20introduction%20to%20operating%20systems%20%282001%29%20-%20Mark%20Burgess%20%28PDF%29.pdf - Page 77, 1%20A%20short%20introduction%20to%20operating%20systems%20%282001%29%20-%20Mark%20Burgess%20%28PDF%29.pdf - Page 78, 1%20A%20short%20introduction%20to%20operating%20systems%20%282001%29%20-%20Mark%20Burgess%20%28PDF%29.pdf - Page 79, 1%20A%20short%20introduction%20to%20operating%20systems%20%282001%29%20-%20Mark%20Burgess%20%28PDF%29.pdf - Page 80, 1%20A%20short%20introduction%20to%20operating%20systems%20%282001%29%20-%20Mark%20Burgess%20%28PDF%29.pdf - Page 81, 1%20A%20short%20introduction%20to%20operating%20systems%20%282001%29%20-%20Mark%20Burgess%20%28PDF%29.pdf - Page 82, 1%20A%20short%20introduction%20to%20operating%20systems%20%282001%29%20-%20Mark%20Burgess%20%28PDF%29.pdf - Page 83, 1%20A%20short%20introduction%20to%20operating%20systems%20%282001%29%20-%20Mark%20Burgess%20%28PDF%29.pdf - Page 84, 1%20A%20short%20introduction%20to%20operating%20systems%20%282001%29%20-%20Mark%20Burgess%20%28PDF%29.pdf - Page 85, 1%20A%20short%20introduction%20to%20operating%20systems%20%282001%29%20-%20Mark%20Burgess%20%28PDF%29.pdf - Page 86, 1%20A%20short%20introduction%20to%20operating%20systems%20%282001%29%20-%20Mark%20Burgess%20%28PDF%29.pdf - Page 87, 1%20A%20short%20introduction%20to%20operating%20systems%20%282001%29%20-%20Mark%20Burgess%20%28PDF%29.pdf - Page 88, 1%20A%20short%20introduction%20to%20operating%20systems%20%282001%29%20-%20Mark%20Burgess%20%28PDF%29.pdf - Page 89, 1%20A%20short%20introduction%20to%20operating%20systems%20%282001%29%20-%20Mark%20Burgess%20%28PDF%29.pdf - Page 90, 1%20A%20short%20introduction%20to%20operating%20systems%20%282001%29%20-%20Mark%20Burgess%20%28PDF%29.pdf - Page 91, 1%20A%20short%20introduction%20to%20operating%20systems%20%282001%29%20-%20Mark%20Burgess%20%28PDF%29.pdf - Page 92, 1%20A%20short%20introduction%20to%20operating%20systems%20%282001%29%20-%20Mark%20Burgess%20%28PDF%29.pdf - Page 93, 1%20A%20short%20introduction%20to%20operating%20systems%20%282001%29%20-%20Mark%20Burgess%20%28PDF%29.pdf - Page 94, 1%20A%20short%20introduction%20to%20operating%20systems%20%282001%29%20-%20Mark%20Burgess%20%28PDF%29.pdf - Page 95, 1%20A%20short%20introduction%20to%20operating%20systems%20%282001%29%20-%20Mark%20Burgess%20%28PDF%29.pdf - Page 96, 1%20A%20short%20introduction%20to%20operating%20systems%20%282001%29%20-%20Mark%20Burgess%20%28PDF%29.pdf - Page 97, 1%20A%20short%20introduction%20to%20operating%20systems%20%282001%29%20-%20Mark%20Burgess%20%28PDF%29.pdf - Page 98, 1%20A%20short%20introduction%20to%20operating%20systems%20%282001%29%20-%20Mark%20Burgess%20%28PDF%29.pdf - Page 100, 1%20A%20short%20introduction%20to%20operating%20systems%20%282001%29%20-%20Mark%20Burgess%20%28PDF%29.pdf - Page 101, 1%20A%20short%20introduction%20to%20operating%20systems%20%282001%29%20-%20Mark%20Burgess%20%28PDF%29.pdf - Page 103, 1%20A%20short%20introduction%20to%20operating%20systems%20%282001%29%20-%20Mark%20Burgess%20%28PDF%29.pdf - Page 104, 1%20A%20short%20introduction%20to%20operating%20systems%20%282001%29%20-%20Mark%20Burgess%20%28PDF%29.pdf - Page 105, 1%20A%20short%20introduction%20to%20operating%20systems%20%282001%29%20-%20Mark%20Burgess%20%28PDF%29.pdf - Page 107, 1%20A%20short%20introduction%20to%20operating%20systems%20%282001%29%20-%20Mark%20Burgess%20%28PDF%29.pdf - Page 108, 1%20A%20short%20introduction%20to%20operating%20systems%20%282001%29%20-%20Mark%20Burgess%20%28PDF%29.pdf - Page 110, 1%20A%20short%20introduction%20to%20operating%20systems%20%282001%29%20-%20Mark%20Burgess%20%28PDF%29.pdf - Page 111, 1%20A%20short%20introduction%20to%20operating%20systems%20%282001%29%20-%20Mark%20Burgess%20%28PDF%29.pdf - Page 112, 1%20A%20short%20introduction%20to%20operating%20systems%20%282001%29%20-%20Mark%20Burgess%20%28PDF%29.pdf - Page 113, 1%20A%20short%20introduction%20to%20operating%20systems%20%282001%29%20-%20Mark%20Burgess%20%28PDF%29.pdf - Page 116, 1%20A%20short%20introduction%20to%20operating%20systems%20%282001%29%20-%20Mark%20Burgess%20%28PDF%29.pdf - Page 119, 1%20A%20short%20introduction%20to%20operating%20systems%20%282001%29%20-%20Mark%20Burgess%20%28PDF%29.pdf - Page 120, 1%20A%20short%20introduction%20to%20operating%20systems%20%282001%29%20-%20Mark%20Burgess%20%28PDF%29.pdf - Page 122, 1%20A%20short%20introduction%20to%20operating%20systems%20%282001%29%20-%20Mark%20Burgess%20%28PDF%29.pdf - Page 124, 1%20A%20short%20introduction%20to%20operating%20systems%20%282001%29%20-%20Mark%20Burgess%20%28PDF%29.pdf - Page 125, 1%20A%20short%20introduction%20to%20operating%20systems%20%282001%29%20-%20Mark%20Burgess%20%28PDF%29.pdf - Page 127, 1%20A%20short%20introduction%20to%20operating%20systems%20%282001%29%20-%20Mark%20Burgess%20%28PDF%29.pdf - Page 130, 1%20A%20short%20introduction%20to%20operating%20systems%20%282001%29%20-%20Mark%20Burgess%20%28PDF%29.pdf - Page 131, 1%20A%20short%20introduction%20to%20operating%20systems%20%282001%29%20-%20Mark%20Burgess%20%28PDF%29.pdf - Page 133, 1%20A%20short%20introduction%20to%20operating%20systems%20%282001%29%20-%20Mark%20Burgess%20%28PDF%29.pdf - Page 135, 1%20A%20short%20introduction%20to%20operating%20systems%20%282001%29%20-%20Mark%20Burgess%20%28PDF%29.pdf - Page 136, 1%20A%20short%20introduction%20to%20operating%20systems%20%282001%29%20-%20Mark%20Burgess%20%28PDF%29.pdf - Page 137, 1%20A%20short%20introduction%20to%20operating%20systems%20%282001%29%20-%20Mark%20Burgess%20%28PDF%29.pdf - Page 138, 1%20A%20short%20introduction%20to%20operating%20systems%20%282001%29%20-%20Mark%20Burgess%20%28PDF%29.pdf - Page 139, 1%20A%20short%20introduction%20to%20operating%20systems%20%282001%29%20-%20Mark%20Burgess%20%28PDF%29.pdf - Page 140, 2%20Project%20Oberon%20The%20Design%20of%20an%20Operating%20System%2C%20a%20Compiler%2C%20and%20a%20Computer%20-%20Niklaus%20Wirth%2C%20J%C3%BCrg%20Gutknecht%20%28PDF%29%20%20UsingOberon.pdf - Page 2, 2%20Project%20Oberon%20The%20Design%20of%20an%20Operating%20System%2C%20a%20Compiler%2C%20and%20a%20Computer%20-%20Niklaus%20Wirth%2C%20J%C3%BCrg%20Gutknecht%20%28PDF%29%20%20UsingOberon.pdf - Page 3, 2%20Project%20Oberon%20The%20Design%20of%20an%20Operating%20System%2C%20a%20Compiler%2C%20and%20a%20Computer%20-%20Niklaus%20Wirth%2C%20J%C3%BCrg%20Gutknecht%20%28PDF%29%20%20UsingOberon.pdf - Page 4, 3%20BIOS%20Disassembly%20Ninjutsu%20Uncovered%201st%20Edition%20-%20Darmawan%20Salihun%20%28PDF%29%20POST_Memory_Manager_Specification.pdf - Page 1, 3%20BIOS%20Disassembly%20Ninjutsu%20Uncovered%201st%20Edition%20-%20Darmawan%20Salihun%20%28PDF%29%20POST_Memory_Manager_Specification.pdf - Page 2, 3%20BIOS%20Disassembly%20Ninjutsu%20Uncovered%201st%20Edition%20-%20Darmawan%20Salihun%20%28PDF%29%20POST_Memory_Manager_Specification.pdf - Page 3, 3%20BIOS%20Disassembly%20Ninjutsu%20Uncovered%201st%20Edition%20-%20Darmawan%20Salihun%20%28PDF%29%20POST_Memory_Manager_Specification.pdf - Page 7, 3%20BIOS%20Disassembly%20Ninjutsu%20Uncovered%201st%20Edition%20-%20Darmawan%20Salihun%20%28PDF%29%20POST_Memory_Manager_Specification.pdf - Page 8, 3%20BIOS%20Disassembly%20Ninjutsu%20Uncovered%201st%20Edition%20-%20Darmawan%20Salihun%20%28PDF%29%20POST_Memory_Manager_Specification.pdf - Page 9, 3%20BIOS%20Disassembly%20Ninjutsu%20Uncovered%201st%20Edition%20-%20Darmawan%20Salihun%20%28PDF%29%20POST_Memory_Manager_Specification.pdf - Page 16, 3%20BIOS%20Disassembly%20Ninjutsu%20Uncovered%201st%20Edition%20-%20Darmawan%20Salihun%20%28PDF%29%20POST_Memory_Manager_Specification.pdf - Page 17 ================================================== **Elapsed Time: 15.47 seconds** ================================================== FINAL ANSWER Answer: ================================================== **Elapsed Time: 0.00 seconds** ==================================================