If a system is going to run multiple applications simultane-ously then it must be able to ensure that one application doesn’t affect another. This is done through several layers of resource protection. Resource protection within MS-DOS and Windows 3.1 is a rather hit and miss affair. There is nothing to stop an applica-tion from directly accessing an I/O port or other physical device and if it did so, it could potentially interfere with another applica-tion that was already using it. Although the Windows 3.1 environ-ment can provide some resource protection, it is of collaboration level and not mandatory. It is without doubt a case of self-regulation as opposed to obeying the rules of the system.
The most important resource to protect is memory. Each process is allocated its own memory which is protected from interference by other processes through programming the memory management unit. This part of the processor’s hardware tracks the executing process and ensures that any access to memory that it has not been allocated or given permission to use is stopped.
Hardware such as I/O devices are also protected by the memory management unit and any direct access is prevented. Such accesses have to be made through a device driver and in this way the device driver can control who has access to a serial port and so on. A mechanism called a spinlock is also used to control access. A process can only access a device or port if the associated spinlock is not set. If someone else is using it, the process must wait until they have finished.
Coping with crashes
If a process crashes then it is important for the operating system to maintain as much of the system as possible. This requires that the operating system as well as other applications must have its own memory and resources given to it. To ensure this is the case, processes that are specific to user applications are run in a user mode while operating system processes are executed in a special kernel mode. These modes are kept separate from each other and are protected. In addition, the operating system has to have detailed knowledge of the resources used by the crashed process so that it can clean up the process, remove it and thus free up the resources that it used. In some special cases, such as power failures where the operating system may have a limited amount of time to shut down the system in a controlled manner or save as much of the system data as it can, resources are dedicated specifi-cally for this functionality. For example, the second highest inter-rupt priority is allocated to signalling a power failure.
Windows NT is very resilient to system crashes and while processes can crash, the system will continue. This is essentially due to the use of user and kernel modes coupled with extensive resource protection. Compared to Windows 3.1 and MS-DOS, this resilience is a big advantage.
There is a third difference with Windows NT that many other operating systems do not provide in that it supports multi-threaded processes. Processes can support several independent processing paths or threads. A process may consist of several independent sections and thus form several different threads in that the context of the processing in one thread may be different from that in another thread. In other words, the process has all the resources defined that it will use and if the process can support multi-threaded operations, the scheduler will see multiple threads going through the process. A good analogy is a production line. If the production line is single threaded, it can only produce a single end product at a time. If it is multi-threaded, it separates the production process into several independent parts and each part can work on a different product. As soon as the first operation has taken place, a second thread can be started. The threads do not have to follow the same path and can vary their route through the process.
The diagram shows a simple multi-threaded operation with each thread being depicted by a different shading. As the first thread progresses through, a second thread can be started. As that progresses through, a third can commence and so on. The re-sources required to process the multiple threads in this case are the same as if only one thread was supported.
The advantage of multi-threaded operation is that the proc-ess does not have to be duplicated every time it is used: a new thread can be started. The disadvantage is that the process pro-gramming must ensure that there is no contention or conflict between the various threads that it supports. All the threads that exist in the process can access each other’s data structures and even files. The operating system which normally polices the environment is powerless in this case. Threads within Windows NT derive their priority from that of the process although the level can be adjusted within a limited range.
The addressing space within Windows NT is radically different from that experienced within MS-DOS and Windows 3.1. It provides a 4 Gbyte virtual address space for each process which is linearly addressed using 32 bit address values. This is different from the segmented memory map that MS-DOS and Windows have to use. A segmented memory scheme uses 16 bit addresses to provide address spaces of only 64 kbytes. If addresses beyond this space have to be used, special support is needed to change the segment address to point to a new segment. Gone are the different types of memory such as extended and expanded.
This change towards a large 32 bit linear address space improves the environment for software applications and increases their performance and capabilities to handle large data structures. The operating system library that the applications use is called WIN32 to differentiate it from the WIN16 libraries that Windows 3.1 applications use. Applications that use the WIN32 library are known as 32 bit or even native — this term is also used for Windows NT applications that use the same instruction set as the host processor and therefore do not need to emulate a different architecture.
To provide support for legacy MS-DOS and Windows 3.1 applications, Windows NT has a 16 bit environment which simu-lates the segmented architecture that these applications use.
The idea behind virtual memory is to provide more memory than physically present within the system. To make up the short-fall, a file or files are used to provide overflow storage for applica-tions which are to big to fit in the system RAM at one time. Such applications’ memory requirements are divided into pages and unused pages are stored on disk.
When the processor wishes to access a page which is not resident in memory, the memory management hardware asserts a page fault, selects the least used page in memory and swaps it with the wanted page stored on disk. Therefore, to reduce the system overhead, fast mass storage and large amounts of RAM are normally required.
Windows NT uses a swap file to provide a virtual memory environment. The file is dynamic in size and varies with the amount of memory that all the software including the operating system, device driver, and applications require. The Windows 3.1 swap file is limited to about 30 Mbytes in size and this effectively limits the amount of virtual memory that it can support.
The internal architecture
The internal architecture is shown in the diagram below and depicts the components that run in the user and kernel modes. Most of the operating system runs in the kernel mode with the exception of the security and WIN32 subsystems.
The environments are protected in that direct hardware access is not allowed and that a single application will run in a single environment. This means that some applications or combi-nations may not work in the Windows NT environment. On the other hand, running them in separate isolated environments does prevent them from causing problems with other applications or the operating system software.
Virtual memory manager
The virtual memory manager controls and supervises the memory requirements of an operating system. It allocates to each process a private linear address space of 4 Gbytes which is unique and cannot be accessed by other processes. This is one reason why legacy software such as Windows 3.1 applications run as if they are the only application running.
With each process running in its own address space, the virtual memory manager ensures that the data and code that the process needs to run is located in pages of physical memory and ensures that the correct address translation is performed so that process addresses refer to the physical addresses where the infor-mation resides. If the physical memory is all used up, the virtual memory manager will move pages of data and code out to disk and store it in a temporary file. With some physical memory freed up, it can load from disk previously stored information and make it available for a process to use. This operation is closely associated with the scheduling process which is handled within the kernel. For an efficient operating system, it is essential to minimise the swapping out to disk — each disk swap impacts performance — and the most efficient methods involve a close correlation with process priority. Low priority processes are primary targets for moving information out to disk while high priority processes are often locked into memory so that they offer the highest perform-ance and are never swapped out to disk. Processes can make requests to the virtual memory manager to lock pages in memory if needed.
User and kernel modes
Two modes are used to isolate the kernel and other compo-nents of the operating system from any user applications and processes that may be running. This separation dramatically improves the resilience of the operating system. Each mode is given its own addressing space and access to hardware is made through the operating system kernel mode. To allow a user process access, a device driver must be used to isolate and control its access to ensure that no conflict is caused.
The kernel mode processes use the 16 higher real-time class priority levels and thus operating system processes will take preference over user applications.
Local procedure call (LPC)
This is responsible for co-ordinating system calls from an application and the WIN32 subsystem. Depending on the type of call and to some extent its memory needs, it is possible for applications to be routed directly to the local procedure call (LPC) without going through the WIN32 subsystem.
The kernel is responsible for ensuring the correct operation of all the processes that are running within the system. It provides the synchronisation and scheduling that the system needs. Syn-chronisation support takes the form of allowing threads to wait until a specific resource is available such as an object, semaphore, an expired counter or other similar entity. While the thread is waiting it is effectively dormant and other threads and processes can be scheduled to execute.
The scheduling procedures use the 32 level priority scheme previously described in this chapter and is used to schedule threads rather than processes. With a process potentially support-ing multiple threads, the scheduling operates on a thread basis and not on a process basis as this gives a finer granularity and control. Not scheduling a multi-threaded process would affect several threads which may not be the required outcome. Schedul-ing on a thread basis gives far more control.
Interrupts and other similar events also pass through the kernel so that it can pre-empt the current thread and reschedule a higher priority thread to process the interrupt.
Windows NT supports three types of file system and these different file systems can co-exist with each other although there can be some restrictions if they are accessed by non-Windows NT systems across a network, for example.
File allocation table is the file system used by MS-DOS and Windows 3.1 and uses file names with an 8 character name and a 3 character extension. The VFAT system used by Windows 95 and supports long file names is also supported with Windows NT v4 in that it can read Windows 95 long file names.
High performance file system is an alternative file system used by OS/2 and supports file names with 254 characters with virtually none of the character restrictions that the FAT system imposes. It also uses a write caching to disk tech-nique which stores data temporarily in RAM and writes it to disk at a later stage. This frees up an application from waiting until the physical disk write has completed. The physical disk write is performed when the processor is either not heavily loaded or when the cache is full.
The NT filing system is Windows NT’s own filing system which conforms to various security recommendation and allows system administrators to restrict access to files and directories within the filing system.
All three filing systems are supported — Windows NT will even truncate and restore file names that are not MS-DOS compat-ible — and are selected during installation.
As previously stated, Windows NT supports most major networking protocols and through its multi-tasking capabilities can support several simultaneously using one or more network connections. The drivers that do the actual work are part of the kernel and work closely with the file system and security modules.
I/O drivers are also part of the kernel and these provide the link between the user processes and threads and the hardware. MS-DOS and Windows 3.1 drivers are not compatible with Win-dows NT drivers and one major difference between Windows NT and Windows 3.1 is that not all hardware devices are supported. Typically modern devices and controllers can be used but it is wise to check the existence of a driver before buying a piece of hardware or moving from Windows 3.1 to Windows NT.
The hardware abstraction layer (HAL) is designed to pro-vide portability across different processor-based platforms and between single and multi-processor systems. In essence, it defines a piece of virtual hardware that the kernel uses when it needs to access hardware or processor resources. The HAL layer then takes the virtual processor commands and requests and translates them to the actual processor system that it is actually using. This may mean a simple mapping where a Windows NT interrupt level corresponds to a processor hardware interrupt but it can involve a complete emulation of a different processor. Such is the case to support MS-DOS and Windows 3.1 applications where an Intel 80x86 processor is emulated so that an Intel instruction set can be run.
With the rest of Windows NT being written in C, a portable high level language, the only additional work to the recompilation and testing is to write a suitable HAL layer for the processor platform that is being used.