|
|
Unlike a small computer operating system, the UNIX system is designed to run continuously. Constant operation allows it to schedule tasks a long way in advance, and ensures that the services it provides are available on demand, whenever they are needed. All systems need to be shut down periodically for maintenance, but it is not uncommon for a UnixWare system to run for several weeks or even months between shutdowns.
Whenever you start up a UNIX system, it goes through the following complex life cycle:
If all is well, the light on the computer's first floppy disk drive flashes. If a disk containing a small program called a boot program is present in the drive, it will then read the program in and proceed to the next stage; if there is a hardware fault and the POST fails, the computer will either beep a series of tones at you or display a message on its monitor, and refuse to go any further.
At this stage, the computer is minimally functional. The boot(1M) program cannot make use of virtual memory, mount filesystems, or do any of the other tasks associated with the system; neither can it run under the system when it is operational. What it can do is prompt you for the name of a file to execute, then search the root directory of the root filesystem for that file and load it. To do this it places a prompt on the system console:
[boot]#and then it waits for you to type the name of the kernel, or any additional instructions that it recognizes. If you do not type anything, it will time out after a specified period and load the default file listed in /etc/default/boot.
When the kernel begins to run, it starts by setting up a number of internal lists, or tables. These tables are used to keep track of running processes, memory allocation, open files, and a number of other things; they are not directly accessible to you. However, two of them which are of interest are the process table (portions of which you can list out with the ps command) and the buffer cache, which is described in ``Understanding filesystems and devices''.
After initializing its tables, the kernel creates three dummy processes; sched, pageout and bdflush (with process IDs 0, 2 and 3 respectively). These processes are sections of kernel code which must be called periodically; pageout provides virtual memory paging services, sched provides swapping services, and bdflush flushes the buffer cache periodically. None of these processes can be killed; they are part of the kernel, and are essential to the correct running of the UNIX system.
Finally the kernel creates a third process: init(1M), or process 1. init starts up as a dummy process, then achieves independence: it runs as the first true process on the system. init runs continuously; it is the parent of all other processes on the system.
init executes other programs via the fork system call. Each time init calls fork, it passes control to the kernel, which creates a new entry in the process table, allocates a temporary storage area called a U-area, and copies the calling processes' local data (including the stack) into the U-area. The kernel then returns control to the child process, which may make an exec call, overwriting itself with a new program. init periodically reads a file called /etc/inittab, which tells it which programs to execute at any given run level.
The init(1M) program should not be confused with the init process; the former is an executable program which can be used by the administrator to change the run level of the system or cause the init process to reread the /etc/inittab file.
It is not uncommon for a system to remain in multiuser mode for days or weeks at a time. However, it is necessary for the system administrator to shut it down for maintenance at regular intervals.
The kernel effectively mediates the demands of each process, by scheduling the processes to run one after another. The signal for the kernel to take over is sent by the system clock; every hundredth of a second the kernel wakes up and checks to see if the current process has had its time allocation. If so, the kernel suspends the process and switches execution to the process on the queue with the highest priority.
The kernel also mediates all requests for memory and requests to load and run other processes. The requesting process (be it init or any other process) issues a ``system call'', a request to the kernel to deliver a service; it then suspends execution (sleeps) until the kernel can deliver the requested facility.