Vous êtes sur la page 1sur 251

LITERATURE

1983 will be a year of transition for Intel's catalog program. In order to better serve you, our customers, we are reorganizing many of our catalogs to more completely reflect product groups. In addition to the new product line handbooks listed below, an INTEL PRODUCT GUIDE (Order No. 210846) will be available free of charge in March. This GUIDE will contain a listing of Intel's complete product line along with information on quality/reliability, packaging and ordering, customer training classes and product services. Consult the Intel Literature Guide (no charge, Order No. 210620) for a complete listing of Intel literature. Literature is presently available in other forms for those handbooks that will not be published until later in the year. Write or call the Intel Literature Department, 3065 Bowers Avenue, Santa Clara, CA 95051, (800) 538-1876, or (800) 672-1833 (California only).

HANDBOOKS
Memory Components Handbook (Order No. 210830) Contains all application notes, article reprints, data sheets and other design information on RAMs, DRAMs, EPROMs, E2 PROMs, Bubble Memories. Microcontroller Handbook (Available in May) Contains all application notes, article reprints, data sheets, and other user information on the MCS-48, MCS-51 (8-bit) and the new MCS-96 (16-bit) product families. Military Handbook (Order No. 210461) Contains complete data sheets on all military products. Microprocessor and Peripherals Handbook (Order No. 210844) Contains data sheets on all microprocessors and peripherals. (Individual User Manuals are also available on the 8085, 8086, 8088, 186, 286, etc.) Development Systems Handbook (Available in April) Contains data sheets on development systems and supporting software. OEM Systems Handbook (Available in May) Contains all application notes, article reprints and data sheets for OEM boards and systems. Software Handbook (Available in May) Contains software product overview as well as data sheets for all Intel software. Quality/Reliability Standards Handbook (Available in April)

iAPX 286 OPERATING SYSTEMS WRITER'S GUIDE


1983

Intel Corporation makes no warranty for the use of its products and assumes no responsibility for any errors which may appear in this document nor does it make a commitment to update the information contained herein. Intel retains the right to make changes to these specifications at any time, without notice. Contact your local sales office to obtain the latest specifications before placing your order. The following are trademarks of Intel Corporation and may only be used to identify Intel Products:
2 BXp, CREDIT, i, ICE, 1 1CE, ICS, iDBP, iDIS, iLBX, i m , iMMX, Insite, INTEL, intel, Intelevision, Intellec, inteligent Identifier, intelBOS, inteligent Programming, Intellink, iOSp, iPDS, iRMS, iSBC, iSBX, iSDM, iSXM, Library Manager, MCS, Megachassis, Micromainframe, MULTIBUS, Multichannel Plug-A-Bubble, MULTIMODULE, PROMPT, Ripplemode, RMX/80, RUPI, System 2000, and UPI, and the combination of ICE, iCS, iRMX, iSBC, MCS, or UPI and a numerical suffix.

MDS is an ordering code only and is not used as a product name or trademark. MDSE is a registered trademark of Mohawk Data Sciences Corporation. ' MULTIBUS is a patented Intel bus. Additional copies of this manual or other Intel literature may be obtained from: Intel Corporation Literature Department 3065 Bowers Avenue Santa Clara, CA 95051

@ INTEL CORPORATION. 1983

ii

PREFACE
This book is written for systems designers and operating system designers and programmers who plan to use the Intel iAPX 286 microprocessor in its protected, virtual-address mode. The protected-mode iAPX 286 is designed for multitasking systems: systems that serve many users or that simultaneously run several programs. This book analyzes operating system functions that are appropriate for the iAPX 286 when used in a variety of multitasking applications, including Communications, such as automated PBXs Real-time, such as instrumentation or process control Multi-user, such as time-sharing or office systems

Many of the features of the iAPX 286 are intended for use by an operating system. This book identifies and explains those features and gives examples of how they can be used in an operating system.

AUDIENCE
This book assumes that you have a knowledge of multitasking operating systems at least equivalent to that presented in introductory undergraduate textbooks on the subject. It also assumes that you have had some exposure to the architecture of the iAPX 286 through attending an introductory course or reading introductory literature such as Introduction to the iAPX 286.

RELATED PUBLICATIONS

Intel Literature
The following manuals contain additional information of use to operating-system designers and programmers:

ASM286 Assembly Language Reference Manual, 121924 Component Data Catalog, 210298 iAPX 286 Architecture Extension Kernel (K286) User's Guide, 121961 iAPX 286 Programmer's Reference Manual, 210498 iAPX 286 System Builder User's Guide, 121935 iAPX 286 Utilities User's Guide, 121934 iAPX 286/10 High Performance Microprocessor with Memory Management and Protection (Data Sheet),210253 Introduction to the iAPX 286, 210308 PL/M-286 User's Guide, 121945

iii

121960-001

PREFACE

External Literature
Many aspects of operating system construction for the iAPX 286 are the same as for other processors. The following are sources of generally applicable theories and algorithms referred to in the text of this book. Coffman, E.G., Jr., and Peter J. Denning, Operating Systems Theory (Englewood Cliffs, N.J.: Prentice-Hall,1973) Denning, Peter J., "Virtual Memory," Computing Surveys, Vol. 2, No.3 (September 1970) Knuth, Donald E., Fundamental Algorithms, Vol. 1 (Reading, Mass.: Addison-Wesley, 1973) Peterson, James L., Petri Net Theory and the Modeling of Systems (Englewood Cliffs, N.J.: PrenticeHall, 1981)

RELATED PRODUCTS
Designers interested in operating systems for the protected-mode iAPX 286 should also be aware of Intel's iAPX 286 Architecture Extension Kernel K28. K286 is an operating-system kernel designed for a wide variety of applications, including real-time, communications, business systems, and timesharing. K286 provides Short-term, priority scheduling and management of multiple tasks Interrupt management Multiprocessor support Virtual memory support Data sharing among tasks with synchronization Intertask signals and messages Extended protection

Whether you use K286 "as is," for greatest possible efficiency, or whether you add layers of software to more fully support your applications, K286 can significantly reduce your system development time. Since K286 has been designed by the architects of the iAPX 286 and implemented and tested by Intel's software engineers, using K286 can make your system more reliable. K286 implements many of the concepts discussed in this book, which can therefore give you additional understanding of why and how to use K286.

HOW TO USE THIS MANUAL


This manual has two related objectives: To identify features of the iAPX 286 architecture that are unique when applied to the implementation of an operating system To show how you can effectively use these unique features in the design of familiar operating system functions

iv

121960-001

PREFACE

In pursuit of these objectives, Chapters 2 thru 13 share a general, three-part structure:


1.

Identifing an operating system function (or class of functions). The functions chosen are those with which you might already be familiar, since they are similar to those used in state-of-the-art operating systems such as iRMX 86 (from Intel Corporation) or UNIX (from Bell Laboratories). Reviewing the iAPX 286 features that support that function. While this portion of each chapter may cover some material available in other Intel literature, it provides added value by discussing in one place all the iAPX 286 features that bear on a given operating system function and by identifying relationships among those features. Outlining some examples of how to use those iAPX 286 features in an implementation of the identified function. It is, of course, impossible to illustrate all the ways to design any given function, but these examples serve to illustrate a few of the ways that the designers of the iAPX 286 architecture intended for it to be applied.

2.

3.

Chapter 1 introduces the iAPX 286 architecture; identifies the role of an operating system in a protected, multitasking environment; and shows how Intel's Binder and Builder utilities aid in the construction of an operating system. You may skip Chapter 1 if you are already familiar with multitasking operating systems and with the Binder and the Builder. Both Chapter 2 and Chapter 5 contain key information about manipulating the protection features of the iAPX 286. Be sure not to omit these chapters when scanning the contents of the book. For the remaining chapters, you may turn directly to the subjects that interest you most. You will find the reading easier, however, if you observe the partial orderings outlined in table 0-1.

NOTATIONAL CONVENTIONS

UPPERCASE
italic system-id

Characters shown in uppercase must be entered in the order shown. You may enter the characters in uppercase or lowercase. Italic indicates a meta symbol that may be replaced with an item that fulfills the rules for that symbol. The actual symbol may be any of the following: Is a generic label placed on sample listings where an operating systemdependent name would actually be printed. Is a generic label placed on sample listings where the version number of the product that produced the listing would actually be printed.
Table 0-1. Prerequisites by Chapter
Target Chapter Prerequisites

Vx.y

6 7
8 9 12

4 6 4, 6 6,7 4,6,7

121960-001

Table of Contents
CHAPTER 1 INTRODUCTION TO PROTECTED MULTITASKING ON THE iAPX 286 Tasks ............................................................................................................ Structure of a Program .............................................................................. Segmented Memory .................................................................................. Multitasking ............................................................................................... Privilege Levels .............................................................................................. Levels of Segments ............................................................... ..................... Rules of Privilege ....................................................................................... Software System Structure ........................................................................... Role of the Operating System ...................................................................... Common O.S. Functions ........................................................................... O.S. Functions in a Dynamic Environment ...... .......... ........ ......................... Constructing the Initial Run-Time Environment ............................................. Building a Static System ............................................................................ Building a Dynamic System .......................................................................
Page

1-1 1-1 1-1 1-1 1-3 1-4 1-4 1-4 1-6 1-7 1-8 1-8 1-9 1-9

CHAPTER 2 USING HARDWARE PROTECTION FEATURES Addressing Mechanism ................................................................................ . Descriptors .................................................................................................... Descriptor Format ..................................................................................... . Control Flow Transfer .................................................................................. . Gate Descriptors .......... ~ ........................................................................... . Control Transfer Mechanisms ................................................................... . Privilege Rules for Gated Intersegment Transfers .................................... . Descriptor Tables .......................................................................................... Local Descriptor Table .............................................................................. . Global Descriptor Table ............................................................................ . Interrupt Descriptor Table ......................................................................... . Selectors ....................................................................................................... Format of Selector .................................................................................... . Null Selector .............................................................................................. Alias Descriptors ........................................................................................... Explicit Variation of Type .......................................................................... . Variation of Length ................................................................................... . Sharing Segments among Tasks .............................................................. . Protection and Integrity with Aliasing ........................................................ . Example of Descriptor Manipulation ............................................................ .. Slot Management ..........................................................................................
VI

2-1 2-2 2-2 2-7 2-8 2-9 2-11 2-12 2-14 2-14 2-15 2-15 2-15 2-17 2-17 2-18 2-18 2-19 2-19 2-20 2-22
121960-001

TABLE OF CONTENTS

CHAPTER 3 REAL MEMORY MANAGEMENT Memory Management Functions .......................... ......................................... Example of a Memory Manager .................................................................... Data Structures ......................................................................................... PL/M-286 Code ......................................................................................... Protection Structure ................................................. .......... .... .... ............... Advanced Memory Management .................................................................. CHAPTER 4 TASK MANAGEMENT Hardware Task-Management Features ...................................... ................... Storing Task State ........... .............................................. ........................... Switching Tasks ........................................................................................ Role of Operating System in Task Management ..... ;..................................... State Model of Task Scheduling ................................................................ Interfacing with the Hardware Scheduler ................................................... Changing Scheduling State ....................................................................... Structuring Task Information ..................................................................... Example of a Dispatcher ............................................................................... CHAPTER 5 DATA SHARING, ALIASING, AND SYNCHRONIZATION Data-Sharing Techniques .............................................................................. Sharing via the GOT .................................................................................. Sharing via Common LOT ......................................................................... Sharing via Aliases .................................................................................... Alias Management ......................................................................................... Alias Database .......... ..... .. .. ........... .. ............................... ....... .......... .. ..... .... Alias Procedures ........................................................................................ Synchronization ............................................................................................. Low-Level Mutual Exclusion ...................................................................... High-Level Mutual Exclusion ...................................................................... Message Passing .......................................................................................... Message-Passing Example ........................................................................ Variations on the Mailbox Theme .............................................................. CHAPTER 6 SIGNALS AND INTERRUPTS Interrupt Features of the iAPX 286 Architecture ........................................... Vectoring ....... ....... .... ... .... .. .. ................................................... ........ ......... .. Enabling and Disabling Interrupts .............................................................. Interrupt Descriptor Table .......................................................................... Interrupt Tasks and Interrupt Procedures ..................................................
vii

Page

3-1 3-1 3-2 3-6 3-7 3-10

4-1 4-1 4-3 4-4 4-5 4-6 4-7 4-10 4-13

5-1 5-1 5-1 5-2 5-3 5-3 5-3 5-4 5-5 5-6 5-10 5-10 5-16

6-1 6-1 6-2 6-2 6-2


121960-001

TABLE OF CONTENTS

Page

Operating System Responsibilities ................................................................ Manage lOT ............................................................................................... Switch Scheduling Modes ......................................................................... Manage Interrupt Controller ........................................................................ Provide Task-Level Interrupt Procedures .................................................. Provide Software Signals ..........................................................................

6-4 6-5 6-5 6-6 6-7 6-9

CHAPTER 7 HANDLING EXCEPTION CONDITIONS Fault Mechanism ........... ..................................................................... ........... Fault Recovery .............................................................................................. Locating the Faulting Instruction .......................... ...................... .... ........... Error Code ................................................................................................. Application Interface ...................................................................................... Exception Conditions .................................................................................... Interrupt O-Divide Error .......................................................... ................. Interrupt 1-Single Step ............................................................................ Interrupt 3-Breakpoint ............................................. ................................ Interrupt 4-0verflow ................................................................................ Interrupt 5-Bound Check ........................................................................ Interrupt 6-Undefined Opcode (UO) ........................................ ................. Interrupt 7-Processor Extension Not Available (NM) ............................... Interrupt 8-Double Fault (OF) .................................................................. Interrupt 9-Processor Extension Segment Overrun ................................ Interrupt 10-lnvalidTSS (TS) ........................ ;......................................... Interrupt 11-Segment.Not Present (NP) .... ................. ...... ............. .......... Interrupt 12-Stack Exception (SS) .......................................................... Interrupt 13-General Protection Exception (GP) ...................................... Interrupt 16-Processor Extension Error (MF) ............................... :.......... Interrupt 17-Run-Time Exceptions .......................................................... Restartability Summary .................................................................................

7-1 7-1 7-1 7-2 7-2 7-2 7-3 7-3 7-3 7-3 7-4 7-4 7-4 7-5 7-5 7-5 7-6 7-6 7-7 7-8 7-8 7-8

CHAPTER 8 INPUT / OUTPUT 110 and Protection ......................................................................................... 110 Privilege Level (IOPL) .......................................................................... . Controlling 110 Addresses ........................................................................ . 110 and Memory Management ..................................................................... . Partitioning 110 Functions .............................................................................. Requirements for Parallelism and Synchronization .................................. .. Requirements for Protection ..................................................................... . Implementation Alternatives .......................................................................
viii

8-1 8-1 8-2 8-3 8-3 8-4 8-4 8-5

121960-001

TABLE OF CONTENTS

CHAPTER 9 VIRTUAL MEMORY Hardware Mechanisms .................................................................................. Accessed Bit ............................................................................................. Present Bit ......................................... ,....... ,........................ ,.. .. .. ... .. .. ... .. .... Software Mechanisms .................................................................... ,............. . Secondary Storage Management .............................................................. Level Zero Support Procedures ................................................................. Swapping Managers .................................................................................. Software Policies .................................. ,................................ ,....... ,... ......... .. Fetch ......................................................................................................... Placement .................................................. ,... ... ..... .............. .... .. .. .. .... ...... .. Replacement ............................................................................................. Thrashing ...................................................................................................... CHAPTER 10 SYSTEM INITIALIZATION Initial State .................................................................................................... Switching to Protected Mode ........................................................................ Initializing for Protected Mode ....................................................................... Interrupt Vector ......................................................................................... Stack ......................................................................................................... Global Descriptor Table ............................................................................. Starting First Task ........................................................................................ . Example of Initialization ................................................................................. Initialization Module ENTP ......................................................................... CHAPTER 11 BINDING AND LOADING Binding Model ................................................................................................ Modules ..................................................................................................... Segmentation ............................................................................................ Interfaces ................................................................................................... Naming ..................................................................................................... . Timing ........................................................................................................ Implementing According to the Model .......................................................... . Source Code ............................................................................................. Compilers ................................................................................................... Binding Utilities ......................................................................................... . Overview of Loading .................................................................................... . Converting a Program into a Task ........................................................... .. iAPX 286 Object Module Format .............................................................. . Flow of Loader .................. ,........................ ,........................................ ,.... . Load-Time Binding ....................................................................................... . Example Loader ............................................................................................
ix

Page

9-1 9-1 9-1 9-2 9-2 9-3 9-4 9-6 9-6 9-6 9-7 9-8

10-1 10-1 10-2 10-2 10-2 10-2 10-2 10-3 10-3

11-1 11-1 11-2 11-2 11-3 11-3 11-3 11-4 11-4 11-5 11-8 11-9 11-10 11-11 11-12 11-12

121960-001

TABLE OF CONTENTS

CHAPTER 12 NUMERICS PROCESSOR EXTENSION iAPX 286/20 Numerics Processing Features ................................................ ESCAPE Instructions ................................................................................. Emulation Mode Flag (EM) ........................................................................ Math Present Flag (MP) ............................................................................. Task Switched Flag (TS) ........................................................................... WAIT Instruction ........................................................................................ Summary ................................................................................................... Initialization ................................................................................................... Task State .................................................................................................... Numerics Exceptions .................................................................................... Interrupt 7-Processor Extension Not Available (NM) ... .... .... ....... ... ... ... .... Interrupt 9-Processor Extension Segment Overrun (MP) ........................ Interrupt 16-Processor Extension Error (MF) .......................................... CHAPTER 13 EXTENDED PROTECTION Extended Type .............................................................................................. Type Extension Code with Descriptor ....................................................... Type Extension Code in Segment ............................................................. Indirect Naming ......................................................................................... Parameter Validation ...................... ....... ... .... ......... .......... ........... ...... ......... .. .. Defensive Use of ARPL ............................................................................. Point-of-Entry Scrutiny .............................................................................. Usage Privilege Level ...... .......................... ................... ...... .... ..... .. .... .... ........ Send Privilege Level ........... ........................... .. ............. .... .......... ... ..... .. ........ . Constructing Shared Objects ............. .... ....... ........ .............. .... ... ........ .. ......... GLOSSARY INDEX LIST OF TABLES
Table Title

Page

12-1 12-1 12-1 12-2 12-2 12-2 12-2 12-2 12-3 12-3 12-3 12-4 12-5

13-1 13-1 13-1 13-2 13-2 13-2 13-3 13-4 13-5 13-5

Page

0-1 2-1 2-2 3-1 4-1 6-1


7-1

12-1 13-1

Prerequisites by Chapter ..................................................................... . Categories of Control Flow Transfer ................................................... . Control Transfer Mechanisms ............................................................. . Actions for Combining Segments ........................................................ . Task SWitching Operations ................................................................. . Interrupt Response Time ..................................................................... . Restart Conditions ............................................................................... . Interpretation of MP and EM Flags ...................................................... . Access Checking Instructions ............................................................. .

v
2-7 2-10 3-9 4-3 6-5

7-8
12-3 13-2
121960-001

TABLE OF CONTENTS

LIST OF FIGURES
Figure Title Page

1-1 1-2 1-3 1-4


1-5

1-6
1-7 1-8

1-9
2-1

2-2
2-3 2-4 2-5 2-6 2-7 2-8 2-9 2-10 2-11 2-12 2-13 2-14 2-15 2-16 2-17

3-1
3-2

3-3
3-4 3-5 3-6 3-7 3-8 3-9

4-1
4-2 4-3

4-4
4-5 4-6

Segregation of Segments by Tasks with Private LDTs ..................... . Global Segments in System .............................................................. . Segment Segregation by Privilege Level within a Task ..................... . A Four-Level Protection Structure ..................................................... . A Two-Level Protection Structure ..................................................... . A One-Level Unprotected Structure .................................................. . Independent Operating-System Tasks .............................................. . Building a Static System ................................................................... . Building a Dynamic System ............................................................... . Abstraction of Addressing Mechanism .............................................. . Data Segment Descriptor . ~ ................................................................ . Executable Segment Descriptor ........................................................ . System Segment Descriptor ............................................................. . Calling a Conforming Segment .......................................................... . Gate Descriptor ................................................................................. . Intralevel Control Transfers ............................................................... . Gated Interlevel Call and Return ........................................................ . Valid and Invalid Interlevel Transfers ................................................. . Format of a Selector ......................................................................... . Aliasing for Debugger ........................................................................ . Aliases for System Tables ................................................................. . Aliases with Differing Limit ................................................................ . Application of Segment Sharing ....................................................... .. Aliases for Segment Sharing ............................................................. . Descriptor Manipulation Example ...................................................... . Available Slot List ............................................................................... . Memory Fragmentation ..................................................................... . Information Hiding in Memory-Management Example ....................... . Example Memory-Management Data Structures ............................... . Using Boundary Tags ........................................................................ . Hiding Boundary Tags ....................................................................... . Example GDT Layout ........................................................................ . Splitting an Available Block of Memory ............................................. . Possibilities for Combining Segments ............................................... . Code for Memory-Management Example .......................................... . Task State Segment and Register .................................................... . Scheduling State Transition Diagram ................................................ . Expanded Scheduling State Transition Diagram ............................... . Changing Scheduling Mode .............................................................. .. Task Information Structure A ............................................................ . Task Information Structure B ............................................................ .

1-2 1-3 1-4


1-6
1-7 1-8

1-9
1-10 1-11

2-1
2-3 2-4 2-5 2-6 2-9 2-11 2-12 2-13 2-16 2-17 2-18

2-19
2-20 2-21 2-23 2-26 3-2 3-3 3-4 3-5 3-6 3-7 3-8 3-11 3-15 4-2 4-5 4-6 4-8 4-11 4-12

xi

121960-001

TABLE OF CONTENTS
Title

Figure

Page

4-7 4-8 4-9 5-1 5-2 5-3 5-4 5-5 5-6 5-7 6-1 6-2 6-3 6-4 7-1 8-1 8-2 8-3 10-1 10-2 10-3 11-1 11-2 11-3 11-4 11-5 11-6 11-7 13-1

Task Information Structure C ........................................................... .. Scheduler Queue Segment ............................................................... . Dispatcher Example .......................................................................... . Segment via Common LOT ............................................................... . Alias List ............................................................................................ . Identifying Alias List .......................................................................... . Semaphore Structure ......................................................................... Semaphore Example .......................................................................... Mailbox Structure .............................................................................. . Example of Mailbox Procedures .............................................. ,......... . Interrupt Vectoring for Tasks ........................................................... .. Interrupt Vectoring for Procedures .................................................... . Interrupt Procedure's Stack .............................................................. . Private Interrupt Procedure ............................................................... . Exception Error Code ........................................................................ . Petri Net Graph Symbols ................................................................... . Synchronization with Simple Device Driver ....................................... . Synchronization with Two-Part Device Driver .................................. .. Initialization Module ENTP ................................................................. . Dummy Segments for ENTP ............................................................. . Initial Task INIT ................................................................................. . Subsystem for Kernel Exports .......................................................... . Binder Specifications for XOS Kernel ................................................ . Builder Specifications for XOS .......................................................... . Specifying Dummy Gate Exports ...................................................... . Strategy for Load-Time Binding ........................................................ . Binding Loader .................................................................................. . BOND Module of Binding Loader ...................................................... . Caller's CPL .......... ; ........................................................................... .

4-13 4-14 4-15 5-2 5-4 5-5 5-6 5-8 5-11 5-13 6-3 6-3 6-4

6-8
7-2 8-5

8-6 8-6
10-4 10-14 10-15 11-5 11-6 11-7 11-13 11-14 11-15 11-24 13-3

xii

121960-001

Introduction to Protected Multitasking on the iAPX 286

CHAPTER 1 INTRODUCTION TO PROTECTED MULTITASKING ON THE iAPX 286


The iAPX 286 architecture views the software system (the operating system as well as applications) as a number of asynchronous tasks, each task possibly consisting of levels of procedures deserving different degrees of "trust." An operating system for the iAPX 286 must (with the help of the hardware) coordinate the activities of multiple tasks and administer protection among tasks and among levels of procedures within tasks.

TASKS
A task is the execution of a sequence of steps. A program is a logical entity that can have many representations: for example, source code file or object program file. A program becomes a task when it is actually available for execution. This is achieved by converting source (with a compiler and program loader, for example) to a representation suitable for execution and notifying the operating system that the task is ready for installation and execution. The distinction between programs and tasks is most clear in a multitasking system, where it is possible for two or more tasks to use one program simultaneously. The line editor program in a timesharing system is a common example. Even though each line editor task uses the same program, each task produces different results, since it receives different inputs.

Structure of a Program
Each program is formed from modules created by language translators and bound together into a single executable unit. The translators (for example, ASM286, PL/M-286, Pascal-286, and FORTRAN-286) and the object program utilities (for example, Intel's Builder and Binder) support the concept of logical segments. A logical segment is a contiguous block of either instructions or data. Each logical segment can contain up to 64K bytes of code or data. Logical segments are the units that may be combined when a program comprises more than one module.

Segmented Memory
The iAPX 286 structures the address space of a task into physical segments of variable length. A physical segment is a contiguous block of memory that does not (normally) overlap another physical , segment. Each physical segment may contain up to 64K bytes of either instructions or data. Each physical segment contains one or more logical segments of a task. The segments reflect how tasks are organized into code, data, and stack areas.

Multitasking
One of the most important features of the iAPX 286 is its ability to switch rapidly from executing one task to executing another task. This gives the appearance that the processor is executing more than one task at a time.

1-1

121960-001

INTRODUCTION TO PROTECTED MULTITASKING ON THE iAPX 286

Hardware system tables enable both the hardware and the operating system to distinguish between the physical segments of individual tasks. Figure 1-1 shows how physical segments of one task are logically separate from those of other tasks. Since references to physical segments are always relative to system descriptor tables, the actual locations of physical segments in physical memory are not significant to the tasks and therefore are not illustrated. Descriptor tables serve not only to identify the segments that belong to a task but also to isolate the address space of one task from that of another, so that one task cannot inadvertently affect the operations of another. Multitasking works through close interaction of the operating system with hardware features. When the executing task needs to wait for some event (such as the arrival of data from some I/O device), it notifies the operating system. The operating system determines which other task should execute next, and then causes the processor to store the state of the current task, retrieve the state of the next task, and begin executing the next task at the point where its processing last halted. The processor then executes that task until the task needs to wait for some event. (This is a somewhat oversimplified

TASK A PlIM-286 COMPILATION

TASK 0 MULTIPLAN

TASKB FORTRAN ANALYZER

TASK C AEDIT'"

121960-40

Figure 11. Segregation of Segments by Tasks with Private LOTs

1-2

121960-001

INTRODUCTION TO PROTECTED MULTITASKING ON THE iAPX 286

description of what can be a complex operating system function. Chapter 4 covers the subject of task switching in more detail.) Figure 1-2 illustrates how the global descriptor table defines an address space that is accessible to all tasks in the system. This global space is useful for translation tables, run-time libraries, operatingsystem code and data, and the like.

PRIVILEGE LEVELS
The iAPX 286 architecture uses the concept of privilege levels to protect critical procedures within a task from less trusted procedures in the same task. For example, with previous generations of microprocessors, applications code could access and possibly destroy tables used by the operating system. An error of this sort could cause the operating system to incorrectly service a subsequent request from another unrelated task. With the iAPX 286, such situations are prevented by hardware-enforced barriers between different levels of procedures.

GLOBAL SPACE

LOCAL SPACES

121960-58

Figure 1-2. Global Segments in System

1-3

121960-001

INTRODUCTION TO PROTECTED MULTITASKING ON THE iAPX 286

Applied to procedures, privilege level is a measure of the degree to which you trust a procedure not to make a mistake that might affect other procedures or data. Applied to data, privilege level is a measure of the protection you think a data structure should have from less trusted procedures. Privilege level also applies to instructions. Certain instructions (those that deal with system tables, interrupts, and I/O, for example) have such an effect on the system as a whole that only highly trusted procedures should have the right to use them.

Levels of Segments
With regard to privilege, you can view the segments of a task as being grouped into four levels. Level zero is for the most privileged procedures and the most private data; level three is for the least trusted procedures and the most public data. You (or your operating system) associate each segment of each task with one of these four levels of privilege. The privilege level of a segment applies to all the procedures or all the data in that segment. Figure 1-3 illustrates the logical segregation of segments into privilege levels. (Later chapters explain why operating-system segments are included within the task.)

PRIVILEGE LEVEL

PRIVILEGE LEVEL 1

PRIVILEGE LEVEL

2
LOT PL=O PL=O PL=O PL=1 PL=1 PL=1 PL=1 PL=2 PL=2 PL=2 PL=2 PL=2 PL=3 PL=3 PL=3 PL=3 PL=3 PL=3 PL=3

PRIVILEGE LEVEL 3

} }
>121960-41

Figure 1-3. Segment Segregation by Privilege Level within a Task

1-4

121960-001

INTRODUCTION TO PROTECTED MULTITASKING ON THE iAPX 286

Rules of Privilege
The 80286 processor controls access to both data and procedures between levels of a task. These rules define access rights: Data can be accessed only from the same or a more privileged level. A procedure can be called only from the same level (or from a less privileged level, if the service is deliberately "exported" to that level. Refer to gates in Chapter 2.).

SOFTWARE SYSTEM STRUCTURE


The way you choose to distribute software and data among tasks and privilege levels affects the reliability, efficiency, and flexibility of your system. Operating-system modules may be segregated into their own tasks or may be distributed among and shared by every task. Some advantages of placing operating-system modules in separate tasks are Finer granularity of protection is achieved by using task separation as well as privilege levels. Operating-system functions can execute in parallel with the caller. When only one task at a time can perform the function (for example, reading from a keyboard), serialization of requests is automatic; you do not need to synchronize among requesting tasks.

Some advantages of distributing operating-system functions are The communication between application and operating system is faster. It may be possible for all tasks to execute the same operation-system function in parallel. (You must ensure reentrancy and provide for synchronization, however.)

Figures 1-4 through 1-7 illustrate some general approaches that you may consider. The approach shown in figure 1-4 takes maximum advantage of the four privilege levels. The critical procedures and data of the operating system kernel (for example, memory allocation tables and procedures, information about tasks) are protected from all other procedures in the system. Those parts of the operating system that are less reliable, either due to inherent complexity (for example, the I/O subsystem) or due to occasional changes (for example, policies designed to increase overall throughput), are at a lower level but are still protected from application levels. Application logic has two levels so that application services (such as database management) can be protected from less trusted application code, yet application services cannot affect the integrity of the operating system. Operatingsystem procedures and application services are shared among all the tasks in the system. Figure 1-5 illustrates that you do not need to use all four privilege levels. You may prefer this two-level approach if you are converting from a traditional multitasking system that offers protection only between the two levels defined by application and operating system. The iAPX 286 can also emulate one-level systems, as illustrated in figure 1-6. This approach may be useful in the initial stages of converting from an unprotected system, but it does not take advantage of many of the protection features offered by the iAPX 286. It does isolate tasks from one another, but it does not protect the operating system from applications software. Some operating system functions are better structured as independent operating-system tasks, not as privileged procedures within a task. Certain I/O functions are suited to this treatment. Because of the complexity of I/O code, the extra protection offered by a task boundary contributes to the reliability

1-5

121960-001

INTRODUCTION TO PROTECTED MULTITASKING ON THE iAPX 286

GLOBAL SPACE

D~~~~:~ING

TASK B

APPLICATION

121960-43

Figure 1-4. A Four-Level Protection Structure

of the system. Because many I/O functions involve waiting for responses from I/O devices, it is most convenient to treat these functions as a separate task that can run asynchronously with respect to the tasks that invoke them. Figure 1-7 illustrates a structure with independent operating-system tasks.

ROLE OF THE OPERATING SYSTEM


The role that an operating system may play in managing a multitasking execution environment depends on the nature of the application. Applications can be classified according to the volatility of tasks

1-6

121960-001

INTRODUCTION TO PROTECTED MULTITASKING ON THE iAPX 286

GLOBAL SPACE

D D

OPERATING SYSTEM

TASK

B
APPLICATION

121960-44

Figure 1-5. A Two-Level Protection Structure

executing over a period of time. Applications in which tasks frequently begin and end (for example, time-sharing systems or multi-user business systems) are called dynamic systems. Applications in which the mix of tasks does not change (for example, process control systems in which tasks service a fixed number of sensors and effectors) are called static systems.

Common 0.5. Functions


The operating-system roles common to both static and dynamic applications are Allocation of the processor or processors to tasks Coordination and communication among cooperating tasks Processing of interrupts and exception conditions Standardization of interfaces to I/0 devices Control of the numerics processor extension

1-7

121960-001

inter

INTRODUCTION TO PROTECTED MULTITASKING ON THE iAPX 286

GLOBAL SPACE

~ ~

APPLICATION DATA

121960-45

Figure 1-6. A One-Level Unprotected Structure

O.S. Functions in a Dynamic Environment


Even though many of the duties of an operating system in a dynamic environment resemble those in a static environment, the dynamic environment often introduces new complexities_ Some additional functions that a dynamic system may require include . Real memory management Program loading Command language interface Virtual memory management Load-time binding

CONSTRUCTING THE INITIAL RUN-TIME ENVIRONMENT


Intel's System Builder program helps you create the initial executable system. The Builder program collects object modules into one module, assigns physical addresses, creates system tables, and assigns privilege levels. A specification language gives you the ability to control precisely what the Builder does.

1-8

121960-001

INTRODUCTION TO PROTECTED MULTITASKING ON THE iAPX 286

APPLICA TrONS TASKS

OPERATING-SYSTEM TASKS

OPERATING SYSTEM APPLICATIONS

121960-1

Figure 1-7. Independent Operating-System Tasks

Building a Static System


In the case of static systems, the Builder does nearly all the work in constructing a running system. Refer to figure 1-8 for an illustration of the building process. The output of the Builder is a single module that contains all the tasks, both for the operating system and for applications, as well as all system tables and protection information. The Builder's output file has a format that simplifies creation of a bootstrap loader for the system.

Building a Dynamic System


With dynamic systems, the Builder constructs as much of the final system as you can specify in advance, but the nature of dynamic systems is such that the operating system must do at run-time many of the operations that the Builder does for static systems (for example, allocation of memory and assignment of physical addresses). The operating system must update system tables and administer the protection mechanisms as the running environment changes.

1-9

121960-001

INTRODUCTION TO PROTECTED MULTITASKING ON THE iAPX 286

Figure 1-9 illustrates the process of constructing a dynamic system. The Builder creates a loadable module containing those operating-system functions that permanently reside in the running operating system, and it also creates a file that contains information about linking to operating-system primitives. Either a static linker (such as Intel's Binder) or a dynamically linking loader can use this information to help dynamically loaded tasks use operating-system functions.

PLAN FOR PROTECTED MULTITASKING SYSTEM

OPERATING SYSTEM AND APPLICATION MODULES (FROM ASM286, PLlM-286, PASCAL 286, FORTRAN 286, BND286)

MEMORY IMAGE APPLICATION


DEVICE DRIVER

O.S.

r=LOAOABLE~
" - CODE .,;

BOOTLOADER

.--.

KERNEL lOT GOT

121960-4

Figure 1-8. Building a Static System

1-10

121960-001

INTRODUCTION TO PROTECTED MULTITASKING ON THE iAPX 286

OPERATING SYSTEM MODULES

MEMORY IMAGE

BUILDER

BOOTLOADER OPERATING SYSTEM

' -_ _- . . I

LOADABLE APPLICATION MODULES

APPLICA TIONS DYNAMIC LOADER

APPLICATION MODULES

121960-5

Figure 1-9. Building a Dynamic System

1-11

121960-001

Using Hardware Protection Features

CHAPTER 2 USING HARDWARE PROTECTION FEATURES


The architecture of the iAPX 286 enables you to organize software systems so that each task is protected from inadvertent or malicious damage by other tasks and so that privileged procedures are protected from lower-level procedures. You control the degree of protection in your system by the way you set up protection parameters through the Builder or through operating system procedures. The processor interprets the protection parameters and automatically performs all the checking necessary to implement protection.

ADDRESSING MECHANISM
The protection mechanism of the iAPX 286 is embedded in the addressing mechanism. For an introduction to the addressing mechanism, refer to figure 2-1, which shows those portions of the addressing mechanism that are not concerned with protection features. From the point of view of the applications programmer, an address is a pointer. A pointer consists of two parts: a selector and an offset. The

PHYSICAL MEMORY

~---------------------------------~

TARGET SEGMENT CPU MEMORY OPERAND

-------,
I I I I I I I I I

DESCRIPTOR TABLE

SEGMENT BASE ADDRESS SEGMENT DESCRIPTOR

DESCRIPTOR TABLE BASE ADDRESS

L __________________

I I

I L _________________________________ I

121960-6

Figure 2-1. Abstraction of Addressing Mechanism

2-1

121960-001

USING HARDWARE PROTECTION. FEATURES

se1ector portion identifies a segment of the address space and the offset addresses an item within the segment relative to the beginning of the segment. A selector identifies a segment by reference to a descriptor table. Each entry in a descriptor table is a descriptor. A selector contains an index that identifies a particular descriptor in a particular descriptor table. The descriptor contains the physical address and access rights of the segment. Both selectors and descriptors contain additional information that relates to the protection features of the iAPX 286.

DESCRIPTORS
A reference from one segment to another is realized indirectly through a descriptor, which contains information about the referenced segment. All descriptors reside in a descriptor table. Every segment must have at least one descriptor; otherwise there is no means to address the segment. Descriptors are strictly under your control via the Builder or operating system procedures. The existence and function of descriptors is completely invisible to the applications programmer.

Descriptor Format
There are four variations in descriptor format, corresponding to the four classes of descriptor: 1. 2. 3. 4. Data segment descriptors refer only to segments that contain system or application data, including stacks (see figure 2-2). Executable segment descriptors refer only to segments that contain executable instructions (see figure 2-3). System segment descriptors refer only to segments that contain special hardware-recognized data. structures, such as descriptor tables (see figure 2-4). Gate descriptors define entry points for control transfers. A gate descriptor does not directly address a memory segment; instead it provides a. protected pointer to an exported entry point. (Refer to the section "Gate Descriptors" later in this chapter.)

The first two types of descriptor hold information that any operating system must maintain. The iAPX 286, however, requires that such information be in a fixed format so the CPU can interpret it directly. These descriptors are often created dynamically while a program executes (for example, a data-segment descriptor may be created when a task needs additional memory to store an expanding data structure). The second two types of descriptor are unique to the iAPX 286. They are constructed either once when the system is built or once when a task is created. Code to manipulate these descriptors is limited to the procedures of a dynamic operating system that create new tasks. Several of the descriptor formats have common fields. These fields are listed first in the following discussions of descriptor contents.
PRESENT BIT

This Boolean is set if the segment addressed by the descriptor is actually present in memory, reset if not present. Operating systems for dynamic applications that implement virtual memory must set and

2-2

121960-001

USING HARDWARE PROTECTION FEATURES

o
+6

RESERVED FOR iAPX 386 MUST BE ZERO

,
1
0
ED W A

DPL

BASE2J.16

+4

_I

BASE 15-0

+2

LIMIT

P DPL ED W A

PRESENT BIT DESCRIPTOR PRIVILEGE LEVEL EXPANSION DIRECTION WRITABLE ACCESSED

121960-46

Figure 2-2. Data Segment Descriptor

reset this bit as program segments are brought into or eliminated from memory. Reference to a segment whose present bit is reset causes a fault, providing an opportunity for the operating system to load the segment from virtual store. (Chapter 9 takes up implementation of virtual memory systems.) In systems that do not implement virtual memory, this bit is always set for allocated segments.

DESCRIPTOR PRIVILEGE LEVEL

The value of this item defines the privilege level of the segment addressed by this descriptor. You control the values in the descriptor privilege level (DPL) by the parameters you give to the builder when creating a static system or the resident portion of a dynamic system, or by the procedures your operating system uses when loading segments dynamically.

INTEL RESERVED

This portion of the descriptor is reserved by Intel and should always be initialized with zeros. Other use of this field in a valid descriptor will prevent compatability with the iAPX 386 and other additions to Intel's family of processors.

2-3

121960-001

USING HARDWARE PROTECTION FEATURES

o
I

o
+6

RESERVED FOR iAPX 386 MUST BE ZERO

DPL

BASE 23_16

+4

BASE l5-0

+2

LIMIT

P DPL C R A

PRESENT BIT DESCRIPTOR PRIVILEGE LEVEL CONFORMING READABLE ACCESSED

121960-47

Figure 2-3. Executable Segment Descriptor

SEGMENT BASE

This field contains the physical address of the beginning of the memory segment referred to by this descriptor. The 24 bits of this address give the 80286 a 16-megabyte range of real addresses. This is the only place that physical addresses are used. All other addresses are relative to the physical addresses stored in descriptors, making it possible to relocate executable and data segments without making any changes to the relocated segments or to code that refers to the segments. The only changes necessary to relocate segments are changes to the physical addresses stored in descriptor tables. You can control the actual location of segments by means of specifications to the Builder or by means of the algorithms your operating system uses to allocate memory to segments that are loaded dynamically.
SEGMENT LIMIT

Segment limits prevent accidental reading or writing beyond the space allocated to a segment. The value of this field is one less than the length of the segment (in bytes) relative to the beginning of the segment. The 16 bits of this field make it possible to have segments up to 64K bytes long. The hardware automatically checks all addressing operations to ensure that they do not exceed the segment limit of the segment to which they refer. This protects other segments from such common programming errors as runaway subscripts.

2-4

121960-001

USING HARDWARE PROTECTION FEATURES

o
+6

RESERVED Fr-' iAPX 386 MUST Bl 'ORO

DPL

TYPE

BASE23'16

+4

BASE,5_0

+2

LIMIT

121960-48

Figure 2-4. System Segment Descriptor

Note that the segment limit field has a different meaning for "expand down" data segments. Refer to the "expansion direction" bit later in this chapter.
SEGMENT TYPE

For system segments, the type field distinguishes between kinds of system segments. System segment types are 1 and 3 Task state segment, a segment used for storing the context of a task. Chapter 4 discusses task state segments more fully. Local descriptor table. The three kinds of descriptor tables are explained later in this chapter.

The processor interprets the type field to ensure that each segment is actually used as intended; for example, an attempt to jump to a local descriptor table is obviously a mistake, and the processor detects this error while examining the target segment's descriptor during the JMP instruction.
EXPANSION DIRECTION

Data segments may contain stacks as well as other data structures. Stacks expand toward lower addresses while most other data structures expand toward greater (higher) addresses. This field indicates the growth pattern for the segment. A value of zero in this field indicates that the segment expands upward

2-5

121960-001

USING HARDWARE PROTECTION FEATURES

(from the base address toward the segment limit value that is also contained in the descriptor). A value of one indicates that the segment expands downward (from offset FFFFH toward the limit).
WRITABLE

This field applies only to data segment descriptors. A value of one permits the CPU to write into the segment; a value of zero protects the segment from attempts to write into it. Translation tables are but one example of data that deserve the extra protection afforded by storage in a read-only segment.
CONFORMING

This field applies to executable-segment descriptors only. Ordinarily (when the conforming bit is zero) a called procedure executes at the privilege level defined by the DPL in the descriptor of the segment in which the procedure resides. When the conforming bit of the called segment is set, however, the called procedure executes at the calling procedure's privilege level. This feature cannot be used to decrease (numerically) a segment's privilege level below that defined by it's DPL. Figure 2-5 shows graphically how a conforming segment works. This feature is useful when you want to make procedures (mathematical subroutines or run-time support procedures, for example) available to a number of other procedures running at different privilege levels, but when you do not want to provide increased privilege while the subroutine is executing.

121960-7

Figure 2-5. Calling a Conforming Segment

2-6

121960-001

USING HARDWARE PROTECTION FEATURES

READABLE

This field applies only to executable-segment descriptors. When reset, it prevents procedures in other. segments from reading this code segment; the contents of the segment can be executed only. It is common, however, for executable segments to contain read-only data, in which case this bit must be set.
ACCESSED

The processor sets this bit when the descriptor is accessed (that is, loaded into a segment register or used by a selector test instruction). Operating systems that implement virtual memory may, by periodically testing and resetting this bit, monitor frequency of segment usage. This bit also indicates whether a segment should be written to secondary storage before the RAM space it occupies is reused.

CONTROL FLOW TRANSFER


Transfers of control are also subject to protection rules. Within the application-oriented part of a task, the protection rules allow unlimited access to code and data. Control transfers to privileged operatingsystem functions and to other tasks, however, are controlled by gate descriptors. With gate descriptors, the iAPX 286 architecture can perform functions in hardware that operating systems on other processors must do in software. These functions are invoked directly by ordinary CALL and JMP instructions, not by special interrupt or trap instructions. As table 2-1 illustrates, transfers of control can be classified into four categories, depending on whether control passes to another segment, another privilege level, or another task. This classification can help clarify how privilege levels, descriptor tables, and tasks are used. Processor functions that cause a change in the flow of control are Jump instruction (JMP) Procedure call instruction (CALL) Procedure return instruction (RET) Software interrupt instruction (INT) External interrupt

Table 2-1. Categories of Control Flow Transfer


Category Segment Privilege Level Task

Intrasegment Intersegment Interlevel

same different different same or different

same same different same or different

same same same

Intertask

different

2-7

121960-001

USING HARDWARE PROTECTION FEATURES

Processor-detected exception condition Interrupt return instruction (lRET)

Control transfers within the same privilege level may be either short (within same segment) or long (to another segment). A short transfer simply specifies the offset of the instruction to which control is transferred in the same segment. A long transfer also uses a selector to identify the segment to which control is transferred. For control transfer to a different privilege level or different task, the iAPX 286 introduces gate descriptors.

Gate Descriptors
A gate descriptor is a type of descriptor used only for transferring control flow to instructions in another segment. Gates provide an indirect reference that is useful for binding and protection purposes. By requiring interlevel and intertask control transfers to reference gate descriptors, the iAPX 286 provides two additional protection features:
1.

You can hide a procedure by not providing a gate for its entry point. You can control access to a procedure via the privilege assigned to the gate. This allows hiding critical procedures from untrusted software.

2.

Figure 2-6 illustrates the format of a gate descriptor.


DESTINATION SELECTOR

For call, interrupt, and trap gates, this field contains a selector for the segment descriptor of the destination executable segment. For task gates, the selector in this field points to a descriptor for a task state segment, and the RPL field is not used.
DESTINATION OFFSET

For call, interrupt, and trap gates, this field contains the offset of the entry point within the destination executable segment (not used with task gates).
WORD COUNT

For each privilege level within a task, there is a separate stack. For calls through a call gate, the processor automatically copies parameters from the stack for the calling procedure's privilege level to the stack for the destination's privilege level. In this field, you specify the number of words to copy.
GATE TYPE

For gate descriptors, the type field distinguishes among the four kinds of gates:

Call gate

1 Task gate 2 Interrupt gate 3 Trap gate

2-8

121960-001

USING HARDWARE PROTECTION FEATURES

o
+6

RESERVED FOR lAP X 386 MUST BE ZERO

DPL

TYPE

WORD COUNT ONLY FOR TYPE = 00

+4

.
DESTINATION SELECTOR X X

+2

DESTINATION OFFSET NOT USED FOR TYPE = 0 1 or 11

XX -

NOT USED

121960-49

Figure 2-6. Gate Descriptor

PRESENT BIT

Since a gate descriptor does not refer directly to a segment, the present bit in a gate descriptor does not necessarily indicate whether a segment is present. It can be used for other purposes, however. Refer to Chapter 11 for an example of using the present bit to facilitate late binding_

Control Transfer Mechanisms


Table 2-2 summarizes the mechanisms for each class of control flow transfer_ Control transfers within a segment function similarly to intrasegment transfers on the iAPX 86,88, except that the processor checks that the destination address does not exceed the segment limit. Figure 2-7 illustrates a change in control flow between segments at the same privilege level. Any of the following instructions can effect such a transfer:

J MP offset selector CAL L offset selector


RET
(offset and selector taken from stack) The selector selects a descriptor for an executable segment. The DPL in the target segment's descriptor must be the same as the privilege level under which the calling segment is running. A CALL or

2-9

121960-001

inter
Transfer Type Intrasegment Intersegment (*)

USING HARDWARE PROTECTION FEATURES

Table 2-2. Control Transfer Mechanisms


Operation JMP, CALL, RET JMP, CALL, RET, IRET CALL, JMP Descriptor Referenced (none) code segment call gate (same PL) trap or interrupt gate (same PL) call gate . trap or interrupt gate code segment task state segment task gate task gate GOT/LOT GOT/LOT Table

INT instruction, external interrupt, or exception Interlevel CALL INT instruction, external interrupt, or exception RET,IRET Intertask CALL, JMP, IRET

lOT

GOT/lOT lOT

GOT/lOT GOT

CALL, JMP INT instruction, external interrupt, exception

GOT/LOT lOT

* Includes cases in which the target segment is incidentally the same as the calling segment.

JMP instruction may also reference a call gate. If the target executable segment is at the same privilege level, no level change occurs. For transfers of control between segments at different privilege levels (as illustrated in figure 2-8) there are three differences: Only the following instructions cali be used:

CAL L offset selector


RET
Jumps between privilege levels within a task are not allowed. The selector does not select the descriptor of an executable segment but rather selects a gate descriptor. The offset operand must be present but is ignored.

2-10

121960-001

USING HARDWARE PROTECTION FEATURES

EXECUTABLE SEGMENT

-GATE

INTRASEGMENT

INTERSEGMENT VIA GATE

INTERSEGMENT

1219608

Figure 2-7. Intralevel Control Transfers

Privilege Rules for Gated Intersegment Transfers


An intersegment transfer through a gate involves four privilege level fields: The current privilege level (CPL) of the currently executing segment The requested privilege level (RPL) in the selector used in the CALL The DPL in the gate descriptor The DPL in the segment descriptor of the target executable segment

A transfer is valid only if the following relationships among privilege level numbers both hold: MAX (CPL, RPL) < = gate DPL target DPL < = CPL Figure 2-9 illustrates both valid and invalid attempts to perform an interlevel transfer. Path E4,G5,E7 is not valid because the privilege level of gate G5 is numerically less than that of segment E4. Path E4,E8 is not valid because all interlevel transfers must pass through a gate. Path E4,G4,E6 is not valid because the privilege level of E6 is numerically greater than that of G4. Only paths El ,G2,E2; El,G 1,E3; and E2,G 1,E3 satisfy the privilege rule above.

2-11

121960-001

USING HARDWARE PROTECTION FEATURES

o-

EXECUTABLE SEGMENT

-GATE

121960-9

Figure 2-8. Gated Interlevel Call and Return

DESCRIPTOR TABLES
A descriptor table is simply a segment containing an array of eight-byte entries, where each entry is a descriptor. Descriptors are stored in one of three classes of descriptor table: Local descriptor table (LDT) Global descriptor table (GDT) Interrupt descriptor table (IDT) The descriptors in these tables define all the segments in the system. Each table has a variable upper limit, so the size of the table need be no larger than required for the actual number of segments used. You define the initial contents of descriptor tables through the Builder. An operating system for dynamic applications may change the contents of descriptor tables and may create and delete LDT's as tasks come and go. Correct management of descriptors is the heart of protection on the iAPX 286.

2-12

121960-001

USING HARDWARE PROTECTION FEATURES

r-"'f1 L.::..J

EXECUTABLE SEGMENT

-GATE INVALID

121960-10

Figure 2-9. Valid and Invalid Interlevel Transfers

2-13

121960-001

USING HARDWARE PROTECTION FEATURES

Local Descriptor Table


An LOT contains the descriptors that are private to a task. Each task may have an LOT. The LOT keeps the descriptors private to one task separate from those private to other tasks. A task cannot normally gain access to the segments defined by another task. A local descriptor table may contain any of the following types of descriptor: Oata segment Executable segment Call gate Task gate

The executable segment and data segment descriptors in an LOT normally refer to segments private to a task. Call gates and task gates in an LDT provide private entry points to other procedures and programs. The processor uses a task's LOT automatically for certain addressing operations. The base address and limit of the LOT segment of the executing task are kept in the LOT register. Only two operations are available to programmatically change the contents of the LDT register: During a task switch operation, the processor loads the LOT register from the task state segment (TSS). The LLOT instruction loads the LOT register directly. The LLDT instruction can be executed only at privilege level 0 (PL 0). Initialization procedures use LLDT to give the LDT register its initial value. Note that if you change the LOT register you must also change the LOT selector in the TSS (refer to Chapter 4). An operating system may need to change the LOT register temporarily to gain access to the address space of another task when passing information between tasks.

You can use the SLOT instruction to read the contents of the LOT register. Operating-system procedures that operate on LDTs may usually be called from any task. These procedures may use the SLDT . instruction to find which LOT belongs to the current task. In PL/M-286, the built-in variable LOCAL$TABLE gives access to the LDT register. An LDT may contain up to 8,192 descriptors (the number of 8-byte descriptors that fit into a maximumsized segment of 65,536 bytes).

Global Descriptor Table


Descriptors that are shared among tasks reside in the GDT. There is only one GDT for the entire system. The GOT can contain any of the following types of descriptor: Oata segment Executable segment Task state segment Local descriptor table segment Call gate Task gate

2-14

121960-001

USING HARDWARE PROTECTION FEATURES

Since the GOT is shared among all tasks, its entries are usually protected. The privilege-level field in each descriptor provides this function. When operating-system functions are distributed among and shared by all tasks, the executable segments and data segments of the operating system are normally kept in the GOT. Call gates then provide controlled access to privileged operating system functions. The processor uses the GOT automatically for certain addressing operations. The base address and limit of the GOT are kept in the processor's GOT register. Only the LGOT instruction (RESTORE$GLOBAL$TABLE in PL/M-286) can alter the contents of the GOT register, and the LGOT instruction can be executed only at PL 0 (i.e., by the operating system) . . The SGOT instruction (SAVE$GLOBAL$TABLE in PL/M-286) reads the contents of the GOT register. A GOT may contain up to 8,191 descriptors (the number of 8-byte descriptors that fit into a maximumsized segment of 65,536 bytes). The first entry cannot be used as a descriptor. (A null selector is identified by the fact that it refers to this first entry in the GDT.)

Interrupt Descriptor Table


When processing an interrupt, the processor refers to the lOT to determine what interrupt-handling code to execute. Each interrupt is associated with an interrupt identifier, an integer that ranges from 0-255. The interrupt identifier is supplied either by the INT instruction or externally by the processor's INTA cycles. The interrupt identifier indexes an entry in the lOT. An lOT entry may be An interrupt gate A trap gate A task gate

In a manner similar to executable segment and data segment descriptors, each gate descriptor has a descriptor privilege level. The OPL of a descriptor in the lOT determines the privilege required to execute an INT n instruction (where n is the interrupt indentifier that corresponds to the descriptor). This use of privilege levels prevents unauthorized programs from invoking interrupt handlers. The processor locates the lOT by way of the lOT register. The lOT register can be changed only by the LIOT (load lOT) instruction (RESTORE$INTERRUPT$TABLE in PL/M-286). Only PL-O procedures (i.e., the operating system) can execute an LIOT instruction. The SlOT instruction (SA VE$INTERRUPT$TABLE in PL/M-286) reads the contents of the lOT register. Refer to Chapters 6 and 7 for more detailed information on how the lOT is used.

SELECTORS
A selector references a segment indirectly by identifying the location in a descriptor table where a descriptor for that segment is stored.

Format of Selector
See figure 2-10 for the format of a selector.

2-15

121960-001

inter
15

USING HARDWARE PROTECTION FEATURES

:~E~ : : : : :
TI RPL TABLE INDICATOR REQUESTED PRIVILEGE LEVEL

IT'I

":L

121960-50

Figure 2-10. Format of a Selector

INDEX

The index field of a selector specifies a descriptor in either the GOT or the task's LOT. The index field may take on values from 0 through n-l, where n is the number of descriptors in the table. The processor compares the index with the limit of the descriptor table to ensure that the index refers to a defined descriptor.

TABLE INDICATOR

This bit item tells which descriptor table is indexed by the selector. A value of zero specifies the GOT; one specifies the LOT. (The lOT cannot be referenced via a selector; only via an interrupt identifier.)

REQUESTED PRIVILEGE LEVEL

Selector privilege is specified in the RPL field of a selector. Selector RPL may establish a less trusted privilege level than the current privilege level for the use of that selector. RPL cannot effect an increase in privilege. A task's effective privilege level is the numeric maximum of the RPL and the current privilege level. For example, if a task is executing at PL = 2, an RPL = 3 reduces the task's effective privilege to level 3 for access to that segment. On the other hand, if RPL = 1, the task's effective privilege level remains at 2. RPL is generally used by an operating system to ensure that selector parameters passed to the more privileged levels of the operating system do not give access to data at a level more privileged than the calling procedure. The RPL field is a convenient place to store the privilege level of the procedure that originated the selector. Any use of the selector can be restricted to the usage allowed its originator. The ARPL instruction (AOJUST$RPL built-in function in PL/M-286) allows the operating system to set the RPL of a selector either to CPL or to the privilege level of the originator, whichever is (numerically) larger. Refer to Chapter 13 for more information on the use of RPL.

2-16

121960-001

inter
Null Selector

USING HARDWARE PROTECTION FEATURES

A selector that has a value of zero in both the index and table indicator fields (i.e., appears to point to the first entry of the G DT) is a null selector. You .can load such a selector into the DS or ES register, but any attempt to reference memory via that register causes an exception condition.

ALIAS DESCRIPTORS
The need arises in dynamic applications for the operating system to maintain more than one descriptor for a segment; however, care must be taken to preserve system integrity and protection. As an example of the need for an alternate descriptor, consider the case of an executable segment. Ordinarily, the processor fetches instructions from an executable segment that is typed execute-only. However, if the operating system supports a debugger, the debugger needs to read the executable segment in order to display its contents. The debugger may also need to write to the executable segment in order to set breakpoints. If the debugger tries to use an execute-only segment descriptor to read from or write to the segment, the processor detects a protection exception. To properly use that segment, the debugger must use another descriptor that identifies the segment as a data segment. Figure 2-11 illustrates this situation. The use of more than one descriptor for a segment is known as aliasing. Descriptors used in this way are known as aliases, because they provide alternate names for segments.

/1
APPLICATION LOT EXECUTE ONLY CODE SEGMENT

/
o.s.
DEBUGGER LOT DATA SEGMENT

\
(

INSTRUCTIONS

/
121960-11

Figure 2-11. Aliasing for Debugger

2-17

121960-001

USING HARDWARE PROTECTION FEATURES

Explicit Variation of Type


Figure 2-11 illustrates one kind of need for aliasing: the need for a different type specification for a segment. Figure 2-12 shows another example of the same need. In a dynamic application, the operating system may need to modify the GDT, the IDT, TSSs, and LDTs. Changing the interrupt handler for a specific interrupt vector requires changing the IDT. When the operating system places a new segment into the address space of a task (as, for example, when transferring an I/O buffer from an I/O task), it must update the task's LDT. Starting a new task may require modification of the GDT to add descriptors for the new task's LDT and TSS. With the iAPX 286, however, it is not possible to read or write a system segment by loading its selector into OS or ES. This restriction prevents indiscriminate use of system segments within the operating system. Such use of a system segment requires that the operating system have a descriptor that identifies the system segment as a data segment. The Builder allows for defining aliases for system segments. The Builder, by default, creates datasegment aliases for the GDT and the IDT at fixed locations in the GDT. Note that aliases for descriptor tables should have PL 0 in order to maintain the integrity of the protection mechanism; otherwise, procedures outside the operating system could indiscdminately chang'e the contents of descriptor tables.

Variation of Length
As illustratt~d in figure 2-13, aliases for a segment need not always have the same length. In the case shown, the processor's use of a descriptor to a TSS requires only that the segment contain 44 bytes. However, the operating system maintains another descriptor that includes additional information about the task.

GDT

IDT

e(

le(

e(

!;t
c

ALIAS FOR GDT SHOULD ALWAYS BE AVAILABLE TO KERNEL.

121960-12

Figure 2-12. Aliases for System Tables

2-18

121960-001

USING HARDWARE PROTECTION FEATURES

TASK PARAMETERS
4--

TASK PRIORITY SCHEDULING PARAMETERS MESSAGE QUEUE POINTERS RESOURCE POOL POINTERS

GOT

TSS ETC.

ALIAS TSS

TSS DESC.

121960-13

Figure 2-13. Aliases with Differing Limit

Sharing Segments among Tasks


Yet another reason for using aliases is the need for sharing a segment among tasks. Consider an application in which a memory-mapped video display shows status information for a production process. In this application, there are two tasks, each monitoring different aspects of the process but interleaving data on the display (see figure 2-14). Figure 2-15 illustrates how both tasks can access the memory segment containing the display buffer. You can find segment sharing needs of this sort in both static and dynamic systems. Note that there are other techniques for segment sharing that do not use aliases; for example, placing the segment's descriptor in the GDT, or permitting tasks to share a single LDT. The aliasing technique illustrated here has the advantages that

No other tasks have access to the display buffer. (Putting its descriptor in the GDT makes it available to all other tasks.) Other segments in each of the tasks remain protected from the other task. (With a shared LDT, all segments of each task are accessible from the other.)

Protection and Integrity with AliaSing


You must use aliases with care; improper use can compromise the protection and integrity of your system.

2-19

121960-001

inl:el~

USING HARDWARE PROTECTION FEATURES

FLUID-LEVEL SENSORS

TEMPERATURE SENSORS

RESERVOIR ABC TASK A

~~[I~lI~~
LT EE VM EP L LT EE VM EP L LT EE VM EP L LT EE VM EP L LT EE VM EP L VIDEO DISPLAY

n
D

E TASK B

121960-14

Figure 2-14. Application of Segment Sharing

CONTROL ACCESS TO ALIASES

When you use an alias to provide an alternate type for a system segment (to write to an LDT), any procedure that has access to that alias also has unlimited power to affect the entire system. Therefore, in constructing an operating system that uses such aliases, you must restrict them to the highest privilege levels of the operating system; that is, the DPL of such aliases should always be zero.

PLAN FOR CHANGE

When you design a dynamic system that uses aliases for segment sharing, you must consider what will happen when there is any change in a segment to which aliases are pointing. For example, when a segment is relocated, all descriptors pointing to the relocated segment must be updated. When a segment is deleted, all aliases to it must be nullified. Chapter 5 presents a strategy for handling these changes.

EXAMPLE OF DESCRIPTOR MANIPULATION


As an example of how to manipulate descriptors and descriptor tables using an alias, consider the procedures POINT_AT and NULLIFY in figure 2-16. POINT_AT creates a descriptor at a given slot in the GDT. NULLIFY invalidates a descriptor in the GDT. It is intended for use in connection with POINT_AT to prevent accidental use of descriptors that are no longer needed.

2-20

121960-001

USING HARDWARE PROTECTION FEATURES

121960-15

Figure 2-15. Aliases for Segment Sharing

NULLIFY invalidates a descriptor by writing a value of 80H in the access rights byte. A value of 80H is invalid because it indicates a system segment of type zero, but no type zero is defined for system segments. POINT_AT purposely loads the access rights byte of the descriptor last, to ensure that an accidental use of the descriptor (as might occur if an external interrupt gives control to another procedure or task) does not find partially complete information in a descriptor that otherwise looks valid. These procedures do no checking of the privilege level of the calling procedure, and they freely create descriptors of any type (except gate descriptors) and any DPL. Therefore, they are suitable for use only at PL O. As long as no gates for these procedures are provided at another privilege level, they can be called only by other PL-O procedures. For an example of how you might use such procedures, refer to the example of a memory manager in Chapter 3. When writing code to manipulate descriptors, you must be careful about changing a descriptor that is currently loaded in either of the processor's data-segment registers (DS or ES). Either disable interrupts or move zero to the register before changing the descriptor, for example:

MOV DS,O
Failure to do this leaves open the possibility that an external interrupt may cause the processor to reload the segment register using the partially modified descriptor. When coding in PL/M-286, use the compiler's CODE option to view the way the generated code handles the DS and ES registers. This situation does not arise in the present example. DS points to the data segment that contains the sole

2-21

121960-001

USING HARDWARE PROTECTION FEATURES

global data item GDT~SEL. PL/M-286 uses ES for all the BASED variables used here. Referencing the descriptor table via its alias selector causes PL/M-286 to load ES with the alias descriptor, thereby ensuring that ES does not contain the descriptor to be modified.

Remember that once a descriptor has been modified, it cannot be used to access a segment until it is loaded into a segment register.

Be aware also that in a multitasking system, changes to shared segments (such as the GDT) must be synchronized. Synchronization is the. subject of Chapter 5. This example does not provide for synchroniza tion.

SLOT MANAGEMENT

The previous example assumes that the caller of POINT_AT already knows what descriptor-table slot to use. Often, slots can be reserved in advance for specific operating system and applications functions. But in general, dynamic systems require that the operating system dynamically allocate descriptor table slots.

Figure 2-17 illustrates a way of identifying available slots in a descriptor table. A value of zero in the access rights byte is invalid for any descriptor, so it can mark a free slot. A value of 80H (as used in the previous example) is also invalid and can mark a reserved but unused slot.

In larger systems, the time needed to search a descriptor table linearly for free slots may become excessive. Shorter search times may result from linking available slots together in a manner similar to that shown in figure 2-17. Contiguous free slots are treated as a block, with a count of the number of slots in the first and last slots of the block. (Note that the block size is stored in the reserved word of available descriptor slots. Since available descriptor slots contain an invalid type code, this use of the reserved word does not prevent upward compatibility.) All the free blocks are linked in a circular, twoway list that includes the list header. The list header can reside at a fixed slot location that is the same in all descriptor tables (in the case of figure 2-17 the list header is at slot number one). Algorithms normally used for managing memory space may also apply to blocks of' free descriptors. Refer to Chapter 3 for an example of such an algorithm.

It is convenient for the operating system to use adjacent descriptor slots for related purposes; for example, . by locating together all the descriptors that the operating system uses for one task, the operating system can quickly find any of those descriptors as long as it knows the location of one. Therefore, the algorithm used for slot management should combine adjacent free slots into a single block. The procedures used to manage free slots should then have a parameter that specifies the number of adjacent slots.

2-22

121960-001

USING HARDWARE PROTECTION FEATURES

PL/M-286 COMPILER

96(3-505

date

PAGE

system-ID PL/M-286 Vx.y COMPILATION OF MODULE POINT OBJECT MODULE PLACED IN :Fl:POINT.OBJ COMPILER INVOKED BY: PLM286.86 :Fl:POINT.PLM

$ PAGEWIDTH(71) TITLE('96G-505') $ NOLIST 1

INCLUDE

(:Fl:NUCSUB.PLM)

POINT:

DO;

/*******************************************************/ /* Global declarations. */


2
1

DECLARE DESC_STR LITERALLY 'LIMIT WORD, LO BASE WORD, /* Format of a descriptor. */ HI-BASE BYTE, BYTE, RIGHTS SW RESRVD WORD' ; DECLARE DT SIZE GDTA SEL GDTA-WSEL INITIAL GOT LITERALLY '200', SELECTOR, /* Points to GOT alias */ WORD AT (@GDTA SEL) (8), /* Slot #1 by convention */ BASED GDTA SEL (OT SIZE) STRUCTURE (DESC_STR);

/*******************************************************/ /* Subroutine to determine either the alias for */ /* the GOT or the alias for this task's LOT, */ /* depending on the TI bit in SEL. */
4
5 6 1

FIND DT ALIAS: PROCEDURE (SEL) SELECTOR PUBLIC REENTRANT; DECLARE SEL WSEL DECLARE LOT SEL LDT-WSEL SELECTOR, WORD AT (@SEL); SELECTOR, WORD AT (@LDT_SEL);

2 2
2 2 3 3

IF (WSEL AND 0004H)=0 THEN /* It's a selector to the GOT. */ RETURN GDTA_SEL; ELSE DO; /* It's a selector to this task's LOT. */ LOT SEL=LOCAL$TABLE; /* PL/M 286 built-in; stores a selector to the GOT descriptor for this task's LOT. */ LOT WSEL=LDT WSEL+8; /* Add 1 to index field. */ /* By convention, next slot holds alias. */ RETURN LDT_SEL; END; END FIND_DT_ALIAS; $ EJECT

10
11

12
13

3 3
2

14

Figure 2-16. Descriptor Manipulation Example

2-23

121960-001

USING HARDWARE PROTECTION FEATURES

PL/M-286 COMPILER

960-505

date

PAGE

/*******************************************************/ /* Create a descriptor at a given slot to a given */ /* segment, and return selector that points */ /* to that slot. */

15
16

POINT AT:

PROCEDURE(SLOT, RIGHTS, PHYS_ADDR_PTR, LIMIT) PUBLIC REENTRANT;

DECLARE SLOT SELECTOR, SLOTW WORD AT (@SLOT), /* Alternate type */ RIGHTS BYTE, PHYS ADDR PTR POINTER, PHYS-ADDR- BASED PHYS ADDR PTR STRUCTURE (LO-WORD WORD, -HI-WORD WORD) , LIMIT WORD; DECLARE SLOT I DTA SEL DT WORD, /* Slot index */ SELECTOR, /* To be set to either GDT alias or LDT alias. */ BASED DTA SEL (DT SIZE) STRUCTURE-(DESC_STR);

17

18 19 20 21 22 23
24

25 26

2 2 2 2 2 2 2 2 2

DTA SEL = FIND DT ALIAS(SLOT); SLOTI = SHR(SLOTW73); /* Expose index value. */ DT(SLOTI) .LO BASE PHYS ADDR.LO WORD; DT(SLOTI) .HI-BASE LOW(PHYS ADDR.HI WORD); DT (SLOTI) .LIMIT LIMIT; DT(SLOTI) .SW RESRVD 0; DT(SLOTI) .RI~HTS RIGHTS; RETURN;

/*******************************************************/ /* Invalidate descriptor indexed by SLOT. */


27

NULLIFY: PROCEDURE (SLOT) PUBLIC REENTRANT; DECLARE SLOT SLOTW DECLARE SLOTI DTA_SEL DT SELECTOR, WORD AT (@SLOT); /* Alternate type */ WORD, /* Slot index */ SELECTOR, /* To be set to either GDT alias or LDT alias. */ BASED DTA SEL (DT SIZE) STRUCTURE-(DESC_STR);

28 29

2
2

30 31 32

2 2 2 2
2

33 34

DTA SEL = FIND DT ALIAS(SLOT); SLOTI = SHR(SLOTW73); /* Get index part of selector. */ DT(SLOTI) .RIGHTS 80H;/* This invalid value prevents use of the descriptor. */ RETURN;

END NULLIFY; /*******************************************************/

Figure 2-16. Descriptor Manipulation Example (Cont'd.)

2-24

121960-001

USING HARDWARE PROTECTION FEATURES

PL/M-286 COMPILER

960-505

date

PAGE

35

END POINT;

MODULE INFORMATION: CODE AREA SIZE CONSTANT AREA SIZE VARIABLE AREA SIZE MAXIMUM STACK SIZE 129 LINES READ o PROGRAM WARNINGS o PROGRAM ERRORS DICTIONARY SUMMARY: 96KB MEMORY AVAILABLE 5KB MEMORY USED (5%) 0KB DISK SPACE USED END OF PL/M-286 COMPILATION 00CAH 0000H 0002H 0018H 202D OD 2D 24D

Figure 2-16. Descriptor Manipulation Example (Cont'd.)

2-25

121960-001

cf
SLDT FORMAT

L > .. ..............

LIMIT NEXT

BASE,.,o PREVIOUS

ACCESS RIGHTS

BYTE
FLAG DESCRIPTOR TABLE

BA~",,~

RESERVED FOR iAPX 386

# SLOTS IN BLOCK

,
13 12 11 10
I

I
.L

OOH OOH OOH OOH

, ,

c: en Z
l>

G)

,
/8,
.. \

::I:
4
....

~1\
..

:IJ C

9 8
I\)

)10

0>

r\J

I?>I

\ .............. \
.: ..... :.'
I

r
.

\
.
,.

80H

== l>
1

';-3

I:. ...............
I:.:: .,

6
5

....
'

..

I
.....

..

I
I
.l

OOH

m
"tJ

:IJ :IJ

BOH SOH
OOH
..
1

o -4 m
3

o -4

4
3
...........

\
:

~8

...

:.

\. J
" 3';

r
D
3

)1

~1
HEAD OF FREE SLOT LIST 0

~10'
1

OOH OOH 80H 80H 80H


..
...

o Z
"T1

3
I
..
.

en
6

:IJ

c:

l> -4

"I

Iii

RESERVED

AVAILABLE

~
<0 Ol

Figure 2-17. Available Slot List

121960-51

Real Memory Management

CHAPTER 3 REAL MEMORY MANAGEMENT


In dynamic applications, when tasks begin and end frequently, the operating system is responsible for allocating memory to tasks. Without the control that an operating system provides, independent tasks cannot be trusted to share the system's memory harmoniously. The iAPX 286, through the descriptor mechanism, gives the operating system the power to control memory usage. For static systems, you can use the Builder to allocate memory. This chapter presents an example of how to manage real memory dynamically, using dynamically created descriptors.

MEMORY MANAGEMENT FUNCTIONS


Procedures at various levels in a system have a need to get memory for their use. Some of the functions that use memory dynamically include Loading the code and data segments for a new task Creating the TSS and LDT of a new task Expanding an application data structure Expanding system stack segments when stacks grow too large Allocating buffers for a newly opened file

In allocating memory statically using the Builder, you or the Builder must keep account of what memory locations are available and what locations are used. A dynamic memory allocation module must do the same, but, in addition, it needs to reuse the space vacated by tasks that have finished. Even tasks that are still executing may no longer need all of the memory they once were using, so you need to provide some means for them to return that space dynamically. The need to reclaim formerly used memory space provides considerable challenge to operating system designers.
Protection usually requires that segments not overlap. The operating system should accurately keep track of allocated memory to prevent new segments from overlapping current segments. Allocation of memory to tasks in a dynamic environment is complicated by the facts that segments have differing lengths and that the order of creation and deletion is unpredictable. Consequently, after a number of tasks have come and gone, memory becomes fragmented, as illustrated in figure 3-1. It becomes increasingly difficult to find free areas large enough to accomodate requests for space. It may happen that no single free area in all of memory is large enough to fill a request for memory even though the total of all smaller available areas is larger than the amount needed. Knuth (see "External Literature" in the Preface) discusses how various memory-management mechanisms can minimize or magnify this problem. Memory management on the iAPX 286 differs from memory management on other processors in that descriptors must be constructed to access any region of physical memory.

EXAMPLE OF A MEMORY MANAGER


As an example of how a memory manager can manipulate descriptors and segments, consider a memory management module that implements a version of the "first fit" algorithm (as described by Knuth) and combines adjacent free segments as a way to reduce fragmentation. This example employs the

3-1

121960-001

REAL MEMORY MANAGEMENT

o-

AVAILABLE MEMORY

ALLOCATED MEMORY

121960-17

Figure 3-1. Memory Fragmentation

"first fit" algorithm because it provides an opportunity to illustrate how to create descriptors dynamically to access free memory areas, not because it necessarily performs best in any specific application. Knuth discusses other algorithms, including the "buddy system." Figure 3-2 illustrates conceptually the structure of this module. Hidden inside the module are the list of available memory space, the aliases that permit modification of the GDT and LDTs, and the spacemanagement algorithms. The PUBLIC procedures ALLOCATE and FREE are the only interfaces with the world outside the module.

Data Structures
Figure 3-3 illustrates the data structures implemented in this example memory manager. One-word tags bound every memory area on the low and the high end. These boundary tags indicate whether the area is free or in use by some task. Free areas are chained into a two-way linked list that uses physical addresses to point to the next and prior segments in the list. The size of an area (in bytes) is stored with the link addresses in the low-addressed end of the area. At the high-addressed end, a physical address points to the beginning of the area. With boundary tags at both ends of every memory area, the memory manager can, when freeing a segment that is no longer needed, easily determine whether either of the adjoining areas is free. Figure 3-4 illustrates how adjacent free areas can be combined to reduce memory fragmentation. Figure 3-5 illustrates that boundary tags are invisible to procedures outside the memory management module because the tags are not within the base and limit addresses in the segment descriptor that the memory manager returns to the caller.

3-2

121960-001

REAL MEMORY MANAGEMENT

ALLOCATE

GATE

MEMORY MANAGEMENT ALGORITHMS

0.
0
GLOBAL DATA

FREE SPACE LISTS

c::J c::J c::J c::J

FRELSEG

GATE

121960-16

Figure 3-2. Information Hiding in Memory-Management Example

This memory manager does not maintain descriptors to free segments; instead, it creates descriptors dynamically when it needs to address the boundary tags and space-management linkages. This policy minimizes the number of descriptors in the GOT. Note that as a result, free areas may be larger than 64K bytes. Physical addresses are stored as double words CDWORD) to take advantage of double word arithmetic in PL/M-286. In an actual implementation, you may wish to store physical addresses in three-byte fields to save space, but you would need to implement arithmetic operations for three-byte operands. The total size of the memory-management items associated with each free area is 20 bytes; therefore, to ensure that no memory area is too small to contain the memory-management items, this algorithm chooses the size of the allocated space to be a mUltiple of the next integer greater than 20 that is also a multiple of 16. This number is identified as BLOCICMODULUS.

3-3

121960-001

inter

REAL MEMORY MANAGEMENT

LINKED LIST OF AVAILABLE SEGMENTS

NULL NULL

ALLOCATED SEGMENT

CURRENT AVAILABLE

FIRST AVAILABLE

BOUNDARY TAG

--~:C5"U~S~ED[':'J

121960-18

Figure 3-3. Example Memory-Management Data Structures

The memory manager maintains physical-address pointers to the first segment in the available segment list and to the last. It also maintains a "current available" pointer that corresponds to Knuth's "roving pointer." This example also makes some assumptions about the placement of descriptors in the GDT. Figure 3-6 illustrates these assumptions: The memory manager frequently needs to create temporary descriptors for such purposes as reading and updating the boundary tags and link fields. For its own convenience, the memory manager reserves GDT slots for these temporary descriptors. This example identifies the slots as SLOT_A, SLOT_B, and SLOT_C. Adjacent slots in the GDT contain all the descriptors to information for one task. This way, given a selector for one task descriptor, simple addition or subtraction yields selectors for other descriptors for the same task.

3-4

121960-001

inter

REAL MEMORY MANAGEMENT

BEFORE

, AFTER

"USED"

"USED"

"USED" "USED"

I I

"USED" "FREE" START

J 1

SEGMENT TO BE FREED

I
I

"USED" "FREE" START

I
L

SIZE NEXT PRIOR

SIZE NEXT PRIOR

"FREE"

"FREE"

121960-56

Figure 3-4. Using Boundary Tags

3-5

121960-001

REAL MEMORY MANAGEMENT

ALLOCATED MEMORY BOUNDARY TAG SEGMENT DESCRIPTOR

SEGMENT

BOUNDARY TAG

121960-300

Figure 3-5. Hiding Boundary Tags

There are two ways to reserve slots in a descriptor table: 1. 2. Code absolute selector values in the program and use the Builder's RESERVE statement to prevent the Builder from allocating other descriptors to those slots. This is the method used in this example. Use EXTERNALs to dummy segments coded in an ASM286 module, and allow the Builder to assign slots for the descriptors of the dummy segments. The Builder resolves the EXTERNALs.

PL/M-286 Code
This example separates space-management functions from descriptor-management functions. The spacemanagement procedures are DELINK, FIND_FIRST_FIT, and RETURN_SPACE. The public procedures ALLOCATE and FREE_SEG call on POINT~T and NULLIFY to manipulate descriptors for allocated segments. (Refer to Chapter 2 for definitions of POINT_AT and NULLIFY.) The PL/M-286 built-ins used to manipulate system structures in this example include

5 ELEe TOR $ 0 F (pointer) GET$SEGMEHT$LIMIT

(se~c~~

The external procedure GET$SEGMENT$BASE extracts the segment base address from the specified descriptor. When the procedure FIND_FIRST_FIT finds an available space that is much larger than requested, it allocates the higher-addressed portion of the space and leaves the lower-addressed portion in the freespace list. Figure 3-7 illustrates the process of splitting an available space.

3-6

121960-001

REAL MEMORY MANAGEMENT

GLOBAL DESCRIPTOR TABLE

I
I I

I
I

I
I

CURRENT TASK DESCRIPTORS

I
1
11

n+3 n+2 n: 1

LOT ALIAS LOT TSS ALIAS TSS


I I

RESERVED FOR OPERATING SYSTEM

WORK DESCRIPTORS FOR MEMORY MANAGER

m+-2

SLOTC SLOTB SLOT A


I I

+1

:
GOT ALIAS

NULL

121960-19

Figure 3-6. Example GOT Layout

When returning an unneeded segment to the available list, the procedure RETURN_SPACE checks the boundary tags of both the lower and higher adjacent segments to see whether there is another free segment with which to combine. Four cases are possible, as illustrated in figure 3-8 at the end of this chapter. Table 3-1 summarizes the actions taken in each of the four cases. See figure 3-9 at the end of this chapter for the PL/M-286 code that implements this example of a memory manager.

Protection Structure
Where in the two-dimensional grid of protection offered by the iAPX 286 should the memorymanagement module lie? There are two approaches that offer different advantages:
1.

The module can be structured as privileged procedures that execute as part of every task that calls them. The module can execute as a separate task.

2.

3-7

121960-001

inter

REAL MEMORY MANAGEMENT

BEFORE

AFTER

SIZE 2: 16 BYTES

121960-20

Figure 3-7. Splitting an Available Block of Memory

GLOBAL PROCEDURES
Placing the module's segment descriptors in the GDT allows all tasks in the system to share the module yet requires only one copy of the module's segments to be present in memory. This approach allows for fastest communication between the application and the memory manager. The procedures of the memory manager synchronize with the calling procedure (that is to say, the calling procedure waits until the memory-management procedure returns). However, more than one task can be executing the memory-management procedures at one time. This can be an advantage (as when there are multiple CPUs and the requests are for different regions of the memory space), but it requires synchronization of changes to space-management data structures (not shown in this example). Segments containing procedures and data structures internal to this most critical operating-system module should have the greatest protection possible. Because none of these procedures and data structures are PUBLIC, no other modules can gain knowledge of the locations of data and procedures. This by itself, however, does not constitute positive protection from accidental or intentional snooping or destruction. The segments containing these procedures and data should have privilege level 0 (PL 0) so that the processor can prevent any access from less trusted procedures.

3-8

121960-001

REAL MEMORY MANAGEMENT

Table 3-1. Actions for Combining Segments


Case 0 Case 1 Case 2 Case 3

Action

Hi Lo Free Free
Lo START

Lo Hi Free Used
Lo START

Lo
Used

Hi Free

Lo
Used

Hi Used
This Base Null

CURR_AVLBL=

This Base Hi LINK. PRIOR Hi L1NK.NEXT No No

CURR_L1NK.PRIOR =

Yes No

No No

CURR_L1NK.NEXT= DELINK HI FIRST_AVLBL= CURR_AVLBL? PRIOR FREE LlNK.NEXT= CURR_AVLBL? NEXT FREE L1NK.NEXT= CURR_AVLBL?

FIRST-AVLBL No Yes

No

No

Yes

No

No

No

Yes

Yes

The PUBLIC interface procedures ALLOCATE and FREE_SEG should execute at PL 0 to access the internal data structures and procedures, which are also at PL O. ALLOCATE and FREE_SEG should have gates at PL 3, however, so that even least trusted application procedures can get the space they need for such purposes as dynamic data structures.

SEPARATE TASK

Another possible structure, not exemplified here, is to treat the memory-management module as a separate task. The iAPX 286 features for isolation of tasks provide the needed protection for the critical memory-management structures and procedures. Within the memory-management task, privilege levels can be used to isolate the various internal procedures and data structures from one another. The memory-manager task can use a message passing mechanism such as that shown in Chapter 5 to receive requests and to pass segments to the requesting task. With the memory-manager executing as a separate task, serialization of requests for space is automatic, thereby eliminating the need for synchronization when modifying space-management structures. The separate-task approach is also advantageous when there is a need to have the requesting task wait until sufficient memory becomes available to fullfil a request. While one task is waiting, the memory manager can continue to service requests from other tasks.

3-9

121960-001

REAL MEMORY MANAGEMENT

ADVANCED MEMORY MANAGEMENT


In actual applications, the memory-management module may need to deal with such topics as Different kinds of memory. The ALLOCATE procedure needs a parameter to specify (for example) slow versus fast memory, and each type of memory needs its own free-space list. Multiprocessing. When multiple processors share some, but not all, of the available memory, the memory management module must know what memory addresses each processor can access. ALLOCATE must provide memory that is accessible to the processor that is ru~ming the calling task. You need to partition memory into areas so that all the addresses in a given area satisfy a common accessibility constraint. (The criteria for partitioning may also inClude memory types as mentioned previously.) Each area needs its own free-space list. Dynamic deletion of memory. When a memory parity error occurs, the need for continued system operation may require deleting the affected block of memory from the available-space lists, so that it cannot cause more trouble. Fixed-location segments. Often certain addresses of memory have specific uses, for example, video refresh buffers, and communication blocks for intelligent peripheral controllers. The memory manager must be aware of these areas and not use them for other purposes. Its interfaces must include the means for a task to request a specific special-purpose area. Compaction. It can happen that no single free memory space is large enough to satisfy an ALLOCATE request, even though there is enough total free memory. Some memory-management subsystems call on a compaction algorithm in such cases. Whether implementation of a compaction algorithm is worthwhile depends primarily on the pattern of memory usage in a given application. In many applications, this situation arises only when memory is nearly full anyway; compaction in this case merely delays the inevitable by an insignificant time. If you do implement compaction, you may choose to associate with each allocated segment a pointer that helps the compaction algorithm find the descriptors for that segment. With a memory-management scheme such as that exemplified here, the boundary tags are the most convenient container for descriptor pointers. With descriptor pointers in place, the compaction algorithm need only follow the available-space lists to discover all the opportunities for compaction.

3-10

121960-001

REAL MEMORY MANAGEMENT

BEFORE

CASE #0

AFTER

"FREE" START

"FREE" START

FROM NEXT FREE SEGMENT

(
FROM PRIOR FREE SEGMENT

SIZE NEXT PRIOR

I I

"FREE" "USED"

I I

SEGMENT TO BE FREED

I I

"USED" "FREE" START

I I

SIZE NEXT PRIOR

NEW SIZE NEXT PRIOR

"FREE"

"FREE"

121960-21

Figure 3-8. Possibilities for Combining Segments

3-11

121960-001

REAL MEMORY MANAGEMENT

BEFORE

CASE #1

AFTER

"USED"

"USED"

I
I

"USED" "USED"

I
I

I I

"USED" "FREE" START

I L

SEGMENT TOBE . FREED

I I

"USED" "FREE" START

SIZE NEXT PRIOR

SIZE NEXT PRIOR

"FREE"

"FREE"

121960-21

Figure 3-8 .. Possibilities for Combining Segments (Cont'd.)

3-12

121960-001

intel'

REAL MEMORY MANAGEMENT

BEFORE

AFTER

"FREE" START

CASE #2

"FREE" START

FROM PRIOR FREE SEGMENT

SIZE NEXT PRIOR

"FREE" "USED"

FROM NEXT FREE SEGMENT

SEGMENT TO BE FREED SIZE NEXT PRIOR

I I

"USED" "USED"

I I
FROM PRIOR FREE SEGMENT

I
I

"FREE" "USED"

I
I

"USED"

"USED"

VALUE OF ADDRESS ~ MOVEMENT OF ADDRESS ___ . .

121960-21

Figure 3-8. Possibilities for Combining Segments (Cont'd.)

3-13

121960-001

REAL MEMORY MANAGEMENT

BEFORE

AFTER

"USED"

CASE #3

"USED"

I J

"USED" "USED"

I I

I I

"USED" "FREE" START

I I
TO FORMER HEAD OF LIST

SEGMENT TO BE FREED

FROM FORMER HEAD OF LIST

"USED" "USED"

SIZE NEXT PRIOR

.~LJ
I I
"::"

I I

"FREE" "USED"

NULL

HEAD OF LIST

"USED"

"USED"

121960-21

Figure 38. Possibilities for Combining Segments (Cont'd.)

3-14

121960-001

REAL MEMORY MANAGEMENT

PL/M-286 COMPILER

960-501

date

PAGE

system-ID PL/M-286 DEBUG Vx.y COMPILATION OF MODULE MEMORY OBJECT MODULE PLACED IN :Fl:MEMORY.OBJ COMPILER INVOKED BY: :F3:PLM286.86 :Fl:MEMORY.PLM CODE DEBUG

$ PAGEWIDTH(71) TITLE('960-501') $ NOLIST


1

INCLUDE (:Fl:NUCSUB.PLM)

MEMORY:

DO; Externals. */

/*******************************************************/
/*
2 1

2
2 1
2

4
5 6
7

8 9 10

2 1 2 2

PROCEDURE (SLOT, RIGHTS, PHYS ADDR PTR, LIMIT) EXTERNAL; DECLARE SLOT SELECTOR, RIGHTS BYTE, PHYS ADDR PTR POINTER, LIMIT WORD; END POINT AT; NULLIFY: PROCEDURE (SLOT) EXTERNAL; DECLARE SLOT SELECTOR; END NULLIFY; GETSEGMENTBASE: PROCEDURE (SEL, BASE ADDR PTR) EXTERNAL; DECLARE SEL SELECTOR, BASE ADDR PTR-POINTER; END GETSEGMENTBASE; --

POINT AT:

/*******************************************************/
/*
11

Space-management definitions.

*/

DECLARE PARAGRAPH LITERALLY '16'; /* To run under SIM286, all segments must have a base address equal to zero mod PARAGRAPH. This is not required when running on iAPX 286 hardware. */ DECLARE MEM LINK LITERALLY 'PADDING (8) BYTE, START DWORD, HI TAG WORD, LO-TAG WORD, PRIOR DWORD, NEXT DWORD, SIZE DWORD'; /* Base address of link descriptor is always PARAGRAPH less than address of PRIOR field. Address of PRIOR field is always 0 mod PARAGRAPH. PRIOR, NEXT, and SIZE fields always point to a PRIOR - PARAGRAPH address. */ DECLARE TAGS SIZE LITERALLY '4'; /* The space used by both tag words */ DECLARE LINK LIMIT LITERALLY '27'; /* Limit used to construct descriptors for MEM_LINK */ DECLARE BLOCK MODULUS LITERALLY '32'; /* All memory blocks are an integral multiple of BLOCK_MODULUS in length.

12

13

14 15

*/

Figure 3-9. Code for Memory-Management Example

3-15

121960-001

REAL MEMORY MANAGEMENT

PL/M-286 COMPILER

960-501

date

PAGE

16

1
1

DECLARE NULL_PHYS_ADDR LITERALLY '0'; DECLARE USED LITERALLY '1', FREE LITERALLY '0'; /* Values of boundary tags */ DECLARE OK LITERALLY '0', FAILED LITERALLY '8000H'; /* Values of exception codes */ DECLARE DWRIGHTS LITERALLY '92H' /* For manipulating space-management data structures, this module needs these rights parameters: Present, DPL=0, data segment, grow up, writable. */;

17

18

19

/*******************************************************/

/*

Space-management data structures.

*/

20

DECLARE (FIRST AVLBL,LAST AVLBL,CURR AVLBL)DWORD PUBLIC; /* Physical-address pointers to chaIn of available space. These always point to PRIOR - PARAGRAPH to avoid calculating base addresses for MEM_LINKs. */ DECLARE SLOT A SELECTOR PUBLIC, WSLOT A WORD AT (@SLOT A) INITIAL (38H), /* 7 */ SLOT 8 SELECTOR PUBLIC, WSLO~ B WORD.AT (@SLOT B) INITIAL (40H), /* 8 */ SLOT_C SELECTOR PUBLIC, WSLOT C WORD AT (@SLOT C) INITIAL (48H); /* 9 */ /* "Scratch"-slots for addres~ing MEM LINKS. */ /* Be sure to reserve these slots with the Builder */

21

/*******************************************************/ Round a size parameter upwards to next greater */ /* or equal (N * BLOCK_MODULUS) ~ TAGS_SIZE for some N */
/*
22
23 24
1 2

ROUND_SIZE: PROCEDURE (A_PTR) PUBLIC REENTRANT; DECLARE A PTR POINTER, ADDR BASED A PTR DWORD; ADDR BLOCK MODULUS

* (((ADDR + TAGS SIZE


- TAGS_SIZE; 25
2

~ 1)

/ BLOCK_MODULUS) + 1)

END ROUND_SIZE;

/*******************************************************/ /* Delink from available space list. */


26
27
1

DELINK:

PROCEDURE (THIS_SEL) REENTRANT; SELECTOR, BASED THIS SEL STRUCTURE (MEM_LINK); STRUCTURE (MEM_LINK),

2 2

DECLARE THIS SEL THIS-LINK

28

DECLARE PRIOR LINK BASED SLOT_C

Figure 3-9. Code for Memory-Management Example (Cont'd.)

3-16

121960-001

REAL MEMORY MANAGEMENT

PL/M-286 COMPILER

960-501 NEXT LINK

date

PAGE

BASED SLOT_C

STRUCTURE (MEM_LINK);

29 30 31 32 33 34 35 36 37 38 39 40 41 42 43

2 2 2 3 3 3 2 2 2 3 3 3 2 1
2

IF THIS LINK. PRIOR = NULL PHYS ADDR /* This is the beginning of the list. */ THEN FIRST AVLBL = THIS LINK.NEXT ; ELSE DO; /* Update link-from prior segment. */ CALL POINT AT(SLOT C, DWRIGHTS, -@THIS LINK.PRIOR, LINK_LIMIT); PRIOR_LINK. NEXT = THIS_LINK. NEXT; END; IF THIS LINK. NEXT = NULL PHYS ADDR /* This is the end of the list. */ THEN LAST AVLBL = THIS_LINK. PRIOR; ELSE DO; /* Update link from next segment. */ CALL POINT AT(SLOT C, DWRIGHTS, -@THIS LINK.NEXT, LINK_LIMIT); NEXT_LINK. PRIOR THIS_LINK. PRIOR; END; END DELINK;
/***************************************************** **/

FIND FIRST FIT: PROCEDURE (SIZE,BASE ADDR PTR) WORD REENTRANT; DECLARE SIZE WORD, BASE ADDR PTR POINTER, BASE-ADDR-BASED BASE ADDR_PTR DWORD; DECLARE CURR LINK BASED SLOT_A STRUCTURE (MEM_LINK), PHYS-SIZE DWORD, SIZE-DIFF DWORD, /* Boundary tag items */ BOUND ADDR DWORD, BOUND-MID BASED SLOT B STRUCTURE (MEM LINK) , BOUND=HI BASED SLOT=B STRUCTURE (MEM=LINK); DECLARE TOP LOOP LABEL; PHYS SIZE = SIZE; CALL-ROUND SIZE(@PHYS SIZE); CALL POINT-AT(SLOT A,-DWRIGHTS, @CURR_AVLBL, LINK_LIMIT); TOP LOOP: IF-SLOT A SELECTOR$OF(NIL) /* Check for end of list */ THEN DO; IF FIRST AVLBL = NULL PHYS ADDR /* The list is empty~ */ THEN RETURN FAILED; END; ELSE CALL POINT AT(SLOT A, DWRIGHTS, @FIRST AVLBL, LINK LIMIT); /* Continue from beginning of list. */ IF CURR LINK. SIZE < PHYS SIZE THEN /* This segment is-too small, so . */

44

45 46 47 48 49 50 51 52 53 54

2 2 2 2 2
2 3

3 3 2

55

Figure 3-9 .. Code for Memory-Management Example (Cont'd.)

3-17

121960-001

REAL MEMORY MANAGEMENT

PL/M-286 COMPILER 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70
2

960-501

date

PAGE

3 3 3 4 4 4 3 3
2

DO; /* Look at next free segment in the list. */ CALL POINT AT(SLOT A, DWRIGHTS, @CURR LINK.NEXT, LINK LIMIT); IF CURR AVLBL = CURR LINK. NEXT /* Have searched entire list without a hit. */ THEN DO; CALL NULLIFY(SLOT A); RETURN FAILED; END; GOTO TOP LOOP; END; /* Segment too small. */ SIZE DIFF = CURR LINK. SIZE - PHYS SIZE; /* Always a multiple of BLOCK_MODULUS */ IF SIZE DIFF = 0 THEN DO; /* This segment is a close fit. */ CURR AVLBL = CURR LINK. NEXT; CALL-DELINK (SLOT=A);

2 2

3 3 3 3 3 3 3 3 3 3 3 3
2

71
72

73 74 75 76 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 95 96 97

/* set lower boundary tag */ CURR LINK.LO TAG = USED; /* set upper-boundary tag */ CALL GET$SEGMENT$BASE (SLOT A, @BOUND_ADDR); BASE ADDR = BOUND ADDR; BOUND ADDR = BOUND ADDR + CURR LINK.SIZE + TAGS SIZE; CALL POINT AT(SLOT-B,DWRIGHTS,@BOUND ADDR,LINK LIMIT); BOUND_HI. HI_TAG =USED; - CALL NULLIFY(SLOT A); CALL NULLIFY(SLOT_B); BASE ADDR = BASE ADDR + PARAGRAPH; RETURN OK; END; /* Close fit. */ ELSE DO; /* It will fit here with room to spare. */ CALL GET$SEGMENT$BASE (SLOT A, @CURR AVLRL); /* Set boundary tag at end-of new segment. */ BOUND ADDR = CURR AVLBL + CURR LINK. SIZE + TAGS SIZE; CALL POINT AT(SLOT B,DWRIGHTS,@BOUND ADDR,LINK LIMIT); BOUND HI.HI TAG = USED; /* Calculate starting address of the new segment. */ BOUND ADDR = CURR AVLBL + SIZE DIFF; BASE ADDR = BOUND ADDR + PARAGRAPH; /* set the boundary fields between the 2 segments. */ CALL POINT AT(SLOT B,DWRIGHTS,@BOUND ADDR,LINK LIMIT); BOUND MID. START = CURR AVLBL; BOUND-MID.HI TAG = FREE; BOUND-MID.LO-TAG = USED; /* Change size of available segment, considering the 2 boundary tag words. */ CURR LINK. SIZE = SIZE DIFF - TAGS SIZE; CALL-NULLIFY(SLOT A);-CALL NULLIFY(SLOT B); RETURN OK; END; /* Room to spare. */ END FIND FIRST FIT; $EJECT -

3 3 3 3 3 3 3 3 3 3 3 3 3 3
2

Figure 3-9. Code for Memory-Management Example (Cont'd.)

3-18

121960-001

inter
PL/M-286 COMPILER

REAL MEMORY MANAGEMENT

960-501

date

PAGE

/*******************************************************/ /* Place a segment into the available space list. */


98 99 100
1 2 2

RETURN_SPACE:

PROCEDURE (FREE_SEG) REENTRANT; BASED FREE SEG SELECTOR, STRUCTURE (MEM LINK);

DECLARE FREE SEG FREE=LINK

DECLARE CURR LINK BASED SLOT A STRUCTURE (MEM_LINK), DWORD, NEIBR ADDR NEIBR-LINK BASED SLOT B STRUCTURE (MEM_LINK), DWORD, FREE BASE FREE-SIZE DWORD, DWORD, HI SIZE BYTE, NCASE HI USED LITERALLY '01H', LO-USED LITERALLY '02H'; CALL GET$SEGMENT$BASE (FREE SEG, @FREE BASE); FREE BASE = FREE BASE - PARAGRAPH; /* point to tags */ FREE SIZE = GET$SEGMENT$LIMIT (FREE SEG); FREE-SIZE = FREE SIZE + 1; CALL-ROUND SIZE (@FREE SIZE); /* Determine which case. */ NCASE = 0; /* Check higher neighbor. */ NEIBR ADDR = FREE BASE + FREE SIZE + TAGS SIZE; CALL POINT AT (SLOT B,DWRIGHTS,@NEIBR ADDR,LINK LIMIT); IF NEIBR LINK.LO TAG = USED THEN NCASE=NCASE OR-HI_USED; ELSE HI SIZE = NEIBR LINK. SIZE; /* Save */ /* Check-lower neighbor. */ NEIBR ADDR = FREE BASE; CALL POINT AT(SLOT B,DWRIGHTS,@NEIBR ADDR,LINK LIMIT); IF NEIBR LINK.HI_TAG=USED THEN NCASE~NCASE OR La_USED;

1'H 1'32 103 104 105

2 2 2 2 2

106 107 108 109 111

2
2 2 2 2

112 113 114


116 117 118 119
120 121 122 123

2 2 2 2 2 2 2 2 2 2
2

/* Which segment should become the new current one? */ IF (NCASE AND La USED)<>O THEN CURR AVLBL-= FREE BASE; /* low neighbor used */ ELSE CURR-AVLBL = NEIBR LINK. START; /* low free */ CALL POINT=AT (SLOT_A, DWRIGHTS,@CURR_AVLBL, LINK_LIMIT) ;

124 125 126 127 128 129


130

2 2

/* Calculate size of new segment. */ IF (NCASE AND LO USED) = La USED /* if low neibr used */ THEN CURR LINK.SIZE = 0; ELSE /* already contains size of low neighbor */ CURR LINK. SIZE = CURR LINK. SIZE + TAGS_SIZE; IF (NCASE AND HI USED) <> HI USED /* if high neighbor free *7 THEN CURR LINK.SIZE = CURR LINK.SIZE+HI SIZE+TAGS_SIZE; CURR_LINK.SIZE = CURR_LINK.SIZE + FREE_SIZE;

2 3 3 3

/* Set next and prior links in new segment. */ IF NCASE = 3 /* neither neighbor free */ THEN DO; /* insert at head of available list */
CURR LINK. PRIOR = NULL PHYS ADDR; CURR=LINK.NEXT FIRST=AVLBL; END;

Figure 3-9. Code for Memory-Management Example (Cont'd.)

3-19

121960-001

REAL MEMORY MANAGEMENT

PL/M-286 COMPILER 131 132 133 134 135 136 137 138 139
2 2

960-5131

date

PAGE

3 3 3 3 3
4 4

140
141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 166

4
3
2
2

ELSE IF (NCASE AND HI USED) <> HI USED /* if high neighbor-free */ THEN DO; /* Dispose with high neighbor's links. */ /* Make selector for high neighbor. */ NEIBR ADDR = FREE BASE + FREE SIZE + TAGS SIZE; CALL POINT AT(SLOT B,DWRIGHTS~@NEIBR ADDR~LINK LIMIT); IF NCASE =-0 /* both neighbors free */ THEN /* remove one from available list. */ CALL DELINK (SLOT B); ELSE /* Must be case 2. * / DO /* Transfer links to new current. */; CURR LINK. PRIOR = NEIBR LINK.PRIOR; CURR-LINK.NEXT = NEIBR-LINK.NEXT; END; END; /* disposing with high neighbor's links. */ IF (NCASE AND LO USED) = LO USED /* if low neighbor used. */ THEN DO; /* Fix up links in prior and next segments. */ IF CURR LINK. PRIOR = NULL PHYS ADDR THEN /* there is no prior */ FIRST AVLBL CURR AVLBL; ELSE DO; /* fix up prior */ NEIBR ADDR = CURR LINK.PRIOR; CALL POINT AT (SLOT B, DWRIGHTS, @NEIBR_ADDR, LINK-LIMIT); NEIBR_LINK.NEXT = CURR_AVLBL; END; IF CURR LINK. NEXT = NULL PHYS ADDR THEN /* there is no next */ LAST AVLBL = CURR AVLBL; ELSE DO; /* fix up-next */ NEIBR ADDR = CURR LINK. NEXT; CALL POINT AT (SLOT B, DWRIGHTS, @NEIBR_ADDR, LINK-LIMIT); NEIBR LINK. PRIOR = CURR AVLBL; END; END; /* Fixing up links. */

3 3 3 4 4
4 4 3

3 3 4 4
4 4 3 2
2 2

2
2

2
2

/* Set tag words */ CURR LINK.LO TAG = FREE; /* Set START-field in new current segment. */ NEIBR ADDR = CURR AVLBL + CURR LINK. SIZE + TAGS SIZE; CALL POINT AT(SLOT B,DWRIGHTS,@NEIBR ADDR,LINK LIMIT); NEIBR LINK~START =-CURR AVLBL; NEIBR-LINK.HI TAG = FREE; CALL NULLIFY (SLOT_A); CALL NULLIFY (SLOT_B);
END RETURN SPACE; $EJECT -

Figure 3-9. Code for Memory-Management Example (Cont'd.)

3-20

121960-001

REAL MEMORY MANAGEMENT

PL/M-286 COMPILER

960-501

date

PAGE

/***************************************************** **/

167 168

ALLOCATE: PROCEDURE (SLOT, RIGHTS, SIZE, EXCEP PTR) PUBLIC REENTRANT; DECLARE SLOT SELECTOR, BYTE, RIGHTS SIZE WORD, EXCEP PTR POINTER, EXCEP-BASED EXCEP PTR WORD; DECLARE BASE_ADDR DWORD;

169 170 171 172 173 174 175 176 177

2 2 2 3 3 3 2 2 2

IF OK <> FIND FIRST FIT (SIZE, @BASE_ADDR) THEN DO; EXCEP = FAILED; RETURN; END; CALL POINT AT (SLOT, RIGHTS, @BASE_ADDR, SIZE-I); EXCEP = OK; END ALLOCATE;
/***************************************************** **/

178 179

1 2

FREE SEG: PROCEDURE (SLOT, EXCEP_PTR) PUBLIC REENTRANT; DECLARE SLOT SELECTOR, EXCEP PTR POINTER, EXCEP-BASED EXCEP PTR WORD; CALL RETURN SPACE (SLOT); CALL NULLIFY (SLOT); EXCEP = OK;

180 181 182 183

2 2 2 2

/***************************************************** **/

184

END MEMORY;

Figure 3-9. Code for Memory-Management Example (Cont'd.)

3-21

121960-001

Task Management

CHAPTER 4 TASK MANAGEMENT


The primary responsibility of an operating system is to allocate the processor to the executing tasks so that each task makes progress consistent with its role in the application. This chapter examines how the task-oriented features of the iAPX 286 hardware apply to conventional task-management concepts.

HARDWARE TASK-MANAGEMENT FEATURES


The operating system's responsibility for managing a multitasking system is reduced by iAPX 286 features for saving and restoring task state and switching between tasks.

Storing Task State


The state of a task (from the processor's point of view) is the contents of the registers used by that task. The architecture of the iAPX 286 defines a special type of segment, the task state segment (TSS), for storing the 80286-related state of a task. Multitasking operating systems on any processor need to store similar information. The iAPX 286 requires merely that a specific format be used so that the CPU can store and restore task state automatically. Figure 4-1 illustrates a TSS and related hardware structures. The processor keeps the location of the TSS of the currently executing task in the task register. The task register has two parts: The "visible" portion, which a task can access. This part contains a selector to the descriptor (in the G DT) for the current TSS. The "invisible" portion, which tasks do not control. When the contents of the visible portion are changed, the processor loads the invisible portion with the base and limit values from the TSS descriptor indexed by the selector in the visible portion.

There are two ways to change the task register: By one of the task switching operations described later in this section. By the L TR instruction. L TR is used to give the task register its initial value during system initialization. Only privilege-level 0 (PL~O) procedures can execute LTR.

Because TSSs correspond one-to-one with tasks, the selector of a TSS uniquely identifies a task. The STR instruction reads the task register into a selector. Operating-system procedures can use STR to identify the calling task. The built-in variable TASK$REGISTER gives PL/M-286 programs access to the task register. The items in the TSS fall into four classes: Back link. Contains a selector to the TSS of the calling (or interrupted) task (if any). LDT selector. Contains a selector to this task's LDT.

4-1

121960-001

TASK MANAGEMENT

CPU TASK REGISTER

INTEL RESERVED

TR~----t-'"
r- __ ..!.5 ____ 0___ ,

pln01001~1

BASE 23_,.

~
0

SYSTEM SEGMENT

BASE,._o

1
I

il
I 23

I
I

PROGRAM INVISIBLE

15

~A~:'T

i }t --------________________J
LlMIT,._o
J

I I

DESCRIPTOR

L____

0 1----__ I

15
TASK LOT SELECTOR OS SELECTOR SS SELECTOR CS SELECTOR ES SELECTOR
01

o OFFSET
42 40 38 36 34 32 30 28 26 24 22 20 18 16 14 12 10
8 INITIAL STACKS FOR CPL 0,1,2 CURRENT TASK STATE

BYTE

SI BP SP BX
'-----I~

TASK STATE SEGMENT

OX CX AX FLAG WORD IP (ENTRY POINT) SS FOR CPL 2 SP FOR CPL 2 SS FOR CPL 1 SP FOR CPL 1 SS FOR CPL 0 SP FOR CPL 0 BACK LINK SELECTOR TO TSS

6
4

121960-23

Figure 4-1. Task State Segment and Register

Processor registers and flags. Used to store the processor state of the task. Note in particular the NT flag, which indicates when the BACK LINK contains a valid selector.

Initial stacks. Contain the initial SS and SP values to be used when a CALL transfers control to any of the higher PLs (0, 1, or 2). No stack pointer is needed in the TSS for the PL-3 stack because that stack is either the current stack (pointed to by the SS:SP fields) or is locatable via the chain of stack pointers in higher-level stacks.

4-2

121960-001

TASK MANAGEMENT

The processor updates only the back link, the registers, and the flags as part of a task switching operation. The processor merely reads the initial stack fields (during interlevel CALLs) and the LDT selector (during a task switch). The operating system is responsible for initializing the stack and LDT fields. It must also update the LDT selector before changing the LDT register.

Switching Tasks
Since a multitasking system typically has more tasks than it has processors to execute those tasks, there must be some provision for causing a processor to cease executing one task and begin executing another. The 80286 has several such mechanisms, each appropriate to different situations. All use ordinary JMP, CALL, INT, or IRET instructions. The destination operand determines whether a task switch occurs. Table 4-1 summarizes the operations and operands that cause switching of tasks. In PL/M-286, an indirect CALL statement to the selector of a TSS descriptor or task gate causes generation of an intertask CALL instruction. The W AIT$FOR$INTERRUPT built-in procedure generates an IRET instruction. The operand of a CALL or JMP instruction is a pointer containing both selector and offset parts; in this case, the offset is not used, however. The selector portion may refer either to the descriptor of a TSS or to a task gate for a TSS. The result is the same in either case. The difference lies in the protection of access to the TSS. TSS descriptors, which may reside only in the GDT, normally have DPL set to zero to prevent unauthorized task switching by procedures outside the operating system. Task gates may reside in any descriptor table, giving task switching ability to procedures that have access to the gate. A task gate in an LDT gives task switching power only to that LDT's task. A task gate in the IDT gives task switching power to interrupts. This reduces operating-system involvement in interrupt handling, and thereby reduces the time needed to respond to interrupts. The operating system normally uses a JMP instruction to a TSS descriptor to cause a task switch. A CALL instruction to a task gate in an LDT is useful for implementing coroutines. The IRET instruction exits from a nested task that is invoked by a CALL as well as from one invoked by an interrupt. (You cannot use the RET instruction to exit from a CALLed task; RET does not perform a task switch.) The NT (nested task) flag controls the function of the IRET instruction. When a CALL (or interrupt) causes a task switch, the processor sets the NT flag as the new task begins and fills the back-link of the new TSS with the selector of the calling task's TSS. When the NT flag is set, the IRET instruction causes a task switch to the task whose TSS selector is stored in the back-link. The new task must be marked as busy (type code = 3); otherwise an exception occurs.

Table 4-1. Task Switching Operations


Operation Descriptor Referenced Descriptor Table

CALL, JMP, IRET CALL, JMP INT instruction, external interrupt, exception

TSS task gate

GDT GDT, LDT

task gate

IDT

4-3

121960-001

TASK MANAGEMENT

If the processer, while executing an IRET instruction, finds the NT flag not set, this indicates a return to an interrupted procedure in the same task. Refer to Chapter 6 for details on interrupt procedures.
For CALL and JMP instructions, success of a task switch operation depends on the type field of the TSS descriptor. If the type code is 1, denoting an available task, then the task switch proceeds. If the type code is 3, denoting a busy task, then an attempt to switch to the task causes an exception. A task is busy under either of these conditions: The task is the currently executing task. The task is on the chain of TSS back-links from the currently executing task. This prevents recursion of task invocations. A task should be restarted only by the the task that interrupts it or by the operating system after the task has been removed from the back-link chain.

If the target task is not busy, the processor takes these steps in executing a task switch:
Saves all registers in current TSS Loads TR with new TSS descriptor Loads all registers and flags from new TSS (including LDT register)

If switch is due to CALL (or interrupt), sets NT flag and sets back-link in new TSS to point to previous TSS

If switch is due to JMP or IRET, changes the old task's descriptor type code to one, indicating that the task is no longer busy
Resumes new task where it left off (i.e., CS:IP from new TSS)

Note that you cannot pass parameters by an intertask CALL. It is possible to share data between tasks, however. Chapter 5 takes up this subject.

ROLE OF OPERATING SYSTEM IN TASK MANAGEMENT


Task switching without operating-system involvement is possible (though not necessarily advisable) in static systems. Consider the following two application-driven scheduling strategies for static systems: 1. A fixed sequence of tasks is defined, and each task, when ready to relinquish the processor, voluntarily calls or jumps to the next task in sequence. Barring any errors, each task gets a share of processor time. All tasks in the system service external events. The interrupt mechanism of the iAPX 286, by means of interrupt tasks, causes task initiation in real-time response to those events.

2.

Strategy 1 is not viable in a highly protected system. Errors do happen. An erroneous program might easily skip a task entirely. A programming error that causes a tight loop in one task would prevent all other tasks from being serviced. Strategy 2 can be adequate by itself for certain real-time systems with a static mix of tasks. Task switching by interrupt is usable in dynamic systems, too, but rarely do all tasks in a dynamic system deal exclusively with interrupts. Therefore, in dynamic systems, in highly protected systems, and in systems with tasks that do not provide real-time processing, the operating system may need to assist the processor with task switching.

4-4

121960-001

inter

TASK MANAGEMENT

State Model of Task Scheduling


The role that the operating system must play in using the iAPX 286 task features is most conveniently expressed in terms of a state-transition model. To distinguish from the processing state of a task (as stored in the TSS), the term scheduling state is used here. Figure 4-2 illustrates the scheduling states that a task may assume and the events that may cause a change of state. A RUNNING task is the one that the processor is executing. A RUNNING task continues to execute until
It voluntarily gives up control because it needs to wait for some event, such as completion of an I/O operation, data from another program, or the end of a specific period of time. It is preempted, i.e., forced to give up control. The interrupt mechanism may cause preemption in order to execute an interrupt task, or the operating system may preempt periodically (via timer interrupt) to give another task a chance to receive its share of the processor's attention.

A WAITING task may be waiting for any of several events: Completion of a request to the OS for I/O A signal from another task Data from another task The end of a time-delay period

The READY state is really a special case of the WAITING state. A READY task is waiting for one specific event: the availability of a processor to execute it. A task becomes READY when first created. A WAITING task becomes READY upon occurrence of the event (or events) for which it is waiting. A RUNNING task becomes READY when preempted.

,.

INITIATE

121960-22

Figure 4-2. Scheduling State Transition Diagram

4-5

121960-001

TASK MANAGEMENT

Usually, termination of a task is possible regardless of its scheduling state; therefore, this diagram does not illustrate the transition to "terminated" state.

Interfacing with the Hardware Scheduler


Many applications of the iAPX 286 need both software scheduling (by the operating system) and hardware scheduling (by the interrupt mechanism), but when two schedulers work with the same set of tasks, you must ensure that they work together harmoniously. Figure 4-3 illustrates the additional complexity of dual schedulers. Note that scheduling state under hardware scheduling is nearly analogous to scheduling state under software scheduling. The priority concept, often used in software scheduling, has its analog in the priority mechanism implemented by the interrupt controller. The priority of hardware-scheduled tasks relative to software-scheduled tasks is controlled by two factors: The CPU's interrupt-enable flag (IF), and the instruction's CLI (which clears IF) and STI (which sets IF) The 8259A Programmable Interrupt Controller, an LSI component that allows selective masking of interrupts so that software can prevent some external interrupts.

When IF is set, all hardware-scheduled tasks whose interrupts are not masked out have higher priority than all software-scheduled tasks. When IF is reset, all hardware-scheduled tasks have lower priority than the currently executing task. Only the operating system (CPL < = IOPL) has the right to execute

HARDWARE SCHEDULED

INITIATE

SOFTWARE SCHEDULED

121960-27

Figure 4-:3. Expanded Scheduling State Transition Diagram

4-6

121960-001

TASK MANAGEMENT

eLI and STI instructions due to the significant effect that priority setting has on correct, overall system operation. The ability for an interrupt handler to be an independent task not only I~rotects the handler from the rest of the system but also permits greater flexibility in the kinds of fUll", '1S an interrupt handler can perform. An interrupt handler that is a task can use operating system fUll~lions that might change its scheduling state. For example, if an interrupt handler requests the operating system to read a disk record, the operating system may change the interrupt handler task's scheduling state from RUNNING to WAITING while the I/O operation takes place. (Other tasks may then execute in the meantime.) If the interrupt handler were a procedure instead of a task, it would be difficult to identify it separately from the task that it interrupted. The operating system must keep track of whether a task is attached to an interrupt (i.e., has a task gate in the IDT). Occurrence of an interrupt can at any time dispatch the task attached to the interrupt. This happens without intervention by the operating system; therefore, when a task calls on operating system services, the operating system cannot assume that the calling task is the same as the latest software-scheduled task. An operating system can easily determine whether the current task is hardware or software scheduled if it associates with each task a Boolean that indicates whether the task was software-scheduled. The operating system must ensure that only one task at a time is so marked. The operating system can use the STR instruction to identify the current task. If the current task is not marked as software-scheduled, then the interrupt mechanism must have dispatched it. By knowing whether a task is attached to an interrupt, the operating system can Avoid executing a task that is awaiting an interrupt. A software-scheduled task cannot respond to an interrupt. An exception occurs when an interrupt attempts to invoke a busy task. Avoid preempting an executing interrupt task. That task should finish before software schedules another task. Decide what action to take when an interrupt-dispatched task calls on operating-system scheduling services. Such action might be to mask off the interrupt or to place a gate for a counting task in the IDT to mark lost interrupts.

When the operating system changes a task from hardware scheduling to software scheduling, it must update the chain of tasks that threads through TSSs. Every hardware scheduled task has a link in its TSS to the TSS of the interrupted task. If the system's interrupt structure permits nesting of interrupts, then the chain of interrupted tasks may be arbitrarily long. To change a task to software-scheduled mode, the operating system must take these actions (as figure 4-4 illustrates): Reset the nested-task flag (NT) of the current task. Nullify the back-link field in the current TSS (as insurance in case it is ever used). Dispatch the prior task on the back-link chain.

Changing Scheduling State


In terms of the state model of scheduling, the operating system's job is to effect transitions between scheduling states according to the expressed needs of individual tasks and of the application as a whole. In many cases, applications drive the scheduling activities of the operating system. Applications express their scheduling needs by calls to operating system functions that indirectly relate to scheduling. For

4-7

121960-001

TASK MANAGEMENT

TASK X TSS FLAGS NT=1 BACK LINK TSS FLAGS NT=1 TSS FLAGS NT=1 TSS FLAGS NT=1

L,/

BACK LINK

L,/

BACK LINK

L/

BACK LINK CURRENTLY EXECUTING TASK

B E

'\
.r

~I R

-----------------------------------------------------SOFTWARE-SCHEDULED TASKS
TSS FLAGS NT=O BACK LINK CURRENT SOFTWARESCHEDULED TASK TS!> FLAGS NT=O TSS FLAGS NT=O

HARDWARE-SCHEDULED TASKS

BACK LINK

.r-

BACK LINK

TSS FLAGS NT=1 BACK LINK

TSS FLAGS NT=1

TSS FLAGS NT=1

L,/

BACK LINK

BACK LINK CURRENTLY EXECUTING TASK

A F

-----------------------------------------------------~ I SOFTWARE-SCHEDULED TASKS


TASK X

HARDWARE-SCHEDULED TASKS

\
~

TSS FLAGS NT=O BACK LINK CURRENT SOFTWARESCHEDULED TASK

TSS FLAGS NT=O

TSS FLAGS NT=O

TSS FLAGS NT=O

-:r-

BACK LINK

BACK LINK

.r-

BACK LINK

121960-57

Figure 4-4. Changing Scheduling Mode

4-8

121960-001

TASK MANAGEMENT

example, when an application calls the operating system to request receipt of a message from another task, the operating system determines whether a message is waiting for delivery. If no message is waiting, then the operating system must switch the task from RUNNING state to WAITING state. Later when another task calls the operating system to send a message to the waiting task, the operating system must change the task from WAITING state to READY state. In cases such as these, the operating system plays a bookkeeping role, simply keeping track of which tasks are waiting and associating events with the correct waiting tasks. The operating system plays a much more significant role, however, when it determines which of the ready tasks to dispatch (the transition from READY state to RUNNING state) or when to preempt the task that is executing (the transition from RUNNING state to READY state). These decisions affect the overall performance of the system, both throughput and response to external events.

POLICIES AND MECHANISMS

Because of the difficulty of establishing an effective policy for dispatching and preemption decisions, it is desirable to clearly separate mechanisms from policies. The only control an operating system can exercise over tasks is deciding which task to execute and how long to let it run before changing to another task. The scheduling mechanisms must exert such control in a manner that the policies can adjust. For example, to control how long a task executes, the scheduler implements a mechanism for preempting the task after a certain time period has elapsed. The mechanism consists of an interval timer (such as Intel's 8254 Programmable Interval Timer) that interrupts the executing task periodically so that the operating system can determine whether the task has yet exceeded the time-slice allocated to it. The length of the time-slice is a variable that the policy layer can control. The policy layer sets the length of the time-slice to reflect the importance of the task. The separation of policy and mechanism applies as well to deciding which task to execute next. For example, the scheduling mechanism associates a priority number with each task. When changing tasks it always chooses the task with highest priority. The priority, however, is a variable, and the policy layer determines its value. For the policy layer to make reasonable decisions about scheduling, the mechanism layer may need to collect statistics about the run-time behavior of tasks, for example:

Elapsed time in the system Total of actual time serviced by processor Running average of actual length of time-slice

(Note that interrupt-scheduled tasks subtract from the time allocated to software-scheduled tasks.) The privilege levels of the iAPX 286 architecture can support the separation between mechanisms and policies. The mechanisms belong to the kernel of the operating system, and as such they should be well tested, highly reliable, and not subject to frequent change; in other words, they are good candidates for PL O. Policies, on the other hand, are subject to frequent change and, as a result, are less reliable. Running scheduling policies at PL 1 ensures that errors cannot corrupt kernel procedures.

4-9

121960-001

TASK MANAGEMENT

SCHEDULING POLICIES

The actual implementation of scheduling policies depends on the needs of the application and the behavior of the tasks in the system. Consider a simple policy that Gives all tasks equal priority Allocates the processor once to each task in turn Allocates the same maximum time-slot to each task

Even this seemingly "fair" policy actually favors certain tasks over others. A task that frequently relinquishes the processor voluntarily (because, for example, it frequently has to wait for I/O) rarely uses the full time-slot. A "processor-bound" task (for example, a computational task that uses many instructions to accomplish its purpose but rarely does I/O), on the other hand, almost always uses the full time-slot, forcing the operating system to preempt it. Over a period of many time-slots, processorbound tasks will receive much more attention from the processor than I/O-bound tasks. Whether this situation is desirable depends on the roles of the tasks in the application. Attempting to discriminate against processor-bound tasks by introducing a priority mechanism can result in different problems. Suppose all I/O-bound tasks have higher priority than all processor-bound tasks. At the end of a time-slice or when a task voluntarily gives up the processor, the scheduler switches to one of the higher-priority tasks if one is ready; if none is ready, it switches to one of the lowerpriority tasks. The problem occurs when there is a such a number of I/O-bound tasks that at least one of them is always ready. In this case, the lower-priority, processor-bound tasks never execute. Many more scheduling policies than those outlined here are possible. The examples given merely illustrate how important it is that the characteristics of the tasks in the system be known and that the policies match those characteristics. Refer to Coffman and Denning (see "External Literature" in the Preface) for a survey of these and other policies.

Structuring Task Information


If your operating system is to manipulate tasks efficiently, you must structure task-related information so that the operating system can get the information it needs as quickly as the application requires. The processor implements part of this structure through interlocking links in the GDT, LDT, and TSS. In addition to this structure, the operating system must deal with additional state information, which might include

The data-segment alias to the task's LDT The data-segment alias to the task's TSS Scheduling state Scheduling parameters (for example, time-slice, priority) Scheduling statistics (for example, total processor time used, average time-slice used, expected running time) Links for queues of waiting and ready tasks

4-10

121960-001

TASK MANAGEMENT

This additional state information is referred to here as the task database (TDB). There are two common modes of access to the task database: 1. 2. From within the current task to information about the current task. Most operating system services use this mode of access, including the scheduler's time-slice interrupt procedure. From within the current task to information about other tasks. The scheduler uses this mode of access to find the next task to execute.

ACCESS MODE 1

Access mode 1 can be efficiently implemented via the GOT. All descriptors for the key segments relating to one task reside in adjacent GOT slots. If the operating system can focate one of these descriptors (as by using the STR instruction to obtain a selector to the current TSS), then it can locate any of the others by a simple addition or subtraction. Figure 4-5 suggests one possible way of organizing the TOB. In this example the TOB is stored in a data structure called the task information block (TIB). In large systems you may need to minimize the number of GOT slots used for task information, so as not to unduly limit either the number of tasks or the number of other descriptors that GOT can hold.

TIB

GOT
I

I I I I
I

I I I

TIB LOT ALIAS LOT TSS ALIAS TSS


I

~ '\. -:'\
~
I I I I I I I
\

--

--

LOT

I
I I I
I

TSS

' .... _--

LOT SELECTOR

121960-24

Figure 4-5. Task Information Structure A

4-11

121960-001

TASK MANAGEMENT

The example in figure 4-5 illustrates the general case in which all the pertinent information is in separate segments. This case uses five GOT slots. You can free one GOT slot by including the TSS within the TIB. The TIB descriptor can serve as the data-segment alias for the TSS. Figure 4-6 illustrates such a configura tion. Speed of access to the TOB is critical in some applications. Figure 4-7 shows another configuration of task information that helps improve access speed. Here the task's stack segment for PL 0 contains both the TSS and the TIB. The advantage of this approach is that the TIB and the TSS can be addressed relative to the base address that the processor loads into SS when transferring control to a PL-O operatingsystem procedure. This eliminates the need for loading the OS or ES register to access the current task's TSS or TIB and also frees a segment register for other use. In such a case, the SP portion of the TSS initial stack values for PL 0 is set to an offset beyond the TIB. In many. applications it is still desirable for the GOT to hold a descriptor for the TIB so as to facilitate access to TIBs for tasks other than the current one.
ACCESS MODE 2

When the scheduler is dispatching a different task, it needs quick access to the queues of waiting and ready tasks. If the links that implement these queues thread through the many segments that contain TIBs, the time needed to search and update the queues is extended by the time needed to load a

LOT

GOT

LOT ALIAS LOT TSS TIB

*'
,

TIB

"

TSS ' ....... _ LOT SELECTOR

'--.

121960-25

Figure 4-6. Task Information Structure B

4-12

121960-001

TASK MANAGEMENT

LOT

D
PRIVILEGE-LEVEL ZERO STACK SEGMENT LOT LOT TSS TIB ALIAS STACK TIB TSS LOT SELECTOR

121960-26

Figure 4-7. Task Information Structure C

segment register for each segment visited. This suggests that these queues all reside together in a separate scheduler queue segment. A pointer in each queue element can refer back to the corresponding task. Figure 4-8 illustrates such a structure.

EXAMPLE OF A DISPATCHER
The process of changing a READY task to RUNNING stateis known as "dispatching." Figure 4-9 shows a simple dispatching procedure. This procedure executes at PL 0 in the task that calls it. No call gate is provided, so only other operating system procedures can call DISPATCHER; for example, a procedure that switches the calling task to WAITING state, or a timer interrupt procedure that determines when to preempt the task that it interrupts. The DISPATCHER procedure is coded in ASM286 instead of PL/M-286 because it is more convenient to code an indirect, intertask JMP instruction in ASM286. DISPATCHER makes two assumptions about the rest of the operating system that justify the use of an intertask JMP instead of an intertask CALL: A task can call operating system procedures that change it from RUNNING state, so a task does not need to execute an IRET for that purpose. The operating system procedure that calls DISPATCHER may set the TSS back link so as to intercept an IRET if the task executes one. (When the operating system dispatches a task, it does not make sense for an IRET to return to the previously executing task. That task may, for example, be waiting for an event and not be ready to execute.)

4-13

121960-001

inter

TASK MANAGEMENT

SCHEDULER QUEUE SEGMENT QUEUE ELEMENTS READY QUEUES BY PRIORITY

GOT

WAITING QUEUES BY EVENT

121960-52

Figure 4-8. Scheduler Queue Segment

4-14

121960-001

TASK MANAGEMENT

iAPX286 MACRO ASSEMBLER

960-503

04/22/83

PAGE

SERIES-III iAPX286 MACRO ASSEMBLER V1." ASSEMBLY OF MODULE DISPATCHER OBJECT MODULE PLACED IN :F5:DISP.OBJ ASSEMBLER INVOKED BY: ASM286.86 :F5:DISP.ASM LOC OBJ LINE
1 +1

SOURCE TITLE ('960-503')

2
3 4
5 6 7 8

STACK

NAME DISPATCHER EXTRN DEQUEUE READY: FAR PUBLIC DISPATCHER STACKSEG 4 DWORD PTR [BP-4] \>/ORD PTR [BP-2] WORD PTR [BP-4] SEGMENT ER PUBLIC

-0004 [] -0002 [] -0004 []

0000 0000 00"4 0005 OOOA OOOD C8"40000 FA 9A"OOO---3D0000 740B

9 10 11 12 13 14 15 16 17 18 19 20 21

TSS PTR EQU TSS::::SEL EQU TSS_OFFSET EQU

DISPATCHER PROC ENTER

NEAR 4,0 DEQUEUE_READY AX,O D_EXIT WE'LL FORM POINTER ON STACK RETURNS S ELECTOR IN AX TO TSS SAME TASK? JUST RETURN

CLI
CALL CMP JE

22
FORM POINTER 23 MOV TSS SEL, AX TSS-OFFSET, 0 NO'r USED ANYWAY MOV 24 TSS-PTR TASK SWITCH JMP 25 26 001A 27 D EXIT: STI WHEN THIS TASK EVENTUALLY REGAINS CONTROL, 001A FB 28 IT RESUMES EXECUTING HERE, SINCE THE OFFSET 001B C9 29 LEAVE OF THIS INSTRUCTION WAS THE LATEST VALUE IN 001C C3 30 RET THE IP REGISTER FOR THIS TASK 31 32 33 DISPATCHER ENDP 34 35 NUCLEUS CODE ENDS WARNING #160, LINE #35, SEGMENT CONTAINS PRIVILEGED INSTRUCTIONS 36 END 000F 8946FE 0012 C746FC0000 0017 FF6EFC ASSEMBLY COMPLETE, 1 WARNING, NO ERRORS

Figure 4-9. Dispatcher Example

4-15

121960-001

Data Sharing, Aliasing, and Synchronization

CHAPTER 5 DATA SHARING, ALIASING, AND SYNCHRONIZATION


Even the simplest multitasking applications present a need for sharing data among tasks. In fact, examples presented in earlier chapters of this book have used data sharing, as in the example procedures in Chapter 3 that manipulate the free space list. For simplicity, these examples have avoided many of the implications of data sharing. However, sharing data among tasks is a complex activity that offers many opportunities for one task to cause another to fail. Therefore, for the protection of the system as a whole, the operating system must provide services that promote reliable data sharing.

OA T A-SHARING TECHNIQUES
The architecture of the iAPX 286 allows segments to be shared among tasks through several mechanisms. Each mechanism has different advantages and disadvantages, and requires different degrees of support from the operating system. Note that while the primary subject of this chapter is data sharing, these segment-sharing techniques apply as well to code segments.

Sharing via the GOT


All tasks in the system can access a segment whose descriptor resides in the GDT. This mode of sharing is especially useful for operating-system databases. Many operating-system procedures can be called from any task; they can access system data only if that data resides in segments accessible to every task. Normally, the system designer decides in advance which descriptors are to reside in the GDT and which in LDTs, and uses the Builder to install them in the appropriate descriptor table. The only support required from the operating system is to provide synchronization for access to the shared data.

It is not always desirable to use GDT descriptors for sharing segments that only a few tasks use. A segment that has a descriptor in the GDT is accessible by all tasks, and exposing it to access from unrelated tasks may compromise the system's protection goals. Deletion of GDT descriptors may have unknown effects, because it is diffucult to control usage of GDT descriptors. GDT space may be needed for other purposes.

Sharing via Common LOT


When two (or more) tasks share most of the segments accessible to either one, then it is feasible for them to actually use that same LDT. Figure 5-1 illustrates' how to share an LDT by placing the GDT selector of the LDT in the LDT field of the TSS of each task. LDT sharing is appropriate if the sharing tasks are designed to cooperate, and if you are willing to take the risk that a failure in one task might adversely affect the other tasks that use the same LDT.

5-1

121960-001

DATA SHARING, ALIASING, AND SYNCHRONIZATION

121960-301

Figure 5-1. Segment Sharing via Common LOT

Sharing via Aliases


When tasks need to share simultaneously some, but not all, segments with selected other tasks, then aliasing is an appropriate method. As figure 2-15 illustrates, each task that shares a segment has a copy of the descriptor for that segment in its LDT. The term alias is used when there are mUltiple descriptors for a segment because each descriptor provides an alternate name for the segment. Not all the aliases for one segment need to be identical. Aliases may, for example, have different type or different access rights. Descriptor manipulation must be restricted to privilege level 0 (PL 0), but procedures at any privilege level can benefit from aliasing. Therefore, the operating system must provide high-level interfaces that cause creation and deletion of aliases. The operating system makes copies of descriptors for the shared segments and installs the copies in the LDTs of the sharing tasks (or possibly at other slots in the GDT). The operating system must strictly control which tasks may receive copies of which descriptors. The presence of mUltiple copies of a segment's descriptor creates additional complexities for the operating system when it relocates, deletes, or otherwise modifies the segment. Beware of the confusion that can arise when tasks share data structures that contain selectors to alias descriptors. Task A may find a selector that points to a slot in Task B's LDT. Nothing prevents Task

5-2

121960-001

DATA SHARING, ALIASING, AND SYNCHRONIZATION

A from using the selector to reference its own LDT, but if it does so, the selector will likely refer to the wrong descriptor. One way to avoid this potential problem is by reserving the same slot position in the LDTs of all sharing tasks.

ALIAS MANAGEMENT
In any system that uses aliases for segment sharing, the operating system must ensure that all the aliases for a given segment remain consistent in spite of changes to the segment. The operating system may relocate a segment, transfer it to or from secondary store, or delete the segment. If allowed to use a descriptor that had not been updated to reflect any of these changes, a task would fail and might cause other tasks to fail. Therefore, an operating system must implement a means to find and update all aliases for a segment when it changes anyone of the aliases.

Alias Database
Figure 5-2 shows an example method for locating aliases. This method maintains a header block for each segment that has aliases. Pointers to all the aliases for that segment are linked to the header. As long as the entire list does not span more than one segment, the link fields (FIRST, LAST, NEXT, PRIOR, and HEADER) need only contain offsets. The doubly linked list shown here aids dynamic creation and deletion of alias pointers; for static systems, a singly linked list would suffice. In addition to the FIRST and LAST links, the list header contains that segment information that might change but that must remain consistent in all the aliases of a segment. Operating-system operations on segments demand that the segment base address and the present bit be consistent. Furthermore, any interrogation of the accessed bit for a segment demands that the accessed bits in all the aliases be ORed together. This example assumes that the operating system does not permit creation of aliases with differing limit or expansion direction. When a task that has a selector for an alias descriptor calls on operating system functions that make changes to segment attributes, those changes must be broadcast to all other aliases for the segment. Therefore, the operating system must have a means, given any descriptor, to find the alias list that includes that descriptor. Figure 5-3 illustrates one technique for doing this. Each descriptor table has a parallel table of pointers to alias list headers. The index in a selector that locates a descriptor in the descriptor table also locates a pointer in the parallel table. A descriptor that has no alias has a null entry in the corresponding position in the parallel table. For applications in which aliases are few, you can employ a hashing algorithm to reduce the number of entries in the parallel table.

Alias Procedures
Implementation of procedures for alias management for the 80286 is a straightforward application of list processing algorithms and therefore is not illustrated here. At a minimum, the operating system should provide a CREATE_ALIAS procedure and a DELETE_ALIAS procedure. The operating system must enforce a correspondence between the existence of descriptors for a segment and the existence of the segment itself. A segment must always have a descriptor, and an active descriptor must always point to a valid segment. A convenient way to enforce these rules is to permit only the DELETE-ALIAS procedure to call the segment FREE procedure. DELETE-ALIAS should cause deletion of a segment only when the last descriptor for the segment has been deleted. Creating an alias is only the first step toward segment sharing. The CREATE_ALIAS procedure can only create an alias for a segment that is accessible to the task that calls CREATE_ALIAS. The next

5-3

121960001

inter

DATA SHARING, ALIASING, AND SYNCHRONIZATION

LINKED LIST OF POINTERS TO ALIAS DESCRIPTORS FOR ONE SEGMENT

-------

})

121960-29

Figure 5-2. Alias List

step toward segment sharing is to pass the alias to another task. This subject is taken up in a later section of this chapter, "Message Passing."

SYNCHRONIZA TION

Consider the example of a memory manager given in Chapter 3. While a memory management procedure manipulates the links that manage free space, there are instants when the data in the links is temporarily inconsistent (for example, the next-pointer in one segment has been set, but the previouspointer in the next segment has not yet been updated). If the processor interrupts the task in which the memory-management procedure is running to run another task (or even another procedure in the same task) and if the new task (or procedure) calls the memory manager, then the the memory manager is likely to behave incorrectly. For the protection of the system, the operating system must prevent such forms of incorrect function in its own logic and must provide synchronization operations that enable application logic to avoid such failures as well.

5-4

121960-001

DATA SHARING, ALIASING, AND SYNCHRONIZATION

DESCRIPTOR TABLE

POINTER TABLE

ALIAS LISTS

~-----------------------------~

INDEX FROM SELECTOR

HEADER

0--------0

t------Il~
POINTER DESCRIPTOR TABLE POINTER TABLE

i
I I
INDEX FROM SELECTOR

r-----------------------------,
HEADER

0 0---------0

10
i
I I

L ____________________________ _

t------Il~
POINTER

r-----------------------------,
HEADER

0 0---------0
121960-31

10

L ____________________________ _ I

Figure 5-3. Identifying Alias List

Low-Level Mutual Exclusion


The most basic form of synchronization is control over critical sections. A critical section is a sequence of instructions that operates on shared resources in such a way that errors could result if another sequence of instructions operated on the same resources within the same time span. Any means that prevents any two critical sections from overlapping in time would prevent such errors. In a singleprocessor system, only an interrupt can cause the operations of one critical section to interleave with those of another. Disabling interrupts provides the necessary mutual exclusion. Procedures that disable interrupts to provide mutual exclusion must adhere to certain rules: Determine the maximum permissible delay for servicing an interrupt, and do not code a critical section that takes more time. Avoid causing a fault that might keep interrupts disabled for a longer time than permissible.

5-5

121960-001

DATA SHARING j ALIASING; AND SYNCHRONIZATION

Do nofnest critical sections; there is only one interrupt flag. Do not switch tasks; doing so may enable interrupts. Disabling interrupts as a means to provide mutual exclusion is not a generally applicable technique. The rules above are too restrictive for many situations, and the CLI and STlinstructions for disabling and enabling interrupts are restricted to procedures whose CPL does not numerically exceed IOPL. An operating system can, however, use this technique for its own short-term, high-speed exclusion requirements and as the basis for more general synchronization operations.

High-Level Mutual Exclusion


A more generally applicable form of mutual exclusion must permit interleaving (via interrupts and software task switching) of unrelated critical sections.
SEMAPHORE DATA STRUCTURE

Figure 5-4 illustrates an example data structure for implementing a general purpose form of control over critical sections: binary semaphores. The semaphore structure consists of a counter and a queue. Every shared resource subject to the effects of contention needs one semaphore structure to provide mutual exclusion for the tasks using the resource. The value of the counter is one minus the number of tasks waiting at the semaphore. A value of one indicates that the semaphore is available; a value of zero indicates the the semaphore has been acquired

SCHEDULER QUEUE SEGMENT

r---------------------------,
HEAD OF QUEUE SEMAPHORE TO TASK ENTRIES IN GOT QUEUE ELEMENTS

COUNTER

QUEUE POINTER

121960-28

Figure 5-4. Semaphore Structure

5-6

121960-001

DATA SHARING, ALIASING, AND SYNCHRONIZATION

but no other tasks are waiting for the semaphore; a negative value indicates that some tasks are queued, waiting for the semaphore to be released. The queue is circular so that the pointer to the head of the queue also identifies the tail of the queue. Semaphore structures may be stored individually in separate segments or may be stored together in one or more segments. In the latter case the operating system must provide a means for identifying individual semaphores within a segment. Storing the semaphore counter in a segment by itself yields two important advantages: The processor can individually protect each semaphore. The selector of the descriptor for the semaphore segment serves as a convenient identifier for the semaphore.

Semaphore structures are sensitive data that must be .cloistered behind the level 0 protection wall. Semaphores may reside either in the GDT or in the LDTs of the tasks that use them. The same considerations apply as for shared data segments.

SEMAPHORE-MANAGEMENT PROCEDURES

The minimum set of operating-system procedures needed to use semaphores includes WAIT_SEMAPHORE to acquire a semaphore if it is not already acquired SIGNAL_SEMAPHORE to signal departure from a critical section

Dynamic systems may also need to define semaphores dynamically with procedures such as CREATE_SEMAPHORE for setting up a new semaphore structure DELETE_SEMAPHORE to eliminate a semaphore structure that is no longer needed

The operating system's responsibilities in managing binary semaphores include Ensuring that no more than one task holds a semaphore When a task requests a semaphore that has not been signalled, placing the task in a waiting queue, and dispatching another task When a task signals a semaphore, awakening the next task in the waiting queue for that semaphore . and placing it in the ready queue Preventing or being prepared to handle any deadlock that may result from using semaphores

Figure 5-5 shows simple examples of how to use a low-level synchronization technique to implement WAIT_SEMAPHORE and SIGNAL_SEMAPHORE procedures. These procedures must run at PL 0 to access the semaphore structures. With segment descriptors in the GDT and with call gates at PL 3, any procedure in the system can call these synchronization primitives.

5-7

121960-001

DATA SHARING, ALIASING, AND SYNCHRONIZATION

PL/M-286 COMPILER

960-S04

date

PAGE

system-ID PL/M-286 Vx.y COMPILATION OF MODULE SEMAPH OBJECT MODULE PLACED IN :Fl:SEMAPH.OBJ COMPILER INVOKED BY: PLM286.86 :Fl:SEMAPH.PLM DEBUG

$ PAGEWIDTH(71) TITLE('960-S04') INCLUDE (:Fl:NUCSUB.PLM) $ NOLIST


1

SEMAPH: /*

DO; Externals */

/*******************************************************/
2 3
4 S 6
7 8 9 1
2

DISPATCHER: PROCEDURE EXTERNAL; END DISPATCHER; ENQUEUE WAIT: PROCEDURE(QUEUE 10) EXTERNAL; DECLARE QUEUE ID SELECTOR; END ENQUEUE_WAIT; DEQUEUE WAIT: PROCEDURE(QUEUE ID,EXCEP P) EXTERNAL; DECLARE QUEUE 10 SELECTOR, EXCEP P POINTER; END DEQUEUE_WAIT; -

1 2 2 1 2
2

/*******************************************************/
/* 10
1

Semaphore Data Structures

*/

DECLARE SEMAPHORMAT LITERALLY 'FILLER (2) WORD, COUNTER WORD'; DECLARE OK /* LITERALLY '0'; Test a semaphore; wait if not set PROCEDURE (SEMAPH 10, EXCEP P) PUBLIC-REENTRANT; */

11

/*******************************************************/
12
1

WAIT SEMAPHORE:

13
14

DECLARE SEMAPH 10 SELECTOR, SEMAPH-BASED SEMAPH_ID STRUCTURE(SEMAPHORMAT); DECLARE EXCEP P EXCEP-BASED EXCEP P POINTER, WORD;

is 16 17 18 19 20 21 22 23

2 2 2
2

3 3 3 3
2

DISABLE; SEMAPH.COUNTER=SEMAPH.COUNTER-l; IF ZERO /* Test the zero flag. */ THEN /* Semaphore was set. */ DO; ENABLE; EXCEP=OK; RETURN; END; /* Semaphore is not set; this task must wait. */ CALL ENQUEUE_WAIT (SEMAPH ID);

Figure 5-5. Semaphore Example

5-8

121960-001

DATA SHARING, ALIASING, AND SYNCHRONIZATION

PL/M-286 COMPILER
24

96(3-5(34

date

PAGE

25 26

2 2 2

ENABLE; CALL DISPATCHER; END WAIT_SEMAPHORE;


/***************************************************** **/

/*

Set a Semaphore

*/

27 28 29 3(3 31 32 33 34 35 36 37 38 39 4(3 41
42

1
2

SIGNAL_SEMAPHORE:

PROCEDURE (SEMAPH ID, EXCEP P) PUBLIC REENTRANT;

DECLARE SEMAPH ID SELECTOR, SEMAPH-BASED SEMAPH_ID STRUCTURE(SEMAPHORMAT); DECLARE EXCEP P EXCEP-BASED EXCEP P POINTER, WORD;

2 2 2
2

3 3 3 3
2 2 2 2

DISABLE; SEMAPH.COUNTER=SEMAPH.COUNTER+1; IF NOT (ZERO OR SIGN) /* Test flags. */ THEN /* No one is waiting at this semaphore. */ DO; ENABLE; EXCEP=OK; RETURN; END;
/* Someone is waiting at this semaphore. */ CALL DEQUEUE WAIT (SEMAPH ID, @EXCEP); ENABLE; CALL DISPATCHER; EXCEP=OK;

END SIGNAL_SEMAPHORE;
/**********~***********.********************************/

43

END SEMAPH;

MODULE INFORMATION: CODE AREA SIZE . CONSTANT AREA SIZE VARIABLE AREA SIZE MAXIMUM STACK SIZE 1(37 LINES READ (3 PROGRAM WARNINGS (3 PROGRAM ERRORS DICTIONARY SUMMARY: 91KB MEMORY AVAILABLE 4KB MEMORY USED (4%) 0KB DISK SPACE USED END OF PL/M-286 COMPILATION (3084H 0(3(3(3H (3 (3 (3 (3H (3(31(3H 132D (3D (3D 16D

Figure 5-5. Semaphore Example (Cont'd.)

5-9

121960-001

DATA SHARING, ALIASING, AND SYNCHRONIZATION

OTHER FORMS OF SYNCHRONIZATION

You may wish to implement other forms of synchronization; for example: Conditional variation of WAIT_SEMAPHORE that does not force a task to wait when the semaphore has not been signalled. Timed waiting, so that a task can be awakened if the semaphore is not signalled within a reasonable time. (This helps guard against deadlocks.) An extension of the semaphore concept known as a region. A region is similar to a semaphore except that only the task that acquires a region can release (signal) it, and a task that holds a region cannot be suspended.

MESSAGE PASSING
Message passing is a general purpose means for transferring data from the address space of one task to the address space of another, cooperating task. There are two aspects to the technique: Transferring data from a segment in one task's address space into a segment in the receiving task's space Transferring a segment from one task's space into another's

The first case is suitable for passing relatively small amounts of data, such as parameters, information describing events, etc. The second case has two primary applications: For transferring large "consumable resources" such as I/O buffers For transferring aliases that implement the previously described method of "sharing via aliases"

When an alias is passed as part of a message, the operating system installs the alias in a descriptortable slot determined by the receiving task.

Message-Passing Example
Figure 5-6 shows an example data structure for implementing a simple form of message passing. This structure defines a mailbox, a queue of tasks waiting for messages from the mailbox, and a queue of undelivered messages. The system may contain one mailbox for every communication channel between tasks. For simplicity, this example assumes that the format of messages for all mailboxes is the same, consisting of a fixed-length data item and two descriptors.

If each mailbox resides in a unique segment, then these advantages result:


Mailboxes are protected from operations on other mailboxes. A selector can serve as the identifier of a mailbox.

Only the sending and receiving tasks need access to a mailbox; therefore, the appropriate tables for descriptors for mailbox segments are the LDTs of each of the tasks that share a mailbox. All tasks can share a global mailbox, however, if its descriptor is in the GDT. The DPL for all mailbox segments should be zero to prevent procedures outside the operating system from interfering with message passing. Mailboxes -require at least two procedures: SEND_MESSAGE and RECEIVE_MESSAGE. Figure 5-7 shows examples of these procedures. Both procedures must run at PL 0 to access level-O mailbox

5-10

121960-001

DATA SHARING, ALIASING, AND SYNCHRONIZATION

I 1 I I

r---------------------------,
QUEUE ELEMENTS

SCHEDULER QUEUE SEGMENT

'II
I I I I I I
HEAD OF QUEUE

~~~----~

*--f-....

TO TASK ENTRIES INGDT

MAILBOX

TASK QUEUE POINTER

I I I I I I I L__________________________ _ I

HEAD OF MESSAGE QUEUE TAIL OF MESSAGE QUEUE

QUEUE OF UNDELIVERED MESSAGES

~---------------------------,

NEXT

DATA

DESCRIPTORS

L__________________________ _

121960-33

Figure 5-6. Mailbox Structure

5-11

121960-001

DATA SHARING, ALIASING, AND SYNCHRONIZATION

segments. If there are call gates in the GOT at PL 3, then these procedures are accessible to all other procedures in the system. SEND_MESSAGE fills a message with the specified data and descriptors, removes the descriptors from the descriptor table, and links the message at the tail of the message queue. If a task is waiting at the mailbox, SEND_MESSAGE causes it to be linked into the ready queue so that it will find the message the next time it is scheduled to run.
If RECEIVE_MESSAGE finds no messages waiting at the mailbox, then it links,the task into a waiting queue. The task queue threads through the task database. The task will continue executing when another task sends a message to the mailbox. If (or when) a message is waiting, RECEIVE_MESSAGE writes the data portion of the message at a specified location in the receiving task's space and installs the descriptor portion in specified slots in one of the receiving task's descriptor tables (GOT or LOT).

These examples do not include management of space and queues for messages because conventional GET_MSG_SPACE, ENQUEUE_MESSAGE, algorithms apply. External procedures DEQUEUE_MESSAGE, and FREE_MSG_SPACE provide these functions. Special handling is required to accommodate the fact that a descriptor in a message is temporarily not in any descriptor table. There are two cases to consider: The descriptor is the sole descriptor for the segment. In this case, no changes can be made to the segment because it is temporarily inaccessible. You should take care that no failure in the communication process causes the descriptor to become lost. A memory area without a descriptor cannot be freed. The descriptor is an alias (i.e., one of several descriptors for the same segment). Since the segment is (presumably) accessible via the other aliases, it is possible for some task to request some operation on the segment during the time the descriptor in the message is absent from any descriptor table. Normally, the operating system updates all aliases when it makes any major changes to a segment (for example, relocation or swapping to secondary store). This is not possible (given the aliasing scheme previously presented in this chapter) when the alias is not in a descriptor table. To solve the problem, this example assumes there are two procedures: a. DISABLE_ALIAS_PTR that marks the alias list element to indicate to the alias manager that the alias is in a mailbox b. FDCALIAS_PTR that, when the message is delivered, updates the alias pointer with the new location of the alias and with any segment information that may have changed while the alias was absent from the alias list. Dynamic systems may need to create and delete mailboxes dynamically. The only difficulty in creating a mailbox is ensuring that no task uses it while it is being constructed. (The next section considers this problem.) To delete a mailbox the operating system must awaken any tasks that are waiting for messages, delete any descriptors (aliases) that reside in undelivered messages, and delete the undelivered messages themselves. The operating system may, as part of the process of task creation, give each task at least one mailbox. If the mailbox feature is the only means of passing aliases among tasks, a task cannot receive an alias for a mailbox unless it already has a mailbox. Some operating system designs may require every task to have a mailbox for such purposes as receiving memory segments from the memory-allocation module.

5-12

121960-001

DATA SHARING, ALIASING, AND SYNCHRONIZATION

PL/M-286 COMPILER

960-508

date

PAGE

system-I 0 PL/M-286 Vx.y COMPILATION OF MODULE MAILBOX OBJECT MODULE PLACED IN :Fl:MBOX.OBJ COMPILER INVOKED BY: PLM286.86 :Fl:MBOX.PLM DEBUG

$ PAGEWIDTH(71) TITLE('960-508') $ NOLIST 1

INCLUDE

(:Fl:NUCSUB.PLM)

MAILBOX:

DO;

/*******************************************************/ /* Definitions */
2
1

DECLARE FAILED OK

LITERALLY '8000H', LITERALLY '0';

/*******************************************************/ /* Externals */
3 4 5

1 2 2
1 2 2

NULLIFY: PROCEDURE (SLOT) EXTERNAL; DECLARE SLOT SELECTOR; END NULLIFY; STORE DESCR: PROCEDURE(SLOT,PTR) EXTERNAL; DECLARE SLOT SELECTOR, PTR POINTER; END STORE_DESCR; LOAD DESCR: PROCEDURE(PTR,SLOT) DECLARE PTR POINTER, SLOT SELECTOR; END LOAD_DESCR; DISPATCHER: PROCEDURE EXTERNAL; END 01 S PATCHER; ENQUEUE WAIT: PROCEDURE(QUEUE 10) EXTERNAL; DECLARE QUEUE 10 SELECTOR; END ENQUEUE_WAIT; DEQUEUE WAIT: PROCEDURE(QUEUE 10, EXCEP P) EXTERNAL; DECLARE QUEUE 10 SELECTOR, EXCEP P POINTER; END DEQUEUE_WAIT; DISABLE ALIAS PTR: PROCEDURE (SLOT) EXTERNAL; DECLARE SLOT-SELECTOR; END DISABLE_ALIAS_PTR; FIX ALIAS PTR: PROCEDURE(ALIAS LIST 10) EXTERNAL; DECLARE ALIAS LIST 10 POINTER; END FIX_ALIAS_PTR; GET MSG SPACE: PROCEDURE(BOX ID,MSG P P,EXCEP P)EXTERNAL; DECLARE BOX 10 SELECTOR, (MSG_P_P~ EXCEP_P)-POINTER; END GET_MSG_SPACE; EXTERNAL;

6 7 8
9

10
11

1 2 2
1 2

12 13 14 15 16 17 18 19 20 21 22
23
24

1 2 2
1
2

2
1 2 2
1

25 26 27 28

2 2 1
2

Figure 5-7. Example of Mailbox Procedures

5-13

121960-001

inter

DATA SHARING, ALIASING, AND SYNCHRONIZATION

PL/M-286 COMPILER 29 30 31 32 33 34 35 36 37 ' 1 2 2 1 2 2 1 2 2

960-508

date

PAGE

FREE MSG SPACE: PROCEDURE(BOX ID,MSG_PTR) EXTERNAL; DECLARE-BOX ID SELECTOR, MSG-PTR POINTER; END FREE_MSG=SPACE; ENQUEUE MESSAGE: PROCEDURE (BOX ID, MSG_PTR) EXTERNAL; DECLARE BOX ID SELECTOR, MSG-PTR POINTER; END ENQUEUE MESSAGE;

DEQUEUE_MESSAGE: BROCEDURE (BOX ID, MSG_P_ P, EXCEP P) EXTERNAL; DECLARE BOX ID SELECTOR, (MSG_P_ P, EXCEP_P) POINTER; END DEQUEUE MESSAGE; -

/*******************************************************/
/*
38 39 1 1 Mailbox Data Structures LITERALLY '46' ; LITERALLY BYTE, WORD, WORD' ;

*/

DECLARE MDATA_SIZE DECLARE MESSAGE FORMAT , MDATA (MDATA_SIZE) DESCRl (4 ) DESCR2 (4 )

/*******************************************************/
/*
40 41
1

Send Message via Mailbox

*/

SEND MESSAGE: PROCEDURE(BOX ID, MDATA PTR, SLOT1, SLOT2, EXCEP_P) - PUBLIC REENTRANT; DECLARE BOX ID SELECTOR, MDATA PTR POINTER, (SLOT!, SLOT2) SELECTOR; DECLARE EXCEP P EXCEP- BASED EXCEP P POINTER, WORD;

42 43

2 2

DECLARE MSG PTR POINTER, MESSAGE BASED MSG PTR STRUCTURE (MESSAGE_FORt1AT) T CALL GET MSG SPACE (BOX ID, @MSG PTR, @EXC.EP); IF EXCEP~FAILED THEN /* the box-is full of messages */ DO; CALL DISPATCHER; RETURN; END; /* The next statement will cause an exception if the segment containing the data is not present. Therefore interrupts are enabled. */ CALL MOVB (MDATA PTR,@MESSAGE.MDATA,MDATA SIZE); IF SLOT1=SELECTOR$OF(NIL) THEN MESSAGE.DESCR1(2)=0; /* Mark as null */ ELSE DO; CALL STORE DESCR(SLOT1,@MESSAGE.DESCR1); CALL DISABLE_ALIAS_PTR(SLOT1);

44 45 46 47 48 49

2
2

2 3 3 3

50 ,51 52 53 54 55

2
2 2

3 3

Figure 5-7. Example of Mailbox Procedures (Cont'd.)

5-14

121960-001

DATA SHARING, ALIASING, AND SYNCHRONIZATION

PL/M-286 COMPILER 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70
71

960-508

date

PAGE

3 3 2 2 2 3 3 3 3 2 2 2 2 2 2 2

CALL NULLIFY(SLOT1); END; IF SLOT2=SELECTOR$OF(NIL) THEN MESSAGE.DESCR2(2)=0; /* Mark as null */ ELSE DO; CALL STORE DESCR(SLOT2,@MESSAGE.DESCR2); CALL DISABLE ALIAS PTR(SLOT2); CALL NULLIFY(SLOT2); END; DISABLE; CALL ENQUEUE MESSAGE(BOX ID, MSG PTR); CALL DEQUEUE-WAIT (BOX ID~@EXCEP); ENABLE; CALL DISPATCHER; RETURN; END SEND_MESSAGE;

/*******************************************************/ /* Receive Message from Mailbox */


72 1

RECEIVE_MESSAGE: PROCEDURE (BOX ID, MDATA PTR, SLOTl, SLOT2, EXCEP=P) PUBLIC-REENTRANT; DECLARE BOX ID MDATA PTR (SLOT!, SLOT2) SELECTOR, POINTER, SELECTOR; POINTER, WORD;

73

74 75

2
2

DECLARE EXCEP P EXCEP BASED EXCEP P

DECLARE MSG_PTR POINTER, MESSAGE BASED MSG PTR STRUCTURE (MESSAGE_FORMAT); CHECK MAIL: DISABLE; CALL DEQUEUE MESSAGE (BOX ID, @MSG PTR, @EXCEP); IF EXCEP=FAILED THEN /* No mail today */ DO; CALL ENQUEUE_WAIT (BOX_ID); ENABLE; CALL DISPATCHER; GOTO CHECK_MAIL; END; ENABLE;

76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91
92

2 2 2 3 3 3 3 3 2

2 2 3 3 3
2

93 94

/* Next statement may cause exception. */ CALL MOVB(@MESSAGE.MDATA, MDATA PTR, MDATA SIZE); IF MESSAGE.DESCRl(2)<>0 /* Test-for null descriptor */ THEN DO; CALL LOAD DESCR(@MESSAGE.DESCRl, SLOTl); CALL FIX_ALIAS_PTR(@MESSAGE.DESCR1); END; IF MESSAGE.DESCR2(2)<>0 /* Test for null descriptor */ THEN DO; CALL LOAD_DESCR(@MESSAGE.DESCR2, SLOT2);

Figure 5-7. Example of Mailbox Procedures (Cont'd.)

5-15

121960-001

DATA SHARING,ALlASING, AND SYNCHRONIZATION

PL/M-286 COMPILER 95 96
97 3 3 2 2
2

960-508

da"te

PAGE

98
99

CALL FIX ALIAS_PTR(@MESSAGE.DESCR2); END; CALL FREE MSG SPACE(BOX ID,@MESSAGE); EXCEP=OK;END RECEIVE_MESSAGE;
/**********************************~~*******************/

100

END MAILBOX;

MODULE INFORMATION: CODE AREA SIZE CONSTANT AREA SIZE VARIABLE AREA SIZE MAXIMUM STACK SIZE 193 LINES READ o PROGRAM WARNINGS o PROGRAM ERRORS DICTIONARY SUMMARY: 91KB MEMORY AVAILABLE 6KB MEMORY USED (6%) 0KB DISK SPACE USED END OF PL/M-286 COMPILATION 016EH 0000H "0000H 0020H 3660 00 00 320

Figure "5-7. Example of Mailbox Procedures (Cont'd.)

Variations on the Mailbox Theme


Some of the features appropriate for semaphores are also appropriate for mailboxes, namely: Conditional receive Timed wait For applications in which speed is not the overriding goal, mailboxes can substitute for semaphores. A mailbox is analogous to a semaphore, with the counter of a semaphore corresponding to the number of messages waiting at a mailbox. A mailbox with null messages is identical in function to a semaphore. Most applications that use mailboxes require different message formats (different data size, different number of descriptors) for different communication channels. With dynamically created mailboxes, message format may be defined by parameters to the creation procedure, encoded in the mailbox, and interpreted by the SEND_MESSAGE and RECEIVE_MESSAGE procedures.

5-16

121960-001

DATA SHARING, ALIASING, AND SYNCHRONIZATION

Systems that implement "pipes" as a form of intertask communication can call mailbox procedures from the device drivers for the pipes.

It is possible to use mailboxes as the sole means of interface between applications and operating system. For example, the operating system has one mailbox through which it receives service requests from all applications; each task has a mailbox through which it receives responses from the operating system. To get more memory, a task would send a memory request message to the operating system; the operating system would return a message containing an alias for the allocated memory segment and install the alias in the task's LDT. The advantage is simplicity. Only two global gates are needed: one for SEND_MESSAGE and one for RECEIVE_MESSAGE. A task can wait for only one purpose: for a message from a mailbox. The disadvantage is inefficiency. Any implementation of mailboxes is bound to be less efficient than the interlevel CALL instruction normally used to communicate with an operating system.
All of these forms of message-passing can use the primitive synchronization and descriptor-manipulation techniques illustrated in this section.B

5-17

121960-001

Signals and Interrupts

CHAPTER 6 SIGNALS AND INTERRUPTS


Interrupts are a mechanism long used in single-task microprocessors for reacting quickly to external events. In the multitasking architecture of the iAPX 286, each task may have the same needs for information about external events as the one task in a single-task system. In a multitasking system, several generalizations of interrupts are useful: Some tasks may do nothing but service a specific external event. While the task waits for an event to occur, the processor can service other tasks. Information about an external event must be routed to the correct task. Events external to a task may include events occurring in other tasks as well as events external to the processor. The ability to selectively ignore events must then extend to those events occurring in other tasks. Each task can benefit from a vector table to automatically route information about events to the correct handler procedures within the task. Scheduling of tasks that service events must be coordinated with the software scheduler, while retaining the ability to respond rapidly to events.

The 80286 implements some of these generalizations of interrupts onto the multitasking environment, but the operating system has responsibility for others. Not all are relevant to every application of the 80286.

INTERRUPT FEATURES OF THE iAPX 286 ARCHITECTURE


The iAPX 286 architecture includes a number of features that work together to enable efficient response to events.

Vectoring
The processor associates each event with an identifying number in the range 0-255. The processor recognizes three classes of events: External. Events occurring outside the 80286 processor's environment are communicated to the processor via the INTR or NMI (non-maskable interrupt) pins. The NMI is interrupt 2. Other external interrupts share the INTR pin via one or more 8259A Programmable Interrupt Controllers, which can map each interrupt to a unique interrupt 10 in the range 32-255. Processor. When.the processor detects a condition that it cannot handle, it communicates this fact by causing an interrupt with an 10 in the range 0-16 (except for interrupt 2, which is the NMI). Software. Programs can generate signal events by executing the instructions INT n and INTO. With INT n, the value of n can be any interrupt indentifier in the range 0-255. This gives software the ability to simulate hardware interrupts as well as the ability to cause interrupts that are not directly associated with hardware events. (Note that many software systems use the software interrupt to call on operating-system services. With the iAPX 286, an interlevel CALL through a CALL gate serves this purpose.)

6-1

121960-001

SIGNALS AND INTERRUPTS

When an interrupt occurs, the processor uses the interrupt identifier as an index into the interrupt descriptor table (IDT).

Enabling and Disabling Interrupts


The interrupt flag (IF) controls whether the processor immediately reacts to' external events. When reset, IF masks out signals presented to the INTR pin. It has no effect on NMI, on processor-detected exceptions, or on software signals (lNT and INTO). To set IF, use the STI instruction (ENABLE statement in PL/M-286); to reset IF, use CLI (OISABLE).

Interrupt Descriptor Table


The lOT associates each interrupt identifier with a descriptor for the instructions that process the associated event. The lOT is similar to the GOT and LOTs but is different in two important respects: The processor references the lOT only as the result of an interrupt. The only descriptors permitted in the lOT are three kinds of gate descriptors: task gates, interrupt gates, and trap gates (descriptor types 5-7, respectively). The IDT may dwell at any location in memory. The processor locates the lOT via the lOT register. The operating system uses the instruction LIOT (load lOT) to set the lOT register. The instruction SlOT (store lOT) reads the contents of the lOT register. There can be only one lOT, but the operating system can use the LIOT instruction to substitute another array of gate descriptors.

Interrupt Tasks and Interrupt Procedures


In response to an event, the processor interrupts the currently executing task and begins executing the instructions identified by the lOT gate descriptor that is associated with the event. The instructions that execute as the result of the event may either be A task other than the current task A procedure within the current task

If the descriptor indexed by the interrupt identifier is a task gate, which points to a task state segment, then the processor causes a task switch. Figure 6-1 illustrates the links that identify the interrupt task. Chapter 4 discusses the .mechanisms associated with task switching and considers the impact that hardware task switching has on the operating system's task scheduler. If the descriptor indexed by the interrupt identifier is either an interrupt gate or a trap gate (which point to executable segments), then no task switch occurs. Instead the processor behaves similarly to the way it would if the current task had called the indicated procedure via a call gate. Figure 6-2 illustrates the links that identify the interrupt procedure. The iAPX 286 protection mechanism requires either that the target segment have a privilege level numerically less than or equal to CPL or that the target segment be conforming. If one of these conditions is true, then the indicated procedure begins executing in the current task. The major mechanical difference between invoking a procedure by an interrupt and invoking by a CALL is that, with an interrupt, the processor pushes the flag word onto the stack of the invoked procedure before the return address (as illustrated in figure 6-3) and clears the single-step flag (TF).

6-2

121960-001

inter

SIGNALS AND INTERRUPTS

lOT

GOT TSS

INTERRUPT 10

TASK GATE

TSS DESCRIPTOR

n
121960-304

Figure 6-1. Interrupt Vectoring for Tasks

lOT

EXECUTABLE SEGMENT

OFFSET

INTERRUPT 10

--.

TRAP GATE OR INTERRUPT GATE

~
----..

ENTRY POINT

LOT OR GOT

SEGMENT DESCRIPTOR

BASE

121960-302

Figure 6-2. Interrupt Vectoring for Procedures

Note that if an interrupt occurs while a privilege-level 0 (PL-O) procedure is executing, an attempt to transfer to a less privileged level violates protection rules. (The same protection rules apply as for a CALL to a less privileged segment.) In general it is impossible to predict when an interrupt occurs; therefore, it is equally impossible to avoid a protection violation when a less privileged procedure has an interrupt gate or trap gate in the IDT.

6-3

121960-001

SIGNALS AND INTERRUPTS

STACK

HIGH DIRECTION OF GROWTH

CALLER'S SS CALLER'S SP PARAMETER RETURN CS RETURN IP

!
SP
~

RPL

......-

CALLER'S CPL IS STORED IN RPL FIELD OF RETURN ADDRESS CS SELECTOR.

1---------1
LOW

121960-36

Figure 6-3. Interrupt Procedure's Stack

What is the difference between an interrupt via an interrupt gate and an interrupt via a trap gate? In the case of an interrupt gate, the processor automatically disables interrupts before transferring control to the interrupt procedure; therefore, an interrupt gate is normally used with external interrupts. In the case of a trap gate, the processor does not disable interrupts; therefore, trap gates are normally used with processor-detected exception conditions, which are also known as "traps." The IRET instruction returns control from an interrupt regardless of whether a task gate, interrupt gate, or trap gate is used to enter the interrupt handler. In all cases, executing IRET restores IF to its value before the interrupt. In the case of an interrupt procedure, the processor restores flags from the stack; in the case of an interrupt task, from the interrupted task's TSS. The difference in speed between handling an event by a task gate versus by an interrupt or trap gate is not great, as table 6-1 illustrates.

OPERATING SYSTEM RESPONSIBILITIES


Given the number of hardware features that automate event handling, you might wonder what is left for the operating system to do. In fact, for static systems in which interrupt tasks do not call on operating system functions and in which there is no need to change the IDT, the operating system need not concern itself with interrupts. Few applications are so simple, however. The following sections discuss some extensions to the processor's event-handling features that you may find useful in your operating

6-4

121960-001

SIGNALS AND INTERRUPTS

Table 6-1. Interrupt Response Time


Response Time (in number of clock cycles) Operation Task Gate Interrupt or Trap Gate (to different PL)

Hardware interrupt processing Save registers PUSHA PUSH DS PUSH ES Initialize registers MaV AX,SEG item-1 MaV DS,AX MaV AX,SEG item-2 MaV ES,AX
Total Clocks

167

78

done by task switch

17

3 3

done by task switch

2 17 2 17

167

139

system. The common goal in all these extensions is to structure the software so that, when an event occurs, the hardware can handle interrupt administration chores automatically within the efficiency and protection requirements of the application.

ManagelDT
Many applications require the ability to change the association between an event and the procedure or task associated with it. Even relatively static systems require this ability if interrupt procedures and interrupt tasks are not loaded until after system initialization. Only PL-O procedures can effect runtime changes to the IDT because the data-segment alias for the IDT should have PL O. The techniques for changing the IDT are similar to those already illustrated in Chapter 2 for the GOT and LOTs.

Switch Scheduling Modes


An application may include tasks that run sometimes as interrupt tasks and other times as normal tasks under the supervision of the operating system's scheduler. Examples of such situations include the following: An interrupt task calls on operating system services that might force the task to wait (for example, RECEIVE_MESSAGE). ' The task loader (in a dynamic system) does not distinguish between interrupt tasks and regular tasks, leaving it up to the task itself to request that the operating system attach it to an interrupt.

6-5

121960-001

SIGNALS AND INTERRUPTS

If such situations can arise, the operating system must

Keep track of whether a task is in

hardware~scheduled

mode or in software-scheduled mode

Provide services to switch a task between hardware-scheduled and software-scheduled mode

Note, however, that an interrupt task that is in software-scheduled mode cannot service interrupts. If it is possible for further interrupts of the same type to occur during the time the interrupt task is software-scheduled, then switching to software-scheduled mode is not such a good idea. An alternative . strategy is to allocate interrupt-servicing duties among two or more tasks: one hardware-scheduled and the others software-scheduled. The hardware-scheduled task responds to the interrupt and invokes one of the software-scheduled tasks through a mechanism such as message-passing as discussed in Chapter 5. If there are any delays in servicing that interrupt, it is one of the software-scheduled tasks that waits, not the hardware-scheduled task.

Manage Interrupt Controller


Intel's 8259A Programmable Interrupt Controller (PIC) is key system resource in a multitasking system. The 8259A PIC is a flexible device that gives the main processor the ability to service up to 64 external events via the processor's single INTR pin. The 8259A PIC gives software control over such critical parameters as the relative priorities among interrupts and the means for acknowledging interrupts. Correct operation of the system requires proper use of the interrupt controller. For the operating system to manage this critical resource is only consistent with the protection features of the iAPX 286. At system initialization the operating system may initialize the 8259A PIC according to system configuration and the needs of the application. Initialization may include Setting the 8259A to operate in iAPX86 mode Setting up master jslave relationships when the hardware configuration includes multiple PICs Specifying whether interrupts are triggered by edge or by level Setting interrupt priority mode: rotating or masked Determiningwhether priority is fully nested (if priority is set by masking) Determining whether interrupts are acknowledged automatically or by explicit EOI command Refer to the Component Data Catalog for details of these and other features of the 8259A PIC.
If you choose an interrupt policy in which the 8259A automatically determines interrupt priority and automatically acknowledges interrupts, then there may be no need, after initialization, for either the operating system or interrupt tasks and procedures to deal with the 8259A. If, on the other hand, you choose a dynamically changing priority scheme (whether by specific rotation or by mask commands) or explicit end-of-interrupt commands, then you must also choose whether run-time control of the 8259A is the responsibility of the interrupt tasks and procedures or of the operating system.

For the operating system to maintain run-time control over the 8259A PIC, it may provide a procedure such as the following that applications programs CALL instead of executing the IRET instruction.

PROC FAR
IRET j Switch to task on back-link Execution resumes here upon interrupt
6-6

121960-001

SIGNALS AND, INTERRUPTS

Send RET

interrupt Return
ENDP

mask to

to

PIC procedure

application

The operating system executes the IRET instruction within WAIT_FaR_INTERRUPT. WAIT_FOILINTERRUPT would need to run as a privileged procedure within the calling task. With this approach, the operating system has control just before the task begins to wait for an interrupt as well as when the task begins to execute after the interrupt occurs. The operating system then has the opportunity to send interrupt masks, end-of-interrupt commands, and specific priority rotation commands, as appropriate for the application.

Provide Task-Level Interrupt Procedures


GDT interrupt procedures (i.e., those invoked via interrupt gates and trap gates in the IDT that point to executable-segment descriptors in the GDT) provide a global mechanism for a task to react to events. The mechanism is global in the sense that one set of interrupt procedures applies to all of the tasks in the system. For example, suppose a GDT interrupt procedure handles the "divide error" exception. Then, a divide error in task A is handled by the same procedure as a divide error in task B because there is just one gate for divide errors. There is often a need, however, for one task to take different action than that taken by other tasks. For example, task A may need to terminate in case of a divide error, while task B may need to continue.
INTERRUPT DISTRIBUTION

The software system designer has a choice of mechanisms that make it possible for different tasks to have different interrupt procedures for a given interrupt type
1.

LOT-based interrupt procedures An interrupt distributor

2.

You must deploy alternative 1 carefully. If a trap or interrupt gate in the IDT contains a selector for an LDT slot, then there must be a system-wide convention that every LDT wiIl have an appropriate descriptor in that slot. When the interrupt occurs, the processor uses the LDT of the current task to locate the interrupt procedure. Alternative 2 demands less from convention, but more from the operating system and the processor. With this approach, each task has (in the task database) a table that is its own private analog of the IDT. The operating system supplies a GDT interrupt procedure that merely indexes the current task's handler table to find a pointer to the appropriate handler procedure. If the task does not supply an interrupt procedure for a specific interrupt, the operating system can invoke a default procedure.
CONFORMING INTERRUPT PROCEDURES

For certain interrupt procedures (for example, a divide-error exception handler that substitutes a fixed value for the quotient), the appropriate privilege level at which to run the interrupt procedure is the same as that of the interrupted procedure. In these cases, the interrupt procedure can be placed in a conforming segment. For interrupt procedures in conforming segments, the processor automatically sets CPL to the DPL of the segment containing the interrupted procedure. Note, however, that this

6-7

121960-001

inter

SIGNALS AND INTERRUPTS

technique does not apply to procedures called by an interrupt distribution procedure (because the distribution procedure always runs at PL 0).

"OUTWARD CALL"

An application may contain some interrupt procedures that should run at a fixed privilege level that is grea ter than zero. The processor, on the other hand, prevents calls from PL n to PL m if n<m. For privilege-checking purposes the processor treats interrupts to procedures as calls. It is a privilege violation if the interrupt procedure resides in a segment that has a DPL numerically greater than that of the interrupted procedure. Since interrupts may occur at arbitrary times, it is possible for CPL to be less than the DPL of the interrupt procedure, which would be an exception. A similar problem results when an interrupt distribution procedure (which runs at PL 0) attempts to call a less privileged procedure identified in the task's interrupt handler table. The problem results even if the interrupt distributor attempts to simulate a conforming interrupt procedure by using the interrupted procedure's CPL as the RPL value in the selector of the interrupt handler. The operating system can employ the shadow task strategy to overcome this contradiction. Figure 6-4 outlines the shadow task strategy for invoking a lesser-privileged procedure from PL O. Only a PL-O

lOT

TASK'S HANDLER TABLE SHADOW T1SK OS INTERRUPT PROCEDURE (PL 0)


~

INTERRUPT 10

TASK'S HANDLER PRoe

MAIN TASK

121960-53

Figure 6-4. Private Interrupt Procedure .

6-8

121960-001

inter

SIGNALS AND INTERRUPTS

procedure such as the interrupt distribution procedure described previously can implement this mechanism. Instead of calling the handler procedure (which could be a privilege violation), the operating system's interrupt procedure Creates a shadow task containing the handler procedure Sets the CS and IP fields of the shadow task's TSS to the entry point of the handler procedure Calls the shadow task An IRET instruction in the interrupt handler procedure returns control to the interrupt distributor procedure in the main task. Creating a shadow task involves simply allocating space for the new TSS and initializing it. Setting the LDT field of the new TSS to the same value as in the main task's TSS lets the shadow task have access to all the same segments as the main task, including the segment containing the handler procedure. The operating system may create the shadow task either at the time the main task is created or dynamically, at the time the interrupt occurs.

Provide Software Signals


In some applications there is a need for one task to send a signal to another task that is not waiting for the signal. The "quit" signal in an interactive system is an example. For the target task to respond quickly to the signal, the signal must trigger some form of interrupt mechanism. The mechanisms described previously for private interrupt procedures have the appropriate features: each task can define the action to take upon receipt of the signal, and the signal handler can run at a restricted privilege level. Additional components needed to implement software signals include Extended task handler table with entries for each possible software signal Operating system procedure that any task can call to send a signal to another task

A software signalling mechanism is also a convenient way for the operating system to signal tasks. This method is particularly suited to Reporting exception conditions detected by the operating system Giving a task the chance to put its affairs in order before the operating system terminates it.

6-9

121960-001

Handling Exception Conditions

CHAPTER 7 HANDLING EXCEPTION CONDITIONS


When the processor recognizes a condition that it cannot handle, an exception condition, operating system or applications software must temporarily take control and dispose of the condition. Exception conditions are also known as "faults."

FAULT MECHANISM
The processor reports an exception condition by causing one of a predefined set of interrupts; one interrupt vector is associated with each exception condition that the processor recognizes. As with any interrupt, either a procedure or a task can field a fault. Faults resemble other interrupts, but they differ in two significant ways: You cannot disable a fault. For certain faults, the processor pushes an error code onto the stack of the fault handler (whether procedure or task) to help with recovery.

FAULT RECOVERY
When a fault occurs, the fault handler has three possible ways of dealing with the exception: Ignore it and continue execution of the task. Fix the problem and retry the faulting instruction. Kill the faulting task.

Ignoring an exception is not generally advisable. Killing a task is sometimes unavoidable, but, for critical tasks, the handler should make every effort to recover from the exception. In many cases, the iAPX 286 helps the exception handler identify the faulting instruction and the conditions that caused the fault.

Locating the Faulting Instruction


Usually, a fault handler can locate the faulting instruction either via the return pointer on the stack (if the exception handler is an interrupt procedure) or via the IP stored in the TSS of the faulting task (if the exception handler is an interrupt task). This stored value of the IP is used to return control to the interrupted task, but the exception handler can also use the stored IP value to examine the faulting instruction. There are three cases to consider: The stored IP value points to the location of the faulting instruction (including all prefixes). This is the normal case. The stored IP value points to the location of the next instruction. The stored IP value is unrelated to the fault. This occurs, for example, with 80287 instructions (which execute in parallel with 80286 instructions), or when the 80286 processor discovers a fault while attempting to handle an external interrupt.

7-1

121960-001

HANDLING EXCEPTION CONDITIONS

Error Code
With exceptions that may relate to a specific segment, the processor pushes an error code onto the stack of the exception handler (whether procedure or task). Figure 7-1 illustrates the error code. The format of the error code resembles that of a selector. However, instead of an RPL field, the error code . contains two one-bit items: The processor sets the EX (external) bit when the fault does not directly result from an action of the task. Occurrence of this condition generally indicates a "system" problem as opposed to an "application software" problem. The processor sets the I (IDT) bit if the index portion of the error code refers to a gate descriptor in the IDT. When the I bit is set, the handler can ignore the TI bit. If the I bit is reset, then the TI bit identifies either the GDT or an LDT, just as in a selector.

The index field identifies the descriptor associated with the exception (if any). In some cases the error code on the stack is null, in which case all bits in the word are zero. For some faults, the handler can gain additional information about the fault by determining whether the error code is null.

APPLICATION INTERFACE
Since some of the actions appropriate for exception conditions depend on the requirements of individual application programs, the operating system may need to provide an application interface to the exception handling system. Chapter 6 discusses mechanisms for doing so.

EXCEPTION CONDITIONS
The action appropriate to each type of exception depends both on the type of exception and the needs of the application. This section provides details for each type of exception. Some of the exception conditions are identified by a two-character mnemonic that some other Intel literature uses.

I EX

= =

1 IF DESCRIPTOR IS IN lOT 1 IF EXCEPTION DETECTED DURING EVENT EXTERNAL TO TASK

12196035

Figure 7-1. Exception Error Code

7-2

121960-001

HANDLING EXCEPTION CONDITIONS

Interrupt O-Divide Error


This exception may occur during DIY (unsigned divide) and IDlY (integer divide) instructions. The processor causes a divide-error exception in case of division by zero or quotient overflow. A divide-error handler might, for example, replace the quotient with a predetermined value and permit the faulting task to continue. The return pointer indicates the first byte of the divide instruction, so the handler must increment the return pointer before returning.

Interrupt 1-Single Step


The processor causes a single step exception at the end of every instruction when the TF (trap flag) is set. When the processor invokes any interrupt procedure, it saves the flags and resets the TF so that the exception handler does not cause a single-step exception. Executing IRET at the end of the exception handler restores TF. The exception handler for this exception typically belongs to a debugging system. Single stepping is a valuable debugging tool. It allows the exception handler to act as a "window" into the syst'em through which you can observe task operation instruction by instruction. A single-step handler may, for example, display register contents, the value of the instruction pointer, key variables, etc., as they change after each instruction. The single-step exception handler should take care, however, not to violate the system's protection goals by its actions. To protect the operating system from the debugging activities of an applications programmer, the debugger should not give access to the more privileged levels. The debugger can check, either before or after each instruction, whether the instruction causes a control transfer to a prohibited level. After such a transfer, the return pointer identifies the next instruction in an accessible segment. The debugger can set a breakpoint at that instruction and suspend single stepping until the breakpoint trap occurs.

Interrupt 3-Breakpoint
The INT 3 instruction causes this exception. The INT 3 instruction is one byte long, which makes it easy to insert a breakpoint anywhere in an executable segment. The operating system or a debugging subsystem can use a data-segment alias for an executable segment to place an INT 3 instruction anyplace where it is convenient to arrest normal execution so that some sort of special processing can be performed. Debuggers typically use breakpoints as a way of displaying registers, variables, etc., at crucial points in a task. The saved IP value points to the next instruction. If a debugger has replaced a planted breakpoint with a valid opcode, it must subtract one from the saved IP value before returning.

Interrupt 4-0verflow
This exception occurs when the processor encounters an INTO instruction and the OF (overflow) flag is set. Since signed arithmetic and unsigned arithmetic both use the same arithmetic instructions, the processor can not tell which is intended and therefore does not cause an overflow exception. Instead it merely sets OF when the results, if interpreted as signed numbers, would be out of range. When doing arithmetic on signed operands, careful programmers and compilers either test OF directly or use the INTO instruction.

7-3

121960-001

HANDLING EXCEPTION CONDITIONS

An exception handler usually terminates the faulting task; however, in some applications it is feasible to place a "maximum value" in the receiving operand and permit the task to continue. The return pointer indicates the next instruction.

Interrupt 5-Bound Check


This exception occurs when the processor, while executing a BOUND instruction, fiods that the operand exceeds the specified limits. This condition usually indicates a programming error. The safest action for the handler is to terminate the faulting task. In some applications, however, it is feasible to "adjust" the erroneous operand. The return pointer points to the beginning of the faulting instruction.

Interrupt 6-Undefined Opcode (UO)


This exception occurs when the processor detects an invalid operation code in the instruction stream. Such an exception may occur, for example, if a programmer mistakenly causes a jump to read-only data in an executable segment. This exception has several variations: The first byte of the instruction is completely invalid; for example, 64H. The first byte of the instruction indicates a two-byte opcode, but the second byte is invalid; for example, OFH followed by OFFH. One of the operands of the instruction is not valid for use with the opcode. The opcode extension in the second byte of an instruction contains a value that is invalid for use with the opcode; for example, opcode OF6H with xxOOlxxxB in the second byte. The opcode requires a memory operand, but the operand actually indicates a register, for example, LGDT AX.

The offending opcode is invalid, so the handler should not restart the instruction. You can use this exception to implement extensions of the iAPX 286 instruction set. The exception handler would interpret the instruction and advance the return pointer beyond the extended instruction before returning.

Interrupt 7-Processor Extension Not


This exception occurs in either of two conditions:

~vailable

(NM)

The processor encounters an ESC (escape) instruction, and the EM (emulate) bit of the machine status word (MSW) is set.The processor encounters a WAIT instruction, and both the MP (math present) and TS (task switched) bits of theMSW are set.

Refer to Chapter 12 for details concerning the 80287 Numerics Processor Extension.

7-4

121960-001

HANDLING EXCEPTION CONDITIONS

Interrupt a-Double Fault (OF)


This exception occurs when the processor detects an exception while trying to invoke the handler for a prior exception, for example: The code segment containing the exception handler is marked "not present." Invoking the exception handler causes a stack to overflow.

The processor pushes a null error code onto the stack. If this or any other action while invoking the double-fault handler causes an additional fault, the processor shuts down. To avoid the catastophe of a shut-down, the double-fault handler must be a separate task (so that pushing the error code does not cause a stack fault) and must always be present (so that invoking it does not cause a "not present" fault). Recovery is sometimes possible by eliminating the cause of the second exception and re-executing the faulting instruction so that the original fault can be handled appropriately. The greatest difficulty lies in identifying the cause of the second exception. Often, however, a double-fault condition indicates a serious error, and the faulting task should be terminated.

Interrupt 9-Processor Extension Segment Overrun


This exception occurs when a memory operand of an 80287 instruction has a segment-limit violation. Since the 80287 executes in parallel with the 80286, the occurrence of this exception may not relate directly to the instruction stream being executed by the current task. A task switch may have occurred since the 80287 began executing the instruction. Even if the interrupted task is the correct task, its IP may have been advanced by several instructions beyond the 80287 instruction. Refer to Chapter 12 for more information about this exception.

Interrupt 10-lnvalid TSS (TS)


This exception occurs when the processor detects any of the following abnormalities in a TSS:
1.

The value of the limit field of the descriptor to the TSS is too small (discovered during a task switch). The LDT indicated in the TSS is invalid or not present (task switch). Note that a null LDT selector does not cause an exception during a task switch. One of the segment register fields (SS, CS, DS, or ES) in the TSS is invalid (task switch). One of the privileged-stack selectors is invalid (interlevel CALL). The back-link selector is invalid (intertask IRET).

2. 3. 4. 5.

This exception does not occur when a segment-register field or the back link is marked "not present" but is otherwise valid. A "not present" exception occurs in this case. If, during an interlevel CALL, a privileged-stack selector in the TSS points to a descriptor marked "not present," then a stack exception occurs. The handler for this exception must be a separate task, invoked via a task gate in the IDT. The processor pushes an error code onto the stack of the handler. The error code either identifies the faulty TSS (case 1) or contains the faulty selector from the TSS (cases 2-5). The instruction causing the fault can be restarted. An IRET at the end of the exception handler causes the faulting instruction to execute again. .

7-5

121960-001

HANDLING EXCEPTION CONDITIONS

A few of the conditions that can cause this exception are recoverable. If the system incorporates virtual memory, the solution for a not present LDT may be to bring it in from virtual store. In the case of an invalid back-link, you can make the assumption that the NT flag was set by mistake, give control to the scheduler, and hope ....

Interrupt 11-Segment Not Present (NP)


This exception occurs when the processor detects that the present bit of a descriptor is reset. It may occur in any of these cases: While loading the CS, DS, or ES registers, but not while loading the SS register (a stack fault occurs in that case). While loading the LDT register with an LLDTinstruction, but not while loading the LDT register during a task switch operation (the "invalid TSS" fault occurs in that case). While attempting to use a gate that is marked "not present."

An operating system typically uses the "not present" exception to implement a virtual memory system. Refer to Chapter 9 for more information on virtual memory. The processor pushes an error code onto the stack of the exception handler. The error code contains the selector of the descriptor that is marked "not present." A "not present" indication in a gate descriptor usually has special significance for the operating system. For gates in the IDT, the present bit may serve as a sign that the interrupt task is in software scheduled mode and temporarily unable to service an interrupt. If an interrupt arrives in this case, there may be an error either in the device that generates the interrupt or in the handling of the Interrupt Mask Register of the 8259A PIC. (Refer to Chapter 6 for more information on interrupt handling). For gates in the GDT or LDTs, the present bit may serve to signal an unresolved linkage. (Refer to Chapter 11 for information on binding.) The instruction that causes a "not present" fault is restartable (except in the case of a task switch). Execution of an IRET by the exception handler causes the processor to execute the faulting instruction again. When the processor detects the "not present" exception while loading CS, DS, or ES during a task switch, the exception occurs in the new task, and the return pointer points to the first instruction of the new task. .

Interrupt 12-Stack Exception (SS)


This exception occurs in either of two general conditions: As a result of a limit violation in any operation that refers to the SS register. This includes stackoriented instructions such as POP, PUSH, ENTER, and LEAVE as well as other memory references that implicitly use SS (for example, MOV AX,[BP+6] ). ENTER causes this exception when the stack is too small for the indicated local variable space. An interlevel CALL reference's two stacks; a stack-limit exception can result from either of them. . When attempting to load the SS register with a descriptor that is marked "not present" but is otherwise valid. This can occur in a task switch, an interlevel CALL,.an interlevel return, or a MOV or POP instruction to SS.

7-6

121960-001

HANDLING EXCEPTION CONDITIONS

The processor pushes an error code on the stack of the exception handler. If the exception is due to a not-present stack segment or to overflow of the new stack during an interlevel CALL, the error code contains a selector to the segment in question (the exception handler can test the present bit in the descriptor to determine which exception has occurred); otherwise the error code is null. The instruction that causes a stack fault is usually restartable. Execution of an IRET by the exception handler causes the processor to execute the faulting instruction again. The one case that is not restartable is a PUSHA or POPA intruction that attempts to wrap around the 64K boundaries of a stack segment. This condition is identified by one of the values FFFEH, FFFFH, OOOOH, or OOOIH inthe saved SP. When the processor detects a stack fault while loading SS during a task switch, the exception occurs in the new task, and the return pointer has the value that the IP field of the new TSS held at the time the task switch began. When stack overflow causes the exception, the stack fault handler can increase the size of the stack segment (up to a maximum of 64K) and permit the faulting task to continue. When the exception is due to a stack segment not being present, recovery action resembles that of the "not present" fault handler.

Interrupt 13-General Protection Exception (GP)


All protection violations that do not cause another exception cause a general protection exception. This includes (but is not limited to) Exceeding segment limit when using DS, ES, or CS Exceeding segment limit when referencing a descriptor table Jumping to a data segment Writing into a read-only segment or an executable segment Loading the SS register with a read-only descriptor (unless the selector comes from the TSS during a task switch, in which case a TSS exception occurs) Loading DS, ES, or SS with the descriptor of a system segment Loading DS, ES, or SS with the descriptor of an executable segment Loading CS (by means of a CALL, JMP, or interrupt) with the descriptor of a data segment Accessing memory via DS or ES when it contains a null selector Switching to a busy task Violating privilege rules

. Reading from an execute-only segment

The processor pushes an error code onto the exception handler's stack. If loading a descriptor caused the exception, the error code contains a selector to the descriptor; otherwise the error code is null. The return pointer points to the beginning of the faulting instruction. Recovery may be possible, but . because programming errors cause most of the conditions leading to a general protection exception, recovery may not be worth the trouble required to identify the cause. A string instruction (any variant of INS, OUTS, MOVS, STOS, SCAS, or CMPS) with a repeat prefix (REP, REPE, or REPNE) is not restartable if it causes a segment limit violation. Check whether SI or DI is near the segment limit.

7-7

121960-001

inter
SBB).

HANDLING EXCEPTION CONDITIONS

An instruction that both tests and modifies the carry flag is not restartable (ADC, RCL, RCR; or

Interrupt 16-Processor Extension Error (MF)


The 80286 causes this exception when it detects a signal from the 80287 on the 80286's ERROR input pin. The 80286 tests this pin only at the beginning of certain floating-point instructions and when it encounters a WAIT instruction while the EM bit of the MSW is re'set (no emulation). Refer to Chapter 12 for more information on this exception.

Interrupt 17 -Run-Time Exceptions


Intel's run-time support software uses this interrupt to communicate exception conditions regarding range checks and procedure stack overflow. Applications should avoid using this interrupt for any other purpose.

REST ART ABILITY SUMMARY


Table 7-1 summarizes the information pertinent to restarting the faulting instruction.

Table 7-1. Restart Conditions


Vector Exception Return Address Relative to Faulting Instruction First byte Next instr. Next instr. Next instr. First byte First byte Unrelated First byte Unrelated First byte First byte First byte First byte Unrelated Restartable? Error Code? No No No No No No No Yes (always nUll) No Yes Yes Yes Yes No

0 1
.3 4

5
6
7

8
9 10 11 12
13 16

Divide error Single step Breakpoint Overflow Bound check Undefined opcode Processor extension not available Double fault Processor extension segment overrun Invalid TSS Segment not present Stack exception General protection Processor extension error

Yes No

No Yes No Yes No No Yes Yes Yes No

7-8

121960-001

Input / Output

CHAPTER 8 INPUT /OUTPUT


Many of the concepts previously introduced in this book apply to the design of the I/O subsystem of an operating system; in addition, the iAPX 286 has several I/O features of special interest. The functions typically performed by an I/O subsystem include Centrally implementing and standardizing I/O logic so that all application programs can share it. Providing a uniform, high-level interface by which application procedures can request I/O services (as a minimum, the functions READ and WRITE). A more sophisticated system may need a full, file-oriented set of interfaces such as Intel's Universal Development Interface (UDI). Administering device naming. Often this includes transforming logical device identifiers into physical identifiers, so that applications that use the logical identifiers can maintain independence from physical devices. Managing use of memory resources for I/O buffers. Managing sharing of physical devices. Often this reduces to giving one task exclusive use of a device (for example, a printer) until the task relinquishes it. With disk devices, tasks can usually share the device as long as each uses a different set of disk addresses. A sophisticated database-management system may require unlimited disk sharing (the database system assumes responsibilityfor blocklevel synchronization, deadlock detection, and recovery). Providing device-driver procedures to deal with the vagaries of various I/O devices. Optimizing I/O efficiency. This might include any of these techniques: blocking, buffer pooling, automatic seek-ahead, reduction of disk arm movement.

This discussion of I/O classifies physical I/O operations thus: Direct I/O, in which the 80286 processor itself communicates directly with the peripheral device. Direct I/O breaks down further into a. Memory-mapped, in which I/O is triggered by processor instructions that reference certain memory locations. b. I/O-mapped, in which special I/O instructions cause the processor to do I/O. Indirect I/O, in which an external processor (such as the Intel 8089 I/O Processor) performs the I/O.

1/0 AND PROTECTION


The concept of protection as applied to I/O deals not only with the memory used in I/O operations but also with the right to execute I/O operations.

1/0 Privilege Level (IOPL)


You can limit to specific privilege levels the right to execute I/O and I/O-related instructions. 10PL (a two-bit field in the flag word) restricts a task's right to execute any of these instructions: IN INS input input string

8-1

121960-001

inter
OUT OUTS STI CLI LOCK

INPUT /OUTPUT

output output string set interrupt flag (enable interrupts) clear interrupt flag (disable interrupts) lock bus

When interpreting any of these restricted instructions, the processor compares CPL to 10PL. If CPL exceeds 10PL, the processor causes a general protection exception and does not carry out the instruction. Only a privilege-level 0 (PL-O) procedure (i.e., the operating system) can change 10PL. There is no instruction that explicitly affects IOPL; however, any of the operations that load the flag word can, in some cases, change 10PL. The only mechanisms for changing the flag word are A task switch The POPF (pop flags) instruction IRET

When CPL is greater than zero, the POPF instruction does not change 10PL, even though it changes other flags in the flag word. The processor issues no error indication when this occurs. A task switch loads the flags from the Task State Segment (TSS). As long as the operating system does not make data-segment aliases for the TSS available to less privileged levels, only the operating system can change 10PL in theTSS. For maximum protection, the procedures of an I/O subsystem that run in the calling task should run at a protection level numerically greater than the operating-system kernel but less than applications procedures. 10PL can then include the I/O subsystem but exclude applications procedures. Used this way, 10PL forces less privileged application procedures to call on I/O subsystem procedures for I/O functions, thereby giving the operating system control over many I/O operations .. Tasks that deal primarily with I/O (device drivers, for example) may have an 10PL value as great as three. If that is the case, all procedures in the task have access to I/O operations, yet all four privilege levels are available to protect the procedures of the task from one another.

Controlling I/O Addresses


Protection is incomplete if not applied to memory accesses by I/O operations. 10PL does not apply to memory-mapped I/O nor to interface with intelligent controllers (because none of the restricted instructions are used). The operating system designer must make special provisions to control these I/O operations, either via the operating system or with the Builder.
HARDWARE ADDRESS CHECKING

Memory-mapped I/O is subject to the segment-level protection mechanism of the iAPX 286. A task can execute a memory-mapped I/O operation only if it has access to a descriptor for a data segment that contains one of the memory addresses reserved for I/O. Giving a task descriptors for only the I/O memory addresses that it has the right to use yields a double benefit: The task cannot access I/O devices assigned to other tasks. Within the task, I/O is restricted to those procedures whose privilege level is numerically less than or equal to the DPL of the I/O memory address segments.

8-2

121960-001

INPUT/OUTPUT

You can still take advantage of I/O memory address protection even though the I/O devices on the bus respond to I/O commands. A hardware address mapper can convert the processor's memory cycles for the I/O memory space into I/O cycles on the bus. The address mapper will not initiate a bus I/O cycle unless the memory operation passes the processor's protection checking.

SOFTWARE ADDRESS CHECKING AND CONVERSION

With indirect I/O, the external controller accesses I/O buffers independently of the 80286. This presents a three-fold problem to the operating system: Memory access by the controller is not subject to the automatic protection checking of the 80286. The controller (probably) uses "flat" addresses (i.e., addresses that are not relative to a base address). The addressing range of the controller may not coincide completely with that of the 80286.

The flow of control for indirect I/O requests must pass through operating-system procedures at PL 0 so that the operating system can Check memory addresses and privilege levels against information stored in the task's descriptors Transform base-relative addresses to a flat format recognizable by the controller

1/0 AND MEMORY MANAGEMENT


An I/O subsystem can place additional requirements on the operating system's memory manager; for example: I/O functions may use certain dedicated memory locations (for example, the addresses used for memory-mapped I/O, and the communication blocks and buffers that external controllers expect to find a fixed locations). The memory manager must be aware of these locations and must not ' allocate them for other purposes. When buffers for external controllers are allocated dynamically, addressing limitations of the controller may require the memory manager to find space within the portion of memory that the controller can address. Once it allocates a segment for the use of an external controller, the memory manager must not move, delete, or swap out the segment without cooperation from the controller.

PARTITIONING 1/0 FUNCTIONS


To determine how best to distribute I/O functions across tasks and privilege levels, you must consider The opportunities for parallelism The needs for synchronization The requirements for protection

8-3

121960-001

INPUT IOUTPUT

Requirements for Parallelism and Synchronization


The requirements for parallelism and synchronization in the I/O subsystem may include any of the following: The application procedure that requests a READ operation may run in parallel with the I/O subsystem until that procedure needs to reference the requested data, at which point it must wait until the data arrives or an exception occurs. The procedure that requests a WRITE operation can usually run in parallel with the I/O subsystem. Some applications require acknowlegement of the completion of a WRITE operation (in order, for example, to synchronize with a database recovery system), in which case that procedure must wait until the acknowledgement arrives. SEEK operations normally run in parallel with the requesting procedure. The I/O device can always run in parallel with some task in a multitasking system, whether it be the task that requested the I/O operation or some other task that is not waiting for I/O. In a simple I/O subsystem in which a device driver only manages one I/O operation at a time, the driver can simply wait until the device signals that the operation finishes. If the requesting procedure is blocked, the device driver can merely convert the I/O-complete signal into a wake-up signal for that procedure. In a more sophisticated I/O subsystem (for example, one in which a disk driver handles more than one spindle and more than one task can share a disk device), greatest efficiency results only when device drivers run in parallel with I/O devices as well as with requesting procedures. An 1/0complete signal from a device may arrive when the device driver is busy.

Figure 8-1 explains the symbols used in a Petri net graph. Figures 8-2 and 8-3 use Petri net graphs to illustrate two approaches to synchronization between parts ofan I/O subsystem. A horizontal line represents an event of interest that occurs only under certain conditions. Circles preceding an event represent the conditions under which the event can occur. Circles after an event represent the conditions that result from occurrence of the event. A dot inside a circle is called a token. A token represents a condition that is in effect. An event occurs if and only if there are tokens for all its input conditions. When an event occurs, tokens flow into all its output conditions. Figure 8-2 assumes the simple device driver mentioned previously and points out how such a driver can service only one task at a time. Figure 8-3 shows how a two-part driver can deal with more than one I/O request at a time (assuming that the I/O device can do so as well). I/O requests from applications procedures drive part A, while interrupts drive part B. Not shown by the Petri net graphs is the fact that the two parts of the driver must share information about outstanding I/O requests. Both figures show simplified device drivers to highlight the interactions among parts of the I/O subsystem; for example, a real device driver may issue multiple physical I/O commands in response to one I/O request and may retry I/O operations in case of certain error indications from the device.

Requirements for Protection


The requirements for protection in an I/O subsystem include (in addition to the protection considerations previously discussed) Device allocation tables and any other data used by the primary I/O interface procedures must be protected from all but those procedures privileged to do I/O, but must be available to every task in which the I/O interface procedures can run. Only the device driver should have access to a device's control parameters (for example, head settling time for a disk drive).

8-4

121960-001

inter

INPUT /OUTPUT

Only the operating system and the I/O subsystem should use queues of buffers and I/O requests. An application procedure must not use a buffer that an I/O device is simultaneously using.

Implementation Alternatives
If descriptors for data global to the I/O subsystem (such as device allocation tables) reside in the GDT with DPL equal to the I/O privilege level, then I/O procedures can access them regardless of what

o o

FALSE CONDITION

TRUE CONDITION EVENT

CONDITIONAL EVENTS

ENABLED CONDITIONAL EVENTS

t t fa ~
8-5

OCCURRENCES OF EVENTS

121960-39

Figure 8-1. Petri Net Graph Symbols

121960-001

INPUT IOUTPUT

APPLICA nON

DEVICE DRIVER

REQUEST

110
CONTINUE PROCESSING DO OTHER PROCESSING RECEIVE RESPONSE HARDWARE 1/0 DEVICE

APPLICATION REQUEST 1/0 CONTINUE PROCESSING DO OTHER PROCESSING RECEIVE RESPONSE

121960-37

Figure 8-2. Synchronization with Simple Device Driver

APPLICATION

DEVICE DRIVER (PART A)

REQUEST 1/0 CONTINUE PROCESSING DO OTHER PROCESSING RECEIVE RESPONSE HARDWARE 1/0 DEVICE

GET COMMAND

DO 1/0 APPLICATION REQUEST 1/0 CONTINUE PROCESSING DO OTHER PROCESSING RECEIVE RESPONSE CAUSE INTERRUPT

121960-38

Figure 8-3. Synchronization with Two-Part Device Driver


8-6

121960-001

INPUT IOUTPUT

task the I/O procedures run in. The I/O interface procedures (READ, WRITE, etc.) must have DPL equal to that of the global I/O data and therefore must have call gates at the privilege level of application procedures (PL 3). If these call gates reside in the LOTs of application tasks, then I/O interface procedures can be shared by (but limited to) those tasks that need them. The call gates can also reside in the GOT, where all tasks can access them. In either case the interface procedures run in the calling task. The possibilities for running device drivers in parallel with the calling task suggests that they be separate tasks. Such a separation also serves to protect applications and device drivers from one another, a definite advantage because inherent complexity and frequency of change tend to place device drivers among the least reliable of operating system functions. The I/O interface procedures have the responsibility for managing the details of communication between the calling task and the device drivers. You can implement a sophisticated device driver such as that illustrated in figure 8-3 as two cooperating tasks: one scheduled by interrupts via a task gate in the lOT, and the other scheduled by I/O requests via an operating-system mailbox facility.
It is possible to implement device drivers as interrupt procedures that run within applications tasks. Such a structure is advantageous in these cases:

Efficiency of I/O is an overriding goal. Interrupts may arrive when a driver is busy.

The lack of protection inherent in such a structure becomes apparent, however, when you consider that the driver procedure that fields an I/O-complete interrupt may run as part of a task completely unrelated to the task that originally requested the I/O operation, and must run at PL O. Viewing the possible implementations of buffers from the perspective of the iAPX 286 architecture, the most pertinent consideration is whether a segment contains just one buffer or several buffers. An approach that uses one segment per buffer has several advantages: The protection mechanism of the iAPX 286 (working as it does on segment descriptors) focuses on each buffer individually. The selector of a buffer segment serves as a convenient buffer identifier, fitting easily into the aliasing and mailbox schemes outlined in Chapter 5.

You can avoid the potential GOT congestion that may result from having one segment (and therefore at least one segment descriptor) per buffer by storing buffer descriptors in LOTs. When tasks share buffers (as between an application task and one or more device-driver tasks), you have a choice between Leaving the buffer at all times within the address spaces of all the sharing tasks Transferring the buffer from the address space of one task into that of another

The mailbox scheme outlined in Chapter 5 easily accomplishes the latter approach. This scheme has the advantage that the application task cannot use the buffer at the same time as I/O is in progress. The "usage privilege level" (UPL), if set to 10PL, provides additional protection by limiting mailbox access to I/O procedures. The application's requirements for I/O efficiency may, however, preclude use of mailboxes for this purpose.

8-7

121960-001

Virtual Memory

CHAPTER 9 VIRTUAL MEMORY


The memory legitimately addressed by the tasks running on an iAPX 286 (the virtual memory) may exceed the actual memory available. You can use this capability to lower memory costs, substituting disk or other less expensive storage media for relatively expensive RAM. Virtual memory isolates programmers from the amount of real memory in a computer system. The system designer can trade off performance against system cost using identical software. A system that supports virtual memory can be analyzed in terms of mechanisms and policies. The iAPX 286 has mechanisms that help your operating system manage the swapping of segments between RAM and less expensive memories. The operating system must implement additional mechanisms as well as policies for efficient use of these mechanisms in a specific application.

HARDWARE MECHANISMS
The 80286 provides the essential hardware mechanisms without which virtual memory systems would not be possible. The segment is the basic unit of the virtual-memory scheme, just as it is the basic unit of the real-memory scheme. In each segment descriptor, the iAPX 286 architecture provides an accessed bit and a present bit to aid the operating system in simulating the virtual memory space with available RAM.

Accessed Bit
Every descriptor for an executable segment or data segment has an accessed flag in the least significant bit position of the access rights byte. Each time a task loads segment register with a segment descriptor, the processor automatically sets the accessed bit in that descriptor. The processor does not automatically reset the accessed bit; software must explicitly write a zero into the accessed bit. The accessed bit has a dual function in virtual memory management: By testing and then resetting the accessed bit at regular intervals, the virtual-memory manager can measure how frequently the segment is being accessed. For writable data segments, the accessed bit (when set) indicates that the segment may have been changed.

Present Bit
Every segment descriptor has a present flag in the high-order bit position of the access-rights byte. The processor automatically tests this bit as it loads segment registers. If the present bit is reset, the processor causes a trap. Which trap depends on the circumstances: Trap 11 (Segment not Present) occurs when loading the CS, DS, or ES register with a not-present segment descriptor, when switching to a not-present TSS, when loading the Task Register by means of the LTR instruction with a not-present TSS descriptor, or when loading the LDT register with a not-present LDT descriptor. Trap 11 also occurs when loading CS with a gate descriptor that is marked "not present." This condition does not necessarily mean that a segment is not present, however. The operating system

9-1

121960-001

VIRTUAL MEMORY

may attach other meaning to the present bit of gate descriptors. Refer to the section on load-time binding in Chapter 11 for an example of an alternate use for the present bit in gate descriptors. Trap 12 (Stack Exception) occurs when loading the SS register with a not-present descriptor. The exception handler can distinguish this condition from other stack exceptions by examining the access rights byte of the descriptor selected by the error code. Trap 10 (Invalid TSS) occurs when switching to a TSS that points to a not-present LDT. The exception handler can distinguish this from other "invalid TSS" conditions by examining the access rights byte of the descriptor selected by the error code. Trap 8 (Double Fault) occurs if the processor, while trying to invoke an exception handler due to a previous exception, finds that the code segment containing its entry point is not present. The difficulty of distinguishing between this and other double fault conditions implies that trap 8 is to be treated as an error condition, not a normal use of the present bit.

Refer to Chapter 7 for additional information about these traps.

SOFTW ARE MECHANISMS


The operating system must provide additional mechanisms for a virtual memory system: one for moving a segment from RAM to secondary storage (the swap-out manager) and one for moving a segment from secondary storage to RAM (the swap-in manager). The swapping managers are essentially I/O modules, but there are major differences between swapping managers and the functions of a standard I/O subsystem: Swappers deal with executable segments, system segments, and data segments that are not normally considered I/O buffers. I/O performance of swappers is critical and often calls for specialized device drivers and disk space allocation stategies.

Secondary Storage Management


Virtual-memory mechanisms use a secondary storage medium, such as disk, to simulate a larger memory space than that provided in RAM. The operating system uses this secondary storage (here called the swap space) to store copies of those segments that are currently in the virtual space but may be eliminated from RAM. There are two general approaches for allocating swap space for segments in dynamic systems: The loader can invoke a swap-space allocation procedure as it loads the segments of a task. It can at the same time write an initial image of the segment into the swap space. This is particularly useful for a segment such as an executable segment that is occasionally swapped in but may never be swapped out (when its RAM space is used for another segment) due to the fact that its contents do not change. The operating system may invoke the swap'-space allocation procedure dynamically, either when allocating RAM for the segment or at the first time the operating system swaps the segment out.

Some operating systems may implement both approaches. A system that allocates swap space only at load-time cannot swap out certain segments; namely, segments that a bootloader creates initially and segments that the operating system creates dynamically. In many systems, this is not a problem. Often

9-2

121960-001

VIRTUAL MEMORY

those segments that are bootloaded are just the segments that should not be swapped out. Other operating systems may allocate many segments dynamically: stacks, mailboxes, variable-length arrays, etc. These systems may need both approaches. In designing a dynamic swap-space allocation scheme, you should consider at what time it is best to allocate swap space. The procedure that first allocates RAM space for a segment (a loader, for example) often creates a writable data segment descriptor. Later, when the,procedure has initialized the segment (for example, by writing descriptors into a segment that is to be used as an LOT), it modifies the type code in the descriptor to reflect the intended use of the segment (in this example, it would change the type to LOT). By delaying the allocation of swap space until first swap out, the operating system never allocates swap space for segments that it never swaps out (there is no need to allocate swap space for an LOT, for example, if the operating system does not support swapping of LOTs). Once the operating system allocates swap space for a segment, it must store the swap-space address in a location that is easily accessible when it is time to swap the segment out. Two possible mechanisms for storing the swap-space address are In a boundary tag of the segment, if boundary tags are used. (Refer to Chapter 3 for an example of a space-management scheme that uses boundary tags.) In a table parallel to the descriptor table. To determine whether to call the swap-space allocation procedure when it is time to swap a segment out, the operating system can test whether the swap-space address field contains a null value. When a segment is not present, the operating system can use the 24-bit base-address field in the segment descriptor to store the address of the swap space in which the segment is stored. As long as the present bit of a descriptor is reset, the processor does not use the base-address field. Storing the swap-space address in the descriptor also makes the swap-space address readily accessible to the "not-present" trap handler because the error code presented to the trap handler contains a selector to the descriptor for the not-present segment.

Level Zero Support Procedures


While the swapping procedures are I/O procedures that should run at privilege levels greater than zero, protection of the system demands that highly privileged procedures carry out some details of the swapping process. Only privilege-level 0 (PL-9) procedures have the right to perform such activities as Create read-data or write-data alias descriptors with which the swappers can access the segments they are operating on Change the present bit in a descriptor Overwrite the base-address field of a descriptor Prevent the swapper from operating on segments that must remain RAM-resident Update all the alias descriptors for a segment with its new status

The following checklist identifies some of those segments that should remain permanently in RAM (in your application, there may be others): The GOT. (It is the key to all addressing operations.) LOTs that refer to present segments. (The processor cannot access an LOT segment without fetching its descriptor from the LOT.)

9-3

121960-001

VIRTUAL MEMORY

TSSs that point to present LDTs. (You cannot switch to a task and use its LDT without referring to its TSS.) TSSs whose NT (nested task) flag is set. Certain operating-system kernel segments that are frequently referenced (for example, the segment or segments containing the scheduler's queues). (System performance may degrade excessively.) Segments belonging to the swapping managers.

I/O buffers that are in use by an external device.


Executable segments that contain the entry point of an exception handler. (An exception would result in a double fault.)

Note that, while the iAPX 286 does offer mechanisms that support swapping of TSSs and LDTs, doing so is likely to cause not-present faults in PL-O procedures and to cause unacceptable delays in invoking interrupt tasks that are not present. For either of these reasons, the designers of an operating system may elect not to swap out TSSs and LDTs.

Swapping Managers
Swapping managers may need to distinguish between two classes of segments: Segments of a task superstructure (the TSS, the task database (TDB), and possibly the level-zero stack segment) Segments not part of a task superstructure

Swapping of the task superstructure requires that swapping managers be aware that the kernel may treat the TSS as a "subsegment" of the TDB, which may itself reside within the level-zero stack (as outlined in Chapter 4). The swapping managers should treat these segments as a unit. Considering the complexities associated with swapping the segments of the task superstructure, it is perfectly reasonable for an operating system to simplify its virtual-memory subsystem by leaving those segments in RAM for the duration of the task.
OUT-SWAPPER

The out-swapper works best as a separate task; when the out-swapper must wait for the swappingdevice I/O driver to write a segment, other tasks can continue to run, including the task whose segment is being swapped out. The out-swapper's responsibility is to Mark all the descriptors for the segment "not present." The out-swap per must ensure that the present bits in all descriptors for a segment always appear consistent. It must use a semaphore or region to prevent other access to the aliases while it is changing present bits. Copy the swap-space address into all the descriptors for the segment (or possibly, depending on alias implementation, into a "master descriptor" that is linked to other descriptors). Create a temporary data-segment descriptor to give the swapper the right to read the segment. The operating system must not move or delete this segment until the out-swapper is finished with it. Write the segment to the swap-space allocated for it (but only if the segment is writable and its accessed bit is set).

9-4

121960-001

VIRTUAL MEMORY

Return the RAM space used by the segment. Delete the temporary data-segment descriptor.

IN-SWAPPER

In theory, the fetch policy module, invokes the in-swapper. In practice, when the fetch policy is "on demand," the in-swapper is the "not-present" fault handler, which may also be called by the stack segment fault handler (for not present stack segments) and by the "invalid TSS" fault handler (for not present LDTs). The not-present fault handler can run as a procedure in the task that caused the fault. There is one case, however, that such a procedure cannot handle well. A dispatcher procedure running in task A causes a not-present fault when switching to task B whose TSS is not present. If the notpresent handler procedure continues running in task A, then task A must wait until task B's TSS can be swapped in. Whether this is a problem depends on the role of task A in the application. The notpresent handler procedure can avoid this situation by suspending task B and sending a message to yet another task that is dedicated to swapping in TSSs. The steps that an in-swapper procedure takes are to Get the swap-space address and segment size (limit) from the descriptor indicated by the error code. Allocate a writable data segment in RAM large enough to receive the segment. Copy the segment from swap space to the newly allocated RAM space. Update all regular descriptors for the segment with the new base address, setting the present bit and resetting the accessed bit. (The base address comes from the temporary writable data-segment descriptor.) Delete the temporary writable data-segment descriptor.

An in-swapper task for not present TSSs gets a message from its input mailbox that identifies the descriptor for the TSS and identifies the task to which the TSS belongs. The in-swapper task performs the same steps as an in-swapper procedure, but it must also inform the scheduler when the task is ready to run. You can avoid the additional complexities of not-present TSSs by not swapping TSSs out.
COORDINATION OF IN- AND OUT-SWAPPER

A number of interactions between the in-swapper and out-swapper present pitfalls that the operating system must avoid: A task may attempt to use a segment that is being swapped out. If the in-swapper does not handle this possibility, it may swap in- old, erroneous data from the swap-space. Task A may request swapping in of a shared segment that is being swapped in for task B. If the inswapper blithely reads in the segment again for task A, it may overwrite changes made by task B. A task may delete a segment that is being swapped out. If the swap-space release procedure does not allow for this case, the segment's swap space may be released and reallocated while the outswapper is writing to it.

The in-swapper, out-swapper, and swap-space release procedures can control these interactions by maintaining a shared table of all segments that are in transition. They must use a semaphore or region to coordinate access to the shared table. The swap-space address can serve as the segment identifier in the table.

9-5

121960-001

inter
SOFTWARE POLICIES

VIRTUAL MEMORY

A virtual memory system gives each task the opportunity to affect other tasks in the system. Tasks compete with one another for real memory resources. One task may attempt to use memory in such a way as to unduly impede the progress of other tasks. The operating system must enforce policies which ensure that every task makes appropriate progress. Virtual memory management policies are not unique to the iAPX 286; the computer-science literature contains many discussions of policies that apply to various classes of applications. There is, however, a distinction between segmented architectures and paged architectures. The iAPX 286 has a segmented architecture. Literature that deals with paged architectures may not apply to the iAPX 286. Refer to the paper by Denning (see "External Literature" in the Preface) for a broad survey of the science of virtual-memory management. The remainder of this chapter is an introduction to memory-management policy. The policies you need to consider are of three types: fetch policy, placement policy, and replacement policy.

Fetch
The fetch policy determines which segment to bring from swap space into RAM and determines when to bring it in. The simplest fetch policy is to bring in a segment on demand, that is, at the time it is referenced. Under this policy, the operating system brings in a segment from swap space only when the processor causes a not-present exception as the result of a reference to the segment. All other fetch policies are in some way anticipatory. A simple example of an anticipatory fetch policy on the iAPX 286 is to always bring in the LDT of a task when bringing in its TSS. Some time-sharing systems implement an anticipatory policy that brings in all the segments of a task at once. This policy may be suitable for tasks that consist only of one code segment, one or two data segments, and stack segment (as, for example, simple BASIC programs submitted by students in a university environinent). The swapping managers can use the segment register fields in the TSS (CS, DS, ES, SS) to identify the task's working set. Attempting to implement such a full-task swap policy for more complex tasks that use many segments may result in frequently fetching segments that are not referenced in anyone time slice. The additional complexity of implementing an anticipatory fetch policy is justifiable only if the anticipatory policy performs better than the demand policy. Given the efficiency of the iAPX 286 exception mechanism and given that in a multitasking environment there is usually some other task to service while one task waits for the in-swapper to fetch a segment, an anticipatory policy typically does not provide significantly greater throughput. An anticipatory policy may give better performance, however, when judged by performance standards other than throughput (for example, interrupt latency for specific tasks).

Placement
Determining where in RAM to place an incoming segment is the subject of Chapter 3. In a virtualmemory system, however, the constant reallocation of real memory to segments of varying length places special demands on the operating system's memory management module. When choosing a spacemanagement algorithm for a system that includes virtual memory, you may wish to give extra consideration to the trade-off between speed and memory fragmentation.

9-6

121960-001

VIRTUAL MEMORY

Replacement
The operating system may need to replace one or more other segments that already reside in real memory to make space for a segment that is the object of a "segment-not-present" fault. The replacement policy determines which segments to eliminate and when to eliminate them. The choice of which segments to evict from RAM -is crucial to the performance of the system. The goal is to evict only segments that will not soon be referenced. The difficulty is knowing which segments will not soon be referenced. Many different policies are discussed in the liteniture. They' fall into three general classes:

Naive policies that determine which segment to evict without any knowledge of segment access patterns Historical policies that use information about prior access patterns to determine the probability that a segment will soon be referenced Optimal policies that use analyses of actual program control flow to determine the probability that a segment will soon be referenced

HISTORICAL POLICIES

The iAPX 286 architecture supports gathering of historical information about actual segment access patterns via the accessed bit in executable and data segment descriptors. An operating-system module that periodically tests and resets the accessed bits of descriptors can develop a "profile" of segment usage. The information gathered this way can be used both by the replacement policy module for runtime decision making and by the operating system designers for improving replacement policy. A "profiler" works best if it takes samples at regular intervals. To find all descriptors, it must step thru LOTs. A profiler does not need to examine all descriptors in the system each time it is invoked; it needs only to examine those of tasks that have run since the last time it was invoked. The same timer interrupt procedure used by the scheduler can invoke the profiler at appropriate times. A profiler may run either as a separate task or as a shared procedure in the current task. A profiler that runs as a procedure in the current task can easily locate the LOT with an SLOT instruction. The LSL (load segment limit) instruction helps the profiler find the size of an LOT. The LAR (load access rights) instruction enables the profiler to test the accessed bit. A profiler that runs as a separate task may require the support of a PL-O procedure that locates LOTs and tests accessed bits in other tasks. A profiler must give special consideration to aliases. If the accessed bit in any of the aliases of a segment is set, the segment has been accessed. Here again, a PL-O segment may be needed to step through the kernel's alias lists.
OPTIMAL POLICIES

Many of the optimal policies discussed in the literature are of theoretical interest only. They are used as a standard against which to measure the performance of more practical policies. The segment-register fields of the TSS provide support for a trivial, but possibly useful, optimal policy. The replacement policy can assume that, next time any given task runs, all the segments identified by the CS, OS, SS, and ES fields of the TSS will be referenced. The processor loads all these registers during a task switch and causes a fault at that time for each not-present segment. Since the task cannot run if anyone of these segments is not present, the replacement policy may as well replace all of them

9-7

121960-001

VIRTUAL MEMORY

at once. It then becomes possible to allocate swap space for these segments in such a way as to minimize seek time. Such a policy works well with the full-task fetch policy outlined previously.

THRASHING
If not carefully controlled, the I/O traffic in support of virtual memory may degrade system performance beyond acceptable limits. The, worst case of performance degradation is called thrashing. This happens when RAM is committed to simulating an excessively large virtual-memory, space and the behavior of the tasks in that space is such that no task can run without causing a not-present fault.

You can avoid thrashing by measuring or estimating the minimum amount of RAM a task needs in which to operate without causing frequent not-present faults. If the task loader knows this figure, it can refuse to load a task when not enough RAM is available. You can measure a task's RAM requirements' with a profiler such as that described previously.

9-8

121960-001

System Initialization

10

CHAPTER 10 SYSTEM INITIALIZATION


The initialization performed at power-on or RESET by the 80286 processor is not, by itself, adequate for running in protected mode. Software must perform additional initialization before it is possible to fully use protected mode.

INITIAL STATE
When you power up an 80286 system or perform a RESET, the state of the processor is as follows: The MSW (machine status word) is zero; i.e., the 80286 starts running in the real-address mode. CS:IP be set to FOOO:FFFO, and the CS limit is OFFFFH. The four high-order address lines A 23 -20 are automatically asserted for all subsequent references to CS until your initialization code changes CS. SS, DS, ES are set to zero, and the corresponding limit registers are set to OFFFFH. The flag word is zero. This means that the 80286 starts running with the maskable interrupts disabled.

The initial state of the address lines and CS:IP causes the processor to begin executing instructions at physical address OFFFFFOH. Presumably, this addresses a JMP instruction in an initialization procedure located in ROM or in RAM that has been loaded by another processor. The initialization procedure may occupy any portion of the last 65,536 bytes of the 16-megabyte address space. The JMP instruction at physical address OFFFFFOH transfers control to the actual beginning of the initialization procedure. The first instruction that modifies the CS register causes the processor to cease asserting the high-order four address lines; therefore, the initialization procedure must avoid using any instructions that modify the CS register, except for the final JMP instruction. The initial state of the DS, ES, and SS registers gives the initialization procedure access to the first 65,536 bytes of the address space. The initialization procedure may change these registers, however, to gain access to any location in the first megabyte of the address space. (With regard to segmentation and addressing, the 80286 in real-address mode behaves just as an 8086.) Access to other portions of memory is possible only after switching into protected mode.

SWITCHING TO PROTECTED MODE


You use the LMSW (load machine status word) instruction to set the PE bit in the MSW, thereby switching the 80286 into protected, virtual-address mode. The current privilege level (CPL) starts at zero. The segment registers continue to point to the same physical memory areas as in real-address mode. Immediately after setting the PE flag, the initialization code must flush the processor's instruction queues by executing a JMP instruction. The 80286 fetches and decodes instructions and addresses before they are used; however, after a change into protected, virtual-address mode, the prefetched instruction information (which pertains to real-address mode) is no longer valid. A JMP forces the processor to discard the invalid information. An intrasegment JMP will cause the processor to drop the four high-order address lines; however, in protected mode this is not a problem. All addressing in protected mode uses the 24-bit base address from the segment descriptor; so, once in protected mode, all of physical memory is accessible.

10-1

121960-001

SYSTEM INITIALIZATION

INITIALIZING FOR PROTECTED MODE


You can do most of the initialization needed for protected mode either before or after switching into protected mode. If done after, however, you must be careful to order the code so that it does not use protected mode features that require initialization that is not yet completed.

Interrupt Vector
The initial state of the 80286 leaves interrupts disabled; however, to ensure a predictable action in case an exception or non-maskable interrupt (NMI) occurs, it is a good idea to initialize the lOT register. Since it is unlikely that the NMI interrupt handler or any exception handler has been initialized, the most appropriate value to load into the lOT register is zeros, thereby guaranteeing a shutdown should an interrupt happen. (The 80286 signals shutdown externally as an indication of a severe problem.) Later, when interrupt service routines are ready, you can change the lOT register to point to an actual lOT that contains gate descriptors for the interrupt routines. Interrupts may be enabled at that time.

Stack
Before you perform any stack operations, whether in real-address mode or in protected, virtual-address mode, you must load the SS register with a descriptor to a stack segment in RAM. If the SS register is loaded in real-address mode, it continues to point to the same segment after the switch into protected, virtual-address mode.

Global Descriptor Table


Before you change any segment register in protected, virtual-address mode, the GOT register must point to a valid GOT. The GDT (as well as LDTs) should reside in RAM because the processor modifies the accessed bit of descri ptors. To allow full 16-megabyte addressing in the initialization code, you may find it convenient to build a temporary GDT that contains only enough descriptors to permit the initialization procedure to read the GDT segment from ROM or from a bootloadable module. After placing the real GDT into RAM, you can change the GOT register.

STARTING FIRST TASK


The initialization procedure can run awhile in protected mode without initializing the task register; however, before the first task switch, two conditions must prevail: There must be a valid task state segment (TSS) for the new task. The register fields of the TSS should have appropriate values, the segment register fields must point to valid segments or be null, the stack pointers for privilege levels numerically less than or equal to the initial CPL must point to valid stack segments, the LDT pointer must point to the GDT entry for a valid LDT (or be null if the task does not use an LDT) and, just as insurance, the .back link of the TSS should be null. The task register must point to an area in which to save the current task state. After the first task switch, the information dumped in this area is not needed, and the area can be used for other purposes.

10-2

121960-001

SYSTEM INITIALIZATION

Starting the first task is simply a matter of executing a long JMP via the descriptor of a TSS or via a task gate to that descriptor. This task can perform any remaining initialization work while enjoying the full protection and virtual-address features of the iAPX 286, the state assumed by the development tools.

EXAMPLE OF INITIALIZATION
The following figures present a detailed example of one way to initialize a protected, virtual-address mode system. This example includes assembly language modules that work in conjunction with Builder specifications. Figure 10-1 shows the primary initialization module ENTP (ENTer Protected mode). This module puts the 80286 into protected, virtual-address mode and invokes the first task constructed by BL0286. You use a module such as ENTP by binding it with other modules (presumably those constituting the operating system and the initial task) that you intend to place in EPROM. The module SEGS shown in figure 10-2 supplies dummy segment descriptions for ENTP. The program INIT shown in figure 10-3 serves as the initial task. It merely displays a message when initialization is. complete.

Initialization Module ENTP


The steps that ENTP takes are to Switch into protected mode Create a temporary GOT Create an lOT and GOT copy in RAM from tables in EPROM Point the CPU to the RAM tables Copy all the TSSs and LOTs identified in the GOT from EPROM to RAM Update the RAM GOT to point to the RAM copies JMP to the initialization task in the GOT

The initializations immediately following RESET_STARTUP are redundant. They simulate the hardware RESET initializations in case of a software reset or in case of a branch to RESET_STARTUP during debugging. INITIAL_GOT is a temparary GOT containing descriptors for the lOT and the main GOT in EPROM (the one constructed by BL0286). Since the symbols for these descriptors, GOT....:OESC and IOT_OESC, are PUBLIC, the Builder can insert the actual base and limit values into the table. The code in segment ENTP_CODE is self-relocatable. In an EPROM-based system, you would specify to the Builder the actual address of the segment ENTP_CODE, making sure that the entry point resides at physical address FFFFFOH. ENTP assumes a specific format for the GOT constructed by BL0286. The first two descriptors are the data-segment aliases for the GOT and the lOT. The remaining descriptors are grouped according to the template defined by TASICENTRY. Three adjacent descriptors identify the key segments of each task. ENTP adapts at run time to the actual number of such groups in the GOT. The task that ENTP initiates is identified by a fixed position in the GOT.
10-3

121960-001

iAPX286 MACRO ASSEMBLER

Enter Protected

Mod~

360-516

date

P~G=

systeN-IO iAPX286 ~ACqO ASSEMBLER Vx.y ASSEMBLY CF MODULE ENT? OBJeCT MUDULE PLACED IN :Fl:ENTP.C3J ASSEMBLER INVOKED BY: ASH286.86 :cl:E~TP.A86 LOC 09J LINE
1 +1
2

l
en -< en
Z
r

SOURCE STITLE('Enter Protected Mode 960-516') NAME PUBLIC ENTP IOT_DESC,GDT_JESC,START

3
4

5 6 7

8 9

10
11 12

S~itch the 90286 from real address mode into protected mode. Th& initial EPR~M GOT, lOT, TSS, and LOT (if any) constructed by 9L0286 are copied from EPRO~ into RA~. The RAM areas are defined by data segments allocated as fixed entri2s i~ tha GOT. The CPU registers for the GOT, lOT, TSS, and LDT ar~ ;et to point at the RAM ba;ed segments. The base fields in the RAM GOT are also updated to point at the RA~ based segments.

o
I

.....

13 14 15 16
17

18 19 20
Z1

Interrupts are disabled during this moda s~itching code. The EPROM bas~d GDT, lOT, TSS, and LOT are ch.cked to assure they are valid before copying them to RAM. If any of the RAM-based alias segments are smaller than the EPROM seg~ents they are to hold, halt or shutdown occurs. In general any exception or NMI causes shutdown to occur until the first task is invoked. If the RAM segment is larger than the EPROM segment, the RAM segment is expanded with zeroes. If the initial TS5 specifies an LOT, the LOT is also copied into LOT_ALIAS with zero fill if needed. The EPROM or QA~ based GOT, lOT, TSS, and LOT segments may be located anywhere in physical memory. $EJECT Define layout of a descriptor. DESC

-t m 3:

l>

=t

22
23

o Z

-t

N >

0000 0002 0004 0005 0006


~
<0
(J)

24 25 26 27 +1 28 29 30 31 32
33

LIMIT
BASE_LOW BASE_HIGH ACCESS RES OESC

34
35

36
37

STRUC OW OW 08 DB OW ENDS

o o o o o

Offset of last byte in se~ment Lo~ 16 bits of 14-bit address High 8 bits of 24-bit address Access rights byte Reserved word

38 39 40

Define the fixed GOT selector values for the descriptors that define the EPROM based tables.

Figure 10-1. Initialization Module ENTP

iAPX286 "ACRO ASSEMBLER LOC OBJ

Enter Protected Mode 960-516 LINE 41 42 43 44 45 46 47 4S 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 +1 65 56 61 68 69 70 71 72 73 74 75 76 77 78 19 80 131


S~URCE

date

PAGE

l
en -< en
3:

ODDS 0010 0018 0020 0028

GOT_ALIAS IDT_ALIAS START _ TSS_AUAS START_TASK START _LOT _ALIAS

EQU EQU Eeu EClU EQU

l:C:SIZE 2*SIZE 3*S1ZE 4*SIZE 5*SIZE

nESC nESC OESC DESC OESC

GOT (1) GOT( 2) GOT(3) GOT( 4) GOT(5)

is is is is is

d~t8 segment space for data segment space for data segment sp~ce for TSS for starting task data segl1lent space for

GOT lOT TSS LOT

Define machine status word bit positions. PE EQU Protection enable

0001

Define particular values of descriptor access rights byte. OT_ACCESS OS_ACCESS TSS_ACCESS OPL ACCESSED TI TSS_SIZE LOT_OFFSET TIRPL_MASK SEJECT EeU EeU EQU EeU EQU EQU EQU EQU EQU 82H 92H 8114 60H 1
4

0082 0092 008i 0060 0001 0004 002C 002A 0007

I 01

44 42 "SIZE OESC-l

Access byte value for an LOT Access byte value for data segl1lent: expand up, level 0, .riteable Access byte value for an idle TSS Privilege lev,tI field of access rights Define accessed bit Position of TI bit Siz8 of a TSS Position of LOT in TSS Tl and RPL field mask

-t m

Z =t N
r

l>

Pass control from the power UP address to the mode switch code. The sagment cont~ini"9 this code must be at physical 8ddr~ss FFFElOH to ~lace the JMP instruction at physic~l addrass =FFFFOH. The base address is chosen according to the size of this segment. ENTP COJE
CS_~FFSET

o Z

-t

SEG"'ENT Eeu
O~G

E~

FEIO OlEO OlEO E969FE

JMP

OFElOH OFF;OH-CS_CFFSET RESET_STARTUP

Low 16 bits of st~rting address Start at address FFFFFOH Do not change CSt

Dafina the template ~or a temporary GOT used to locate the 1nitial GOT and stack. This data is copied to location O. This space is 81so used for a temporary stack ~nd finally sarv~s as the TSS written into when ~ntering the initial TSS. QQG INITIU_GDT LABEL Place remaining code below power_up address

0000
~
m
0 <0

82
,'33 34 35

0000 0000 0000

WORD

NULL_DESC

DESt

<>

Filler and null IDT descriptor

Figure 10-1. Initialization Module ENTP (Cont'd.)

iAPX286 lOC 0002 0004 0005 0006 0008 OOOA OOOC 0000 OOOE 0010 0012 0014 0015 0016 0018 OOlA ODIC 0010 ODIE
~

MACR~

ASSE~BLER

~nter

Protect~d

Mod~

360-516

date

PAG~

OSJ 0000 00 00 0000 0000 0000 00 00 0000 0000 0000 00 00 0000 0000 0000 00 00 0000

LINE

S:JU~CE

l
en -< en
~

86

Gn _OESC

DESC

<>.

Descriptor for

EPRO~

GOT

97

lOT _O:::SC

OESC

<>

Descriptor for EPROM lOT

88

T::MP_OESC

OESC

<>

Temporary descriptor

-t m

89 90

m
0020. 0022 0024 0025 0026 3fOO 0000 00 92 0000

92 93 94

Define a descriptor which points the GOT at location Q. This descriptor is also loaded into SS to d~fine th~ initial protected mod3 stack se~m~nt.
TEMP _ST ACK

> rN

Z =t

nESC

<=ND_GOT-INITIAl_GOT-l,O,O,DS_ACC~SS,O>

o Z
95 +1 96
97 98 99

-t

>

SEJECT

Define the TSS descriptor used to allow the task switch to the first task to overwrite this region of memory. The TSS overl~ys the initial GOT and stack at location o.
SAVE_TSS

0028 OOZA 002C OOZO OOZE


~

3FOO 0000 00 81 0000

100 101

DESt

<ENO_GOT-INITIAL_GDT-1,0,O,TSS_ACCESS,0>

0>

<0

0030 (B

102 103 104 105

Define the initial stack space and filler for the end of the TS5. OW 8 OUP (0)

Figure 10-1. Initialization Module ENTP (Cont'd.)

iAPX286 MACRO ASSEMBLER LaC OBJ 0000


)

Enter Protected Hode 960-516 LINE SOURC:

date

PAGE

l
en -< en
m
~

0040 0040 0040 0000 0042 2000

106 107 108 109


110 111 112 113 114 115 116 117 118 119 120 121

END_GOT START _POINTER

LABEL LABEL OW

WORD OWORD O,START_TASK Pointer to initial task

Define tenplate for the task definition list. TASK_ENTRY TSS_SEl TSS_ALI AS LOT _ALI AS TASK_ENTRY TASK_LI ST STRUC OW OW OW ENOS
? ?

0000 0002 0004 0044 0046 0048 004A 004C 004C 004D 004E 0050 0052 0054 0056 2000 1800 2800 0000 FA FC 33FF 8EOF 8ECl 8EOl 8C4000

Define layout of task description Selector for TSS Data seg~ent alias for TSS Data segment alias for LOT if any <START_TASK,START_TSS_ALIAS,START_LOT_ALIAS> Terl1linate list No interrupts allo.edl Use autoincre~ent ~ode Point ES:OI at physical address OOOOOOH

TASK_ENTRY OW

-i

o
I

.....
-....I

122 123 124 125 126


127

RESET_STUTUP:

CLI
CLO XOR MOV MOV MOV MOV SEJECT

:;
N
r

Z =i

128
129

OI,DI DS,DI ES,OI SS,OJ ; Set stack at end of reserved are. SP,ENO_GOT-INITIAL_GDT

o Z

l> -i

130 +1
131 132

133
134 135 136 137 138 139

For~ an adjustment f~ctor from the real CS base of ~FOOOCH to the segment base address assumed by A5M286. Any data reference mad a into CS must add an indexing term CSP) to compensate for the differ~nc. between the offset generated by ASM286 and th~ offset required from the b~se of FFOOOOH.

0059 0059 BOOOO 005C 005C 50 0050 S3ED5C 0060 ZEOF015EOO

START
STA~T1:

PQOC

140
141 142

CALL
PQP SU9

STAHl

The value of IP at run time is not the same as used by ASM1S51 Get true offset of START1 Subtract 4S~296 offset of START1 leaving adjustment factor in SP Set up null lOT to force shutdown on any protection ~rror or interrupt

o 6

en
~

<0

143
144

SP SP, JF"SET STARTl


NULL_uESCCBPJ

145
146

LIDT

Figure 10-1. Initialization Module ENTP (Cont'd.)

iAPXZ86 MACRO ASSEMBLER LOC OBJ

Ent~r

Protectld SOUtlC;:

~ode

960-516

date

P4G':

L.INE
147 148 149 150 151 152 153 154 155 156 151 158 159 160 161 162 163 164 165 166 161 168 169 170 171 112 +1 173 174 175 176 177 178 179 laO 181 182 183 184 185 186
197

Copy the EPROM-based LEA MJY MayS

t~mporary

GOT into RAM. Setup point~r to GOT Set length Put into reserv~d RAM

0055 0068 006B 006C

807600 892000 F3 ZEAS

SI,INITIAL_GDT[SPJ
CX,(END_GOT-I~ITIAl_GDT)/2

R;:P

ES:WORD PTR [OIJ,cs:rSIJ

Switch to protected modI and set up a stack, GOT, and LOT.


S~S""

006E 0071 0074 0077

OFOIEO 000100 OFOIFO EBOO

atl L"ISW JMP

AX AX,PE AX

$+Z

Get current MSW Sat P!: bit Enter protected mode! Clear queue of ipstructions decodad while in Real Address Mode C?L is now 0, CS still points at FFf!:10 in physical memory Put initial GOT into RA"l area Setup SS with v?lid protected mode selector to the RIlM GOT and stack Sit the current lOT to null Any references to it causes an exception causing shutdown Set initial TSS into the low tlAM The task switch n~eds a valid TSS

en -< en
~

-t m

o
(X)

0079 007E 0081 0083 0085

2EOF015620 B82000 8EOO 33CO OFOOOO

lGDT

Mav

T:/oIP _STACK[ gPJ


AX,TEMP_STACK-I~ITIAL_GDi

MOV X:JR LLDT MOY lTR SEJECT

SS,IlX AX,AX AX AX,SAYE_TSS-INITIAL_GOT AX

0088 B82800 008B OF0008

N
:I>

}> r-

Z =i
-t

o Z

Copy the :PROM based GOT into the RAM data segment alias. First the descriptor for the RAM data segment must ~e copied into the temporary GOT. MOV CMP
J9

OOBE 2E8B4608 0092 302FOO 0095 723C 0097 009A 0090 OOAO
~ CD m

AX,GDT_OESCCBOJ.lIMIT AX,6*SIIE DESC-l


BA~_GOT

Get size of GOT Be sure the last entry exp~cted by this code is inside the ~OT Jump if GDT i5nt big enough Form selector to ~PROM GOT Get selector of GOT alias Copy into EPROM Get selector of lOT alias Indicate EPRO~ leT Set up addreSSing into EPROM GOT

B80800 BE0800 E80600 BE1000 00~3 B81000 00A6 E8COOO 00A9 B80800 OOAt 8EOS

188 189 190

MJV MOV CALL MQY MOV CAll MOV MDY

BX,GDT_OESC-INITIAl_GDT SI,GDT_ALIAS COPY_EPRO"'_OT SI, lOT_ALIAS BX,IOT_DESC-INITIAl_GOT COPY_cPROM_OT AX,GDT_DESC-INITIAl_GOT OS,AX

Figure 10-1. Initialization Module ENTP (Cont'd.)

iAPX286 MACRO ASSEMBLER LOC OBJ

Enter Protected Mode 960-515 LINE 191 192 193 194 195 196 197 198 199 200 201 202 203 204
205

date

PAGe:

SOURCE

cl
en -< en
m 3:
-f

OOAE 880800 OOBI OFOl17

MJV LGDT

eX.GOT_ALIA5
(~X ]

Get GOT ali3s data se~ment selector Set GOT to ~AM ~OT S5 and TR remain in low RAM

Copy all tasks TSS and LOT segments into RAM LEA
COPY_TASK_l~OP:

00B4 OOBl 0081 OOBA OOBO OOCO 00C2

805E44 E81BOO 83C306 2E8B07 OBCO 75F3

ex. TASK_LISTrSPJ COPY_TASKS BX,SIZE TASK_ENTRY AX,CS:CBXJ.TSS_SEl AX,AX COPY_TASK_laOp

Define list of tasks to set up Copy them into RA~ Go to next entry See if there is another entry

CALL ADO MOV OR JNZ

With TSS, GOT, and LOT set, start up the initial taskl MOV MOV M:JV LIOT JMP
BA~_GOT:

00C4 00C7 00C9 ooce ooeF

BB0800 BEOB BBI000 OFOllF 2EFF6E40

206 207 208


209

to

0003 0003 F4

0004 0004 F4 0005 0005 0008 OOOA OOOE OOEO 00E3 00E6 00E9 SEOBOO 8EOE 2E8B1702 8EC6 OF03C6 2E8B37 OF0206 75E9

Ol

to

210 211 212 213 214 215 216 217 218 +1 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236

BX,GOT_lLIAS OS.BX BXtIOT_ALIAS (aX] START_POINTERCSPJ

Point OS at GOT Get rOT alias data segment selector Set rOT for errors and interrupts Start the first taskl The 10m RAM area is over.ritten .ith the current CPU context Halt here if GOT isn-t big enough

:;
r-

Z =i

HLT START SEJe:CT ENOP

o
Z

> -f

Copy the TSS and LOT for the task pointed at by CS:BX. If the task has an LOT it mill be copied down. too. BX and BP are transparent. BAO_TSS: HLT COPY_TASKS Halt here if TSS is invalid PROC SI,GOT_ALIAS OS,SI SI,CS:CBXJ.TSS_ALIAS ES,SI AX,SI
SI,CS:C~XJ.TSS_SEL

MOV MOV MOV MaV LSL MOV LAR JNZ

Get addressability to GOT Get selector for TSS alias Point ES at alias data segment Get length of TSS alias Get TSS selector Get alias access rights Jump if invalid reference

OX,SI BAD TSS

Figure 10-1. Initialization Module ENTP (Cont'd.)

iAPX286 MACRO ASSEMBLER lOC OOEB OOEO OOFO 00F3 08J 8A06 80E69F 80FE81 150F

Enter Protected Mode 960-516 LINE 231 238 239 240 241 242 243 244 245 246 241 248 249 250 251 252 253 254 S:JUReE HOV AND eMP JNZ lSl eMP JB Ol,O" OH,NOT OPl OH,TSS_ACeESS
BAO~TSS

date

PACE

Il:
I "

Save TSS descriptor access byte I~nore privilege Su if TSS Jump if not Cet length of EPROM based TSS Verify it is of proper size Jump if it is not big enough

00F5 OF03CE 00F8 83F92B OOFS 1207

ex, SI eX,TSS_SlZE-1 8AO_TSS

Setup for moving the EPROM based TSS to RAM. OS points at GOT. MOV MOV CAll rSIJ.ACeESS,OS_AeCESS OS,SI COPY_WITH_FIll Make TSS into data segment Point OS at EPROM T~S Copy OS~seoment to =S with zero fill CX has copy count, AX-CX fill count

OOFO C6440592 0101 8EOE 0103 E89800

en -< en
3:

Set the COT TSS limit and base address to the RAM values. MOV MOV MOV M::IV AX,GOT_ALIAS OS, AX ES,AX OI,CS:r5Xl.TSS_SEl sr,CS:raXl.TSS_AlIAS
;

255

-t m

!..
0

.....

0106 0109 0108 0100 0110 0114 0115 0116 0111 0119 011A

880800 8E08 SECO 2E883F 2E8S7102 AS AS AD 8AE2 AS AS

0118 011F 0123 0121

2E8E5F02 88362AOO 81E6F8FF 1441

0129 56 012A OF02D6 0120 153C


~

'?
~
0

0>

CD

012F 8A06 0131 80E69F

256 257 258 259 260 261 262 263 264 265 266 261 +1 268 269 270 271 272 273 214 215 276 277 278 279 280 281 282

Restore

G~T

addressing

MDV
MOVSW M:JVSW lOOSW MOV STQSW MOVSW SEJECT

AH,Ol

Get TSS selector Get RAM alias selactor Copy limit Copy low 16 bits of address Get high a bits of address Mark as TSS descriptor Fill in high address and access bytes Copy reserved ~ord

> r -t 5 Z
N

See if a valid lOT is specified for the startup task. If so t~en copy the EPROM version into the RAM alias. MOV MOV AND DS,CS:CBXl.TSS_AlIAS Address TSS to get LOT SI,DS:WORO PTR lOT_OFFSET Ignore TI and RPL SI,NOT TIRPl MASK NO LOT Skip this if no LOT used SI OX,SI BAD LOT OL,DIi CH,NOT OPL Save LOT selector Test descriptor Jump if invalid selector Save LOT descriptor access byte Ignore privitlege

JZ
PUSH lAR JNZ MOV AND

Figure 10-1. Initialization Module ENTP (Cont'd.)

iAPX286 MACRO ASSEMBLER LOC DBJ

Enter Protected Mode 960-516 LINE 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 29S 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 +1 320 321 322 323 324 325 326 327 SOURCE eMP JNE MOV MOV LSL CAll MOV DH,OT_ACC:SS eAO_LDT ES:CSIJ.ACC:SS,DS_ACCeSS; OS,SI AX,51 T:ST_OT_LtMIT CX,AX

date

PAGE

~i

--

0134 80FE82 0137 7532 0139 013E 0140 0143 0146 26C6440592 8EOE OF03C6 E82600 88CS

Be sure it is an LOT descriptor Jump if invalid Mark LOT as data segment Point 05 at EPROM LOT Gat LOT limit Verify it is valid Save for later

Examine the LOT alias segment and, if good, copy to RAM. MOV MOV LSL CALL CALL SI,CS:CBXJ.LOT_ALIAS ES,SI AX,St T!:ST_OT_LIMtT COPY_WITH_FILL Get LOT alias selector Point ES at alias segment Get length of alias seg~ent Verify it is valid COpy LOT into RAM alias segment

014S 014C 014E 0151 0154

2E8S7704 8EC6 OF03C6 E81S00 ES4AOO

en -< en
~

Set the LOT limit and base address to the RAM copy of the LOT. MLlV POP MOV MOV MOV MOV5W MOVSW LOOSW MOV STOSW HOVSW NO_LOT: R:T IIAO_LOT: HLT COPY_TASKS SEHCT ENDP
~t

-t

.....
0

!..

0157 0158 DISC 015F 0161 0163 0164 0165 0166 016S 0169 016A 016A 0168 0168

2ES87704 SF 8S0S00 SEDS SECO AS AS AD 8AE2 AS AS C3 F4

SI,CS:CBXJ.LOT_ALIA5 01 AX,GOT_ALIAS OS,AX ES,AX

Restore LOT alias selector Restore LOT selector Restore G~T addressin9 Move the RAM LOT limit Mova the low 16 bits across Get the high 9 bits Mark as LOT descriptor Set high address and access rights Copy reserved ~ord All done Halt here if LOT is invalid

> rN

Z =i

AH,OL

> 0
Z

-t

Test the descriptor table size in AX to verify that even number of descriptors in length. TEST _OT _LIMIT PUSH AND PROe AX AL,1

is an

016C
~
<0 0>

::!

016C 50 016C 2407

Save length Look at low order bits

Figure 10-1. Initialization Module ENTP (Cont'd.)

iAPX286 MACRO LaC 08J

ASSE~BLER

Enter Protected Mode 960-516 LINE SOURCE C'1P POP JNE RET SAC_oT_L1MIT: HLT TEST_OT _LIMIT ENOl' AL,7 AX BAo_OT_LIMIT Must be all ones Restore length
All OK

date

PAGE

l
en < en
m 3:
-I

016F 3C07 0171 58 0172 7501


0174 C 3 0175 0175 F4

0176.

!..

I\)

0176 0178 017A 017F 0185 0188 018A 0180 0190 0192 0195 0196 0197 019A 019S 01ge 0190 019E 019F

8COO 8Eeo 26C6470592 26C747060000 OF03C3 88CS E80FFF BF0800 8EOF BF1800 57 AD ESDZFF AS AS AS AS 07 SEDS

~
<0

0>

328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 +1 370 371 372 373

Die!

Copy the EPROM oT at selector ex in the te~porary GOT to the alias data segment at selector S1. Any improper descriptors or limits cause shutdownl CoPY_EpROM_OT M!lV PRec AX,SS ES,AX ES:CBXJ.ACCESS,QS_ACCESS; ES:CBXJ.RES,O AX,SX CX,AX TEST_OT_LIMIT oI,GoT_OESC-INIT1AL_GOT oS,DI oI,TEMP_oESC-IN1TIAL_GoT; 01 'TEST_oT_LIMIT Point ES:OI at temporary descriptor Mark descriptor as a data segment Clear reserved word Get li~it of EPROM DT Save for later Verify it is a proper li~it Address EPROM GOT in OS Get selector for temporary descriptor Save offset for later use as selector Get alias segment size Verify it is an even multiple of descriptors in length Put length into temporary Copy remaining entries into temporary ES now points at the GOT alias area OS now points at EPROM DT as data Copy segment to alias with zero fill CX is copy count, AX-CX is fill count Fall into CapY_WITH_FIll

Mav Mav

M;JV

LSl MOV CALL MOV MOV M:JV PUSH lOOSW CALL SToSW MaVSW MOVSW M:lVSW POP MOV

:;
N
r-

o Z

l> -I

ES DS,9X

COPY_EPROM_DT SEJECT

END?

Copy the segment at OS to the segment at ES for length CX. Fill the end with AX-eX zeroes. Use word operations for speed but allow odd byte operations.

Figure 10-1. Initialization Module ENTP (Cont'd.)

iAPX286 MACRO ASSEMBLER LOC OBJ

Ent~r

Protected Mode 160-516 SOURCE

date

PAGE

10

cl
en -< en
-t
~

LINE

OlAl OlAl OlA3 OlA5 01A7 OIAA OlAC DIAD OlAE OlAF 33F6 HFF 2BCI 83CIOI 0109 F3 AS 91 7307

374 375 376 317 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394

COPY _WITH_F ILL XOR XOR SUB ADD RCR REP


~'JVSW

PROC SI,SI 01,01 AX,CX CX,l CX,l AX,CX EVEN_COPY CX,CX EXIT _COpy Start at
be~inning

of segments

Form fill count Convert limit to count Allow full 64K move COpy DT into alias area Get fill count and zero AX Jump if even byte count on cdpy Copy odd byte Exit if no fill Even out the segment offset Adjust remaining fill count count on fill Clear unused words at end
For~ ~ord

XCHG JNC MOVSB DR JZ STOSS DEC EVEN_COPY: SHR REP STOSW

01B1 A4 0lB2 OBC9 0184 7409 01B6 01B7 01B8 0188 01BA 01B8 OIBC
AA

(J.)

.!..

49 01E9 F3 AB 7301

'ex
CX,l

l> r-

***

EXIT COpy 395 JNC 396 STOSS OIBE AA 397 EXIT COpy: 01BF 398 RET 399 01BF C3 400 END? COPY_WIT~_FILL 401 402 403 ENTP_CODE ENOS WARNING .160, LINE .403, SEGMENT CONTAINS PRIVILEGED INSTRUCTIONS 404 END ASSEMBLY COMPLETE, WARNING, NO EIlRJRS

Exit if no odd byte remains Clear last odd byte

o Z

-t

en

<0

Figure 10-1. Initialization Module ENTP (Cont'd.)

LAPX286 MACR3
syst9~-ID

ASSE~BLE~

DEFIN~

SEGM~NTS

N~EJEQ

=O~

I~IT

CJCE
~=F

date

PAG ::

iAPX236 MAC~O ASS ~3L=R VX.y ASSEMeLY CF McaULE S::GMENT 3BJECT MODULE ?LACEO IN :F1: EGS.03J ASSEMBLE~ INVOKED ~Y: :~1:A M286.86 :c1:SEGS.A86 LOC OBJ LINE 1 +1 2
3 4 5 6
7
SJU~CE

t
(J)

STI TlE( DEFINE SEGMENTS NEEJEJ FeR INIT caOE) NAME INIT _ STACKO INIT_STACKO LOT S EG SEGMENT_D::F SEG"IENT Rio! Ow ENDS SEGMENT RW 8 DUP CD CW ENDS SEGMENT RW 8 CUP OW ENDS SEG"IENT iHI 8 OUP DW ENOS S "GMErH RW 8 OUP (1) DW ENCS END Ne
ERRC:~S

0000 1171

Clefine stack 50 mode 5~itc~ code C3n run in protected node Define ali3s segments whose true size ~ust be set by the BLDZ8S com:11and file
(?)

8
9

0000 (8
1111
)

10
11

(J)

-<

-t

m
3:
~

LOT SEG TSS_SEG

12 0000 (8 1171
13 14
15 16 11

TSS_SEG IOT_SEG

:; r N
l>

0
(1)

-t

0000 (B 1171
)

18
19

IJT_SEG GDT_SEG

20 21 0000 (3 1171
)

2.2 23 24 25

GOT _S::G

ASSEMBLY COMPLETE.
~
(0

r-;a I'IARNINGS.

0>

Figure 10-2. Dummy Segments for ENTP

iAPX286 MACRO ASSEM8LER


syst.~-IO

INITIAL TASK

date

PAG=

iAPX286 MACRO ASSEMBLER vx.y ASSEMBLY OF MODULE INIT MOO OBJECT MODULE PLACED IN :Fl:INIT.OBJ ASSEMBLER INVOKED BY: :Fl:ASM286.86 :Fl:INIT.AB6 OBJ LINE 1 +1 2 3
4

LOC

SOURCE STITLEC"INITIAL TASK") NAME EXTRN INIT _ST ACK INIT_DATA


DHAI

INIT_MIJO C:J:FAQ STACKSEG 10

5
6

0000 1111

7 B 9 10
11

ow

SEG~ENT

RW PUBLIC
fJ)

HUT_DATA INIT_CODE MESSAGE

E"lCS
SEG~ENT

12
13

ASSUME DB

ER OS: INIT OAT A 'InitiB1ization Compl~t~!~.OD~.OAH.O

fJ) ~

-<

-"

.!....
01

0000 496E697469616C 697A6174696F6E 20436F60706C65 746521 0018 00 0019 OA OOlA 00

14 15

::

Z =i 5> r N
l>
~

~
U)

***

16 001B 17 INIT_START: 001B SEOOOO 18 MOV SI,OFFSET MESSAGE OOlE FC 19 CLO 001F 20 MESS_LOOP: OOlF 2EAC 21 LOOS CS:BYTE PTR (SI) 0021 OACO 22 OR AL,AL 0023 7408 23 JZ INIT_EXJT 24 25 PUSH AX 0025 50 0026 9AOOOO---E 26 CALL CO 27 J~P MESS_LOOP 002S EBF2 28 INIT_=XIT: 0020 29 HLT 0020 F4 30 31 INIT_CCDE ENOS WARNING .160, LINE .31, SEGMENT CONTAINS PRIVILEGED INSTRUCTIONS 32 END INIT_START,OS:INIT_OATA,SS:INIT_STACK WARNING. NO
ERR~RS

o z

Ol

ASSEMBLY COMPLETE,

Figure 10-3. Initial Task INIT

Binding and Loading

11

CHAPTER 11 BINDING AND LOADING


Binding is the process of converting symbolic references into an implementation that the processor can utilize. The binding process spreads across many stages of software development, including source code, translators, binding utilities, loaders, and execution itself. Intel's program development tools include features that perform much of the needed binding. In some static systems no additional binding may be needed. In dynamic systems, however, you may choose to incorporate some binding functions in the operating system and related software in order to create a style of binding appropriate for the dynamic nature of your application.

BINDING MODEL
To ensure that the binding process works correctly, it is a good idea to start with a model of the system structure you wish to achieve. A binding model includes these factors: Modules-dividing programming into compilation units Segmentation-distributing instructions and data of modules among physical segments Interfaces-specifying the connections among modules Naming-choosing names for modules, segments, and interfaces, avoiding ambiguity but promoting flexibility Timing-determining when to bind various types of symbolic references

As an example of a binding model, assume that the example modules presented in prior chapters constitute a complete operating system, called XOS, and apply each of these factors to XOS.

Modules
The criteria used to separate functions into modules may include Comprehensibility. Each module collects together functions that support a single operating system concept of limited scope (for example, aliases, synchronization). Information hiding. Each module implements a data structure (for example, the alias lists in the ALIAS module) that you can manipulate only by calling the procedures defined in the module for that purpose. Other modules cannot access the data structure. Independent development. You can choose modules so that each can be developed by a different programmer. Points of cooperation and communication among programmers include only the specified interfaces among modules. Minimizing the number and complexity of interfaces reduces project administration costs. Structured testing. Testing of the whole system is simpler when you choose modules so that each can be tested by itself, before testing its interactions with other modules. Flexibility. When you can anticipate changes to the system, you can limit the effects of the changes on other modules by isolating the areas of expected change in a module.

Only the first of these criteria is significant to XOS, but all may be applicable to your operating system design.

11-1

121960~001

BINDING AND LOADING

Modules are relevant to binding in that they (indirectly) define the units that can be distributed among physical segments. A module is a single compilation unit. Intel's translators divide each compilation unit into logical segments. Each logical segment is a named object that can be assigned to a physical segment. You can use the development tool Binder to combine more that one logical segment into a physical segment.

Segmentation
Protection requirements partially dictate how to distribute modules among physical segments: Data and procedures of different privilege levels must reside in different physical segments. Data and procedures of one task must reside in different segments from those of other tasks unless sharing is explicitly intended. Instructions must reside in different physical segments from writable data items. Data structures for which you wish to provide individual protection (for example, the semaphores and mailboxes discussed in Chapter 5) must each be in a separate segment.

Operating system procedures that have the same privilege level and are shared via the GDT can be combined in just one segment (assuming that the total size does not exceed 64K bytes). In fact, doing so has two advantages: all intermodule calls can be implemented as short CALL instructions, avoiding the additional processing associated with changing the contents of the CS register,and more GDT slots are available for other purposes. Of the procedures in XOS, the level-zero procedures presented in Chapters 3 thru 5 can be combined in one segment, while the level-one I/O interface procedures can go in another segment. Each device-driver task has its own code, data, and stack segments.

Interfaces
Possible mechanisms for implementing the interfaces among modules are Intrasegment (short) references. References to data or procedures in the same segment are most efficiently implemented when you can use the current contents of a segment register. Intersegment (long) references. References to data or procedures in a segment not currently indicated by one of the segment registers must cause a segment selector to be loaded into a segment register. Intersegment references permit sharing of functions among many modules and permit access to functions at another privilege level. Sharing by value. Procedures and data can be shared by including a copy of the data or procedures in the same unit (segment or task, as appropriate) as each procedure that uses them. While this approach can yield more efficient execution in some cases, it has limited applicability. It is usually best to share dynamically changing data by name, so that all the procedures that use it can obtain the most up-to-date version. Sharing large or widely used data or procedures by name uses main memory more efficiently. Sharing by name. The "name" referred to here is the descriptor of the shared data or procedure. Chapter 5 discusses methods of sharing by name (namely GDT, common LDT, and aliases).

In XOS, all tasks share the segments of the kernel and I/O-interface segments via the GDT. Applications procedures use long calls to access the primitives in these segments. Calls within the kernel level or within the I/O level to private procedures at the same level are short calls.

11-2

121960-001

BINDING AND LOADING

Naming
The names by which you reference the components of a system influence the way the system can be bound. Classes of names over which you have some degree of control arc Modules. Builder uses the name of a module to represent all publics or all segments within the module. Debuggers use module names to qualify identifiers of variables and procedures. Logical segments. The choice of logical segment names determines the possibilities for segment combination. Binder combines logical segments that have the same name as well as compatible combine-types. Physical segments. The names of physical segments give you the ability to assign segment attributes individually using the Builder. Publics. Public identifiers must be unique among the modules that are bound together. Gates. Gate names identify the entry points to procedures. You can use gate names to give entry points different public names than those used in the source language.

Timing
With respect to time, you can rate bindings on a scale running from early to late. An example of early binding is a compiler's assignment of segment-relative locations to procedures and data. The latest binding is that accomplished by the processor as it adds a segment-relative location to the 24-bit base address of the segment. Between these extremes are other opportunities for binding: Post-compile-time. Through Intel's utilities Builder and Binder, you can combine segments, resolve intersegment references, allocate descriptor table slots, and allocate memory. Load-time. The loader can incorporate various levels of binding. a. If the object module contains fix-up information (as in a linkable module), the loader can bind all references as it loads the segments of a task. b. The call gates of the iAPX 286 architecture make it possible for the loader to efficiently resolve references to predefined classes of procedures (to operating system primitives, for example) at the time a program is being loaded. This chapter presents an example of this form of load-time binding in a later section. Run-time. Call gates also permit binding to an executable segment at the time it is first referenced. By resetting the present bit in a call gate to an unloaded segment, you ensure that a trap will occur when the gate is used. The "not present" trap handler can then load the required segment, allocate a descriptor for it, and fix up the call gate.

IMPLEMENTING ACCORDING TO THE MODEL


With a binding model in mind, consider how to implement that model during the various stages of system development: in source code, by translators, by binding utilities, by loaders, by the operating system, and finally by the processor itself.

11-3

121960-001

BINDING AND LOADING

The model behind the example operating system, XOS, includes these components: Each module contains functionally related data structures and procedures. One segment contains level-zero (kernel) procedures, another segment contains level-zero data, another segment level-one (I/O) procedures, and another level-one data. Operating system tasks (such as device drivers) have their own distinct segments. The GDT contains descriptors of kernel and I/O segments, making them sharable by all tasks. Gates for operating-system primitives, however, reside in the LDTs of the tasks that use them. The segment names created by PL/M-286 set the standard for segment naming in general. (Refer to the chapter entitled "Linking to Modules Written in Other Languages" in the PL/M-286 User's Guide for definition of PL/M-286 segment names). Load-time binding to XOS primitives is an option. (This is one reason for placing gates for operatingsystem primitives in LDTs.)

'Tasks will be loaded dynamically.

Source Code
Since some of the logical segments declared in assembly language may be combined after assembly by the Builder, the assembler needs to know whether the object of an external reference will be in one of those segments whose descriptors it 'assumes to be loaded in segment registers. If the reference is to another segment, the assembler must emit instructions that change the contents of a segment register. The programmer supplies this information via additional assembly language syntax. A variety of forms are available for this purpose, such as

SEGMENT ASSUME N EAR and FAR variants of PRO C and LAB E L segment overrides (for example E S : TAB L E_ I T EM)
(Refer to the ASM286 Assembly Language Reference Manual for details on the use of these items.) The module DISP containing the dispatcher is the only kernel module of XOS written in assembly language (refer to Chapter 4). The logical code segment has the name NUCLEUS_CODE and combine type ER so that it will combine with PL/M-286 segments of the same name. This module has no logical data segment. The procedure DISPATCHER is a NEAR procedure because only other kernel procedures in the same physical segment call it.

Compilers
With PL/M-286, decisions regarding segmentation are not imbedded in source code but rather are implemented by the compiler according to compiler control statements that you supply. (Refer to the SMALL, COMPACT, LARGE, and extended segmentation controls in the PL/M-286 User's Guide.) With these control statements, you have nearly as much control over system structure as with assembly language, but changes in system structure do not require changes to source code. It is just as important, however, that use of these controls conform to a consistent model of system structure. Figure 11-1 shows the segmentation controls used for compiling the kernel modules of XOS. These controls define a subsystem named NUCLEUS that contains all the PL-O modules of XOS. The PL/M-286 compiler prefixes the names of the code and data segments with the subsystem name. The list of exports includes all the primitives. For each of the procedures named in the exports list, the

11-4

121960-001

BINDING AND LOADING

$ COMPACT (NUCLEUS HAS SLOT $ GATE $ DISPATCHER $ SEMAPH $ INTRUPT $ DESCRIPTOR $ DISQUE $ $ EXPORTS RESERVE SLOTS $ ALLOCATE $ CREATE ALIAS $ WAIT SEMAPHORE $ SEND-MESSAGE $ CREATE LDT $ LOAD LOT $ GET GATE POINTER $ ATTACH TO INTERRUPT $

POINT MEMORY ALIAS MAILBOX TASK GATE MESSAGE RELINQUISH_SLOTS FREE SEG CHANGE AR SIGNAL-SEMAPHORE RECEIVE MESSAGE CREATE TASK LOAD_LOT_GATE

WAIT_FOR_INTERRUPT

Figure 11-1. Subsystem for Kernel Exports

compiler generates a long RET instruction at the end of the procedure or at RETURN statements. This enables procedures in other segments to call the the kernel procedures. The keyword COMPACT tells the compiler to generate short RET instructions for procedures not named in the export list.

Binding Utilities
Intel's iAPX 286 Binder (BND286) and System Builder (BLD286) provide a variety of binding services, including Combining logical segments that have the same name and combine type Resolving references among modules Constructing templates for GDT, LDT, and TSSs Allocating memory for bootloadable portions of the system Assigning access rights to segments

11-5

121960-001

BINDING AND LOADING

Constructing gates Formatting object files for the convenience of boot loaders and dynamic loaders Creating export modules that contain gates for operating-system interfaces

Figure 11-2 shows the Binder specifications that combine the level-zero modules of XOS. The input modules contain only three unique segment names (the PL/M-286 names: NUCLEUS_CODE, NUCLEUS_DATA, and STACK); therefore, the output module contains just three segments: one for instructions, one for static data items, and one for the level-zero stack. The name of the output module is NUCLEUS; it is written to the file NUC.LNK. Similar specifications combine the level-one modules. Figure 11-3 shows the specifications to build a bootloadable file for the example operating system. The SEGMENT statement assigns privilege levels to to each of the segments; segments not mentioned in this clause receive privilege level 3 (PL 3) by default. The TABLE statement defines the descriptor tables. The RESERVE clause allocates space for the working descriptors used by such modules as the memory-management module described in Chapter 3. The ENTRY clause identifies the remaining segment descriptors that belong in each table. Builder allocates slots for each of these descriptors. The TASK statement provides information for contructing TSSs. The identifier assigned to each task is the identifier of the descriptor of its TSS. The OBJECT clause identifies the module containing the information Builder can use to fill the segment-register and initial stack fields of the TSS. The GATE statement creates gates for each of the public procedures that are XOS primitives, assigns a privilege level to each gate, and gives each a name different from the procedure name. The EXPORT statement creates a linkable module KERNEL in file XOS.EXP that application modules can use for binding to the gates for XOS primitives.

RUN :F2:BND286 & :Fl:POINT.OBJ, :Fl:SLOT.OBJ, & :Fl:MEMORY.OBJ, :Fl:DISP.OBJ, & :Fl:ALIAS.OBJ, :Fl:SEMAPH.OBJ, & :Fl:MBOX.OBJ, :Fl:INTRPT.OBJ, & :Fl:DESCR.OBJ, :Fl:DISQUE.OBJ, & :Fl:TASK.OBJ :Fl:MESSAG.OBJ, & PLM286.LIB & NAME (NUCLEUS) OBJECT (:Fl:NUC.LNK) NOLOAD DEBUG

Figure 11-2. Binder Specifications for XOS Kernel

11-6

121960-001

inler

BINDING AND LOADING

system-ID

iAPX286 SYSTEM BUILDER, Vx.y

:F1:NUC.LNK, :F1:URTASK.OBJ, :F1:CONSOL.OBJ, :Fl:LOADER.LNK, :F2:LARGE.LB2, :F1:STACKS.OBJ OUTPUT FILE: :F1:XOS CONTROLS SPECIFIED: TITLE(Examp1e O.S.) BOOT LOAD BUILDFILE(:F1:XOS.BLD) OBJECT (:F1: XOS) BUILD FILE:
1 2 3 4 5
6

INPUT FILES:

:F1:XOS.BLD

7 8 9 10

11 12
13

14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46

SEGMENT NUCLEUS CODE NUCLEUS-DATA NUCLEUS:-STACK URTASK CODE URTASK-DATA URTASK:-STACK LQ PLM286 LIB CODE LARGE V1P0.STACK0 LARGE-VIP0.STACKl LARGE-V1P0.STACK2 CONSOLE DRIVER CODE CONSOLE-DRIVER-DATA CONSOLE-DRIVER:-STACK CONSOLE-STACK0 LOADER_STACK0

(DPL=O) , (DPL=0) , (DPL=0, LIMIT=+20), (DPL=0) , (DPL=0) , (DPL=0, LIMIT=+20H), (DPL=0, CONFORMING), (DPL=0) , (DPL=l) , (DPL=2), (DPL=1) , (DPL=1) , (DPL=1, LIMIT=+20), (DPL=0, LIMIT=+20), (DPL=0, LIMIT=+20); DPL=1) DPL=1) DPL=3) DPL=3) DPL=3) DPL=3) DPL=3) DPL=3) DPL=3) DPL=3) DPL=3) DPL=3) DPL=3) DPL=3) DPL=3) DPL=3) DPL=3) , , , , , , , , , , , , , , , , ,

GATE XQ ATTACH TO INTERRUPT (ENTRY~ATTACH TO INTERRUPT, XQ-WAIT FOR INTERRUPT (ENTRY=WAIT FOR INTERRUPT, XQ-RESERVE SLOTS (ENTRY=RESERVE SLOTS, XQ-RELINQUISH SLOTS (ENTRY=RELINQUISH_SLOTS, XQ-ALLOCATE (ENTRY=ALLOCATE, XQ-FREE SEG (ENTRY=FREE SEG, XQ-CREATE ALIAS (ENTRY=CREATE_ALIAS, XQ-CHANGE-AR (ENTRY=CHANGE AR, XQ-WAIT SEMAPHORE (ENTRY=WAIT SEMAPHORE, XQ-SIGNAL SEMAPHORE (ENTRY=SIGNAL SEMAPHORE, XQ-SEND MESSAGE (ENTRY=SEND MESSAGE, XQ-RECEIVE MESSAGE (ENTRY=RECEIVE MESSAGE, XQ-CREATE LDT (ENTRY=CREATE_LDT, XQ-CREATE-TASK (ENTRY=CREATE TASK, XQ-LOAD LDT (ENTRY=LOAD LDT, XQ-LOAD-LDT GATE (ENTRY=LOAD-LDT GATE, XQ-GET GATE-POINTER (ENTRY=GET GATE-POINTER, TI~E SLICE 1INTERRUPT, DPL=0, ENTRY=TI~INT); TABLE GDT (RESERVE=(4 . 9), ENTRY=( NUCLEUS CODE, NUCLEUS-DATA, NUCLEUS:-STACK, LQ PLM286 LIB CODE, LARGE_V1P0.STACK,

Figure 11-3. Builder Specifications for XOS

11-7

121960-001

BINDING AND LOADING

47 48
49

50 51 52 53 54 55 56 57 58 59
60

)
)

LARGE V1P0.STACK0, LARGE-VIP0.STACK1, LARGE-V1P0.STACK2

URTASK LOT (ENTRY=(URTASK, CONSOLE LOT (ENTRY=(CONSOLE DRIVER, CONSOLE STACK0, LOADER TASK LOT (ENTRY=(LOADER, LOADER STACK0, lOT (ENTRY=(15:TIME_SLICE; TASK ADAM (INITIAL, OBJECT LOT CONSOLE DEVICE (OBJECT LOT STACKS LOADER TASK (OBJECT LOT STACKS URTASK, URTASK LOT) , CONSOLE DRIVER, CONSOLE-LOT, (CONSOLE STACK0) ) , LOADER, LOADER TASK LOT, (LOADER_STACK0;

61

62
63 64 65 66 67 68

69
70 71 72 73 74 75 76 77 78 79

EXPORT #:F1:XOS.LB2 (KERNEL XQ RESERVE SLOTS, XQ-RELINQUISH SLOTS, XQ-ALLOCATE, XQ-FREE SEG, XQ-CREATE ALIAS, XQ-CHANGE-AR, XQ_WAIT SEMAPHORE, xQ_SIGNAL SEMAPHORE, XQ-SEND MESSAGE, XQ=RECEIVE_MESSAGE; END

BUILD FILE PROCESSING COMPLETED

Figure 11-3. Builder Specifications for XOS (Cont'd.)

These specifications do not illustrate all the features of Builder; refer to the iAPX 286 System Builder User's Guide for a complete description of Builder syntax.

OVERVIEW OF LOADING
The loader in a dynamic system is not only responsible for copying a program into main memory, but is also a step in the binding process. A loader installs the actual TSS and LDT for a task, thereby making it possible for the processor to interpret the task's memory references.

If all symbolic references are already resolved, a loader's work is simple. The iAPX 286 object module format (OMF) organizes segment information to facilitate rapid loading with little decision-making by the loader program.

11-8

121960-001

BINDING AND LOADING

Converting a Program Into a Task


Before an operating system can switch control to a new task, these structures must be initialized: The TSS (data the processor needs in order to run the task). The task database (TOB) (data the operating system needs in order to run the task).

Either the following structures must be present or some mechanism must be in place to make them present when necessary: Stack segments for each privilege level at which the task runs. (A stack-fault handler could automatically allocate a stack the first time it is used.) Executable and data segments. (A virtual memory system could make these present when referenced.)

Most programs also need an LDT to contain descriptors for segments private to the task. An LOT is not required, however, if all descriptors used by the task reside in the GOT. The initial values in the CS:IP fields of the TSS should point to the entry point of the first procedure of the new task.

STYLES OF LOADERS

There are several ways to structure a loader. The following are just a few examples: 1. As a separate and permanent task. With such a structure the loader constructs data segments in the format of the new task's TSS and LDT. To create the new task, it passes descriptors for these segments to privilege-level 0 (PL-O) procedures that convert them to system segments and start the new task. As procedures that run within an existing task. This approach suits the UNIX EXECUTE function, where the FORK function creates the task in which the loader runs as a duplicate of the task that called the FORK function. The loader deletes the descriptors it finds in the task's LOT (thereby deleting the associated segments unless aliases exist in other tasks) and creates new descriptors for the segments it loads. As procedures in a skeletal task created by the operating-system kernel. The loader has only to allocate an LOT and install descriptors for the segments it loads.

2.

3.

For approaches 2 and 3, the procedures of the loader may have segment descriptors and gates in the GOT so as not to encumber the LOTs.

KERNEL SUPPORT

A loader normally runs at PLs 2 or 3 because it uses of both kernel-level procedures (for example, ALLOCATE to create a segment for the new task) and PL-l procedures (for example, the I/O procedures to read object modules from disk). However, task creation involves some functions that only

11-9

121960-001

intel"

BINDING AND LOADING

PL-O procedures can execute. For these functions the operating system must provide some additional support. These functions include Changing the access rights byte of a descriptor. The loader can create a writable data segment (using a level-O procedure such as the ALLOCATE procedure described in Chapter 3) into which to read a segment from the object file of the program being loaded. But, if that segment is to have some other type in the new task (the segment might be an executable segment, for example), the access rights byte must be changed. Filling the new task's LOT with the base addresses of its segments. When the loader allocates a segment for the new task, the ALLOCATE procedure places the physical base address of the segment in a descriptor table (presumably the loader's LOT, but possibly the GOT). Only PL-O procedures should have access to physical addresses in descriptor tables. Allocating the stack segment for PL O. Insufficient space in this segment can cause failure of PL-O procedures. Also, if the kernel requires the TSS to be located in the PL-O stack segment (as suggested in Chapter 4), then the kernel should handle the complexities of setting up such a structure. Initializing the task database (TOB) for the new task. Only PL-O procedures have access to this data structure. (Refer to Chapter 4 for a discussion of the task database.) Entering the new task in the scheduling queues and setting the back-link and nested task flag in the new TSS. These operations are crucial to proper functioning of the scheduler and therefore should be done at PL O.

iAPX 286 Object Module Format


Intel has defined object module formats (OMFs) for the iAPX 286 to be used by translators, objectprogram utilities, and loaders. There are two classes of object module: Linkable modules, which are produced by translators and consumed by Builder and Binder. Binder can also produce a linkable module from one or more input linkable modules in a process known as incremental binding. Loadable modules, which are produced by the Binder and the Builder and consumed by loaders and debuggers.

Refer to the iAPX 286 System Builder User's Guide for detailed definitions of the iAPX 286 Object Module Format. Loaders that adhere to Intel's OMFs for loadable modules can load object modules created by Intel's program development tools. There are two basic variations of the iAPX 286 OMF for loadable modules: That created by the Binder supports straightforward, single-task modules. That created by the Builder supports more complex variations, including multitask modules with shared segments (possibly including shared LOTs), reserved LOT locations, GOT descriptors to be installed as the task is loaded, etc.

Builder not only produces modules intended for use by dynamic loaders but also produces bootloadable modules designed for use by bootstrap or initializing loaders. Bootloadable modules use absolute addresses. A boot loader must be able to write to absolute physical locations.

11-10

121960-001

BINDING AND LOADING

The OMF of each object module consists of a header followed by a sequence of sections of various kinds. The sections relevant to this discussion are those in loadable modules, including OESCRP: contains all the descriptors for the module. A loader can use this section as a template for the LOT. LOOTXT: contains the data and instructions to be loaded. A loader fills allocated memory segments from the records of LOOTXT. OESNAM: provides symbolic names for segments. A loader can use these symbolic names to provide a load-time interface for making changes to segment parameters (for example, decreasing segment limit of an expand-down stack segment to provide more stack space).

Flow of Loader
A loader must take different action depending on whether the loadable modules are created by the Binder or by the Builder. The main difference in loading the two types of OMF is the source of information for descriptor tables. In the case of Binder OMFs, the OESCRP section is in the format of an LOT. In the case of Builder-created OMFs, information for the GOT, lOT, and LOTs comes from various LOOTXT records. A Boolean in the header of a load able module distinguishes between Buildercreated and Binder-created modules.
FLOW FOR BINDER-CREATED MODULE

1. 2. 3. 4. 5. 6. 7. 8.

Allocate space for LOT segment. The size of the segment is eight times the value of the descriptor count field of the module header. Put LOT descriptor in GOT. Read the OESCR section into the LOT segment. Allocate space for all segments specified in the LOT, updating the base-address fields. Allocate space for the TSS. (Step 3 does not allocate the TSS because the OESCR section does not contain a TSS descriptor.) Put TSS descriptor in GOT. Read first LOOTXT section into TSS segment. (The first LOOTXT record is always a TSS.) Put LOT selector into TSS.

If the LOOTXT section is exhausted, the task is completely loaded. Jump to the TSS.
Read next LOOTXT record into proper segment. Go to step 7.

FLOW FOR BUILDER-CREATED MODULE

1. 2. 3. 4. 5.

Allocate temporary space to hold all entries from the OESCRP section. Read the OESCRP section into this space. Allocate physical segments for all OESCRP entries (except for gates). Read beginning of LOOTXT record. Examine descriptor name of LOOTXT record. The selector name is either a special identifier for the GOT or lOT, or it is an index into the OESCRP entries. The type field of a OESCRP entry distinguishes LOT segments from other types. a. If the LOOTXT record defines entries of the GOT, then, for each entry in the record, obtain the descriptor from OESCRP and install it in the GOT. b. If the LOOTXT record defines entries of the lOT, then, for each entry in the record, obtain the descriptor from OESCRP and install it in the lOT.

11-11

121960-001

inter

BINDING AND LOADING

c. If the LODTXT record defines an LOT, then, for each entry in the record, obtain the descriptor from DESCRP and install it in the LDT. d. If the LODTXT record does not apply to a descriptor table, read the LODTXT record directly into the selected segment. . 6. 7. 8.
If more LODTXT records remain, go to step 4.

Free the space used for DESCRP entries. The task or tasks are loaded. Jump to the TSS identified in the module header.

LOAD-TIME BINDING
As with any system, it is possible on the iAPX 286 to delay many binding operations until load time by incorporating binding functions into the loader. The call gates of the iAPX 286 architecture, however, provide an especially convenient and efficient way to delay one specific binding operation: namely, binding of calls to operating-system primitives. Load-time binding to operating-system primitives is an advantage when The operating system is under development, and GDT locations of operating-system segment descriptors are subject to change Programs may execute under different operating systems that have different GOT layouts

Data structures for implementing load-time binding are An export module of specially marked, dummy gates for operating system primitives. Figure 11-4 shows how you can create such a module through Builder specifications. The NOT PRESENT specification marks the gates by resetting the present bit. Gates used for this purpose must reside in the LDT so that Binder (which works only with LDT descriptors) can use them. You need to update this export file only when you change the number or names of operating-system gates. A table of actual gates for the operating-system primitives. This table must contain, for each primitive, the gate name, a GDT selector for the segment in which the primitive resides, and the entry point (offset) within the segment. It is most convenient to take such information from a Builder export file that exports the gates for operating-system primitives. The example specifications shown in figure 11-3 create such an export file.

Figure 11-5 shows the data flow for load-time binding. By using the gate name from the DESNAM section, the loader associates a marked gate in the LOT with its gate name. Given the gate name, it looks up the actual binding information.

EXAMPLE LOADER
Figure 11-6 shows an example of a loader that reads the iAPX 286 OMF, resolves references to operating-system primitives, and calls kernel procedures to create a new task. In the interest of simplicity, this example recognizes only the single-task OMF produced by the Binder, and all error checking is omitted. This loader calls the kernel procedures CREATE_LDT, LOAD_LDT, LOAD_LDT_GATE, CREATE_TASK, RESERVE_SLOTS, and CHANGE_AR, which are not shown. CREATE_LDT allocates an LDT segment for a new task and installs its descriptors in two of the four GDT slots specified by TASICSEL. LOAD_LDT transfers a descriptor from the LDT of the loader to the LDT of the new task. LOAD_LDT_GATE places a gate in the LDT of the new task. CREATE_TASK

11-12

121960-001

inter

BINDING AND LOADING

system-ID

iAPX286 SYSTEM BUILDER, Vx.y

INPUT FILES: :F1:NUC.LNK OUTPUT FILE: (none) CONTROLS SPECIFIED: TITLE(Gates for Load-Time Binding) NOBOOTLOAD NOOBJECT BUILDFILE(:F1:XOSGAT.BLD) PRINT(:F1:XOSGAT.MP2) BUILD FILE:
1 2 3 4 5 6 7 8 9

:F1:XOSGAT.BLD EXAMPLE_OS; SEGMENT NUCLEUS CODE


NUCLEUS~STACK(DPL=0);

(DPL=0), NUCLEUS DATA (DPL=0),

10 11 12 13 14 15 16 17 18 19 20 21 22 23
24

GATE XQ - RESERVE SLOTS XQ RELINQUISH SLOTS XQ ALLOCATE XQ FREE SEG XQ-CREATE ALIAS XQ=CHANGE-AR XQ WAIT SEMAPHORE XQ SIGNAL SEMAPHORE XQ SEND MESSAGE XQ RECEIVE - MESSAGE -

(ENTRY=RES ERVE SLOTS, (ENTRY=RELINQUISH_SLOTS, (ENTRY=ALLOCATE, (ENTRY=FREE SEG, (ENTRY=CREATE ALIAS, (ENTRY=CHANGE_AR, (ENTRY=WAIT SEMAPHORE, (ENTRY=S IGNAL SEMAPHORE, (ENTRY=SEND MESSAGE, (ENTRY=RECEIVE MESSAGE,

DPL=3, DPL=3, DPL=3, DPL=3, DPL=3, DPL=3, DPL=3, DPL=3, DPL=3, DPL=3,

NOT NOT NOT NOT NOT NOT NOT NOT NOT NOT

PRESENT) PRESENT) PRES ENT) PRESENT) PRESENT) PRESENT) PRESENT) PRESENT) PRES ENT) PRESENT)

, , , , , , , , , ;

TABLE GDT (ENTRY=(NUCLEUS_CODE, NUCLEUS_DATA, NUCLEUS.STACK)), DUMMY (ENTRY= ( XQ RESERVE SLOTS, XQ-RELINQUISH SLOTS, XQ-ALLOCATE, XQ-FREE SEG, XQ-CREATE ALIAS, XQ-CHANGE-AR, XQ-WAIT SEMAPHORE, XQ-SIGNAL SEMAPHORE, XQ_SEND MESSAGE, XQ=RECEIVE_MESSAGE)); EXPORT #:Fl:XOSGAT.LB2 (KERNEL XQ RESERVE SLOTS, XQ-RELINQUISH SLOTS, XQ-ALLOCATE, XQ-FREE SEG, XQ_CREATE ALIAS, XQ-CHANGE-AR, XQ-WAIT SEMAPHORE, XQ-SIGNAL SEMAPHORE, XQ-SEND MESSAGE, XQ-RECEIVE_MESSAGE)); END

25 26 27 28 29 30 31 32
33

34 35 36
37

38 39 40 41
42

43 44 45

BUILD FILE PROCESSING COMPLETED

Figure 11-4. Specifying Dummy Gate Exports

11-13

121960-001

BINDING AND LOADING

BINDING LOADER

TASK BOUND TO OPERATING SYSTEM

121960-55

Figure 11-5. Strategy for Load-Time Binding

finishes creation of the new task by creating a TSS from a template in the loader and placing the new task in the scheduler's queues. RESERVE_SLOTS uses techniques such as those illustrated in Chapter 2 to allocate descriptor table slots. CHANGE_AR is used to place the correct type code into the writable data-segment descriptor used by the loader to fill a segment. The module BOND (shown in figure 11-7) shows the handling of the table of actual gates for operating-system primitives. The procedure GET_LOAD_FILE is not defined here. It simply fetches the file specification for a load able module from, for example, the console or the command line interpreter.

11-14

121960-001

BINDING AND LOADING

PL/M-286 COMPILER

960-515

date

PAGE

system-ID PL/M-286 Vx.y COMPILATION OF MODULE LOADER OBJECT MODULE PLACED IN :Fl:LOADER.OBJ COMPILER INVOKED BY: PLM286.86 :Fl:LOADER.PLM DEBUG

$ $ $ $ $
1

PAGEWIDTH(71) TITLE('960-515') INCLUDE (:Fl:NUCSUB.PLM) NOLIST INCLUDE (:Fl:UDISUB.PLM) NOLIST $ COMPACT DO; Language Extensions LITERALLY LITERALLY LITERALLY LITERALLY LITERALLY LITERALLY LITERALLY 'BYTE' , '0' , '0FFH' , 'WORD' , 'TOKEN' , 'WORD' , 'WHILE TRUE';

LOADER:

/***************************************************** **/

/*
2 1 DECLARE BOOLEAN FALSE TRUE TOKEN CONNECTION OFFSET FOREVER

*/

/***************************************************** **/

/*
3

Ex ternal s

*/

1 2 2 1 2 2 1 2 2 1 2
2

4 5 6 7 8 9 10
11

RESERVE SLOTS: PROCEDURE(TABLE,COUNT,SLOT_PTR,EXCEP_PT~) EXTERNAL; DECLARE TABLE WORD, COUNT WORD, (SLOT_PTR,EXCEP_PTR) POINTER; END RESERVE_SLOTS; CHANGE AR: PROCEDURE (SLOT,RIGHTS,EXCEP PTR) EXTERNAL; DECLARE SLOT SELECTOR, RIGHTS BYTE, EXCEP PTR POINTER; END CHANGE_AR; ALLOCATE: PROCEDURE (SLOT,RIGHTS,SIZE,EXCEP_PTR) EXTERNAL; DECLARE SLOT SELECTOR, RIGHTS BYTE, SIZE WORD, EXCEP PTR POINTER; END ALLOCATE; FREE SEG: PROCEDURE (SLOT, EXCEP PTR) EXTERNAL; DECLARE SLOT SELECTOR, EXCEP_PTR POINTER; END FREE_SEG; CREATE LOT: PROCEDURE(TASK SEL,SIZE,EXCEP PTR) EXTERNAL; DECLARE TASK SEL SELECTOR~ SIZE WORD, EXCEP PTR POINTER; END CREATE_LOT; LOAD LOT: PROCEDURE (TASK SEL, NEW SLOT, OLD SLOT, EXCEP PTR) EXTERNAL; DECLARE (TASK SEL, NEW SLOT, OLD_SLOT) SELECTOR, EXCEP_PTR POINTER; -

12 13 14 15 16 17 18 19

1 2 2 1 2

Figure 11-6. Binding Loader

11-15

121960-001

BINDING AND LOADING

PL/M-286 COMPILER 20 21 22 23 2 1 2 2

960-515

date

PAGE

LOAD LOT GATE: PROCEDURE (TASK SEL, NEW SLOT, RIGHTS, TARGET~ COUNT, EXCEP PTR) EXTERNAL; DECLARE (TASK SEL, NEW SLOT) SELECTOR, RIGHTS BYTE, (TARGET, EXCEP PTR) POINTER, COUNT BYTE; END LOAD_LDT_GATE; CREATE TASK: PROCEDURE (TASK SEL, TEMPLATE, PRIORITY, EXCEP PTR) EXTERNAL; DECLARE TASK SEL SELECTOR, (TEMPLATE, EXCEP_PTR) POINTER, PRIORITY BYTE; END CREATE_TASK; GET LOAD FILE: PROCEDURE (FILE SPEC PTR) EXTERNAL; DECLARE-FILE SPEC PTR POINTERT END GET_LOAD=FILET BUILD BOND TABLE: PROCEDURE (FILESPEC_PTR, EXCEP_PTR) EXTERNAL; DECLARE (FILESPEC PTR, EXCEP PTR) .POINTERi END BUILD_BONO_TABLE; FIND BOND: PROCEDURE (SNAME PTR, ENTRY PTR, SEL_PTR, EXCEP PTR) EXTERNAL; DECLARE (SNAME_PTR, ENTRY_PTR, SEL_PTR, EXCEP_PTR) POINTER; END FIND_BONDi INITIALIZE SYSTEM: PROCEDURE EXTERNAL; END INITIALIZE_SYSTEM; REPORT: PROCEDURE (EXCEP PTR) DECLARE EXCEP PTR POINTER; END REPORT; . EXTERNAL;

24
25 26

1
2 2

27
28 29 30 31 32 33
34

1
2 2 1

2 2
1
2

35 36 37 38 39

2
1

2
1

40 41 42
43

2 2

1 2
2

DQ$ATTACH: PROCEDURE (PATH$P, EXCEP$P) CONNECTION EXTERNAL; DECLARE (PATH$P, EXCEP$P) POINTER; END DQ$ATTACH; PROCEDURE (CONN, EXCEP$P) EXTERNALi DQ$DETACH: DECLARE CONN 'CONNECTION, EXCEP$P POINTER; END DQ$DETACH; DQ$OPEN: PROCEDURE (CONN, ACCESS, NUM$BUF, EXCEP$P) EXTERNAL; DECLARE CONN CONNECTION, (ACCESS, NUM$BUF) BYTE, EXCEP$P POINTER; END DQ$OPEN; DQ$SEEK: PROCEDURE (CONN, MODE, LOCATION, EXCEP$P) EXTERNAL; DECLARE CONN CONNECTION, MODE BYTE, LOCATION DWORD, EXCEP$P POINTER; END DQ$SEEK;

44
45

1
2

46 47 48
49
50 51 52

2 1 2
2
1
2 2

Figur~

11-6. Binding Loader (Cont'd.)

11-16

121960-001

BINDING AND LOADING

PL/M-286 COMPILER 53 54 55 56 57 58
1 2 2

960-515

date

PAGE

PROCEDURE DQ$READ: (CONN, BUF$P, COUNT, EXCEP$P) WORD EXTERNAL; DECLARE CONN CONNECTION, COUNT WORD, (BUF$P, EXCEP$P) POINTER; END DQ$READ; DQ$CLOSE: PROCEDURE (CONN, EXCEP$P) EXTERNAL; DECLARE CONN CONNECTION, EXCEP$P POINTER; END DQ$CLOSE;

1 2 2

/*******************************************************/ /* Da ta */
59
1

DECLARE IN GDT LITERALLY '0', IN-LDT LITERALLY '1', DATA W LITERALLY 'lll10010B', /* Access rights: present~ DPL=3, expand-up, writable, data segment */ DATA WD LITERALLY '111101108', /* Access rights: present, DPL=3, expand-down, writable, data segment */ READ LITERALLY '1', DEFAULT PRIORITY LITERALLY '4', ALLOCATED LITERALLY '80H', OK LITERALLY '0', EXCEPTION LITERALLY 'EXCEP<)OK';

60

/* Disk file to load */ DECLARE PATH NAME (47) BYTE, LOAD-FILE CONNECTION, WORD, ACTUAL EXCEP WORD, SELECTOR, /* First of GDT slots TASK_SLOT for new task */ SELECTOR, /* Data or code segment of new task */ BOND FILESPEC (*) BYTE INITIAL (11 , ' : F 1 : XOS LB 2 ' ) ;
DECLARE FILE_HEADER DECLARE MODULE HEADER TOTAL-SPACE DESCR=COUNT BUILT DATE TIME CREATOR TSS SEL DESCRP LOC LODTXT-LOC IGNORE-l DESNAM-LOC IGNORE-2 IGNORE-3 IGNORE-4 LAST LOC RESERVEDl BYTE; STRUCTURE DWORD, WORD, BYTE, BYTE, BYTE, BYTE, WORD, DWORD, DWORD, DWORD, DWORD, DWORD, DWORD, DWORD, DWORD, DWORD,

61 62

1 1

(8 ) (8 ) (41 )

/* /* /* /* /* /* /* /*

0 */
1 */

2 3 4 5 6 7

*/ */ */ */ */ */

Figure 11-6. Binding Loader (Cont'd.)

11-17

121960-001

BINDING AND LOADING

PL/M-286 COMPILER

960-515 RESERVED2

date DWORD);

PAGE

63

/* Table of segment names from DESNAM section of OMF */ DECLARE DESNAM SEL SELECTOR, DESNAM-WIDTH LITERALLY '41', DESNAM-BASED DESNAM SEL (2) STRUCTURE ( NAME (DESNAM WIDTH) BYTE ), WORD; /* Index */ DIX /* RAM copy of DESCRP section of OMF */ DECLARE DESCRP SEL SELECTOR, SEGDT BASED DESCRP SEL (2) STRUCTURE LIMIT WORD,LO BASE WORD, HI-BASE BYTE, /* Data/code segment descr */ RIGHTS BYTE, RESERVED WORD ), GATET BASED DESCRP SEL (2) STRUCTURE ( ENTRY POINT OFFSET, SEL SELECTOR, WORD COUNT BYTE, /* Gate descriptor */ RIGHTS BYTE, ) , RESERVED WORD LIX WORD; /* Index * / /* Template for Task State Segment for new task */ DECLARE TSS STRUCTURE ( BACKL SELECTOR, SP0 OFFSET, SS0 SELECTOR, SPl OFFSET, SSl SELECTOR, SP2 OFFSET, SS2 SELECTOR, IP OFFSET, FLAG WORD, (AX, CX, DX, BX, SP, BP, SI, DI, ES, CS, SS, DS, LDT_LINK) SELECTOR ); /*******************************************************/ /* Subroutines */

64

65

66 67 68

1
2 2

SECTION_SIZE: PROCEDURE (TOCIX) DWORD; DECLARE TOCIX WORD;/* Index into Table of Contents */ DECLARE TOC(8) DWORD AT (@MODULE_HEADER.DESCRP_LOC), IX WORD; /* Find the size of an OMF section */ DO IX=TOCIX+l TO 7; IF TOC(IX)<>0 /* Skip by null sections */ THEN RETURN TOC(IX)-TOC(TOCIX); END; END SECTION_SIZE; /*******************************************************/ BUILD_DESNAM_TABLE: PROCEDURE (DESNAM_SIZE); DECLARE DESNAM SIZE DWORD;

69 70 71 72
73

3 3 3
2

74
75

1 2

Figure 11-6. Binding Loader (Cont'd.)

11-18

121960-001

BINDING AND LOADING

PL/M-286 COMPILER

9613-515

date

PAGE

76

DECLARE DESNAM USED DWORD, DESNAM-HEADER STRUCTURE (DESCR IN WORD, NAME_LENGTH BYTE); DESNAM USED=!J; /* Allocate a segment for the table */ CALL ALLOCATE (DESNAM SEL, DATA W, DESNAM WIDTH * (MODULE HEADER.DESCR COUNT + 1), @EXCE -P);IF EXCEPTION THEN CALL REPORT (@EXCEP); /* Initialize the table */ DO DIX=!J TO MODULE HEADER.DESCR COUNT; CALL MOVB(@(' '),@DESNAM(DIX).NAME(!J),l); CALL MOVB(@DESNAM(DIX) .NAME(!J), @DESNAM(DIX) .NAME(l) ,DESNAM_WIDTH-l); END; /* Read each descriptor name */ DO WHILE DESNAM USED < DESNAM SIZE; /* Read fixed-portion of DESNAMrecord */ ACTUAL=DQ$READ (LOAD FILE, @DESNAM HEADER, 3, @EXCEP); IF EXCEPTION THEN CALL REPORT (@EXCEP); DE"SNAM USED=DESNAM USED+ACTUAL; DIX=DESNAM HEADER.OESCR IN-I; DESNAM(DIX).NAME(0)=DESNAM HEADER. NAME LENGTH; /* Read rest of name into-table entry-*/ ACTUAL=DQ$READ(LOAD FILE,@DESNAM(DIX) .NAME(l) , - DESNAM(DIX) .NAME(!J), @EXCEP); IF EXCEPTION THEN CALL REPORT (@EXCEP); DESNAM USED=DESNAM USED+ACTUAL; END /* DO LOOP */; -

77
78 79 81 82 83 84 85 86 87 89 90 91
9.2

2 2 2 2 3 3 3 2 3 3 3 3 3 3 3 3 3 2 1 2 2

93 95 96 97 98 99 11313

/*******************************************************/ LOAD_SEGMENTS: PROCEDURE(LODTXT_SIZE); DECLARE LODTXT_SIZE DWORD;

DECLARE LODTXT HEADER STRUCTURE LOAD OFFSET WORD, WORD, DESCR IN LENGTH WORD COUNT WORD, LODTXT USED DWORD;

1131

DECLARE NEW LOT SEL SELECTOR, NEW LOT SEL W WORD AT (@NEW LOT SEL), SEG=RIGHTS BYTE; DECLARE TSS_IN LITERALLY '!JFFFDH'; LODTXT USED=!J; /* Step thru all LODTXT records */ DO WHILE LODTXT_USED<LODTXT_SIZE;

1132 1133 1134

2 2 2

Figure 11-6. Binding Loader (Cont'd.)

11-19

121960-001

BINDING AND LOADING

PL/M-286 COMPILER

960-515

date

PAGE

105 106 108 109 110 III 112 114 115 116 117 118 119 120 121 122 124 125 127 128 129 131 132 133 135 136 137 138 139 140 141 143 144

3 3 3 3 3 4 4 4 4 3 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 3 2 1 2 2 2 3

1* Read in the LODTXT header *1 ACTUAL=DQ$READ(LOAD FILE,@LODTXT HEADER,6,@EXCEP); IF EXCEPTION THEN CALL REPORT (@EXCEP); LODTXT USED=LODTXT USED+ACTUAL; IF LODTXT_HEADER.DESCR_IN=TSS_IN
THEN DO; 1* Load the Task State Segment *1 ACTUAL=DQ$READ(LOAD FILE,@TSS,LODTXT HEADER. LENGTH, @EXCEP); IF EXCEPTION THEN CALL REPORT (@EXCEP); LODTXT USED=LODTXT USED+ACTUAL; END 1* loading Task-State Segment *1; ELSE DO; 1* Load a data or code segment *1 LIX=LODTXT HEADER.DESCR IN-I; IF (SEGDT(LIX) .RIGHTSAND 06H) = 06H 1* expand-down data segment? *1 THEN SEG RIGHTS=DATA WD; ELSE SEG-RIGHTS=DATA-W; 1* Allocate a segment *1 CALL ALLOCATE (DCS SEL, SEG RIGHTS, SEGDT(LIX) .LIMI~+l, @EXCEP); IF EXCEPTION THEN CALL REPORT (@EXCEP); 1* Read LODTXT record into segment *1 ACTUAL=DQ$READ(LOAD FILE, BUILD$PTR(DCS SEL,LODTXT HEADER. LOAD OFFSET), LODTXT HEADER.LENGTH, @EXCEP); IF EXCEPTION THEN CALL REPORT (@EXCEP); LODTXT USED=LODTXT USED+ACTUAL; 1* Put actual access rights in descriptor *1 CALL CHANGE AR (DCS SEL, SEGDT(LIX) .RIGHTS, @EXCEP); IF EXCEPTION THEN CALL REPORT (@EXCEP); 1* Construct selector for slot in new LOT *1 1* DPL = 3; TI = 1 *1 NEW LOT SEL W = (SHL(LIX,3) OR 07H); I*-Transfer descriptor to new LOT *1 CALL LOAD LOT (TASK SLOT,NEW LOT SEL,DCS SEL,@EXCEP); IF EXCEPTION THEN CALL REPORT (@EXCEP);1* Mark descriptor as allocated *1 SEGDT(LIX) .RIGHTS=ALLOCATED; END 1* loading a data or code segment *1; END 1* stepping thru all LODTXT records *1; END LOAD_SEGMENTS;

1*******************************************************1
LOAD_DESCRP: PROCEDURE;

1* Allocate a segment for the DESCRP section *1 CALL ALLOCATE (DESCRP SEL, DATA W, 8*MODULE HEADER.OESCR COUNT, @EXCEP); IF EXCEPTION THEN CALL REPORT (@EXCEP); 1* Step thru all descriptors *1 DO LIX = 0 TO MODULE HEADER.DESCR COUNT-I; 1* Read LOT entry *1 ACTUAL=DQ$READ (LOAD FILE, @SEGDT(LIX), - 8, @EXCEP);

Figure 11-6. Binding Loader (Cont'd.)

11-20

121960-001

inter
PL/M-286 COMPILER 145 147
3 3

BINDING AND LOADING

960-515

date

PAGE

148 149 150


151 152 153 154 155

3 3 4
4 4 4 3
2

IF EXCEPTION THEN CALL REPORT (@EXCEP); /* Is it marked with Present bit = 0 ? */ IF (SEGDT(LIX) .RIGHTS AND 80H)=0 THEN /* Is it a call gate? */ IF (SEGDT(LIX) .RIGHTS AND 0FH)=4 /* Type field */ THEN DO; /* Insert pointer from BOND table */ CALL FIND BOND (@DESNAM(LIX) .NAME, @GATET(~IX) .ENTRY POINT, @GATET(LIX) .SEL, @EXCEP); IF EXCEP=OK THEN /* set present bit. */ GATET(LIX) .RIGHTS=GATET(LIX) .RIGHTS OR 80H; END /* inserting pointer */; END /* stepping through all descriptors */; END LOAD_DESCRP; /*******************************************************/ /* Transfer remaining descriptors to new LOT */

156

TRANSFER REMAINDERS: PROCEDURE; /* Handles descriptors for which there was no LODTXT record (e.g. stacks and gates). DECLARE NEW LOT SEL SELECTOR, NEW-LDT-SEL W WORD AT (@NEW LOT SEL), SEG-RIGHTS BYTE; --

*/

157

158 159 160 161 162

/* Step thru DESCRP entries, skipping LOT alias */ DO LIX = 2 TO MODULE_HEADER.DESCR_COUNT-l; IF (SEGDT (LIX) .RIGHTS AND 0FH) = 4 THEN /* call-gate */ DO; /* Construct selector for slot in new LOT */ NEW LOT SEL W = (SHL(LIX,3) OR 07H); /*-Transfer descriptor to new LOT */ CALL LOAD LOT GATE (TASK SLOT, NEW LOT SEL, GATET(LIX) .RIGHTS,-BUILD$PTR(GATET(LIX) .SEL, GATET(LIX) .ENTRY POINT), GATET(LIX) .WORD COUNT, @EXCEP); IF EXCEPTION THEN CALL REPORT (@EXCEP); END /* call gate */; ELSE IF (SEGDT(LIX) .RIGHTS AND 10H) <> 0 THEN /* unallocated data or code segment */ DO; IF (SEGDT(LIX) .RIGHTS AND 06H) = 06H /* expand-down data segment? */ THEN SEG RIGHTS=DATA WDi ELSE SEG-RIGHTS=DATA-W; /* Allocate a segment */ CALL ALLOCATE (DCS SEL, SEG RIGHTS, SEGDT (LI X) LIMIT+l, @EXCEP); IF EXCEPTION THEN CALL REPORT (@EXCEP)i /* Put actual access rights in descriptor */ CALL CHANGE AR (DCS SEL, SEGDT(LIX) .RIGHTS, @EXCEP); IF EXCEPTION THEN CALL REPORT (@EXCEP); /* Construct selector for slot in new LOT */

3 3

4 4

163 165 166 167 168 169 170 171 172 .174 175

4 4 3 3 4 4 4 4 4 4 4

Figure 11-6. Binding Loader (Cont'd.)

11-21

121960-001

BINDING AND LOADING

PL/M-286 COMPILER

9613-515

date

PAGE

177 178 179 181 182 183

4
4

4 4

/* DPL = 3; TI = 1 */ NEW LDT SEL W = (SHL(LIX,3) OR 1J7H); /*-Transfer descriptor to new LDT */ CALL LOAD LDT(TASK SLOT,NEW LDT SEL,DCS SEL,@EXCEP); IF EXCEPTION THEN CALL REPORT (@EXCEP);END /* unallocated data or code segment */; END /* stepping thru DESCRP entries */; END TRANSFER_REMAINDERS;
/***************************************************** **/

3
2

/* 184 185 186 188 189 191 192 194 195 197 198. 199 21313 2132 2133 205 2136 2138 2139 211 212 214 215 216 218 219 221 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2

Main Line

*/

CALL INITIALIZE_SYSTEM; CALL BUILD BOND TABLE (@BOND FILESPEC,@EXCEP); IF EXCEPTION THEN CALL REPORT (@EXCEP); CALL RESERVE SLOTS (IN LDT, 1, @DCS SEL, @EXCEP); IF EXCEPTION-THEN CALL-REPORT (@EXCEP); CALL RESERVE SLOTS (IN LDT, 1, @DESCRP SEL, @EXCEP); IF EXCEPTION-THEN CALL-REPORT (@EXCEP); CALL RESERVE SLOTS (IN LDT, 1, @DESNAM SEL, @EXCEP); IF EXCEPTION-THEN CALL-REPORT (@EXCEP); DO FOREVER; GET NAME: CALL GET LOAD FILE (@PATH NAME); /* May wait */ LOAD FILE=DQ$ATTACH (@PATH NAME, @EXCEP); IF EXCEPTION THEN GOTO GET-NAME; CALL DQ$OPEN (LOAD FILE, READ, 1, @EXCEP); IF EXCEPTION THEN CALL REPORT (@EXCEP); /* Read file header. */ ACTUAL=DQ$READ (LOAD FILE, @FILE HEADER, 1, @EXCEP); IF EXCEPTION THEN CALL REPORT (@EXCEP); /* Read load able-module header */ ACTUAL=DQ$READ (LOAD FILE, @MODULE HEADER, SIZE(MODULE HEADER)~ @EXCEP); IF EXCEPTION THEN CALL REPORT (@EXCEP); /* Process DESNAM section of OMF */ CALL DQ$SEEK (LOAD FILE,2,MODULE HEADER.DESNAM LOC, @EXCEP); IF EXCEPTION THEN CALL REPORT (@EXCEP); CALL BUILD_DESNAM_TABLE (SECTION_SIZE(3)); /* Tell OS to allocate an LDT */ CALL RESERVE SLOTS (IN GDT, 4, @TASK SLOT, @EXCEP); IF EXCEPTION-THEN CALL-REPORT (@EXCEP); CALL CREATE LDT (TASK SLOT, MODULE HEADER.DESCR COUNT, @EXCEP) ; IF EXCEPTION THEN CALL REPORT (@EXCEP); /* Process DESCRP section */ CALL DQ$SEEK (LOAD FILE,2,MODULE HEADER.DESCRP LOC, @EXCEP); -

Figure 11-6. Binding Loader (Cont'd.)

11-22

121960-001

BINDING AND LOADING

PL/M-286 COMPILER 222 224 225 226 228 229 230 231 233 234 236 237 239 240 242 243 245 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2

960-515

date

PAGE

IF EXCEPTION THEN CALL REPORT (@EXCEP); CALL LOAD_DESCRP;

/* Process LODTXT section */ CALL DQ$SEEK (LOAD FILE,2,MODULE_HEADER.LODTXT_LOC, @EXCEP) ; IF EXCEPTION THEN CALL REPORT (@EXCEP); CALL LOAD_SEGMENTS(SECTION_SIZE(l));
CALL TRANSFER_REMAINDERS;

/* Tell OS to create the new task */ CALL CREATE TASK(TASK SLOT, @TSS, DEFAULT_PRIORITY, @EXCEP); IF EXCEPTION THEN CALL REPORT (@EXCEP);
(LOAD FILE, @EXCEP); CALL DQ$CLOSE IF EXCEPTION THEN CALL REPORT (@EXCEP); CALL DQ$DETACH (LOAD FILE, @EXCEP); IF EXCEPTION THEN CALL REPORT (@EXCEP); CALL FREE SEG (DESCRP SEL, @EXCEP); IF EXCEPTION THEN CALL REPORT (@EXCEP); CALL FREE SEG (DESNAM SEL, @EXCEP); IF EXCEPTION THEN CALL REPORT (@EXCEP); END /* FOREVER */;
/***************************************************** **/

246

END LOADER;

MODULE INFORMATION: CODE AREA SIZE CONSTANT AREA SIZE VARIABLE AREA SIZE MAXIMUM STACK SIZE 508 LINES READ o PROGRAM WARNINGS o PROGRAM ERRORS DICTIONARY SUMMARY: 96KB MEMORY AVAILABLE 11KB MEMORY USED (11%) 0KB DISK SPACE USED END OF PL/M-286 COMPILATION 08B2H 0001H 00FFH 0018H 2226D 10 255D 240

Figure 11-6. Binding Loader (Cont'd.)

11-23

121960-001

BINDING AND LOADING

PL/M-286 COMPILER

960-521

date

PAGE

system-ID PL/M-286 Vx.y COMPILATION OF MODULE BOND OBJECT MODULE PLACED IN :F1:BOND.OBJ COMPILER INVOKED BY: PLM286.86 :F1:BOND.PLM DEBUG

$ $ $ $ $ $
1

PAGEWIDTH(71) TITLE('960-521') INCLUDE (:F1:NUCSUB.PLM) NOLIST INCLUDE (:F1:UDISUB.PLM) NOLIST COMPACT DO; Language Extensions LITERALLY LITERALLY LITERALLY LITERALLY LITERALLY LITERALLY 'BYTE' , '0' , '0FFH' , 'WORD' , 'TOKEN', 'WORD' ;

BOND:

/***************************************************** **/

/*
2 1 DECLARE BOOLEAN FALSE TRUE TOKEN CONNECTION OFFSET

*/

/*******************************************************/
/*
3
1 2 2

Externals

*/

4
5 6

RESERVE SLOTS: PROCEDURE (TABLE,COUNT,SLOT_PTR, EXCEP_PTR) EXTERNAL; DECLARE TABLE WORD, COUNT WORD, (SLOT_PTR, EXCEP_PTR) POINTER; END RESERVE_SLOTS; GET GATE POINTER: PROCEDURE (GATE SEL, SEG_SEL_PTR, SEG OFFSET PTR, EXCEP PTR) EXTERNAL; /* Returns selector and offset from a gate descriptor */ DECLARE GATE SEL SELECTOR, (SEG SEL: PTR, SEG OFFSET PTR, EXCEP PTR) POINTER; END GET_GATE_POINTER; ALLOCATE :.PROCEDURE (SLOT, RIGHTS, SIZE, EXCEP PTR) EXTERNAL; DECLARE SLOT SELECTOR, RIGHTS BYTE, SIZE WORD, EXCEP PTR POINTER; END ALLOCATE; REPORT: PROCEDURE (EXCEP PTR) EXTERNAL; DECLARE EXCEP PTR POINTER; END REPORT; DQ$ATTACH: PROCEDURE (PATH$P, EXCEP$P) CONNECTION EXTERNAL; DECLARE (PATH$P, EXCEP$P) POINTER; END DQ$ATTACH; DQ$DETACH: PROCEDURE (CONN, EXCEP$P) EXTERNAL;

7
8 9

2
2

1
2

10
11

12 13 14 15 16 17 18

1
2

1
2

2 1

Figure 11-7. BOND Module of Binding Loader

11-24

121960-001

BINDING AND LOADING

PL/M-286 COMPILER

96CJ-521

date

PAGE

19
20
21

2 2 1 2 2 1
2

DECLARE CONN CONNECTION, EXCEP$P POINTER; END DQ$DETACH; DQ$OPEN: PROCEDURE (CONN, ACCESS, NUM$BUF, EXCEP$P) EXTERNAL; DECLARE CONN CONNECTION, (ACCESS, NUM$BUF) BYTE, EXCEP$P POINTER; END DQ$OPEN; DQ$SEEK: PROCEDURE (CONN, MODE, LOCATION, EXCEP$P) EXTERNAL; DECLARE CONN CONNECTION, MODE BYTE, LOCATION DWORD, EXCEP$P POINTER; END DQ$SEEK; DQ$READ: PROCEDURE (CONN, BUF$P, COUNT, EXCEP$P) WORD EXTERNAL; DECLARE CONN CONNECTION, COUNT WORD, (BUF$P, EXCEP$P) POINTER; END DQ$READ; DQ$CLOSE: PROCEDURE (CONN, EXCEP$P) EXTERNAL; DECLARE CONN CONNECTION, EXCEP$P POINTER; END DQ$CLOSE;

22 23

24
25 26
27 28

2 1 2
2 1 2 2

29
30 31 32

/*******************************************************/ /* Data */
33
1

DECLARE IN_LOT LITERALLY '1', DATA W LITERALLY 'lll10010B', /* Access rights: present~ DPL=3, expand-up, writable, data segment */ READ LITERALLY '1', EQUALS LITERALLY '0FFFFH', OK LITERALLY '0', EXCEPTION LITERALLY 'EXCEP<>OK'; DECLARE BOND FILE ACTUAL SEL WSEL DECLARE FILE HEADER CONNECTION, WORD, SELECTOR, /* for type conversion */ WORD AT (@SEL); BYTE; STRUCTURE DWORD, WORD, WORD, WORD, WORD, BYTE, BYTE, BYTE, BYTE, BYTE, DWORD, DWORD, DWORD,

34

35

1 1

36

DECLARE MODULE HEADER TOTAL-LENGTH SEGMENT COUNT GATE COUNT PUB COUNT EXT-COUNT LINKED DATE TIME MODULE NAME CREATOR IGNOREl PUBDEF LOC PUBDEF-LENGTH

(8 ) (8 )

(41 ) (41 )
(6)

Figure 11-7. BOND Module of Binding Loader (Cont'd.)

11-25

121960-001

BINDING AND LOADING

PL/M-286 COMPILER

960-521 IGNORE2
(8 )

date DWORD) i

PAGE

37

/* Table of actual locations of O.S. primitives */ DECLARE BOND SEL SELECTOR, BOND-BASED BOND SEL (2) STRUCTURE GATE NAME(41) BYTE, ENTRY POINT OFFSET, GDT SEL SELECTOR ), BIX WORDi /* Index */
DECLARE PUBDEF STRUCTURE (ENTRY POINT GDT IN IGNORE WORD COUNT LENGTH WORD, WORD, WORD, BYTE, BYTE)i

38

/*******************************************************/ /* Subroutines */
/* Create table of actual GDT selectors and
entry points for O.S. primitives. */ 39 40 41 42 43 45 46 48 49 51 52 54 55 57 58 1 2 2 2 2 2 2 2 2 2 2 2 2 2 2 BUILD BOND TABLE: PROCEDURE (BOND NAME PTR, EXCEP PTR) PUBLICi DECLARE (BOND NAME PTR, EXCEP PTR) POINTERi DECLARE EXCEP-BASED EXCEP_PTR-WORDi

/* Initialize file */ BOND FILE=DQ$ATTACH (BOND NAME PTR,@EXCEP)i IF EXCEPTION THEN RETURN i CALL DQ$OPEN (BOND FILE, READ, 1, @EXCEP)i IF EXCEPTION THEN CALL REPORT (@EXCEP)i /* Read file header */ ACTUAL=DQ$READ (BOND FILE,@FILE HEADER,l,@EXCEP)i IF EXCEPTION THEN CALL REPORT (@EXCEP)i /* Read module header */ ACTUAL=DQ$READ (BOND FILE,@MODULE HEADER, SIZE(MODULE HEADER), @EXCEP)i IF EXCEPTION THEN CALL REPORT (@EXCEP)i /* Get space for table */ CALL RESERVE SLOTS (IN LDT,l,@BOND SEL,@EXCEP)i IF EXCEPTION-THEN CALL-REPORT (@EXCEP)i CALL ~LLOCATE (BOND SEL, DATA W, (MODULE HEADER. PUB COUNT+l)*SIZE(BOND(0 ,@EXCEP)i IF EXCEPTION THEN CALL REPORT (@EXCEP)i /* Read the PUBDEF section */ /* (Locations are relative to beginning of module,

60 61 63 64

2 2 2

not beginning of file. Assume module at 1.) */ CALL DQ$SEEK (BOND FILE,2,MODULE HEADER.PUBDEF LOC+l, . @EXCEP)i IF EXCEPTION THEN CALL REPORT (@EXCEP)i /* Loop thru the PUBDEF entries */ DO BIX = 0 TO MODULE HEADER. PUB COUNT-li /*Read fixed part-of PUBDEF record */ ACTUAL=DQ$READ(BOND_FILE,@PUBDEF, 8, @EXCEP)i

Figure 11-7. BOND Module of Binding Loader (Cont'd.)

11-26

121960-001

BINDING AND LOADING

PL/M-286 COMPILER 65 3 3
3

960-521

date

PAGE

67
68 69
71 72 73 75

3 3 3 3
3
2

IF EXCEPTION THEN CALL REPORT (@EXCEP); /* Convert index into GDT selector */ WSEL=SHL(PUBDEF.GDT IN,3); /* Extract gate selector and offset from GDT */ CALL GET GATE POINTER (SEL, @BOND(BIX) .GDT SEL, @BOND(BIX) .ENTRY POINT, @EXCEP)i IF EXCEPTION THEN CALL-REPORT (@EXCEP); /* Read variable-length name */ BOND(BIX) .GATE NAME(0)=PUBDEF.LENGTH; ACTUAL=DQ$READ(BOND FILE,@BOND(BIX) .GATE NAME(l), PUBDEF.LENGTH,@EXCEP); IF EXCEPTION THEN CALL REPORT (@EXCEP); END /* looping thru PUBDEF entries */;

76

/***************************************************** **/

77

FIND BOND: PROCEDURE (SNAME PTR, ENTRY_PTR, SEL_PTR, EXCEP_PTR) PUBLIC; -

/* Search BOND table for given name.


Return items from found entry.
78
79
2

*/

DECLARE (SNAME PTR, PO INTER; DECLARE SNAME ENTRY_POINT GDT SEL EXCEP

ENTRY_PTR, SEL_PTR, EXCEP_PTR) BASED BASED BASED BASED SNAME PTR ENTRY-PTR SEL PTR EXCEP_PTR (41) BYTE, WORD, SELECTOR, WORD;

80 81 82 83 84 85 86 87 88 89 90 91 92

2 3

3 3 4 4 4 4 4 3
2

2
2

DO BIX = 0 TO MODULE HEADER. PUB COUNT-l; IF SNAME(0)=BOND(BIX) .GATE NAME(0) /* Same length? */ THEN /* Compare characters */ IF EQUALS=CMPB(@SNAME(l) ,@BOND(BIX) .GATE_NAME(l), SNAME (0) ) THEN DO; ENTRY POINT=BOND(BIX) .ENTRY POINT; GDT SEL=BOND(BIX) .GDT SEL; EXCEP=OK; RETURN; END; END; EXCEP=NOT OK; RETURN; END FIND_BOND;
/***************************************************** **/

93

END BOND;

MODULE INFORMATION:

Figure 11-7. BOND Module of Binding Loader (Cont'd.)

11-27

121960-001

BINDING AND LOADING

PL!M-286 COMPILER

960-521 02CBH 0000H 00C2H 001CH 715D 0D 194D 28D

date

PAGE

CODE AREA SIZE CONSTANT AREA SIZE VARIABLE AREA SIZE MAXIMUM STACK SIZE 245 LINES READ o PROGRAM WARNINGS o PROGRAM ERRORS DICTIONARY SUMMARY:

96KB MEMORY AVAILABLE 8KB MEMORY USED (8%) 0KB DISK SPACE USED END OF PL!M-286 COMPILATION

Figure 117. BOND Module of Binding Loader (Cont'd.)

11-28

121960-001

Numerics Processor Extension

12

CHAPTER 12 NUMERICS PROCESSOR EXTENSION


The iAPX 286/20 is a configuration of chips consisting of an 80286 CPU and an 80287 Numerics Processor Extension (NPX). With these two cooperating processors it is possible to construct powerful numerics processing systems, but the operating system must multiplex the 80287 among the tasks that use it. If the system does not include an 80287, you may choose to have the operating system emulate its functions.

iAPX 286/20 NUMERICS PROCESSING FEATURES


Several features of the iAPX 286/20 are of special interest to operating-system designers and programmers. You can find more details on how to use the iAPX 286/20 in the iAPX 286 Programmer's Reference Manual.

ESCAPE Instructions
The 80287 NPX extends the instruction set of the iAPX 286 by over fifty opcodes. The CPU identifies the extended instruction set by the bit pattern 11011 B in the high-order five bits of the first byte of the instruction. Instructions thus marked are called ESCAPE or ESC instructions. The CPU performs some functions upon encountering an ESC instruction, before sending the instruction to the NPX. Those functions that are of interest to the operating system include Testing the emulation mode (EM) flag to determine whether NPX functions are being emulated by software. Testing the TS flag to determine whether there has been a context change since the last ESC instruction. For some ESC instructions, testing the ERROR pin to determine whether an error condition exists at the NPX as a result of a previous ESC instruction.

The ASM286 Assembly Language Reference Manual provides more information on each 80287 instruction.

Emulation Mode Flag (EM)


The EM bit of the 80286 machine status word (MSW) indicates to the CPU whether NPX functions are to be emulated. If the processor finds EM set when executing an ESC instruction, it causes trap 7, giving the exception handler an opportunity to emulate the functions of an 80287. The EM flag can be changed with the aid of LMSW (load machine status word) instruction (legal only at privilege level 0 (PL 0)) and tested with the aid of the SMSW (store machine status word). The built-in variable MACHINE$STATUS gives PL/M-286 programs access to the MSW. The EM bit also controls the function of the WAIT instruction. If the processor finds EM set while executing a WAIT, the processor does not check the ERROR pin for an error indication. Note that EM must never be set concurrently with MP.

12-1

121960-001

NUMERICS PROCESSOR EXTENSION

Math Present Flag (MP)


The MP bit of the 80286 machine status word (MSW) indicates to the CPU whether an 80287 NPX is actually attached. The MP flag controls the function of the WAIT instruction. If, when executing a WAIT instruction, the CPU finds MP set, then it tests TS; it does not otherwise test TS during a WAIT instruction. If it finds TS set under these conditions, the CPU causes trap 7. Note that MP must never be set concurrently with EM.

Task Switched Flag (TS)


The TS bit of the MSW helps to determine when the context of the 80287 NPX does not match that of the 80286 CPU. The CPU sets TS each time it performs a task switch (whether triggered by software or by hardware interrupt). If, when interpreting one of the ESC instructions, the CPU finds TS already set, it causes trap 7. The MP flag also relates to TS. The CLTS instruction (legal only at PL 0) resets TS.

WAIT Instruction
The WAIT instruction is not an ESC instruction, but WAIT causes the CPU to perform some of the same tests that it performs upon encountering an ESC instruction: The CPU waits until the NPX no longer asserts the BUSY pin. You can therefore use WAIT to synchronize the CPU with the NPX. The CPU tests the ERROR pin (if EM is not set). You can therefore use WAIT to cause trap 16 if an error is pending from a previous ESC instruction. (The CPU makes this test only after BUSY goes inactive.) Note that, if no 80287 is present, the ERROR pin should be tied inactive to prevent WAIT from causing spurious traps.

Summary
Table 12-1 summarizes functions of the ESC and WAIT instructions that depend on setting of the MP and EM flags.

INITIALIZATION
During its initialization phase the operating system must Set flags in the MSW to reflect the numerics processing environment Reset the 80287 (if present) Switch the 80287 into protected mode

You can use a configuration parameter to communicate the numerics processing environment to the operating system. The FNINIT instruction (lNIT$REAL$MATH$UNIT in PL/M-286) resets the 80287, and the FSETPM instruction places the 80287 into protected mode.

12-2

121960-001

NUMERICS PROCESSOR EXTENSION

Table 12-1. Interpretation of MP and EM Flags


EM Flag

Set Reset N Y Y

Reset Set

Instruction
MP Flag

TRAP 7? WAIT TEST BUSY? TEST ERROR? (TRAP 16) TRAP 7? ESCAPE TEST BUSY? TEST ERROR? (TRAP 16)

if TS=1
Y Y

Y N N

if TS=1
Y Y

TASK STATE
When a task uses the 80287 NPX, the operating system has two additional concerns in keeping track of the task's state: The task database must be expanded to include 47 words of state information for the 80287. The operating system must change 80287 state when a different task attempts to use the 80287.

The state of the 80287 consists of 47 words. Saving and restoring the 80287 state is therefore a relatively expensive operation that should not be performed any more frequently than necessary. Typically, only a few of the active tasks in a system use the NPX; therefore, it would be wasteful to save and update the state information with every task switch. It is preferable for the operating system to record which task is using the 80287 and to swap state information only when some other task attempts to use the 80287. The 80286 supports sharing of the 80287 by providing the TS flag. The processor automatically sets the TS every time a task switch occurs. The first use of an ESC or WAIT instruction when the TS is set causes trap 7. This enables the operating system to keep track of the task to which the NPX is assigned at any given time and to change 80287 state when necessary.

NUMERICS EXCEPTIONS
Three interrupt vector positions are reserved for exceptions that relate to numerics processing. Interrupts for these vectors are not maskable.

Interrupt 7-Processor Extension Not Available (NM)


This exception occurs in either of two conditions: The CPU encounters an ESC instruction and EM is set. In this case, the exception handler should emulate the instruction that caused the exception. TS may also be set.

12-3

121960-001

NUMERICS PROCESSOR EXTENSION

The CPU encounters either the WAIT instruction or an ESC instruction when both MP and TS are set. In this case, the exception handler should update the state of the NPX if necessary.

'EMULATION

The return link points to the first byte of the ESC instruction (or to the prefix byte, if any). As the emulator decodes the ESC instruction, it should step the return pointer so that, at the end of the emulation routine, the return from the exception handler causes execution to resume at the first instruction following the ESC instruction.
UPDATING STATE

To make sure that the state of the NPX corresponds to the current task, the operating system should implement the concept of "ownership" of the NPX. Ownership can be indicated by a Boolean in the task database (TDB). The operating system must ensure that only one task at a time is marked as the owner of the NPX. The exception handler should follow these steps: 1. 2. 3. 4. 5. Use the CLTS instruction to reset TS. Return if the current task owns the NPX. Use the FSA VE ESC, instruction (PL/M-286 SA VE$REAL$STATUS) to store NPX context in the former owner's task database. Record the current task as the owner of the NPX. Use the FRSTOR ESC instruction (PL/M-286 RESTORE$REAL$ST ATUS) to load the NPX context from the new owner's TDB.

Since task switches may occur during execution of the exception handler, steps 3, 4, and 5 are a critical region and must be protected by a mechanism such as a semaphore. The exception handler must run at' PL 0, both because it alters the critical task database at PL 0 and because it uses the privileged instruction CLTS. The exception handler must be an interrupt procedure, not an interrupt task. If it were an interrupt task, the task switch that occurs upon returning from the exception handler would set TS, thereby causing the exception again. The return link points to the first byte of the interrupted instruction. Return from the exception handler causes restart of that instruction, but this time TS is reset and the instruction can proceed.

Interrupt 9-Processor Extension Segment Overrun (MP)


This exception occurs when a memory operand of an 80287 instruction has a segment-limit violation. Since the 80287 executes in parallel with the 80286, two difficulties may arise: The occurrence of this exception may not relate directly to the instruction stream being executed by the current task. A task switch may have occurred since the 80287 began executing the instruction. Even if the interrupted task is the correct task, its IP may have been advanced by several instructions beyond the ESC instruction. Since the exception is not maskable, it may occur while interrupts are disabled. If minimum interrupt latency is important, the exception handler must do as little as possible. It could, for example, record the error for later handling.

12-4

121960-001

NUMERICS PROCESSOR EXTENSION

The offending ESC instruction cannot be restarted. The task containing the ESC instruction (which may not be the current task) must eventually be cancelled. The exception handler must execute an FINIT instruction before executing a WAIT or other ESC instruction; otherwise, the WAIT or ESC instruction will never finish. FINIT does not affect the CS:IP value and data address saved in the 80287. Note that the 80286 CPU detects some addressing violations before sending the ESC instruction to the 80287 NPX. In these cases, the CPU causes trap 13 (pushing an error code of zero), and it is generally possible to restart the ESC instruction. Refer to Chapter 7 for more information regarding trap 13.

Interrupt 16-Processor Extension Error (MF)


The 80287 detects six different exception conditions during instruction execution. If the detected exception is not masked by a bit in the control word, the 80287 communicates the fact that an error occurred to the CPU by a signal at the ERROR pin. The CPU causes interrupt 16 the next time it checks the ERROR pin, which is only at the beginning of a subsequent WAIT or certain ESC instructions. If the exception is masked, the 80287 handles the exception according to on-board logic; it does not assert the ERROR pin in this case. The six exception conditions are

1.

INVALID OPERATION OVERFLOW ZERO DIVISOR UNDERFLOW DENORMALIZED OPERAND PRECISION (INEXACT RESULT)

2.
3.

4.

5.

6.

The steps to be taken to remove the error condition depend on the application. Once the exception handler corrects the error condition causing the exception, the floating point instruction that caused the exception can be restarted, if appropriate. This cannot be accomplished by IRET, however, because the trap occurs at the ESC or WAIT instruction following the offending ESC instruction. The handler must obtain from the 80287 the address of the offending instruction in the task that initiated it, make a copy of it, execute the copy in the context of the offending task, and then return via IRET to the current CPU instruction stream. The ESC instructions that do not cause automatic checking of the ERROR pin are FNCLEX, FNINIT, FSA VE, FSETPM, FSTCW, FSTENV, and FSTSW . You can use the WAIT instruction to test the ERROR pin before these instructions, if necessary.

12-5

121960-001

Extended Protection

13

CHAPTER 13 EXTENDED PROTECTION


Even though the iAPX 286 architecture provides extensive, automatic protection, a fully protected system requires additional protection features in the operating system. Operating-system software can increase the reliability of the system by providing any of these protection features: Extending the "type" concept Validating pointer parameters Defining the right to use operating-system objects Defining the right to delete segments Protecting shared objects that are being constructed

EXTENDED TYPE
It is both convenient and dangerous to use a selector as the name of an operating-system object. The danger arises from the fact that the selector by itself carries no information regarding the type of object it identifies. A program can, for example, mistakenly pass the selector of a semaphore to an operatingsystem procedure that operates on mailboxes, producing catastrophic results. The solution is to associate a type extension code for the object with the segment in which it resides or with a descriptor to that segment. Operating-system procedures can then check the type of objects identified by selector parameters. (The term type extension code is used here to avoid confusion with the processor-recognized type code in a descriptor.) There are three general methods of associating type with operating-system objects: 1. 2. 3. Place the type extension code in the segment in which the object resides. Associate the type code with a descriptor for the segment. Use indirect names and associate the type code with the name of the object.

Only segments likely to contain named operating-system objects need to have type extension codes; namely, privilege-level 0 (PL 0), expand up, writable, data segments.

Type Extension Code with Descriptor


A logical way to store a type extension code is to associate it with the descriptor for the named object (you can view the type extension code as a refinement of the processor-recognized type code in the access-rights byte of the descriptor). The type extension code can be put in a table parallel to the descriptor table (as illustrated in Chapter 5 in connection with alias-list pointers).

Type Extension Code in Segment


It is also possible to place the type extension code at some reserved location in the data segment itself. This approach does not reference another segment and thereby avoids loading a segment register.

13-1

121960-001

inter
Indirect Naming

EXTENDED PROTECTION

The most general approach to naming avoids giving to less privileged procedures any direct links to the named objects. Instead, names are indexes (or perhaps pointers) into a name table, which is administered by the operating system at a highly privileged level. Each entry in the name table holds the type extension code of the object, the selector of the segment in which the object resides, and any other information needed to ensure appropriate use of the object. This approach not only offers the greatest potential for protection, but also makes it possible to change the naming scheme without affecting procedures that use the names and provides a consistent way of naming both those objects that reside in dedicated segments and those that are packed into a segment with other objects.

PARAMETER VALIDATION
There is one type of privilege violation that the iAPX 286 cannot automatically check for. Consider, for example, procedure A at PL 3 that passes a pointer parameter via the stack to procedure B at PL 1. Procedure A could (accidently or purposely) pass a pointer that refers to a data structure at PL 2. Doing so would violate the intent of the protection features of the iAPX 286 because procedure A does not have sufficient privilege to operate on the data structure. However, the processor does not detect the violation because procedure B, which actually addresses the data structure, does have sufficient privilege to do so. The iAPX 286 provides the RPL field in the selector as well as the instructions shown in table 13-1 to help software guard against such protection violations. In addition to type checking as mentioned previously, an operating system can provide two levels of parameter valid:].tion: 1. 2. Defensive use of ARPL instruction Point-of-entry scrutiny

Defensive Use of ARPL


Simply by applying the ARPL instruction to every pointer parameter it receives, an operating system procedure guards against complicity in accessing a segment that the calling procedure has no right to access. ARPL has two selector operands, for example: A R P L seLa J

seLb
Table 13-1. Access Checking Instructions

ASM286 Mnemonic

PL/M-286 Built-In Function

Description

ARPL VERR VERW LAR LSL

ADJUST$RPL SEGMENT$READABLE SEGMENT$WRITABLE GET$ACCESS$RIGHTS GET$SEGMENT$LlMIT

Adjust requested privilege level Verify segment for reading Verify segment for writing Load access rights Load segment limit

13-2

121960-001

EXTENDED PROTECTION

ARPL adjusts the RPL field of seLa to the greater of its current value and the value of the RPL field in seLb. The CPL of the calling procedure is stored in the RPL field of the return pointer on the stack, as figure 13-1 illustrates. Assuming the parameter is also on the stack, statements of the form

AX , STACK_FRAME.RETURN_SEL MOV ARPL STACK_FRAME.PARAM_SEL , AX


can be used to ensure that the RPL field of the parameter is not less that the calling procedure's CPL. When the called procedure uses the parameter, the processor evaluates its right to use the parameter as if it had the privilege level of the calling procedure. If the calling procedure passes a parameter that it has no right to use, an exception will occur when the called procedure uses the parameter. Every operating system procedure should apply the ARPL instruction to every pointer or selector parameter it receives, even if the calling procedure is another operating-system procedure. This provides inexpensive protection against accidental use of invalid parameters.

Point-of-Entry Scrutiny
While use of ARPL alone is sufficient to detect such invalid parameters, it has one drawback: it does not help to isolate the source of the invalid parameter. An exception will eventually occur when some higher-level procedure uses the parameter, but this may not happen until several instructions after the procedure was called, and may not happen until after the called procedure passes the parameter to yet

STACK

HIGH

INTERRUPTED PROCEDURE'S SS DIRECTION OF GROWTH INTERRUPTED PROCEDURE'S SP FLAGS

1
SP - - - - - .

RETURN CS

RETURN IP

LOW

121960-32

Figure 13-1. Caller's CPL

13-3

121960-001

EXTENDED PROTECTION

another procedure. To detect parameter errors at the earliest opportunity, the operating system should examine pointer parameters with the VERR, VERW, LAR, and LSL instructions. The strategy for scrutinizing a pointer parameter includes Using ARPL as described previously to ensure that the RPL field of the pointer parameter contains the calling procedure's privilege level. Using VERR or VERW to ensure that the indicated segment is accessible at the calling procedure's privilege level. VERR also determines whether the indicated segment is readable; an execute-only segment, for example, is not readable. VERW also determines whether the segment is writable; only a writable data segment passes this test. Using LAR and LSL to make sure that the offset portion of the pointer parameter actually points to a location within the boundaries of the segment. LAR makes the access-rights byte of the indicated descriptor available, so you can determine whether the segment is an expand-down data segment. LSL makes the segment-limit field of the descriptor available. If the segment is an expand-down data segment, the offset portion of the pointer parameter must be greater than or equal to the segment limit; otherwise the offset must be strictly less than the limit.

Refer to the appropriate language reference manual for details concerning the use of these instructions. This strategy for parameter validation is somewhat more costly than using the ARPL instruction alone, as described in the previous section. Therefore, you may wish to limit use of this 'strategy to those operating system procedures that can be called by less privileged, applications procedures.

USAGE PRIVILEGE LEVEL


Generally, operating system primitives that act on operating system objects (such as the semaphores and mailboxes discussed in Chapter 5) have call gates at PL 3. Without further protection, procedures at any privilege level in a task can use those objects for which descriptors exist in the LDT. Such freedom violates the principle behind privilege levels, however. Consider these two cases: A database-management system that runs at PL 2 creates a mailbox for passing recovery information to a separate task that is responsible for writing recovery information to a magnetic tape. A task at PL 3 accidently uses the wrong selector in a call to the operating system and sends an unrelated message to that mailbox. Later, when using the audit tape to reconstuct the database, the database system reads the strange record and fails. Procedures of the same database system use a shared data segment so that they can access common database parameters regardless of what task they run in. To synchronize their access to the common data, they define and use a semaphore. A less privileged task uses a wrong selector in a call to the operating system and signals this semaphore prematurely, permitting the shared data to be incorrectly changed. The database system fails when it next tries to use the incorrect data.

These examples illustrate the need for additional protection over the use of operating-system objects, such as semaphores and mailboxes. By associating a usage privilege level (UPL) with objects, the operating system can provide protection analogous to that provided by hardware for access to segments. By means of a privilege-level parameter to the creation procedure, the task that creates an object defines the maximum (numerical) privilege level that can use the object. The UPL can be stored either in the data structures that define the object or (if indirect naming is used) with the name of the object. In the procedures that operate on the object, the operating system can check whether the calling procedure's privilege level exceeds the UPL of.the object. The calling procedure's privilege level is readily available on the stack, as figure 13-1 illustrates.

13-4

121960-001

EXTENDED PROTECTION

SEND PRIVILEGE LEVEL


Moving or deleting the descriptor for a segment or the name of an object may have even more drastic effects on other tasks than using the code or structures in the segment or object. Consider the effect of deleting or mailing away a descriptor for a global data segment (for example, a translation table) shared by all tasks in the system. A task that assumes the existence of the global segment will cause an exception when it references the deleted descriptor slot. This points out the need for control over the right to send or delete a descriptor. One way of implementing such control is to associate with each descriptor (including alias descriptors) a send privilege level (SPL). Procedures that move or delete descriptors (such as SEND_MESSAGE and DELETE~LIAS) interpret the SPL and ensure that the calling procedure cannot delete (send) a descriptor from the GDT or its LDT unless CPL < = SPL. SPL for segments is an attribute of segment descriptors and can be stored in tables parallel to descriptor tables. The SPL and UPL for operating system objects may be different. In general, the SPL of all descriptors in the GDT should be zero or one, limiting the deletion and movement of GDT descriptors to the most privileged levels of the operating system. It is quite reasonable, however, to have GDT-based objects with UPL of three, so that they are accessible from any level.

CONSTRUCTING SHARED OBJECTS


Since the procedure that builds a GDT-based object, such as a mailbox or semaphore, must have a descriptor for the object's data segment, there is a possibility (however slight) that some other task (for example, an interrupt task) might mistakenly use a selector for the object under construction in a request to the operating system to use a similar object. The results are unpredictable, but probably disastrous. There are several possible methods for guarding against such a circumstance: Lock out all other activity for that type of object by using a semaphore or other synchronization primitive. For the purposes of construction only, use a reserved descriptor slot that other operating-system procedures recognize as invalid. For the purposes of construction only, use an LDT slot of the task that is building the object. Use an invalid type extension code for the object until it is completely built.

13-5

121960-001

Glossary

GLOSSARY
8254 Programmable Interval Timer: an Intel counter/timer device that provides three independent 16-bit counters and six counter modes. For operating-system applications the 8254 can provide timed interrupts for use by the software scheduler. 8259A Programmable Interrupt Controller: an Intel device that handles up to eight vectored priority interrupts for the CPU. The chip is designed to minimize software and real-time overhead in handling multi-level priority interrupts. It has several software selectable. modes, permitting optimization for a variety of system requirements. 80286: the CPU chip of the iAPX 286 architecture. 80287: the numerics processor extension chip of the iAPX 286/20 chip set. access rights: the attributes of a segment, defined by a descriptor, that control how a segment can be used by instructions in other segments. accessed bit: a Boolean in the access rights byte of a descriptor that the processor sets when it loads the descriptor into a segment register. address mapper: a hardware device that selectively translates the CPU's addressing signals into signals of another form. alias: one of several descriptors for a segment. Each alias may define a different type, access rights, or (in some cases) limit for the segment. alias list: a data structure that enables the operating system to find all the aliases for a given segment. asynchronous: characterized by unpredictable order in the occurrence of events; not synchronous. back link: the selector field in a TSS that identifies the task to be invoked when the current task executes an IRET instruction. The processor reads the back link only if the NT flag is set. The processor sets the back link to point to the TSS of the former task when a CALL instruction or interrupt causes a task switch. base address: the 24-bit address in physical memory at which a segment starts. busy task: either the currently executing task or a task on a back-link chain from the currently executing task. A busy task has a type code of three in the descriptor for its TSS. Binder: see iAPX 286 Binder. binding: the process of translating a symbolic reference to a form that the processor can interpret directly. bootloader: see bootstrap loader. bootstrap loader: a small, usually ROM-resident, program whose function is to load a larger, fullyfeatured loader.

Glossary-1

121960-001

inter

GLOSSARY

bootloadable module: a module containing absolute object code in a simple format that expedites loading by a bootstrap loader. boundary tag: a field at the low or high end of a block of memory used by the memory allocation algorithm to distinguish between allocated and unallocated blocks. breakpoint: a position in a program marked in such a way that intervention can occur when execution of the program reaches that position. buddy system: a memory-management algorithm that partitions memory into pairs of memory blocks of equal size. When both blocks of a pair are not used, they are combined into a larger block that also has a partner or "buddy" of the larger size. buffer: an area of RAM used for transferring data to or from an external device. built-in: in PL/M-286, a predefined identifier. Builder: see iAPX 286 System Builder. BUSY: an input pin to the 80286 used by a processor extension such as the 80287 to indicate when the processor extension is unable to accept a new instruction. call gate: a gate used to transfer control to a procedure in a segment of the same task at an equal or (numerically) lesser privilege level. carry flag (CF): one of the six arithmetic flags typically used for unsigned integer comparisons and extended precision arithmetic~ CF is set by a carry into, or a borrow from, the high-order bit of a result operand. . code segment: see executable segment. combine type: one of the characteristics that the Binder associates with segments. The Binder combines segments only if they have compatible combine types. compaction: relocating allocated memory segments into consecutive locations in order to bring together all unallocated memory blocks. compiler control statement: source statements that specify options to the compiler. Control statements begin with a dollar sign ($) in the left margin. conforming segment: an executable segment that executes at the CPL of any segment that calls it. A conforming segment is identified by a bit in the access rights byte of its descriptor. control flow transfer: any change.in the normal sequential progress of a program. JMP, CALL, RET, IRET, and INT instructions, as well as exceptions and external interrupts, can cause a change .in control flow. coroutine: a type of subroutine that cooperates with other coroutines in quasi-parallel execution. A set of related coroutines transfer control from one to another. Each coroutine maintains local variables across invocations and maintains an independent instruction counter that determines where to begin execution upon next invocation. critical section: a procedure or portion of a procedure that operates on shared data in such a way that it may act incorrectly if another procedure operates on the same data within the same time interval.

Glossary-2

121960-001

GLOSSARY

CS (code segment) register: the segment register that provides addressability for access to instructions. current privilege level (CPL): the privilege level that the processor is using to execute the currentlyaccessible executable segment. CPL may be equal to OPL of the executable segment, or CPL may be numerically greater that OPL if the segment is conforming. data segment: a segment that contains data (other than immediate data) for an executable segment. A data segment is identified by a specific type code in the descriptor of the segment. descriptor: an eight-byte item that defines the use of memory in an iAPX 286 protected-mode system. descriptor table: one of the processor-recognized tables that contain the descriptors for the system. These tables are the GOT, the lOT, and LOTs. descriptor privilege level (DPL): the privilege level defined in the descriptor of a segment. device driver: the task or procedures that use knowledge of the physical characteristics of an I/O device to carry out higher-level I/O requests. direct I/O: I/O operations in which the CPU participates. dispatching: determining which task the processor should work on, and switching the processor to that task; also known as "scheduling." double fault: a fault that occurs while the processor is attempting to handle a prior fault. DS (data segment) register: one of three segment registers that provide addressability to data segments. dynamic system: an application in which tasks begin and end relatively frequently. EM (emulation mode) bit: a Boolean in the MSW that indicates to the processor whether ESC instruction processing is being emulated by software. emulation: software interpretation of instructions for a processing device (such as the 80287 Numerics Processor Extension) that is not present in the system. entry point: an executable-segment offset that identifies the starting point for execution, as when the segment is invoked via a gate. error code: a word automatically pushed on the stack as a result of certain exceptions. The error code helps identify the segment involved in the exception. ERROR: an input pin of the 80286 used by a processor extension (such as the 80287) to signal error conditions. ES (extra segment) register: one of three segment registers that provide addressability to data segments. ESC or ESCAPE instruction: an instruction (usually for a processor extension) identified by the fivebit prefix 110118: EX (external) bit: a Boolean in the error code which, when set, indicates that the exception is due to factors outside the control of the task in which the exception occurs.

Glossary-3

121960-001

GLOSSARY

exception: a processor-detected condition that requires software intervention. The iAPX 286 communicates exceptions to software by means of the interrupt mechanism. executable segment: a segment that contains processor instructions. An executable segment is identified by a specific type code in its descriptor. execute-only segment: a special case of an executable segment that the processor can access for the purpose of fetching instructions but cannot access for the purposes of reading data. An execute-only segment is identified by a Boolean in the access-rights byte of its descriptor. expand-down segment: a data segment that contains a data structure (such as a stack) that grows toward lower memory locations. An expand-down segment is identified by a Boolean in the accessrights byte of its descriptor. Offset addresses in an expand-down segment extend from the value contained in the limit field of the descriptor thru OFFFFH. exportation: a process by which a system-software interface is made available to applications and other system programs. Gates and segments providing .access to system services (such as operating-system primitives) are placed, via the Builder's export definition, into a linkable module. This module is used when building loadable tasks that depend on the exported services.
EXPORTS list: a clause of PL/M-286's extended segmentation control syntax that specifies the public

identifiers that may be referenced from outside a subsystem. external reference: a reference to an identifier that is defined as PUBLIC in another module. fault: an interrupt that results from an exception. fetch policy: the algorithm that determines which segment to bring into RAM from secondary storage and when to bring it in. first fit algorithm: a dynamic storage allocation algorithm that satisfies a request for space with the first unallocated block of storage whose size is greater than or equal to the requested size. flag: one of several Booleans maintained by the CPU, including the arithmetic flags (CF, PF, AF, ZF, SF, OF), the control flags (TF, IF, DF), and the nested task flag (NT). flag word: a 16-bit register of the 80286 that contains the arithmetic flags, the control flags, the nested task flag, and the IOPL. The processor saves the flag word in the TSS with each task switch and loads the flag word from the TSS of the next task, thereby enabling each task to use the flags without interference from other tasks. fragmentation: a condition resulting from some dynamic storage-allocation algorithms, in which unallocated storage is dispersed in many small areas. gate: a gate descriptor. gate descriptor: a descriptor that defines a protected entry point to an executable segment or task.
GDT register: a register of the 80286 that contains the base address and limit of the ODT.

global descriptor table (GDT): the descriptor table that contains descriptors that can be used by every task in the system. There is only one ODT per processor.

Glossary-4

121960-001

GLOSSARY

handler table: a table of selectors to call gates that identify the procedures for servicing asynchronous events such as interrupts or software signals. A handler table is used by an operating system's interrupt distributor and signalling primitives. I bit: a Boolean in the error code which, when set, indicates that index portion of the error code points to an entry in the lOT. iAPX 286 Binder: an iAPX 286 program development utility used to link modules, combine segments, and create a single-task, loadable output module. iAPX 286 System Builder: the configuration utility for iAPX 286 protected-mode systems. IDT register: an 80286 register that stores the base address and limit of the lOT. index: the field of a selector that identifies a slot in a descriptor table. indirect I/O: a style of I/O interface in which I/O operations are executed by an independent processor, not by the CPU. interrupt: I) the electrical or logical signal that an event has occurred; 2) the mechanism by which a computer system responds quickly to events that occur at unpredictable times. interrupt controller: a device (such as Intel's 8259A Programmable Interrupt Controller) that assists the CPU in responding to mUltiple external interrupt signals by performing such functions as detection, priority resolution, and identification. interrupt descriptor table (IDT): a descriptor table that contains gates to the handler procedures or handler tasks for interrupts and traps. The lOT may contain only interrupt gates, trap gates, and task gates. interrupt distributor: an operating-system interrupt procedure that transfers control to a task-defined procedure for servicing the interrupt. interrupt-enable flag (IF): a control flag of the 80286 that determines whether the processor responds to external interrupt signals presented at the processor's INTR pin. interrupt gate: a gate that identifies the entry point of a procedure for handling an interrupt. When an interrupt transfers control through an interrupt gate, the processor resets the interrupt-enable flag. Interrupt gates are valid only in the lOT. interrupt handler: a procedure or task that is invoked by an interrupt. interrupt latency: the time from the occurrence of an interrupt signal to the execution of the first instruction of an interrupt handler. interrupt procedure: an interrupt handler that is identified by an interrupt gate or trap gate. An interrupt procedure runs in the interrupted task. interrupt task: an interrupt handler that is identified by a task gate and runs as a task separate from the interrupted task. interrupt vectoring: the mapping from an interrupt source to the interrupt handler. In the iAPX 286 architecture, the 8259A and the lOT are components of the interrupt vectoring process.

Glossary-5

121960-001

GLOSSARY

intersegment reference: a reference to a location in a segment other than the segment containing the reference. intrasegment reference: a reference to a location in the same segment as the segment containing the reference. interlevel reference: an intersegment reference to a segment that has a different privilege level than that of the segment containing the reference. intertask transfer: a transfer of control flow to a task other that the current task. I/O-mapped I/O: a style of I/O interface in which I/O devices respond to addresses in an address space that is distinct from the memory address space. Special I/O instructions (IN, INS, OUT, OUTS) trigger I/O operations. The 80286 uses the M/IO pin to distinguish memory addresses from I/O addresses. I/O privilege level (IOPL): a two-bit item in the flag register of the 80286 that controls the current task's right to execute the I/O-related instructions IN, INS, OUT, OUTS, eLI, STI, LOCK. A procedure may not execute any of these instructions if CPL> 10PL. I/O subsystem: the portion of an operating system that deals with filing and I/O. IP (instruction pointer): an 80286 register that contains the offset of the instruction to be executed within the current code segment. kernel: that portion of an operating system that implements the most primitive of its functions. LDT register: an 80286 register that stores the selector, base address, and limit of the current LDT. limit: the field of a descriptor that defines the offset of the last byte of the segment. linkable module: an object module created by iAPX 286 translators, by the Binder, or by the Builder that can serve as input to either the Builder or the Binder. A linkable module requires further processing before it can be executed. linking: the process of combining segments from one or more input modules and resolving references between modules. The Binder provides linking services for iAPX 286 program development. loadable module: an executable object module (usually created by the Builder or the Binder) that has a format suitable for processing by a loader running under control of an operating system. loader: the task or procedures of an operating system that places an object module in RAM and prepares it for execution by the operating system and the processor. load-time: at the time a task is loaded. local descriptor table (LDT): the descriptor table that contains descriptors that are (generally) private to a given task. Each task may have an LDT. A task can use only descriptors that are in its LDT or in the GDT. The LDT protects tasks from one another. logical segment: the representation of a segment used by translators and program development utilities prior to the time when the segment is actually placed in physical memory.

Glossary-6

121960-001

inter

GLOSSARY

machine status word (MSW): an 80286 register that includes the TS, EM, MP, and PE Booleans. These items are global to the system and are not a part of the task state. mailbox: a software mechanism for sending messages between tasks. The mechanism consists of two queues: one a queue of undelivered messages, the other a queue of tasks waiting for messages. Messages are delivered in FIFO order. memory management: the set of operating system functions that deal with the allocation of RAM to tasks. memory-mapped I/O: a style of I/O interface in which I/O devices respond to specific addresses in the memory address space. I/O operations are triggered by standard instructions that read from, and write to, memory locations. message: a unit of intertask communication. module: a compilation unit or a combination of compilation units. MP (math present) flag: a Boolean in the MSW that indicates whether a processor extension (such as the 80287 Numerics Processor Extension) is present. mutual exclusion: preventing two critical sections from executing concurrently. multiprocessing: using more than one CPU to execute a multitasking system. multitasking: the capability to support more than one task either simultaneously (by using more than one CPU) or virtually simultaneously (by multiplexing one CPU among several tasks). nested task (NT) flag: a Boolean in the flag word that indicates the existence of a back link field in the TSS to a previous TSS. non-maskable interrupt (NMI): an external interrupt presented to the NMI pin of the 80286 that the processor does not ignore, even when IF is reset. not-present segment: a segment whose descriptor has the present bit reset. In a virtual-memory system, this condition normally indicates that the segment has been evicted from RAM to make space for other segments. nucleus: see kernel. nullify: assign a null value to. numerics processor extension (NPX): the 80287 processor which cooperates with the 80286 CPU to extend its processing power in mathematical applications. object module format (OMF): a standard for the structure of object code files. OF (overflow) flag: an arithmetic flag that indicates when a signed operation produces a positive number that is too large or a negative number that is too small to fit in the destination operand. offset: the address of a location within a segment, expressed as a quantity to be added to the base address of the segment.

Glossary-7

121960-001

GLOSSARY

outward call: the attempt to call a procedure in another segment whose DPL is numerically greater than CPL. parallel table: a table whose entries have a one-to-one correspondence with the entries of a descriptor table, used to associate additional information with each descriptor. parallelism: concurrent execution of two or more tasks or devices. parameter validation: checking the attributes of parameters passed between procedures at different privilege levels to prevent protection violations or to detect exception conditions. PE bit: a Boolean in the MSW that indicates whether the 80286 is running in real-address mode or in protected, virtual-address mode. Petri net graph: a notation for visualizing Petri nets. Petri nets are a mathematical tool for modeling systems, first proposed by Dr. Carl Adam Petri in 1962. physical address: a 24-bit address, such as that used as a base address, capable of encompassing the entire address space of the 80286. physical segment: a segment as viewed by the processor, to be distinguished from "logical segment." PIC: programmable interrupt controller. See interrupt controller. pipes: a mechanism for intertask communication used in the UNIX operating system. Each task views a communication channel as a file and uses READ and WRITE operations to receive and send messages. placement policy: the algorithm for determining where in RAM to locate a segment. pointer: an item that specifies a memory location. A full or long pointer includes a selector, which indirectly chooses a segment base address, and an offset value, which points to a specific address within that segment. An offset by itself is called a short pointer. preemption: a dispatching process in which the operating system switches to another task 'even though the current task has not requested any function that would cause it to wait. The operating system may preempt one task in order to give other tasks a share of CPU attention. '', prefix: one of several instruction codes that modify the function or the environment of the following instruction. iAPX 286 prefixes include the LOCK prefix, repeat prefixes, segment-override prefixes, and the ESCAPE prefix. present bit: a Boolean in a segment descriptor that indicates whether the segment is actuallly present in RAM. In a virtual-memory system, the segment may have been evicted from RAM to create space for another segment. primitive: one of the operating-system operations made accessible to applications by some explicit mechanism. In the iAPX 286 architecture, primitives are typically procedures with call gates in the GOT or LOTs. privilege: the right to access certain portions of memory or to execute certain processor instructions. privilege level (PL): a measure of privilege. In the iAPX 286 architecture, privilege is measured by integers in the range 0-3, where 0 is the most privileged and 3 the least.

Glossary-8

121960-001

GLOSSARY

privileged instruction: an instruction that can be executed only by a procedure running at privilege level o. Privileged instructions include CL TS, HL T, LGDT, LIDT, LLDT, LMSW, and LTR. processor extension: an optional, special-purpose processor (such as the 80287) that runs in parallel with the 80286 and extends its processing power. profiler: a procedure or task that collects data about segment usage. protected, virtual-address mode: the mode of operation of the 80286 that provides virtual-memory addressing and memory protection. protection: a mechanism that limits or prevents access to areas of memory or to public: a symbol available for intermodule reference. readable segment: an executable segment that can be read. It is necessary to read from an executable segment if that segment contains constants. A readable segment is identified by a Boolean in the access rights byte of its descriptor. read-only segment: a data segment that cannot be written to. A read-only segment is identified by a Boolean in the access rights byte of its descriptor. real-address mode: the mode of operation of the 80286 that provides greatest compatability with the 8086, without protection and virtual memory addressing. real memory: the physical memory, as distinguished from virtual memory. real-time system: a system that responds to external events in a relatively short time, as contrasted with a batch system. region: a mechanism for providing mutual exclusion among critical sections. A region is similar to a semaphore that has the additional properties that I) only the task that acquires a region can release it, and 2) a task cannot be suspended while holding aregion. relocation: changing the physical location of a segment. replacement policy: the algorithm that determines when to remove segments from RAM and which segments to remove when space is (or is likely to be) needed for another segment. resolving reference: see binding. requested privilege level (RPL): the privilege-level field of a selector. A procedure may request a numerically greater privilege level for use of a segment by placing the desired privilege level in the RPL field of the selector that identifies that segment. run-time: the time a task executes. scheduler queue segment: a segment that contains one or more of the task queues used by a scheduler. Keeping a queue in one segment may reduce the time for searching the queue. scheduling: see dispatching. scheduling mode: one of two styles of scheduling a task: hardware- (interrupt-) scheduled mode or software-scheduled mode.
instru~tions.

Glossary-9

121960-001

GLOSSARY

scheduling state: one of several conditions that affect the way a task is treated by the scheduler. A task may be ready to execute, executing, waiting for some event, etc. secondary storage: a slower, less expensive storage medium than RAM (for example, disk). segment: a variable-length area of contiguous memory addresses not exceeding 64K bytes. segment register: one of four 80286 registers that hold addressing information for the segments that are currently addressable by a task. The segment registers are CS (code segment), DS (data segment), ES (extra segment), and SS (stack segment). selector: an item that identifies a descriptor by the location of the descriptor in a descriptor table. semaphore: a synchronization mechanism that communicates the occurrence of an event between two (or more) tasks via a shared memory loca,tion. send privilege level(SPL): a software-implemented measure of the right to send or delete a segment. shadow task: a duplicate task used to enable the operating system to perform an outward call. signal: a mechanism for permitting one task to communicate the occurence of an event to another task that is not waiting for the event to occur. single step: a mode of execution that permits intervention between each instruction; used primarily as a debugging aid. slot: an entry in a descriptor table. SS (stack segment) register: the segment register that provides addressability to the current stack segment. stack segment: a segment used by the processor to hold return addresses, dynamic data, temporary data, and parameters. For greatest protection, each privilege level of a task may have its own stack. Stack segments usually expand downward. static system: an application in which the mix of tasks does not change over time. subsystem: in PL/M-286, a collection of tightly-coupled, logically-related modules that obey the same model of segmentation. swap space: the secondary storage area used to contain segments that have been removed from RAM. swapping: in a virtual-memory system, the process of moving segments between RAM and secondary storage. swapping manager: a procedure or task responsible for swapping. synchronization: imposition of an order on the occurrence of certain events. system segment: a segment containing a descriptor table or task state. table indicator (TI): a Boolean in a selector that identifies the descriptor table to which the selector refers.

Glossary-10

121960-001

GLOSSARY

task: a single thread of execution that has an associated processor state. task database: the collection of information about a task that the operating system needs to store. task information block: a segment or part or a segment used by the operating system to contain all or part of a task database. task gate: a gate that identifies a TSS. A control transfer through a task gate causes a task switch. task register: an 80286 register that points to the TSS of the currently active task. task state segment (TSS): a segment used by the processor to store the contents of the task-variable registers, the stack-segment selectorsand pointers for the three most privileged levels, the selector for the task's local descriptor table, and a back link that may point to another task in a chain of nested task invocations. TF (single step flag): a Boolean in the flag word that, when set, indicates that the processor should cause a trap after each instruction. Typically, TF is used to facilitate debugging. thrashing: in a virtual memory system, a condition in which excessive swapping seriously degrades performance of all tasks. time-sharing system: a multi-user, multitasking system in which processors are multiplexed among users. time slice: the time interval for which the CPU is allocated to a task. translator: an assembler or compiler. trap: an interrupt due to an exception condition. trap gate: a gate that identifies the procedure to handle a trap. An interrupt through a trap gate differs from an interrupt through an interrupt gate in that, with a trap gate, interrupts are not disabled upon entry into the procedure. Trap gates are valid only in the IDT. Trojan horse: a type of protection violation in which a procedure passes a selector that it has no right to use to a more privileged procedure that does have the right to use it. trusted instruction: one of a set of I/O-related instructions that cannot be executed unless CPL is less than or equal to IOPL. The trusted instructions are CLI, STI, IN, INS, OUT, OUTS, and LOCK. type code: a value in a descriptor that specifies the intended use of a segment. The processor interprets the type code to ensure that segments are used only as intended. type extension code: a software extension to the type code concept that includes usages recognized by the operating system. UDI (Universal Development Interface): an Intel standard for interfaces to operating-system services. usage privilege level (UPL): a software-defined measure of the right to use an operating-system object. vectoring: see interrupt vectoring.

Glossary-11

121960-001

GLOSSARY

virtual address: an address that consists of a selector and an offset value. The selector chooses a descriptor for a segment; the offset provides an index into the selected segment. virtual address space: The set of all possible virtual addresses that a task can access, as defined by the GDT and the task's LDT. The maximum possible virtual address space for one task is one gigabyte. virtual memory: a style of memory management that permits the virtual address space to exceed the physical address space of RAM. With the help of processor features, the operating system simulates the virtual address space by using secondary storage to hold the overflow from RAM. word count: a field of a gate descriptor that specifies the number of words of parameters to be copied from the calling procedure's stack to the stack of the called procedure. writable segment: a data segment that can be written to. A writable segment is identified by a ~oolean in its descriptor. XOS (Example Operating System): an imaginary operating system, portions of which are used in this book as examples.

Glossary-12

121960-001

INDEX
8089 I/O processor, 8-1 8254 Programmable Interval Timer (PIT), 4-5, 4-9,4-13 8259A Programmable Interrupt Controller (PIC), 4-6, 6-1, 6-6, 7-6 80287 Numerics Processor Extension (NPX), 1-7, 7-4, 7-5, 7-8, Chapter 12 access rights (field of descriptor), 2-21, 2-22, 9-2,11-5,11-10,13-1,13-2,13-4 accessed bit, 2-7, 5-3, 9-1, 9-4, 9-5, 9-7, 10-2 ADC,7-8 addressing mechanism, 2-1 ADJUST$RPL, 2-16, 13-2 alias, 2-17 thru 2-22, 3-2, 4-10, 4-12, Chapter 5, 6-5, 8-2, 9-3, 9-7, 10-3, 11-2, 11-9, 13-5 ARPL, 2-16, 13-2 thru 13-4 ASM286, 3-6, 4-13, 11-4, 13-2 ASSUME, 11-4 asynchronous execution, 1-6 back link (of TSS), 4-1 thru 4-4, 4-7,4-13,7-5, 7-6, 10-2, 11-10 base address, 2-4, 2-15, 4-1, 5-3, 9-3, 9-5, 10-3, 11-3, 11-10, 11-11 binding, 1-8, 2-8, 2-9, Chapter 11 Binder, see iAPX 286 Binder bootloadable, see module, bootloadable BOUND, 7-4 bound check exception, 7-4 boundary tags, 3-2, 3-5, 3-6, 9-3 breakpoint, 2-17, 7-3 buffer, 2-18, 3-1, 3-10, 5-10, 8-1, 8-3, 8-5, 8-7, 9-2,9-4 Builder, see iAPX 286 System Builder BUSY / pin, 12-2, 12-3 busy task, 4-3, 4-4, 7-7 CALL, 2-7,2-9,.2-10,4-2 thru 4-4, 4-13, 4-17, 6-1, 6-2, 6-4, 6-6, 7-5 thru 7-7, 11-3 carry flag (CF), 7-8 CLI, 4-6, 4-7, 5-6, 6-2, 8-2 CLTS, 12-2, 12-4 CMPS, 7-7 combine type, 11-4 COMPACT, 11-4,,11-5 compaction, 3-10 compiler control statements, 11-4 conforming segment, 2-5, 6-2, 6-7, 6-8 critica1 section, 5-5 thru 5-7, 12-4 CS register, 4-4,6-9, 7-5 thru 7-7, 9-1, 9-6, 9-7, 10-1, 11-3, 11-9, 12-5 current privilege level (CPL), 2-11, 2-16, 4-6, 5-6, 6-2, 6-7, 6-8, 8-2, 10-1, 10-2, 13-3 deadlock, 5-7, 5-10 debugger, 2-17, 7-3, 11-3, 11-10 deletion of segment, 2-20, 5-2, 5-3, 8-3, 9-5, 13-1 of descriptor, 13-5 DESCRP section, 11-11, 11-12 descriptor, 2-2, 2-12, 11-6, 11-9 data segment, 2-2, 2-3, 2-6, 2-14, 2-15, 2-18, 7-7, 9-3 thru 9-5, 9-7 dynamic creation, 3-1, 3-2 executable segment, 2-2, 2-4, 2-6, 2-7, 2-14, 2-15,2-17,6-7,7-7,9-7 gate, 2-2, 2-7 thru 2-11, 2-15, 6-2, 7-6, 9-1, 9-2, 10-2, 11-3, 11-9 system segment, 2-2, 2-5 descriptor privilege level (DPL), 2-3, 2-6, 2-9, 2-11,2-15,2-20,2-21,4-3,5-7,6-7, 6-8, 8-2~ 8-5, 8-7 descriptor table, 2-2, 2-12, 2-15 see also global descriptor table, local -descriptor table, interrupt descriptor table DESNAM section, 11-11 device drivers, 5-17, 8-1, 8-2, 8-4, 8-7, 9-2, 9-4, 11-2,11-4 DI register, 7-7 DISABLE, 6-2, 6-4, 7-1 dispatching, 4-9, 4-13, 5-7, 9-5, 11-4 divide error exception, 6-7, 7-3 double fault, 7-5, 9-2, 9-4 DPL, see descriptor privilege level DS register, 2-17, 2-18, 2-21, 4-12,7-5 thru 7-7, 9-1,9-6,9-7, 10-1 dynamic system, 1-7 thru 1-10,2-2,2-3, 2-12, 2-18 thru 2-20, 2-22, 3-1, 4-4, 5-7, 6-5, 11-8 effective privilege level, 2-16 EM (emulation mode) flag, 7-4, 7-8, 12-1 thru 12-3 emulation, 7-8, 12-1, 12-4 ENABLE, 6-2 ENTER,7-6 ENTRY, 11-6 EPROM,10-3 ERROR/ pin, 7-8, 12-1 thru 12-3, 12-5 error code, 7-1, 7-2, 7-5 thru 7-7, 7-9, 9-2, 9-3, 12-5

Index-1

121960-001

INDEX

ES register, 2-17,2-18,2-21,2-22,4-12,7-5 thru 7-7, 9-1, 9-6, 9-7,10-1 ESCAPE instructions, 7-4, 12-1 thru 12-5 EX (external) bit, 7-2 examples, 2-20 thru 2-26,3-1 thru 3-9, 3-15 thru 3-21,4-15,5-8,5-9,5-13 thru 5-16, 10-3 thru 10-15, 11-6 thru 11-8, 11-12 thru 11-28 exception, 1-7,2-8,2-10,2-17,4-3,4-7,5-5,6-2, 6-4,6-9, Chapter 7, 9-1,11-3,13-3,13-5 handler, 6-7, Chapter 7, 9-2, 9-4, 11-3, 12-4, 12-5 recovery, Chapter 7, 12-3 thru 12-5 EXECUTE, 11-9 execute-only segment, 7-7, 13-4 expand-down segment, 2-5,11-11, 13-4 expansion direction, 2-5, 5-3 EXPORT, 11-6 export module, 11-6, 11-12, 11-13 exports list, 11-4, 11-5 extended segmentation controls, 11-4 EXTERNAL, 3-6

global descriptor table (GOT), 1-3,2-12, 2-14 thru 2-19, 2-22, 3-3, 3-4, 3-7, 3-8, 4-1, 4-3, 4-10 thru 4-12,5-1,5-7,5-10,6-7,7-2,8-7, 10-2,10-3,11-2,11-4,11-5,11-9 thru 11-12, 13-5 handler table, 6-7 hashing algorithm, 5-3 I bit (of error code), 7-2 iAPX 286 Binder, 1-10, 11-3, 11-5, 11-6, 11-10, 11-11 iAPX 286 System Builder, 1-8 thru 1-11, 2-2, 2-4, 2-12, 2-18, 3-1, 3-6; 8-2, 10-3, 11-3 thru 11-6, 11-8, 11-10, 11-11 iAPX 386, 2-3 identifier, 5-7, 5-10, 8-7 see also interrupt identifier lOT, see interrupt descriptor table lOT register, 2-15, 6-2 IF (interrupt-enable) flag, 4-6, 5-"6, 6-2, 6-4 index field (of selector), 2-16, 2-17, 5-3, 7-2 INIT$REAL$MATH$UNIT,12-2 initialization of 80287, 12-2 see also system initialization input/output (1/0),1-4 thru 1-7,2-18,4-5,4-7, 4-10, 5-10, Chapter 8, 9-2, 9-4, 9-8, 11-2, 11-4, 11-9 indirect, 8-3 memory-mapped, 8-2 IN,8-1 INS, 7-7, 8-1 INT, 2-7, 2-10, 2-15,4-3,6-1,6-2,7-3 INTA cycles, 2-15 INTO, 6-1, 6-2, 7-3 INTR pin, 6-1, 6-2, 6-6 interrupt, 1-4, 1-7, 2-10, 2-15, 2-21, 4-3, 5-4 thru 5-6, Chapter 6,7-1,7-6,7-7,8-4,10-1, 10-2 distribution, 6-7 thru 6-9 flag, see IF identifier, 2-15, 6-1, 6-2 handler, 2-15, 2-18, 4-6 latency, see interrupt response time mask, 4-7, 12-4 procedure, 4-4,4-7,4-11,4-13,6-2,6-4 thru 6-7,7-1,12-4 response time, 4-3,5-5,6-5, 12-4 scheduled task, see scheduling software, 6-1 task, 4-4, 4-7, 6-2, 6-4 thru 6-6, 7-1, 7-6, 9-4, 12-4, 13-5 interrupt descriptor table (lOT), 2-12, 2-15, 2-16,2-18,4-3,4-5,4-7,6-2,6-4,6-5,6-7, 7-2, 7-5, 10-2, 10-3, 11-11
Index-2

FAR, 11-4 fault, see exception FINIT,12-5 "first fit" algorithm, 3-1, 3-2 flag word, 4-2 thru 4-4, 6-2, 6-4, 8-1, 8-2, 10-1 FNINIT, 12-2, 12-5 FORK,I1-9 fragmentation, 3-1, 3-2, 9-6 FRSTOR, 12-4 FSA VE, 12-4, 12-5 FSETPM, 12-2, 12-5

gate, 2-8, 2-11, 11-6 call, 2-8, 2-10, 2-12, 2-14, 2-15, 2-21, 3-9, 4-13, 5-7, 5-12, .6-1, 6-2, 8-7, 11-3, 11-12, 11-14 interrupt, 2-8, 2-15, 6-2, 6-4, 6-7 name, 11-6 task, 2-8, 2-14, 2-15, 4-3, 4-7, 6-2, 6-4, 7-5, 10-3 trap, 2-8, 2-15, 6-2, 6-4, 6-7 see also descriptor, gate GATE,11-6 GOT, see global descriptor table GOT register, 2-15, 10-2 general protection exception, 7-7, 8-2 GET$ACCESS$RIGHTS, 13-2 GET$SEGMENT$LIMIT,3-6, 13-2

121960-001

inter

INDEX

"invalid TSS" exception, 7-5 thru 7-7, 9-2, 9-5 IOPL % privilege level), 4-6,5-6, 8-1, 8-2, 8-5 IP register, 4-4, 6-9, 7-1, 7-3,7-5,7-7,10-1, 11-9, 12-4, 12-5 IRET, 2-7, 2-10, 4-3, 4-4, 4-13, 6-4, 6-6, 6-7, 6-9, 7-3, 7-5, 7-7, 8-2, 12-5 JMP, 2-5, 2-7, 2-9, 2-10, 4-3, 4-4, 4-13, 7-7, 10-1, 10-3 LABEL, 11-4 LAR, 9-7, 13-2, 13-4 LARGE,II-4 LDT, see local descriptor table LOT register, 2-14, 4-3, 7-6, 9-1 LDT selector (ofTSS), 4-1, 4-3, 6-9, 7-5, 10-2, 11-11 LEAVE,7-6 LGDT,2-15 LIDT, 2-15,6-2 limit field (of descriptor), 2-4, 2-5, 2-12, 2-15, 2-16,4-1, 5-3, 7-5 thru 7-7, 9-5, 10-1, 10-3, 11-11,12-4,13-2,13-4 linkage, 1-10, 7-6 LLDT, 2-14, 7-6 LMSW, 10-1, 12-1 loading, see program loading local descriptor table (LDT), 2-5, 2-12, 2-14, 2-16,2-18 thru 2-20, 3-1,4-10, 5-1 thru 5-3, 5-10,5-17,6-7,7-2,8-7,9-3,9-4,9-7,10-2, 10-3, 11-2, 11-4, 11-5, 11-8 thru 11-12 not present, 9-1, 9-2 LOCAL$TABLE, 2-14 LOCK,8-2 LODTXT section, 11-11, 11-12 logical segment, 1-1, 11-2 thru 11-5 LSL, 9-7, 13-2, 13-4 LTR, 4-1, 9-1 MACHINE$STATUS, 12-1 mailbox, 5-10 thru 5-12, 5-16, 5-17, 8-7, 9-3, 9-5, 11-2, 13-1, 13-4, 13-5 mechanisms, see policies and mechanisms memory management real, 1-8, 1-9,2-22, Chapter 3, 5-4, 5-12, 5-17, 8-3, 8-5, 11-6 virtual, 1-8,2-2,2-3, 2-7, 7-6, Chapter 9, 11-9 message, 2-19, 3-9, 4-9, 5-4, 5-10, 5-12, 5-16 module, 11-1 thru 11-6 bootloadable, 11-6, 11-10 linkable, 11-6, 11-10 loadable, 1-10, 11-10, 11-11, 11-14 object, 1-8, 1-9, 11-9, 11-10

MOV,7-6 MOVS,7-7 MP (math present) flag, 7-4, 12-1 thru 12-4 MSW (machine status word), 7-4, 7-8, 10-1, 12-1, 12-2 multiprocessor systems, 3-10 mutual exclusion, 5-5, 5-6 naming, 11-1 thru 11-6, 11-11, 11-12, 13-1, 13-2, 13-4, 13-5 NEAR,11-4 NMI (non-maskable interrupt), 6-1, 6-2, 10-2 NOT PRESENT statement, 11-12 "not present" exception, 7-5 thru 7-7,9-1, 9-3 thru 9-8, 11-3 see also present bit NT (nested task) flag, 4-2 thru 4-4, 4-7, 7-6, 9-4, 11-10 Numerics Processor Extension (NPX), see 80287 OBJECT, 11-6 object module format (OMF), 11-8, 11-10, 11-11 OF (overflow) flag, 7-3 OUT,8-2 OUTS, 7-7, 8-2 outward call, 6-8 overflow exception, 7-3 paged architecture, 9-6 parallel table, 5-3, 13-1 parallelism, 1-4, 8-4, 8-7 PE (protection enable) flag, 10-1 Petri net graph, 8-4, 8-5 physical address, 1-8, 1-9, 2-4, 3-2 thru 3-4, 11-10 , physical segment, 1-1, 1-2, 2-12, 2-15, 11-1 thru 11-3 PIC, see 8259A Programmable Interrupt Controller pipes, 5-17 PL/M-286, 2-14 thru 2-16,2-21, 2-22, 3-3, 3-6, 4-1,4-3,4-13,6-2, 11-4, 11-6, 12-2, 12-4, 13-2 pointer parameters, see selector parameters policies and mechanisms scheduling, 4-9, 4-10 virtual memory management, 9-1, 9-6 POP, 7-6 POPA,7-7 POPF,8-2 preemption, 4-5,4-7,4-9,4-10,4-13 prefix, 7-1

.lndex-3

121960-001

INDEX

present bit, 2-2, 2-3, 2-9, 5-3, 7-5, 7-6, 9-1 thru 9-5, 11-12 primitives, 11-3, 11-4, 11-6, 11-12, 11-14, 13-4 priority, 2-19, 4-6, 4-7, 4-9, 4-10, 6-6, 6-7 privilege level, 1-3, 1-4, 1-8, 2-6, 2-7 thru 2-11, 2-15,2-18,2-20,2-21,3-8,3-9,4-1,4-2,4-9, 4-12,4-13,5-2,5-7,5-10,5-12,6-2,6-3,6-5, 6-8,8-2, 8-3, 8-7, 9-3, 9-7, 11-2, 11-6, 11-9, 11-10, 12-2, 12-4, 13 .. 1, 13-2, 13-4, 13-5 PROC, 11-4 "processor extension error" exception, 7-8, 12-5 "processor extension not available" exception, 7-4, 12-3, 12-4 "processor extension segment overrun" exception, 7-5, 12-4, 12-5 profiling, 9-7, 9-8 program loading, 1-8, 1-10, 2-3, 2-4, 3-1, 6-5, Chapter 11 bootstrap, 1-9, 11-10 protected, virtual-address mode, 10-1, 10-2, 12-2 protection, 1-3 thru 1-5, 1-9, Chapter 2, 3-1, 3-7, 4-3, 4-4, 4-6, 5-1, 5-4, 5-7, 5-10, 6-2, 6-3, 6-5,6-6,7-3, 8-1 thru 8-4, 8-7, Chapter 13 violation, 6-4, 6-9, 7-7 PUBLIC, 3-2, 3-6, 3-8, 3-9, 10-3, 11-3, 11-6 PUSH,7-6 PUSHA,7-7 RCL, RCR, 7-8 readable segment, 2-7 read-only segment, 7-7 real address mode, 10-1, 10-2 real memory management, see memory management, real recovery, see exceptions region, 5-10, 9-4, 9-5 REP, REPE, REPNE, 7-7 requested privilege level (RPL), 2-11, 2-16, 7-2, 13-2 thru 13-4 RESERVE,3-6, 11-6 reserved word (of descriptor), 2-3, 2-22 RESET, 10-1, 10-3 RESTORE$GLOBAL$TABLE,2-15 RESTORE$INTERRUPT$TABLE, 2-15 RESTORE$REAL$STATUS, 12-4 return pointer, 6-2, Chapter 7, 12-4, 13-3 return link, see return pointer return address, see return pointer relocation (of segment), 2-4, 2-20, 5-2, 5-3, 5-12, 8-3 RET, 2-7, 2-9, 2-10, 4-3, 11-5 RETURN, 11-5 ROM, 10-1 RPL, see requested privilege level

SAVE$GLOBAL$TABLE,2-15 SAVE$INTERRUPT$TABLE,2-15 SA VE$REAL$STATUS, 12-4 SBB,7-8 SCAS,7-7 scheduling, 2-19, 4-11, 5-12, 9-5 hardware, see scheduling, interrupt interrupt, 4-6, 4-7, 4-9, 6-1, 6-5, 6-6, 8-7 queues, 4-12, 4-13, 9-4, 11-10, 11-14 software, 4-7, 4-9, 6-1, 6-5, 6-6, 7-6 state, 4-5 thru 4-7, 4-10 SEGMENT, 11-4, 11-6 segment, see logical segment, physical segment segment limit, see limit field segmented architecture, 9-6 SEGMENT$READABLE, SEGMENT$WRITABLE,13-2 selector, 2-1,2-2,2-8,2-9,2-15,2-16,3-6,4-1, 4-3,5-7,7-6,7-7,11-12,13-1 parameters, 2-16, 13-1 thru 13-4 null, 2-15, 2-17, 7-7 SELECTOR$OF, 3-6 semaphore, 5-6, 5-7, 5-10, 5-16, 9-4, 9-5, 11-2, 12-4, 13-1, 13-4, 13-5 send privilege level (SPL), 13-5 SGDT,2-15 shadow task, 6-8, 6-9 sharing (of segments), 2-14, 2-15, 2-19, 2-20, 2-22,4-4, Chapter 5, 8-7, 9-5,11-2,11-4, 13-1, 13-4, 13-5 shutdown, 7-5, 10-2 SI register, 7-7 SIDT, 2-15, 6-2 signal, 4-5, 5-7, 5-10, Chapter 6 single-step flag (TF), 6-2, 7-3 SLDT, 2-14, 9-7 slot, 2-20, 2-22, 2-26, 5- 10, 11-6, 11-14, 13-5 SMALL, 11-4 SMSW,12-1 SP register, 4-2, 4-12, 7-6 SPL, see send privilege level SS register, 4-2, 4-12, 7-5 thru 7-7, 9-2, 9-6, 10-1 stack, 2-5, 2-8, 3-1, 4-12, 6-2, 6-4, 7-1, 7-2, 7-6, 7-7,9-3,9-4,9-7, 10-2, 11-6, 11-9 thru 11-11,13-4 initial, 4-2, 4-3, 11-6 overflow, 7-5,7-7 exception, 7-5 thru 7-7, 9~2 static system, 1-7, 1-9, 1-10,2-3,2-19,3-1,4-4, 6-4,11-9 STI, 4-6, 4-7, 5-6, 6-2, 8-2 STOS,7-7 STR, 4-1, 4-7, 4-11

Index-4

121960-001

INDEX

subsystem, 11-4 swapping, 5-12, 8-3, 9-2 thru 9-4, 9-8 synchronization, 2-22, 3-8, 3-9, Chapter 5, 8-4, 8-6, 12-2, 13-4, 13-5 system initialization, 6-5, 6-6, Chapter 10 TABLE,II-6 table indicator (TI), 2-16, 2-17, 7-2 task, 1-1 creation, 2-2, 2-18, 3-1, 5-12, 6-9, 11-9 database (TDB), 4-11,5-12,9-4, 11-9, 11-10, 12-3, 12-4 management, Chapter 4 state, 4-1, 10-2, 12-3 switching, 2-14, 4-1, 4-3, 4-4, 4-9, 5-6, 6-2, 7-5 thru 7-7, 8-2, 9-4, 9-5, 10-2, 11-9, 12-2 thru 12-4 TASK,II-6 task register (TR), 4-1, 4-2, 4-4, 9-1, 10-2 task state segment (TSS), 2-5, 2-14, 2-18, 3-1, 4-1 thru 4-4, 4-10 thru 4-13,5-1,6-2,6-4, 6-9,7-1,7-5,7-7,8-2,9-1,9-4 thru 9-7, 10-2, 10-3, 10-5, 11-6, 11-8 thru 11-12, 11-14 T ASK$REG ISTER, 4-1 TDB, see task database termination (of task), 6-9, 7-1, 7-5, 12-5 TF, see single-step flag

thrashing, 9-8 TI, see table indicator time slice, 4-5, 4-9 thru 4-11 timer, see 8254 Programmable Interval Timer TS (task switched) flag, 7-4, 12-1 thru 12-4 TSS, see task state segment type field of descriptor, 2-5, 2-17, 2-18, 2-20, 2-21, 4-3, 4-4, 6-2, 9-3, 11-10, 11-14, 13-1 extended, 13-1, 13-2, 13-5 UDI (Universal Development Interface), 8-1 "undefined opcode" exception, 7-4 . UNIX, 11-9 usage privilege level (UPL), 8-7, 13-4, 13-5 vectoring, 6-1, 6-3, 7-1 VERR, VER W, 13-2, 13-4 virtual memory, see memory management, virtual WAIT, 7-4, 7-8,12-1 thru 12-5 W AIT$FOR$INTERRUPT, 4-3 word count, 2-8 writable data segment, 2-6, 9-5, 11-10, 11-14, 13-1, 13-4 XOS, 11-1, 11-2, 11-4, 11-6

Index-5

121960-001

inter
ALAIIAMA
Intel Corp, 303 Williams Avenue. S.W. SUIte 1422 HuntsvIlle 35801 Tel: (205) 533-9353 ARIZONA Intel Corp 11225 N. 28th Drive SUIte 2140 Phoenl, 85029 Tel: (802) 869-4980 CALIFORNIA Intel Corp 1010 Hurley Way SUIte 300 Sacramento 95825 Tol: (916) 9294078 Intel Corp 7870 Opportunity Road SUIte 135 San DIego 92111 Tol: (714) 268-3583 Intel Corp.' 2000 East 4th Street SUIte 100 Santa Ana 92705 Tel (819) 8359&42 TWX: 910-595-1114 Intel Corp.' 1350 Shorebird Way Mt. VIew 94043 Tel: (415) 968-8086 TWX: 910-339-9279 910-338-0255 Intel Corp.' 5530 Corbin Avenue SUIte 120 Tarzana 91356 Tel: (213) 708-0333 TWX: 910-495-2045 COLORADO Intel Corp. 4445 Northpark Drive SUIte 100 Colorado Springs 80907 Tel: (303) 594-6622 Intel Corp.' 850 S. Cherry Street Suite 720 Denver 80222 Tel: (3031321-8086 TWX: 910-931-2289 CONNECTICUT Intel Corp.
36 Padanaram Aoad

u.s. SALES OFFICES


GEORGIA Intel Corp. 3300 Holcombe Bridge Road SUIte 225 Norcross 30092 Tel: (4041449-0541 ILLINOIS Intel Corp.' 2550 Golf Road, SUIte 815 Roiling Meadows 60008 Tel: (312) 981-7200 TWX: 910-651-5881 INDIANA Intel Corp. 9100 Purdue Road SUIte 400 IndIanapolIs 46268 Tel: (3171 875-0623 IOWA ImelCorp.
St. Andrews Building

NEW JERSEY Intel Corp.' Rantan Plaza III Rantan Center EdIson 08837 Tel: (20112253000 TWX. 710-480-6238 NEW MEXICO Intel Corp 1120JuanTaboN.E Albuqu.rque 87112 Tel: (50S) 292-8086 NEW YORK Intel Corp.' 300 VanderbIlt Motor Parkway Hauppauge 11768 Tel: (5161231-3300 TWX: 510-227-6236 Intel Corp. 80 WashIngton Street Poughkeepsie 12801 Tel: (9141 473-2303 TWX: 510-248-0060 Intel Corp.' 211 White Spruce Boulevard Rochester 14623 Tel: (7161424.1050 TWX: 510-253-7391 T-Squared &443 RIdings Road Syracuse 13206 Tel: (3151483-8592 TWX: 710-541-0554 T-Squared 7353 Pittsford Victor Road Victor 145&4 Tel: (716) 924-9101 TWX: 510-254-8542 NORTH CAROLINA Intel Corp. 2306 W. M.adow.... ew Road Suite 206 Greensboro 27407 Tol: (919) 294-1541 OHIO Int.1 Corp.' 6500 Poe Av.nue Dayton 45414 Tel:(513) 890-5350 TWX: 810-450-2528 Inlel Corp.' Chagrin-Brainard Bldg., No. 300 28001 Chagrin Boulevard Clev.land 44122 Tol: (21B) 464-6915 TWX: 810-427-9298 OKLAHOMA Intel Corp. 4157 S. Harvard Avenue Suite 123 Tulsa 74135 Tel: (918) 749-8688 OREGON Intel Corp. 10700 SW. Beaverton HIllsdale Highway Suite 22 Beaverton 97005 Tel: (5031 &41-8086 TWX: 910-467-8741

PENNSYLVANIA Intel Corp.' 510 Pennsylvania Avenue Fort WaShIngton 19034 Tel: (2151 &41-1000 TWX: 510-661-2077 Intel Corp.' 201 Ponn Cent.r Boulevard SUIte 301W PIttsburgh 15235 Tel: (412) 823-4970

a E.D. ElectrOniCS
300 N. York Road Halboro 19040 Tel: (215) 674-9600 TEXAS Intel Corp.' 12300 Ford Road SUIte 380 Dallas 75234 Tel: (214) 241-8087 TWX: 910-860-5617
Intel Corp.-

193051. Andrews Drive N.E. Cedar Rapids 52402 Tel: (319) 393-5510 KANSAS Intel Corp. &400 W. IIOth Street Suite 170 Overland Park 66210 Tel: (9131 &42-8080 LOUISIANA Industrial Digital Systems Corp. 2332 Severn Avenue Suite 202 Metal,,", LA 70001 Tel: (504) 831-8492 MARYLAND Intel Corp.' 7257 Parkway Drive Hanover 21076 Tel: (301) 796-7500 TWX: 710-862-1944 Intel Corp. 7833 Walker Drive Greenbelt 20770 Tel: (301) 4311200 MASSACHUSETTS Intel Corp.' 27 Indust"al Avenue Ch.lmslord 01824 Tel: (617) 256-1800 TWX: 710-343-8333 EMC Corp. 385 Elliot Str.et Newton 02164 Tel: (617) 244-4740 TWX: 922531 MICHIGAN Intel Corp.' 26500 Northwest.rn Hwy Suite 401 Southf,eld 48075 Tel: (3131353-0920 TWX: 810-244-4915 MINNESOTA Int.1 Corp. 3500 W. 60th Street SUIte 380 Bloomington 55431 T.I: (6121835-6722 TWX: 910-576-2867 MISSOURI Int.1 Corp. 4203 Earth CIty E,pressway Suite 131 Earth CIty 63045 Tel: (3141291-1990

7322 S.w. Fr.eway SUIte 1490 Houston 77074 Tel: (713) 988-8086 TWX: 910-881-2490 Indust"al DIgItal Systems Corp 5925 SovereIgn Suite 101 Houston 77036 Tel: (713) 988-9421 Intel Corp 313 E. Anderson Lane SUIte 314 Austin 78752 Tel: (512) 454-3628 UTAH Int.1 Corp. 268 West 400 South Salt Lake CIty 64101 Tel: (80t) 533-8086 VIRGINIA Intel Corp. 1803 Santa Rosa Road Suite 109 RIchmond 23288 Tel: (804) 282-5668 WASHINGTON Intel Corp. 110 IIOth Avenue N.E. SUIte 510 Bellevue 98004 Tel: (206) 453-8086 TWX: 910-443-3002 WISCONSIN Intel Corp. 450 N. Suonyslope Road Suite 130 Brook fIeld 53005 Tel: (414) 764-9060

Danbury 0681 0 Tel: (203) 792-8366 TWX: 710-456-1199 EMC Corp. 393 Center Street Wallingford 0&492 Tel: (203) 265-6991 FLORIDA Intel Corp. 1500 N. W. 62nd Street Suite 104 Ft. Lauderdale 33309 Tel: (305) 771-0600 TWX: 510-956-9407 Intel Corp. 500 N. M8I11and Suite 205 Maitland 32751 Tel: (305) 628-2393 TWX: 810-853-9219

inter
ALABAMA t Arrow ElectronIcs. Inc 3611 Memo"al Parkway So. Huntsville 35405 Tel: (205) 8822730 tHamliton/Avnet E~tronlcs 4812 CommercIal Drive NoW Huntsville 35805 Tel: (205) 8377210 TWX: 8107262162 tPloneer/Huntsville 1207 Putnam Drive NoW. Huntsville 35805 Tel: (205) 8379300 TWX: 8107262197 ARIZONA tHamilton/Avnet Electronics 505 S. MadISon Drive Tempe 85281 Tel: (602) 2315140 TWX: 9109500077 tWyle D,strobution Group 8155 N. 24th Street Phoenix 85021 Tel: (602) 2492232 TWX: 9109514282 CALIFORNIA tArrow Electronics. Inc. 521 Weddell Drive Sunnyvale 94086 Tel: (408) 7456600 TWX: 9103399371 tArrow Electronics. Inc. 19748 Dearborn Street Chatsworth 91311 Tel: (213) 7017500 TWX: 9104932086 tHamilton/Avnet Electronics 350 McCormIck Avenue Costa Mesa 92626 Tel: (714) 7546051 TWX: 9105951928 tHamilton/Avnet Electronics 19515 So. Vermont Avenue Torrance 90502 Tel: (213) 6153909 TWX: 9103496263 tHamilton/Avnet Electronics 1175 Bordeau. Drive Sunnyvale 94086 Tel: (408) 7433300 TWX: 9103399332 tHamiiton/Avnet Electronics 4545 Viewridge Avenue San Diego 92123 Tel: (714) 641-4109 TWX: 9105952638 tHamilton/Avnet Electronics 10912 W. Washington Boulevard Culver City 90230 Tel: (213) 5582458 TWX: 9103406364 tHamilton/Avnet ElectronIcs 21050 Erwin Street Woodland Hills 91367 Tel: (213) 8830000 TWX: 9104942207 tHamllton Electro Sales 3170 Pullman Street Costa Mesa 92626 Tel: (714) 6414109 TWX: 9105952638 tHamiton/Avnet Electronics 4103 Northgate Boulevard Sacramento 95834 Tel: (916) 9203150 Kierulff Electronics. Inc. 3969 E. Bayshore Road Palo Alto 94303 Tel: (415) 9686292 TWX: 9103796430 Kierulff Electronics. Inc. 14101 Franklin Avenue Tustin 92680 Tel: (714) 7315711 TWX: 9105952599 Kierulff Electronics, Inc. 2585 Commerce Way Los Angeles 90040 Tel: (213) 7250325 TWX: 9105803666 tWyle Distribution Group 124 Maryland Street EI Segundo 90245 Tel: (213) 3228100 TWX: 9103487140 or 7111 tWyle Distribution Group 9525 Chesapeake Drove San Diego 92123 Tel: (714) 5659171 TWX: 9103351590 tWyle Distribution Group 3000 Bowers Avenue Santa Clara 95051 Tel: (408) 7272500 TWX: 9103380451 or 0451/0 tWyle DistributIon Group 17872 Cowan Avenue Irvine 92714 Tel: (7t4) 6411600 TWX: 9105951572

u.s. DISTRIBUTORS
COLORADO tWyle D,strobut,on Group 451 E. 124th Avenue Thornton 80241 Tel: (303) 4579953 TWX: 9109360770 tHamilton/Avnet Electronic. 8765 E. Orchard Road Suite 708 Englewood 80111 Tel: (303) 7401017 TWX: 9109350787 CONNECTICUT tArrow Electonics. Inc. 12 Beaumont Road Wallingford 06492 Tel: (203) 2657741 TWX: 71()'2201684 tHamiiton/Avnet Electronics Commerce Industrial Park Commerce Drive Danbury 06810 Tel: (203) 7972800 TWX: 710-<156-9974 t Harvey Electronics 112 Main Street Norwalk 06851 Tel: (203) 8531515 TWX: 7104683373 FLORIDA t Arrow Electronics. Inc. 1001 NoW. 62nd Street Suite 108 FI. Lauderdale 33309 Tel: (305) 7767790 TWX: 5109559456 tArrow Electronics. Inc. 50 Woodlake Drive W. Bldg. B Palm Bay 32905 Tel: (305) 7251480 TWX: 5109596337 tHamiiton/Avnet Electronics 6801 NoW. 15th Way FI. Lauderdale 33309 Tel: (305) 9712900 TWX: 5109563097 tHamliton/Avnet Electronics 3197 TeCh. Drive North 51. Petersburg 33702 Tel: (813) 5763930 TWX: 8108630374 tPioneer/Orlando 6220 S. Orange Blossom Trail Suite 412 Orlando 32809 Tel: (305) 8593600 TWX: 8108500177 tPioneer/FI. Lauderdale 1500 62nd Street N.W. Suite 506 FI. Lauderdale 33309 Tel: (305) 771-7520 TWX: 5109559653 GEORGIA tArrow Electronics. Inc. 2979 PaCific Drive Norcross 30071 Tel: (404) 4498252 TWX: 8107660439 tHamilton/Avnet Electronics 5825 D. Peachtree Corners Norcross 30092 Tel: (404) 4477500 TWX: 8107660432 tPioneer/Georgia 5835B Peachtree Corners E Norcross 30092 Tel: (404) 4481711 TWX: 8107664515 ILLINOIS tArrow Electronics. Inc. 2000 E. Alonquin Street Schaumberg 60195 Tel: (312) 3973440 TWX: 9102913544 tHamiiton/Avnet Electronics 1130 Thorndale Avenue Bensenville 60108 Tel: (312) 8607780 TWX: 9102270060 tPioneer/Chicago 1551 Carmen Drive Elk Grove Village 60007 Tel: (312) 4379680 TWX: 9102621182 INDtANA t Arrow Elec1ronocs. Inc 2718 Rand Road IndIanapolIS 48241 (317) 243-9353 TWX: 8103413119 tHami~on/Avnet Elec1ronocs 485 Orodle DrIve Carrnet 46032 Tel: (317) 8449333 TWX: 81 ().28().3966 tPioneer/lndiana 8408 CasHeplaca Drive Indianapolis 48250 Tel: (317) 8497300 TWX: 81()'26().1794 KANSAS
tHami~on/Avnet Electronics 9219 Qulvera Road Overland Pari< 66215 Tel: (913) 6688900 TWX: 91()'743ooo5

NEW HAMPSHIRE tArrow Elec1ronOCI. Inc 1 PerImeter Road Manchelter 03103 Tel: (603) 668-69&8 TWX: 71()'22().1684 NEWJERIEY t Arrow Elec1ronocs. Inc. Plea..nt Valley Avenue Moor"town 08057 Tel: (215) 928-1800 TWX: 71()'897.()829 tArrow Electronics. Inc. 285 Midland Avenue Saddle Brook 07662 Tel: (201) 7975800 TWX: 71()'998-2206 tArrow Electronics. Inc 2 Industrial Road Fairfield 07006 Tel: (201) 575-5300 TWX: 71 ()'998-2206 tHami~on/Avnet Elec1ronic. 1 Keystone Avenue Bldg. 36 Cherry HIli 08003 Tel: (609) 4240100 TWX: 71 ()'94()'0262 tHarvey Electronics 45 Route 46 Pinebrook 07058 Tel: (201) 5753510 TWX: 71 (). 7344382 tMTI Systems Sales 383 Route 46 W Fairfield 07006 Tel: (201) 2275552 NEW MEXICO t Alliance Electronics Inc. 11030 Cochiti S.E. Albuquerque 87123 Tel: (505) 2923360 TWX: 9109891151 tHamiiton/Avnet Electronics 2524 Baylor Drive S.E. Albuquerque 87106 Tel: (505) 7651500 TWX: 9109890614 NEW YORK tArrow ElectroniCS. Inc. 900 Broad Hollow Road Farmingdale 11735 Tel: (516) 6946800 TWX: 5102246126 tArrow ElectroniCS. Inc. 3000 South Winton Road Rochester 14623 Tel: (715) 2750300 TWX: 510253-<1766 tArrow Electronics. Inc. 7705 M altage Drive Liverpool 13086 Tel: (315) 6521000 TWX: 7105450230 tArrow ElectroniCS. Inc. 20 Oser Avenue Hauppauge 117e8 Tel: (516) 231-1000 TWX: 5102276623 tHamllton/Avnet Electronics 333 Metro Park Rochester 14623 Tel: (716) 4759130 TWX: 5102535470 tHamiiton/Avnet Electronics 16 Corporate Circle E. Syracuse 13057 Tel: (315) 4372641 TWX: 7105411560 tHamilton/Avnet Electronics 5 Hub Drive Melville. Long Island 11747 Tel: (516) 4546000 TWX: 5102246166 t Harvey Electronics P.O. Bo. 1208 Binghamton 13902 Tel: (607) 7488211 TWX: 5102520893

MARYLAND tHamiiton/Avnet Electronics 6822 Oak Hall Lane Columbia 21045 Tel: (301) 9953500 TWX: 71()'8621861 t Mesa Technology Corporation 16021 Industrial Drive Gaithersburg 20877 Tel: (301) 9484350 TWX: 7108289702 tPioneer 911lO Gaither Road Gaithersburg 20877 Tel: (301) 9480710 TWX: 7108280545 MASSACHUSETTS tHamilton/Avnet Electronics 50 Tower Office Park Woburn 01801 Tel: (617) 9359700 TWX: 7103930382 tArrow Electronics. Inc. 1 Arrow Drive Woburn 01801 Tel: (617) 9338130 TWX: 7103936770 tHarvey/Boston 44 Hartwell Avenue Le.ington 02173 Tel: (617) 8631200 TWX: 7103266617 MICHIGAN t Arrow Electronics. Inc. 3810 Vr.rsily Drive Ann Arbor 48104 Tel: (313) 9718220 TWX: 8102236020 tPloneer/Michigan 13485 Stamford Livonia 48150 Tel: (313) 5251800 TWX: 8102423271 tHamiiton/Avnet Electronics 32487 Schoolcraft Road Livonia 48150 Tel: (313) 522-<1700 TWX: 8102428775 tHamilton/Avnet Electronics 2215 29th Street S.E. Space AS Grand Rapids. 49508 Tel: (616) 2438805 TWX: 8102736921 MINNESOTA tArrow Electronics. Inc. 5230 W. 73rd Street Edina 55435 Tel: (612) 83().1800 TV/X: 9105763125 tHamilton/Avnet ElectroniCS 10300 Bren Road East Minnetonka 55343 Tel: (612) 9320600 TWX: (910) 5762720 Pioneer/Twin Cities 10203 Bren Road East Minnetonka 55343 Tel: (612) 9355444 TWX: 9105762738 MISSOURI tArrow Electronics, Inc. 2380 Schuetz 51. Louis 63141 Tel: (314) 5676688 TWX: 9107646600 tHamilton/Avnet Electronics 13743 Shoreline Court Earth Cily 63045 Tel: (314) 3441200 TWX: 9107620684

tMicrocomputer System Technical Demonstrator Centers

inter
NEW YORK (C~nt.) tHarvey ElectroniCS 60 Crossways Park West Woodbury. Long Island' 1797 Tel: (5'6) 92'8700 TWX: 5'022'2'84 tHarvey/Rochester 840 Fairport Park Fairport '4450 Tel: (7t6) 38'7070 TWX: 5'0253700' t MTI Systems Sales 38 Harbor Park Drive Port Washington" 050 Tel: (5'6)62'6200 TWX: 5 t 02230846 NORTH CAROLINA OREGON

u.s. DISTRIBUTORS
UTAH tHamllton/Avnet Electronics t 585 West 2100 South Salt Lake City 841'9 Tel: (801) 9722800 TWX: 9'09254018 tArrow Electronics. Inc. 4980 Amelia Earhart Drive Salt Lake City 84112 Tel: (801) 5391135 WASHINGTON t Almac Electronics Corporation '4360 S.E. Eastgate Way Bellevue 98007 Tel: (206) 643-9992 TWX: 9tO444-2067

t Almac Electronics Corporation 8022 S.W. Nimbus. Bldg. 7 Beaverton 97005 Tel: (503) 6419070 TWX: 9104678743
tHamliton/Avnet Electronics
6024 S.w. Jean Road Bldg. C. SUite 10 Lake Oswego 97034 Tel: (503) 6357848 TWX: 9'04558179 PENNSYLVANIA t Arrow Electronics, Inc. 650 Seco Road Monroeville 15'46 Tel: (4'2) 8567000 tPloneer/P,ttsburgh 259 Kappa Drive Pittsburgh 15238 Tel: (4'2) 7822300 TWX: 7107953122 tPioneer/Delaware Valley 261 G,bralter Road Horsham'9044 Tel: (215) 6744000 TWX: 5106656778 TEXAS

tArrow ElectroniCS. Inc.


14320 N.E. 21 st Street Bellevue 98007 Tel: (206) 643-4800 TWX: 910-4442017 tHamilton/Avnet ElectroniCS 14212 N.E. 21st Street Bellevue 98005 Tel: (206) 453-5874 TWX: 910-443-2469 WISCONSIN

t Arrow Electronics. Inc. 938 Burke Street W,nstonSalem 27'0' Tel: (9'9) 72587" TWX: 5'093'3'69 t Arrow Electronics. Inc. 3"7 Poplarwood Court SUite '23 Ralelgn 27265 Tel: (9'9)8763'32 TWX: 5'0928"856 tHamllton/Avnet Electronics 2803 Industrial Drive Raleigh 27609 Tel: (9'9) 8298030 TWX: 5'0928'836 tPloneeriCarollna '03 Industrial Avenue Greensboro 27406 Tel: (9'9)273444' TWX: 5'0925"'4
OHIO

t Arrow ElectroniCS.
, 3715 Gama Road Dallas 75234 Tel: (214) 3867500 TWX: 9108605377

Inc

tArrow Electronics, Inc. 430 W. Rausson Avenue Oakcreek 53154 Tel: (414) 764-6600 TWX: 910-2621193
tHamilton/Avnet Electronics 2975 Moorland Road New Berlin 53151 Tel: (4'4) 784-4510 TWX: 910-2621182

t Arrow Electronics. Inc.


10700 Corporate Drive Suite 100 Stafford 77477 Tel: (7'3) 4914100 TWX: 9108804439

tArrow Electronics. Inc. 7620 McEwen Road Centerville 45459 Tel: (5'3) 4355563 TWX: 8'0459'6" t Arrow E.lectronlcs. Inc 6238 Cochran Road SOlon 44t39 Tel: (2'6) 2483990 TWX: 8'04279409 tHamllton/Avnet ElectrOnic. 954 Senate Drive Dayton 45459 Tel: (5'3) 43306'0 TWX: 8104502531
tHamllton/Avnet Electronics 4588 Emery Industrial Parkway Heights 44128 Tel: (216) 8313500 TWX: 8104279452
Warrensvill~

t Arrow ElectroniCS. Inc 10125 MetropOlitan Austin 78758 Tel: (512) 8354100 TWX: 9108741348
tHamilton/Avnet Electronics 2401 Rutland Auslln 78757 Tel: (512) 8378911 TWX: 9108741319 tHamilton/Avnet Electronics 2111 W. Walnut HIli Lane Irving 75062 Tel: (214) 6594'00 TWX: 910860-5929

tHamilton/Avnet Electronics 8750 West Park Houston 77063 Tel: (7'3)780-177' TWX: 910-881-5523
tPioneer/Austin 9901 Burnet Road Austin 78758 Tel: (512) 635-4000 TWX: 9'0-874-1323 tPioneer/Dallas 13710 Omega Road Dallas 75234 Tel: (2'4) 386-7300 TWX: 91 0-8505563 tPloneer/Houston 5853 Point West Drive Houston 77036 Tel: (7t3) 988-5555 TWX: 910-5762738 tMicrocomputer System Technical Demonstrator Cent.rs

tPloneer/Dayton 4433 Interpoint Boulevard Dayton 45424 Tel: (513)2369900 TWX: 810459,1622 t Pioneer/Cleveland 4800 E. 131st Street Cleveland 44105 Tel: (2'6) 5873600 TWX: 8104222211 OKLAHOMA fArrow ElectroniCS, Inc. 4719 S. Memorial Drive Tulsa 74145 Tel: (918) 6657700

intJ
BELGIUM Intel Corporation S.A Parc Seny
Rue du Moulin a Paplef 51

INTEL EUROPEAN SALES OFFICES


WEST GERMANY Intel Semiconductor GmbH" Seldlstrasse 27 0-8000 Muenchen 2 Tel: (89) 53891 TELEX: 05-23177INTL 0 Intel Semiconductor GmbH" Malnler Strasse 75 0-6200 WIesbaden 1 Tel: (6121) 70 0874 TELEX: 04186183 INTW 0 Intel Semiconductor GmbH Brueckstrasse 61 7012 Fellbach West Germany Tel: (711) 58 00 82 TELEX: 7254826 INTS 0 Intel Semiconductor GmbH" Hohenlollern Strasse 5 3000 Hannover 1 Tel: (511) 34 40 81 TELEX: 923625 INTH 0 Intel Semiconductor GmbH Ober-Ratherstrasse 2 0-4000 Dusseldorf 30 Tel: (211) 6510 54 TELEX, 08-58977 INTL 0 ISRAEL Intel Semiconductor Ltd,P.O. Box 1659 Haifa Tel: 4/524 261 TELEX: 48511 ITALY Intel Corporation !talia Spa Milanofiori, Palazzo E 20094 Assago (Milano) Tel: (02) 824 00 06 TELEX: 315183 INTMIL NETHERLANDS Intel Semiconductor Nederland B.V. Alexanderpoort Building Marten Meeswag 93 3068 Rotterdam Tel: (10) 2133 77 TELEX: 22283 NORWAY Intel Norway AlS P.O. Box 92 HV8mveien 4 N-2013 Skjetten Tel: (2) 742 420 TELEX: 18018 SWEDEN Intel Sweden A.B: Box 20092 Archlmedesvagen 5 5-16120 Bromma Tel: (08) 98 53 85 TELEX: 12261 SWITZERLAND Intel Semlconduct~r A.G: Forchstrasse 95 CH 8032 Zurich Tel: (01) 55 45 02 TELEX: 57989 ICH CH UNITED KINGDOM Intel Corporation (U.K.) Ltd: 5 Hospital Street Nantwlch, Cheshire CW5 5RE Tel: (0270) 626 560 TELEX: 36620 Intel Corporation (U.K.) Ltd: Pipers Way SWlndon, Wiltshire SN3 1RJ Tel: (0793) 468.388 TELEX: 444447 INT SWN eFleld Application Location

BOlte 1 B-1160 Brussels Tel: (02) 661 07 11 TELEX: 24814 DENMARK Inlel Denmark A/S Lyngbyvel 32F 2nd Floor OK-21oo Copenhagen Easl Tel: (01) 182000 TELEX: 19567 FINLAND Inlel Finland OY Hameentle 103 SF - 00550 Helsinki 55 Tel: 0/716 955 TELEX: 123 332 FRANCE Intel Corporation, S.A.R.L: 5 Place de la Balance SIlic 223 94528 RunglS Cedex Tel: (01) 687 22 21 TELEX: 270475 Intel Corporation, S.A.R.L. Immeuble BBC 4 Qual des Etrolts 69005 Lyon Tel: (7) 842 40 89 TELEX: 305153

EUROPEAN DISTRIBUTORS/REPRESENTATIVES
AUSTRIA Bacher Elektronlsche Geraete GmbH Rotemuehlgasse 26
A 1120 Vienna

Tel: (222) 83 63 96 TELEX: 11532 BASAT A BELGIUM Inelco Belgium SA Ave. des CrOix de Guerre 94 B1120 Brussels Tel: (02) 216 01 60 TELEX: 25441 DENMARK MultlKomponent A/S Fabriksparken 31 OK-2600 Gloskrup Tel: (02) 45 66 45 TX: 33355 Scandinavian Semiconductor Supply A/S Nannasgade 18 OK-2200 Copenhagen Tel: (01) 83 50 90 TELEX: 19037 FINLAND Oy Flntronlc AB Melkonkatu 24 A SF-00210 Helsinki 21 Tel: (0) 692 60 22 TELEX: 124 224 Ftron SF FRANCE Jermyn SA rue Jules Ferry 35 93170 Bagnolet Tel: (1) 859 04 04 TELEX: 213610 F Metrologle

WEST GERMANY Electronic 2000 Vertrlebs A.G. Neumarkter Strasse 75 0-8000 Munich 80 Tel: (89) 43 40 61 TELEX: 522561 EIEC 0 Jermyn GmbH PosUach 1180 Schulstrosse 48 0-6277 Bad Camberg Tel: (06434) 231 TELEX: 484426 JERM D Celdls Enetechnlk Systems GmbH Schlilerstruse 14 0-2085 Qulckborn-Hamburg Tel: (4106) 6121 TELEX: 213590 ENA D Proelectron Vertrlebs GmbH Max Planck Strasse 1-3 6072 Drelelch bel Frankfurt Tel: (6103) 33564 TELEX: 417983 IRELAND Micro Marketing Glenageary Office Park Glenageary Co. Dublin Tel: (1) 85 62 88 TELEX: 31584 ISRAEL Eastronlcs Ltd. 11 Ronnls Street P.O. Box 39300 Tel Aviv 61390 Tel: (3) 4751 51 TELEX: 33638 ITALY Eledra 35 S.P.A. VIaie Elvella, 18 I 20154 Milano Tel: (2) 34 97 51 TELEX: 332332 Intesi Milonlior; Pal. E/5 20090 Assogo Milano Tel: (02) 82470 TELEX: 311351

NETHERLANDS Koning & Hartman Koperwerf 30 P.O. Box 43220 2544 EN's Gravenhage Tel: 31 (70) 210.101 TELEX: 31528 NORWAY Nordlsk Elektronlc (Norge) A/S Postofflce Box 122 Smedsvlngen 4 1364 Hvalslad Tel: (2) 786 210 TELEX: 16963 PORTUGAL Oitram Componentes E Electronlca LOA Av. Miguel Bombarda, 133 PI 000 LIsboa Tel: (19) 545 313 TELEX: 14182 Brleks-P SPAIN Interface SA Ronda San Pedro 22, 3 Barcelona 10 Tel: (3) 301 7851 TWX: 51508 ITISESA Miguel Angel 23-3 Madrid 10 Tel: (1) 419 5400 TELEX: 27707 SWEDEN AB Gosta Backstrom Box 12009 Aistroemergatan 22 5-10221 Stockholm 12 Tel: (8) 541 080 TELEX: 10135 Nordlsk Electronlk AB Box 27301 Sandhamnsgatan 71 5-10254 Stockholm Tel: (8) 635 040 TELEX: 10547

SWITZERLAND :ndustrade AG Gemsenstrasse 2 Postcheck 80 - 21190 CH-8021 Zurich Tel: (01) 363 23 20 TELEX: 56788 INOEL CH UNITED KINGDOM Bytech Ltd. Unit 57 London Road Earley, Reading Berkshire Tel: (0734) 61031 TELEX: 848215 Comway MIcrosystems Ltd. Market Street UK-Bracknell, Berkshire Tel: 44 (344) 55333 TELEX: 847201 DECADE Ltd. 100 School Road Tilehurst Reading, Berkshire Tel: (0734) 413127 TELEX: 837953 Jermyn Industries Vestry Estate Sevenoaks, Kent Tel: (0732) 450144 TELEX: 95142 M.E.O.L. East Lane Road North Wembley Middlesex HA9 7PP Tel: (01) 904 93 07 TELEX: 28817 Rapid Recall, Ltd Rapid House/Denmark St High Wycombe Berks, England HPll 2ER Tel: (0494) 26 271 TELEX: 837931 YUGOSLAVIA H. R. Microelectronics Enterprises P.O. Box 5604 San Jose, California 95150 T01: 408/978-8000 TELEX: 278-559

La Tour d' Asmeres


1, Avenue Laurent Cely 92606-Asnleres Tel: (1) 791 4444 TELEX: 611 448 Tekelec AIrtronjc Cite des Bruyeres Rue Carle Vernet F-92310 Sevres Tel: (01) 534 75 35 TELEX: 204552

inter
AUSTRALIA Intel Semiconductor Ply. Ltd. Spectrum BUilding 200 Pacific Highway LeyelO Crow. Nest, NSW, 2089 Australia Tel: 011-61-2-436-2744 TELEX: 790-20097 HONG KONG Intel Semiconductor Corp. 99-105 De. Voeux Rd., Central 18F, Unit B Hong Kong Tel: 011-852-5-499-432 TELEX: 63869

INTEL INTERNATIONAL SALES OFFICES


JAPAN Intel Japan K.K. 5-6 Tokodai, Toyosato-machl TsukuDa-gun, IDarakl-ken 300-26 Tel: 029747-8511 TELEX: 03656-160 Intel Japan K.K. 2-1-15 Naka-machi Atsugi, Kanagawa 243 Tel: 0462-23-3511 Intel Japan K.K." 2-51-2 Kojima-cne Chofu, Tokyo 182 Tel: 0424-88-3151 'Field Application Location Intel Japan K.K. 2-69 Hon-cho Kumagaya, Saitama 360 Tel: 0465-24-6871 Intel Japan K.K." 2-4-1 Terauchi Toyonaka, Osoka 560 Tel: 06-863-1091 Intel Japan K.K 1-5-1 Marunouchi Chiyoda-ku, Tokyo 100 Tel: 03-201-3621/3681 Intel Japan K.K." 1-23-9 Shlnmachi Setagaya-ku, Tokyo 154 Tel: 03-426-2231/427-8845

INTERNATIONAL DISTRIBUTORS/REPRESENTATIVES
CHILE ARGENTINA VLC S.R.L. Sarmiento 1630 PISO (1042) Buenos Aires Tel: 35-1202/9242 TELEX: PuDlic Booth 9900 or 9901 Mailing Address Soimex International Corporation 15 Park Row, Room "1730 New York, New York 10038 (212) 406-3052 Attn: Gaston Briones AUSTRALIA Total Electronics 9 Harker Street Burwood Victoria 3125 Tel: 61 3288-4044 TELEX: .1..1. 31261 Mailing Address Priyate Bag 250 Burwood, Victor,. 3125 Australia Total Electronics "1 Johnstone Lane Lane Coye, N.S.w. 2066 TELEX: 26297 BRAZIL Icetron S.A 05110 Ay. Mutinga 3650-6 Andar PlntuDa Sao Paulo Tel: 261-0211 TELEX: 1122274/1COTBR DIN AV. VIC MCKENNA 204 Casilla 6055 Santiago Tel: 227 564 TELEX: 352003 COLOMIIIA International Computer Machines Carrera 7 No. 72-34 Apdo. Aereo 19403 Bogota 1 Tel: 211-7282 TELEX: 457161CM CO. HONG KONG Schmidt & Co. Ltd. Wing on Centre, 28th Floor 111 Connaught Road Central Tel: 5-455-644 TELEX: 74766 SCHMC HX INDIA Mlcronlc Devices 104/109C, Nirmal Industrial Estate Sion(E) BomDay 400022 Tel: 486-170 TELEX: 011-71447 MDEV IN JAPAN Asahi Electronics Co. Ltd. KMM Bldg. Room 407 2-14-1 Asano, Kokura Kita-Ku, Kitakyushu City 802 Tel: (093) 511-6471 TELEX: AECKY 7126-16 Hamllton-Aynet Electronics Japan Ltd. YU and YOU Bldg. 1-4 Horidome-Cho Nihonbashi Chuo-Ku, Tokyo 103 Tel: (03) 662-9911 TELEX: 2523774 Ryoyo Electric Corp. Konwa Bldg. 1-12-22, Tsukiji Chuo-Ku, Tokyo 104 Tel: (03) 543-7711 Tokyo Electron Ltd. Shin JukU, Nomura Bldg. 26-2 Nishi-Shin Juku-Ichome Shin Juku-Ku, Tokyo 160 Tel. (03) 343-4411 TELEX: 232-2220 LABTEL J KOREA Karam Digital Room 909 Woonam Bldg. 7, 1-KA Bongre-Dong Chung-Ku Seoul 100 Tel: 2-753-8123 TELEX: K25299 KODIGIT NEW ZEALAND McLean Information Technology Ltd. 459 KyDer Pass Road, Newmarket, P.O. Box 9464, Newmarket Auckland 1 , New Zealand Tel: 501-801, 501-219, 587-037 TELEX: NZ21570 THERMAL SINGAPORE General Engineers Corporation Ply. Ltd. Block 3, Units 1003-1008, 10th Floor P.S.A. Multi-Storey Complex TELOK BLANGAH/Pasir Panjang Road Singapore 05 t 1 Tel: 271-3t67 TELEX: RS23987 GENERCO SOUTH AFRICA Electronic Building Elements, Ply. Ltd. P.O. Box 4609 Hazelwood, Pretoria 0001 Tel: 011-27-12-46-9221 or 9227 TELEX: 3-Ot81 SA TAIWAN Taiwan Automation Corp" 3d Floor "75, Section 4 Nanking East Road Taipei Tel: 771-0940 TELEX: 11942 TAIAUTO YUGOSLAVIA H. R. Microelectronics Enterprises P.O. Box 5604 San Jose, California 95150 Tel: (408) 978-8000 TELEX: 278-559

'Field ApplicatIOn Location

inter
CALIFORNIA Inlel Corp 1350 Shorebird Way MI. View 94043 Tel: (415) 968-8086 TWX: 910-339-9279 910-338-0255 Intel Corp. 2000 E. 41h Sireel Suile 110 Sanla Ana 92705 Tel: (714) 835-2670 TWX: 910-595-2475 Inlel Corp. 7670 Opportunily Road San Diego 92111 Tel: (714) 268-3563 Inlel Corp 5530 N. Corbin Avenue Suile 120 Tarzana 91356 Tel: (213) 708-0333 COLORADO Inlel Corp. 650 Soulh Cherry Suite 720 Denver 80222 Tel: (303) 321-8086 TWX: 910-931-2289 CONNECTICUT Intel Corp. 36 Padanaram Road Danbury 06810 Tel: (203) 792-8366 FLORIDA Intel Corp. 1500 NW. 62nd Street Suite 104 FI. Lauderdale 33309 Tel: (305) 771-0600 TWX: 510-956-9407 Intel Corp. 500 N. Maitland Avenue Suite 205 Maitland 32751 Tel: (305) 628-2393 TWX: 810-853-9219 Inlel Corp. 5151 Adanson Street Orlando 32804 Tel: (305) 628-2393 GEORGIA Intel Corp. 3300 Holcomb Bridge Road SUite 225 Norcross 30092 Tel: (404) 449-0541 ILLINOIS Intel Corp. 2550 Golf Road Suite 815 Rolling Meadows 60008 Tel: (312) 981-7230 TWX: 910-253-1825 KANSAS Inlel Corp. 9393 W. 110th Street Suite 265 Overland Park 66210 Tel: (913) 642-8080 MARYLAND Intel Corp. 7257 Parkway Drive Hanover 21076 Tel: (301) 796-7500 TWX: 710-862-1944

u.s. SERVICE OFFICES


MASSACHUSETTS Intel Corp. 27 Industrial Avenue Chelmsford 01824 Tel: (617) 256-1800 TWX: 710-343-6333 MICHIGAN Intel Corp. 26500 Northwestern Highway Suite 401 Southfield 48075 Tel: (313) 353-0920 TWX: 810-244-4915 MINNESOTA Intel Corp. 7401 Metro Boulevard Suile 355 Edina 55435 Tel: (612) 835-6722 TWX: 910-576-2867 MISSOURI 100ei Corp. 4203 Earth City Expressway Suile 143 Earth City 63045 Tel: (314) 291-1990 NEW JERSEY Intel Corp. 385 Sylvan Avenue Englewood Cliffs 07632 Tel: (201) 567-0820 TWX: 710-991-8593 NEW YORK Intel Corp. 2255 Lyell Avenue Rochester 14606 Tel: (716) 254-6120 NORTH CAROLINA Intel Corp. 5600 Executive Drive Suite 113 Charlone 28212 Tel: (704) 568-8966 Intel Corp. 2306 W. Meadowview Road Suite 206 Greensboro 27407 Tel: (919) 294-1541 OHIO Inlel Corp. Chagrin-Brainard Bldg Suite 300 28001 Chagrin Boulevard Cleveland 44122 Tel: (216) 464-6915 TWX; 810-427-9298 Intel Corp. 6500 Poe Avenue Daylon 45414 Tel: (800) 325-4415 TWX: 810-450-2528 OKLAHOMA Intel Corp. 4157 S. Harvard Suite 123 Tulsa 74101 Tel: (918) 749-8688 OREGON Intel Corp. 10700 SW. Beaverton-Hillsdale Highway Suite 22 Beaverton 97005 Tel: (503) 641-8086 TWX: 910-467-8741 PENNSYLVANIA Intel Corp. 500 Pennsylvania Avenue Fort Washington 19034 Tel: (215) 641-1000 TWX: 510-661-2077 Intel Corp. 201 Penn Center Boulevard Suite 301 W. Pinsburgh 15235 Tel: (313) 354-1540 TEXAS Intel Corp. 313 E_ Anderson Lane Suite 314 Austin 78752 Tel: (512) 454-8477 TWX: 910-874-1347 Intel Corp_ 2925 L_B_J_ Freeway Suite 175 Dallas 75234 Tel: (214) 241-2820 TWX: 910-860-5617 Intel Corp_ 7322 SW_ Freeway Suite 1490 Houston 77074 Tel: (713) 988-8086 TWX: 910-861-2490 VIRGINIA Intel Corp. 7700 Leesburg Pike Suite 412 Falls Church 22043 Tel: (703) 734-9707 TWX: 710-931-0625 WASHINGTON Intel Corp. 110 l10th Avenue N.E. Suite 510 Bellevue 98004 Tel: 1-800-538-0662 TWX: 910-443-3002 WISCONSIN Inlel Corp. 150 S. Sunnyslope Road Suite 148 Brookfield 53005 Tel: (414) 784-9080

Vous aimerez peut-être aussi