Operating System Reading Report-Introduction to Real-Time Linux
Abstract: This article makes a simple analysis on a real-time Linux instance nmt rt-Linux, and points out the role of Linux in general real-time operating systems.
Abstract: The paper introduces an exampe of Real-Time Linux, Which is nmt rt-Linux finished by Victor yodaiken and Michael barabanov. and I'll introduce some advantages of using Linux as a general Real-Time OS.
Keywords: real-time operating system, system response time, time limit
1. Introduction to Real-time Operating Systems
Because real-time Linux is a real-time operating system first, some concepts of real-time operating systems are introduced here.
1. Real-time Operating System
Real-time Operating System is designed for operating system features. A real-time operating system is an operating system that supports real-time control of the system. Its primary task is to schedule all available resources to complete real-time control tasks. Secondly, it focuses on improving the efficiency of computer systems. Therefore, its important feature is to meet the time restrictions and requirements.
2. Real-time multi-task operating system and time-based multi-task operating system
They have obvious differences. For a time-based operating system, the execution of the program is not strict with the time requirement. A time error generally does not cause catastrophic consequences (although the user may be dissatisfied ). However, the main task of a real-time operating system is to process events in real time. Although events may arrive at unpredictable times, however, the handler must be able to respond within a strict time limit (system response time) after an event occurs, even under peak load, this should also be the case (that is, the real-time operating system cannot allow the utilization of system resources to reach or close to 100% at a certain time point ). System Response timeout means a fatal failure. In addition, the real-time operating system has the certainty of the system status, that is, the system can make a precise estimation of the best and worst running conditions.
3. Important Concepts in Real-time Operating Systems
L system response time: the time when the system sends a Processing request to the time when the system gives a response signal.
L context-switching time: the time used for switching between tasks.
L interrupt latency: the time when the computer receives the interrupt signal to respond to the operating system and completes the transition to the interrupted service program.
4. Functions of the real-time operating system
1) Task Management (multi-task and priority-based task scheduling)
2) synchronization and communication between tasks (signal lights and mailboxes)
3) optimized memory management (including Rom Management)
4) Real-time clock service
5) interrupt management service
5. Features of Real-time Operating Systems
Tasks in a real-time operating system are equivalent to processes in a time-based operating system. The tasks in the system are in four states: executing, ready, suspended, and dormant ).
L run: Obtain CPU control.
L ready: Enter the task waiting queue. Change to running status through scheduling.
L suspension: The task is blocked, removed from the task waiting queue, and woke up after a real-time system event occurs. To be ready or running.
L hibernation: a task that is cleared due to reasons such as task completion or error. It can also be considered as a task that does not exist in the system.
Ii. History of Real-time Operating Systems
The Study of Real-time Operating Systems (RTOs) started in 1960s. From the perspective of system structure, RTOS has now gone through three phases:
1. Early Real-time Operating Systems
Early real-time operating systems cannot be called real RTOS. They are small, simple, and specific software with weak functions. They can be considered as a real-time monitoring program. It generally provides users with initialization management of the system and simple real-time clock management. Some real-time monitoring programs also introduce functions such as task scheduling and simple inter-task coordination, such real-time monitoring programs include rtmx. Applications, real-time monitoring programs, and hardware running platforms are often closely linked.
2. Dedicated real-time operating system
With the development of applications, the early RTOS has become increasingly apparent. Some real-time system developers develop real-time operating systems that match specific hardware to meet the needs of real-time applications. These dedicated real-time operating systems are called real-time operating system developed in house in foreign countries. It was developed by early users to meet their own development needs. It is generally only applicable to specific hardware environments, and lacks strict evaluation and portability. Such real-time operating systems include Intel imax86.
3. General real-time operating system
In various dedicated RTOS, some multitasking mechanisms, such as priority-based scheduling, real-time clock management, inter-task communication, and synchronization mutex mechanism, are basically the same, the difference is only for their respective hardware environments and application goals. In fact, the same multitasking mechanism can be shared, so this part can be well organized to form a general real-time operation kernel. Most of these real-time operating systems use soft component structures to form a general real-time operating system using software "standard components". On the one hand, different hardware features are shielded at the lowest layer of the RTOS kernel; on the other hand, it provides standard and customizable system service software components for different application environments. This allows users to select different software components based on different real-time application requirements and hardware environments, and also allows real-time operating system developers to reduce repetitive work during development.
These general real-time operating systems include PSOs + of integrated system, irmx386 of Intel, and vrtx32 of Ready system (which is then merged with microtec research. They generally provide kernels with good real-time performance, a variety of task communication mechanisms, network components based on TCP/IP, file management, and I/O services, it provides an integrated development environment integrating editing, compilation, debugging, and simulation, and supports application development using C/C ++.
After years of development, real-time operating systems have evolved from real-time mode to protection mode, from micro-kernel technology to ultra-micro kernel technology, the system scale also evolved from single-processor RTOS to multi-processor RTOS and network RTOS, forming an important branch in the field of operating system research.
Iii. Real-Time Linux
The real-time Linux system discussed in this article is a common real-time operating system, but it is different from the preceding real-time operating systems. Because real-time Linux is built on a general operating system Linux, it is not suitable for processing real-time tasks in terms of efficiency and processing methods of jobs. Moreover, Linux is a multi-platform, universal, and balanced time-based operating system, and a large part of Real-Time Linux applications are based on PC platforms rather than dedicated hardware platforms, as you can imagine, it will be slightly inferior to professional real-time operating systems (and even other general real-time operating systems) in terms of timeliness and efficiency ). However, compared with dedicated hardware platforms, PCs have low prices, strong functions, convenient use, and robustness, as well as a large number of mature tools in general operating systems, user interface GUI, network communication interface, and so on are currently used in many complex real-time systems. Therefore, real-time Linux has been very popular since its appearance.
In a PC architecture, real-time Linux reconstructs the Linux kernel and recompiles the system to make it more suitable for real-time requirements. Here we can see the huge advantages of open source. Obviously, it is unrealistic to use the original Linux kernel for real-time operations (the Linux system response time is too slow compared with the real-time system, such as a Linux interruption, it may take more than 10 ms. For some industrial-controlled applications, their time requirements are generally at a 1 ms level, and Linux cannot meet such requirements at all .), After all, we didn't plan to make it into a real-time system when designing Linux, so the common processing is to re-compile the Linux kernel or add a shell for Linux, this allows real-time tasks to run in a different way than time-based tasks.
Here we need to mention the relationship between POSIX and real-time Linux. POSIX indicates "UNIX-based portable operating system interface", which aims to promote the portability of software written for UNIX and make the work of UNIX programmers more convenient. Some real-time extensions have been reflected in posix.1b or IEEE 1003.1b. These extensions include tools such as traffic signals, Memory Locking, clock and counter, message queue, and priority preemptive scheduling.
POSIX-based real-time operating system standardization is not recognized by everyone. This standard is too large and contains many characteristics that are suitable for UNIX workstations but do not help embedded systems, so it is very bloated. Also, these tools are based on UNIX, making POSIX system calls as complex and cumbersome as UNIX system calls, in VxWorks or PSOs +, a dozen POSIX calls are required for only one or two calls, which cannot be tolerated by embedded system programmers.
Many Linux developers are implementing posix.1b standardization for Linux. This activity has achieved initial success and continues. POSIX Memory Locking tools and decision scheduling algorithms have been implemented. However, the counter function and posix.1b traffic signal mechanism are still incomplete. In particular, traffic signals and message queues that are critical to any real-time operating system have not yet been implemented.
Although POSIX guarantees the implementation of a Real-Time Linux, only "soft" real-time applications can be implemented using the posix.1b function in the current and foreseeable future. The root problem facing porting posix.1b functions to Linux is that the Linux kernel cannot be preemptible. Therefore, it is impossible to implement "hard" real-time features without making major changes to the kernel.
Another non-POSIX route may be more valuable at present, namely the Real-Time Linux (nmt rt-Linux) project of the University of New Mexico science and technology. Note that Linux is an operating system mainly designed for PC users. Developers conclude that it is impossible to migrate real-time functions to a time-based OS. Instead, they implement a simple Real-Time Kernel under the operating system, and Linux itself runs only as a task on that kernel. The system is described in detail below.
4. Introduction to the implemented real-time Linux
Real-Time Linux has two main categories:
The first type is represented by nmt rt-Linux. Their real-time processes are actually a core module. Therefore, they are actually a real-time driver. rtai and network systems have similar structures. The difference is that the hardware categories of their drivers are different.
The second type is Kurt, Linux/rk, and red-Linux. The system response time of these systems is limited by the time resolution that the PC can achieve. Although red-Linux has pushed this limit to about 1 ms, it is very difficult to expect that it will reach below us in the PC architecture. That is to say, 10 K is required
Applications with the above frequencies cannot use this architecture.
1. nmt rt-Linux
NMT is short for New Mexico technology. This system can be said to be the first success of Real-Time Linux, which has been developed to version 3.0. This system is completed by Victor yodaiken and its student Michael barabanov. The concept of this system is "overhead" the Linux kernel, so that the real-time process can be executed as soon as possible.
In fact, real-time tasks in RT-Linux are not a Linux Process, but a Linux loadable kernel module ). Nmt rt-Linux adopts a simple method. It does not use any Linux function and writes jobs that require high time precision into a driver, then, the driver is called directly using the interrupt generated by the PC time series chip (timer chip. In this way, it can bypass the Linux interrupt mechanism and shorten the system response time.
From this perspective, nmt rt-Linux is actually a real-time driver, not a real-time Linux. However, because of its early appearance and its architecture is very suitable for automatic control, there are many users, most of which are related to automatic control applications.
This system will be discussed in more detail below.
Rtai is short for real-time application interface. As the name suggests, it is a set of interfaces that can be used to write real-time applications. Generally speaking, rtai and nmt rt-Linux are the same thing. It also "overhead" Linux, and implements real-time processes directly using the loadable kernel module. Every real-time process is actually a load-able core module.
The biggest difference between rtai and nmt rt-Linux is that it carefully defines a set of real-time hardware abstraction layers on Linux ). Rthal defines the part of rtai that needs to be modified in Linux as a set of program interfaces. rtai only uses this set of interfaces to communicate with Linux. The advantage of doing so is that we can minimize the workload of porting rthal to the new Linux version by directly modifying the program code at the core of Linux.
The biggest reason for rtai to adopt this approach is that nmt rt-Linux has encountered problems during the migration from version 2.0 to Version 2.2, making nmt rt-Linux based on version 2.2 core unable to be completed. So Paolo mantegazza and his colleagues at Dipartimento di ingegneria aerospaziale Politecnico di Milano decided to do the porting on their own, due to the nmt rt-Linux dilemma, they realized that they must adopt the above approaches to solve the compatibility problems that may be re-faced in the future.
Therefore, rtai was born. It is a better nmt rt-Linux than nmt rt-Linux. Although nmt rt-Linux was later transplanted, but that was half a year after rtai was born.
Since rtai cannot be called directly using a Linux system, the solution is to use a RT-FIFO to connect an rtai real-time kernel module with a real Linux Process, this process is responsible for calling the Linux system for it. It seems that its friendliness has been improved, but the price is "real-time, at this time, real-time tasks no longer can perform any preemptive operations (and "preemptive" is regarded as the best way of real-time systems), so the advantages of real-time systems are no longer available.
Kurt is a system created by the University of Kansas. It is very different from nmt rt-Linux and rtai. Kurt is the first real-time Linux that can use system calls. Because Kurt simply replaces the Linux Process Manager with a very simple time-driven process manager, the execution of real-time processes can easily be affected by other non-real-time processes.
This is a system developed by the University of California Irvine. It is similar to Kurt and is a real-time Linux system that can be called by Linux. It features a "preemption point" to improve the system's response speed. As mentioned above, the biggest problem with Kurt is that it is limited by the original Linux architecture, making the system's response time difficult to control. However, the red-linux version has been greatly improved, and its response latency in version 2.0 is about 100 us.
Red-Linux's flexible Process Manager architecture is also one of its features. It enables red-Linux to meet the needs of various complex systems. It divides process management into two parts: dispartcher and allocator. dispatcher is executed in the core while allocator is executed in the user mode. Allocator can be a part of an application or an independent unit. Generally, it is responsible for converting Application resource requests into a format that can be interpreted by the kernel.
V. nmt rt-Linux Introduction
As mentioned above, although nmt rt-Linux does not seem to be a real-time operating system, it is just a real-time driver, however, it is indeed the most effective and efficient method for implementing real-time systems in general operations, and nmt rt-Linux is also widely used in real-time systems.
1. design objectives
Nmt rt-Linux was initially designed because the University of Science and Technology of New Mexico needed a real-time system to control scientific instruments, which was not completed by time-sharing systems, it is particularly worth mentioning that the uncertainty of the time-based system running status and the delay of interruption are slow. Therefore, nmt rt-Linux mainly solves these two problems.
Nmt rt-the design philosophy of Linux is to make the smallest changes to Linux and only provide things necessary to implement real-time applications, in this way, nmt rt-Linux can be easily transplanted to the new version of Linux. At the same time, nmt rt-Linux relies on Linux to provide almost all required services, nmt rt-Linux only provides real-time task creation, installation of interrupt service routines, and queuing of real-time tasks, ISR and Linux processes. The result of this design is that an nmt rt-Linux application can be seen as having two domains: Real-time and non-real-time. Real-time-domain functions can meet real-time requirements, but they must be relatively simple, because the available resources are very limited; on the other hand, non-real-time functions can use the entire Linux Resource, but there is no real-time requirement. Communication tools between two domains are provided, but before using RT-Linux, embedded system designers must ensure that all functions to be implemented are suitable for one of the two domains. Using RT-Linux does not enable the real-time performance of existing Linux programs. For example, assume that the developer has a Linux driver with a serial port. After the serial port receives a byte sequence, the real-time task is enabled and output a line at a fixed time. This driver is not available, because in a non-real-time domain, you do not know when the serial port driver will wake up the real-time task driver and complete the work. Therefore, both the serial port and the parallel port driver must be in the real-time domain, which requires the re-design of the serial port driver.
2. System implementation
Next, let's take a look at the implementation scheme and description of nmt rt-Linux. Process management, communication, and interruption are introduced in two parts.
A. Process Management
Nmt rt-Linux real-time processes are designed as lightweight threads (lwt), which act as the units for real-time unified scheduling.
During initial design, real-time tasks are assigned an independent address space, while the current version shares the Linux address space with the Linux Process. There are two reasons:
1. Using an independent address space will reduce the TLB hit rate and affect the efficiency;
2. Using the shared address space can make the real-time system a core module that can be dynamically loaded, so that Linux can act as both a time-based system and a real-time system.
In addition, real-time Linux provides a set of system calls for process control, as shown below:
L int rtload (const char * file) loads a real-time task file, creates a process, and returns its PID number. The process is suspended until rtrun is executed.
L int rtrun (int pid) starts to execute a real-time process loaded using rtload.
L int rtkill (int pid) destroys a real-time process
L int rtget_time (rtime * t) to get the current time (a 64bit integer value, which is the number of clock beats after the system starts)
L int rtset_params (rtime * Start, rtime * period, int priority) change the scheduling parameters (priority, etc.) of a process)
L int rtwait_start (rtime * Start, rtime * period, int priority) suspends the process until the given start time, and then continues the process execution at the specified priority.
L int rtwait_period () suspends the process until the next cycle (period)
With these functions, we can implement scheduled tasks and Interrupt Drive tasks. This is sufficient for real-time applications that are not very complex.
When an interruption occurs (inter-process mode switching also needs to be attributed to the interruption ), real-Time Linux does not use the hardware switching mechanism provided by Intel x86 (it saves too many States to make the speed too slow), but simply saves the pattern word to the stack, then switch the stack, which greatly reduces the interruption latency. The pattern word of a real-time process only contains an integer register, which ensures fast mode switching.
The system uses a simple priority-based strong-first scheduling algorithm, which selects a process with the highest priority from the ready process queue and makes it the next execution process. The task voluntarily releases the processor or is heavily occupied by a process with a higher priority. In this way, the process scheduling algorithm of Linux from time slice rotation is changed to a strongly occupied process scheduling algorithm.
Although Linux itself runs at the lowest priority in nmt rt-Linux, it can ensure that any real-time task can interrupt Linux. Therefore, real-time tasks cannot contain system calls provided by Linux (this will lead to re-import ). However, some communication mechanisms must be provided. For example, in a system, a real-time task is responsible for polling the port and storing the received information into a FIFO buffer, while the Linux Process is responsible for reading data from the buffer and displaying (or saving it to a file), reading and writing the buffer must prohibit interruption, so the system must provide a shared data zone, when this data is operated, the interruption is forbidden.
In nmt rt-Linux, the system has some functions used to manage these data zones (the data is organized in FIFO form, known as RT-FIFO), as follows:
L int rt1_o_create (unsigned int FIFO, int size) to create a rt-FIFO with a size.
L int rt1_o_destroy (unsigned int FIFO) destroys the specified RT-FIFO.
L int rt1_o_get (unsigned int FIFO, char * Buf, int count) reads count bytes from FIFO to Buf.
L int rt1_o_put (unsigned int FIFO, char * Buf, int count) Write count bytes to Buf in FIFO.
At the same time, the FIFO Mechanism provides a good way to implement traffic signals. Two-State signal lights can be achieved by creating a 1-level FIFO, and the V operation is rt1_o_put (). The data content does not matter, and the returned error is ignored. The P operation is rt1_o_get (). The Count signal lamp can be simply implemented by creating a FIFO with sufficient size to accommodate the expected number of V Operations. The FIFO mechanism provides most of the functions required for task synchronization in real-time applications. The current implementation is still lacking in some features that RTOS users are used to, such as priority prohibition (preventing priority inversion) and task Security deletion. However, careful design can almost always avoid these problems. In addition, although the FIFO operation can be blocked when there is no data (read FIFO) or no space (write FIFO), The syntax is quite complex, and the blocking capability does not seem to be the focus of the design. However, at least one effort to provide simple syntax for FIFO blocking operations is ongoing, and blocking timeout is also implemented, which is an important feature of many embedded applications. RT-the simple and open design of Linux allows users to easily implement similar additional functions.
Like all other UNIX operating systems, Linux kernel can block interruptions for a long time. Of course, this makes Linux a non-real-time operating system. There are two ways to solve this problem: first, re-design the kernel to make it preemptive. However, the Linux kernel is large and complex and cannot be modified frequently. In addition, we didn't plan to make it into a real-time system when designing Linux. Therefore, adding real-time performance to existing code is not feasible. So the nmt rt-Linux designer used another way to make Linux the first. They divide the interruption into two groups: one group controlled by Linux, and the other group controlled by nmt rt-Linux. RT-Linux interruptions are restricted like RT-Linux tasks, which cannot be called in Linux. Therefore, they can safely interrupt the Linux kernel. On the other hand, Linux interruption does not allow kernel interruption. Therefore, nmt rt-Linux forms a virtual interrupt mechanism, so that Linux itself can never block the interruption. Linux uses the "CLI" and "Sti" macro commands to block and enable interruption. In standard Linux, these macros simply execute the corresponding x86/PC Processor commands. Nmt rt-Linux modifies these macros, instead of blocking interruptions when executing CLI, It redirects to some RT-Linux code. If this is an RT-Linux interrupt, allow it to continue; if it is a Linux interrupt, set a standard BIT. Then, after the STI is enabled and interrupted, the suspended Linux interrupt will continue to be executed. In this way, Linux cannot interrupt itself, but nmt rt-Linux can. RT-Linux is simple. It only provides the functions required to implement a real-time system. However, system designers benefit from this simplicity. Most applications should be implemented in the Linux Process, because Linux itself is stable and reliable, and is familiar to the majority of users, even if you have trouble, you can find help. Real-time tasks only include necessary functions to implement real-time I/O and receive or send data from Linux processes.
During interrupt handling, nmt rt Linux has three modifications to the Linux kernel:
L CLI (clear interrupt) is simply modified to 0 for a global variable that controls the "Soft Interrupt enable" (SIE ).
L STI (set interrupt) is modified to simulate the interruption of all pending interruptions.
L low-level wrapper commands (saving and restoring the interrupted state) are modified to use soft return instead of the original hardware mechanism.
When an interruption occurs, the control is transferred to the real-time processing program, which first performs some necessary processing and then transmits the interruption to Linux. If the Soft Interrupt enable flag is 1, the control is transferred to the Linux handler.
At the same time, it should be noted that Linux is very easy to modify, because in standard x86 Linux, CLI () and STI () in fact, it is an assembly macro command (generate command CLI and STI under x86 ). In general, about 2000 lines of new code are required, and about several hundred lines of Linux code are required. The following are three macros:
S_iret saves the least necessary status to ensure that the kernel data address is accessible.
/* These are macros */
S_cli: mov $0, sf1f
S_iret: Push % DS
Pushl % eax
Pushl % edX
Movl $ kernel_ds, % edX
MoV % dx, % DS
Movl sfreq, % edX
Andl sfmask, % edX
Bsrl % edX, % eax
Movl $0, sf1f
JMP sfidt (, % eax, 4)
Not_found: movl $1, sfif
Popl % edX
Popl % eax
Pop % DS
Pushl $ kernel_cs
Pushl $ done_sti
When an interruption occurs, the interrupt handler first executes the necessary code of the real-time system, and then transmits the interruption to Linux (if "Soft Interrupt enabling" is set to 1 ). Since most I/O drivers are not specifically designed for real-time systems, most real-time drive interrupt handlers simply decide to simply notify Linux. On the other hand, when a clock interruption occurs, increase the time cycle variable by 1 and decide whether to run a scheduled task. When appropriate, the interruption is transmitted to Linux.
If a Soft Interrupt is disabled, the returned result is controlled through iret. Otherwise, the macro calls the corresponding handler for the interrupt.
At the same time, it should be pointed out that a compromise must be found between the clock interrupt speed and the event's non-synchronization. A higher clock interruption speed means that more sampling can be performed on the task to reduce the system response time, but the time used for interrupt switching also increases. Otherwise, the event response time may be too long, affecting the system response time, although this reduces the number of interruptions (time ).
1. How to Select a real-time operating system?
If you want your system to respond quickly enough, and it seems that the response time of the current common real-time operating system cannot meet your requirements (or because the faster you want, the better, for example, a radar warning system), you can consider using a dedicated real-time system, and you can consider using assembly language or even machine language, although this requires a huge amount of work (if the extra work is worthwhile compared to the high-speed requirements of the system ).
If your system is a very simple real-time system, such as a single-chip microcomputer processing system for a washing machine, you may not have to consider a general real-time operating system, because there are a lot of things you can't use at all, such as TCP/IP, memory management, process scheduling, etc. Using a common real-time operating system may make code writing easier, however, the cost of the entire system has increased a lot.
In short, I think that if there are no very demanding requirements for a complex system, we should try our best to use a common real-time operating system. If the requirements are lower, we can consider a Real-Time Linux system, this will be a more cost-effective approach, and its maintainability will also be optimal.
2. How can RT-Linux applications be put into use?
It must be noted that the Linux operating system is not the best embedded platform. This is mainly because of its size. A complete GUI system must be based on a disk or be connected to a network for guidance. However, at present, a large number of embedded applications require disks and Linux built-in GUI and network features, and the number of such applications is growing. For example, many medical devices must use attractive user interfaces to be competitive, and industrial machine control must have both GUI and network. At this time, it seems that you can directly use applications developed on RT-Linux without having to spend any other fees, and because of the openness of Linux, such a system may support more features than those dedicated real-time systems.
However, this is not the case with local real-time applications. A bloated PC is too wasteful. In fact, these applications require extremely few functions, the RT-Linux development platform is only for its convenience. After the development is complete, the task that must be completed is to make it boot from EPROM. In this case, you can install only the components required for a specific application to form a diskless system. For example, a Linux system that includes a network (but does not include X-Windows) has been successfully placed on an EPROM of only 2 to 7 MB. Therefore, in practice, an independent non-disk embedded system can also be developed using Linux. In addition, Linux has the ability to boot from the network. An entire X-Windows system can boot from a disk located somewhere on the network. This also provides a way to make the RT-Linux application practical.
This article is my understanding of real-time systems after I have read several articles about real-time operating systems. Therefore, many of my views in this article are my own opinions, at the same time, some of the results for the author's reference to foreign books, because the author's understanding of the real-time operating system is not very deep, so it is difficult to ensure that it is correct, this article is for reference only. For more information about real-time Linux, see references.
Linux as an embedded operating system, operating system developer, http:// OS .silversand.net/
 A Real-Time Linux, Victor yodaiken and Michael barabanov, New Mexico Institute of Technology
 Linux Kernel Analysis, Chen Lijun, people's post and telecommunications Press
 Linux kernel source code analysis, translated by Feng Rui, Xing Fei, Liu longguo, Lu Lina, and Mechanical Industry Press
 The Art of programming embedded systems, Jack. J. ganssle
 Real-Time UNIX systems: Design and Application Guide, borko furht et al., Kluwer Academic Publishers Group