9. Operating System’s Design Guidelines 481
9.1 Run a Simple Program to See What the Operating System Has Done
The most effective way to understand the operating system clearly is to see what the oper- ating system has done when a simple program is executed on a computer.
We take a “hello world” of C language version as example:
9 Operating System’s Design Guidelines
#include <stdio.h>
void main() {
printf(“hello world\n”);
}
After this program is compiled and linked, an executable file will be generated. We run this program on Linux, and eventually the system will display “hello world” on the screen. Intuitively, “hello world” displayed on the screen is all because of the programs we have written, but in fact, the program we have written only plays a small role. Obviously, the program calls the printf library function of C language because the theme of this book is the operating system, so we won’t discuss library function.
Let’s briefly investigate what the Linux 0.11 operating system has done for running the hello program. The following small words are summary descriptions of the operating system work, involving more than 10,000 lines. Except for interprocess communication, it touches on almost all aspects of the operating system. We want readers have an intuitive understanding of what Linux has done when the simplest program is running.
Case description: There is an executable file named hello in hard disk, and the source program of the file is as front:
Now the system has been in the idle state, the user prepares to make the program of the file in the hard disk load and execute through typing a command, “/hello”, and eventually to make the hello world string display.
The first step: The user inputs command, and shell process is waken up to ana- lyze the order.
To achieve this step, the system will do at least the following preparations:
(1) The user stroke, and the information typed in is recorded in terminal equip- ment file tty0.
If the system operates the terminal equipment in the form of file, it needs to construct a set of file systems first, and then load the file system, so as to oper- ate the files on this basis. The file system includes “super block,” “logic block bitmap,” “i node bitmap,” “file i node,” “block,” etc. Second, classify the data according to the different function of files, including regular file, device file, directory file, etc. tty0 belongs to device files. It is likely to operate terminal device file tty0 with these preparations.
(2) After stroke, it also produces the keyboard interrupt, and the system will be able to process the keyboard interrupt.
First of all, the interrupt will transmit to programmable interrupt controller 8259A, so we need to set the interrupt controller 8259A. Then, the interrupt will be communicated with the CPU, and the CPU will find the interrupt descriptor table in memory through the interrupt descriptor table register IDTR and then find the keyboard interrupt handler through searching the interrupt descriptor table and execute the program. In order to realize these operations, it needs to construct a set of interrupt service systems, including the interrupt descriptor table register IDTR setting, and establishing an interrupt descriptor table to link the interrupt service routine. Then it also needs to program the interrupt service routine to be able to serve for the specific interrupt. In addition, it also needs to link the interrupt service routine with the interrupt descriptor table.
(3) The interrupt service routine starts to execute and wakes up process shell.
After that, switch process 0 to process shell to execute through the process scheduling mechanism.
It needs the system to establish a set of process management mechanisms.
For shell, it needs to create process and load process shell, so that we can estab- lish the human-machine interactive interface. At the same time, it also needs to create a process 0 and switch to process 0 to execute when other processes are not in ready state, and once there is a process that has been waken up, switch to the process to execute immediately. This mechanism is applicable to all processes of the operating system. Before supporting multi-processes execution, we need to design a set of process schedule mechanisms, which produce timer interrupt, leading to process switching. There are a lot of prob- lems that need to be considered in this mechanism, such as designing timer interrupt service handler and 8253 timer setting, etc.
(4) Process shell reads the command information that the user has typed from the terminal device file tty0 through the execution of its own program and then analyzes the command and prepares to execute the corresponding treat- ment. Of course, this command cannot be input by knocking the keyboard only once. Each stroke can repeat the action above, and then process shell sleeps again and waits for the next keyboard interrupt.
So far, the system is only responding to the command the user typed, and the official processing hasn’t started yet. These preparations introduced above are the simplest introduction of the specific steps, and behind these prepara- tions, there is more preparation work. Strictly speaking, to carry out this first step, the preparation introduced in the first chapter and second chapter of this book is almost all useful.
The second step: After process shell analyzes the user command, call fork() creates a user process, so that we can control the program of the “hello world” file.
The system needs to create at least a set of process management structures for user process here, and each process will have such a structure in order to control the future loading program. This structure is very complicated, including time slice, priority, process status, the corresponding files of the process, the task state descrip- tor table TSS of the process, and the local descriptor table LDT of the process, etc.
Each of these fields has a strong relationship with the operation of the system. Take TSS as example, it contains all the data in the register for the current running pro- cess, and once there is process switching, the system will store the value of each cur- rent register in the TSS while, at the same time, using the data in the TSS to set the value of each registers of the process which will switch to and finally switch. Visibly, the data in TSS is the fundamental guarantee for process switching. For another example, LDT contains the code segment descriptor and data segment descriptor for the current process, and the two descriptors both control the program controlled by process directly, and the fundamental purpose of process operation is to execute the user program.
In addition, each process has TSS and LDT. To facilitate the management, it also needs to design a set of data structures, which is a global descriptor table GDT, and the TSS of all process and LDT indices are both stored in the GDT. In order to facilitate the operation of GDT and further operation of LDT and TSS, the system also needs to set the special registers of these three tables in CPU, which are global descriptor table register (GDTR), local descriptor table register (LDTR), and task register (TR).
But only these are far from enough, the beginning of the BOOT is the real mode, and the value in each segment register is the actual address value. The data in the segment register becomes the segment selector until the system gets into pro- tected mode, so that the GDT table can participate in the application, so the system should do a full range of preparations in order to converse from the real mode to protected mode.
These above are only expansion analysis for TSS and LDT, the other fields in the process management structure also have a close relationship with the system; for example, the most basic way of process scheduling is through the time slice rotary, and the most important reference of time slice rotary is the time slice of the current process. For another instance, only process is able to operate files, so the process will build comprehensive relationships with the files, including file i nodes, the item in file management table, and the file management pointer table of process itself, and so on.
To create process, we must create a process management structure, with all fields of process management structure, and all of these fields should all be created and set. In addition to process management structure, when creating process, it also needs to duplicate a pages table and create a page directory entry for the new pro- cess, and all of these have a direct relationship with the application of the memory page, and the strategy of the memory application is one of the most complex applica- tion strategies in the whole operation system.
Step 3: After creating a new process, load the corresponding program of file hello world.
To complete this step, process will do comprehensive preparation in two aspects: One is files, and the other is memory. The program “hello world” must be stored in the executable file in the hard disk, so it must check whether the files are available before loading the file. It mainly displays in the file i node detection and the file header testing. I node is the file management information; as long as the i node is involved, it can’t get away from the i node search, so we should analyze the file path, operate directory file and directory entry, operate i node table, and so on, no one less. File header is stored in the data block and can’t manipulate the data block without the support of logical block bitmap, so we will use the whole content involved in the entire file system.
With the file loading conditions, we will load file “hello world” into memory, so the system will solve all issues related to memory, including removing the relationship with the original process shared page. This involves the page reference count, page management mechanism with three level (page directory table, page table, page), page data (read-only/can read write), and a series of problems, and the system will have to establish page write protection mechanisms for this to solve these problems.
From above description, we can easily find that the operating system does a lot of work even to run a simple program. We may conclude that if we think in the contrary way: Without the operating system, we have to write all these complex programs with the function of an operating system even to print a message “hello world” on the screen.
No doubt that without the operating system we can hardly load computer with pro- grams and not even get the results.
So what does the operating system do to run the application on earth?
Through comprehensive analysis, we get some conclusions here: OS is supposed to provide applications of the basic programs for the use of hard disks, monitors, and key- boards. In other words, the operating system provides supports to peripherals for the run- ning of an application. If the operating system doesn’t write these supporting programs, the application has to write them, and the contents of these programs that all the applica-
But only solving these problems is far from enough; the program’s loading is also a very exquisite strategy, of which the most important is page fault interrupt mecha- nism; namely it must analyze whether it needs to apply for a new page to load the content of the program according to the need. For this reason, it needs to judge much related data so as to determine the necessity of loading, such as whether the corre- sponding physical address of linear address have been mapped into the linear address space, etc., which requires a physical address to linear address mapping scheme. In addition, the design of the page fault interrupt mechanism is also very exquisite. Page fault is not equal to must loading in the peripherals program. For example, a page fault exeception as the result of pushing stack also needs to apply for a new page to load data, but this has no relationship with peripherals. These are all problems that the designing of the page fault interrupt mechanism needs to be comprehensively considered.
In short, the load of program “hello world” almost involves all aspects of file management and memory management. Moreover, the above is just the most basic introduction of loading process “hello world”. Linux supports the execution of the processes, and each process is likely to load its own programs, furthermore, files and memory are the resources all processes share, thus there still exists a more complex management relationship between them. For example, when two processes load the same file “hello world”, whether to share, how to share, how to calculate the count of page reference after share, how to determine the attribute of reading and writing, etc., are all problems.
Step 4: Program “hello world” starts to execute, making string “hello world”
display on the screen.
Program “hello world” will start to execute after loading into memory. The pro- gram is simple, and it is to let the string “hello world” display on the screen. But, even so, the system will have to do a lot of work for this, of which the most important is the aspects about display, such as how to determine the video card attributes, display card is monochrome or color; how to determine the video memory location; how to deter- mine the position displaying on the screen; if there are too many characters; whether rolling show is needed and how to display, etc. These problems will be all done by the operating system, and it directly interacts with the bottom hardware of the display.
tions have to write are just alike. So the operating system can be seen as the part that is shared by all the applications.
Modern operating systems like Linux not only provide support to peripherals for appli- cations, but also support the running of several programs at the same time. It means that the operating system not only supports peripherals, but also makes efficient organization man- agement and coordination for many programs that are running, in order to avoid any pro- gram obtains the whole resources of CPU, RAM and peripherals, making the other programs unable to work normally. Besides, it has to prevent mutual reading, writing, and covering among running programs to make sure all the programs work normally. The key is that the operating system can’t be read or written directly by applications, or covered by applications.
9.2 Thoughts on the Design of the Operating System: