Page 427 - DCAP103_Principle of operating system
P. 427

Principles of Operating Systems



                   Notes         Once moved, boot reads the root directory of the boot device. To do this, it must understand
                                 the file system and directory format, which is the case with some bootloaders such as GRUB
                                 BootloaderGRandUnified Other popular bootloaders, such as Intel’s LILO, do not rely on any
                                 specific filesystem. Instead, they need a block map, and low-level addresses, which describe
                                 physical sectors, heads, and cylinders, to find the relevant sectors to be loaded. Then it reads
                                 in the operating system kernel and jumps to it. At this point, boot has finished its job and the
                                 kernel is running.
                                 The kernel start-up code is written in assembly language and is highly machine dependent.
                                 Typical work includes setting up the kernel stack, identifying the CPU type, calculating the
                                 amount  of  RAM  present,  disabling  interrupts,  enabling  the  MMU,  and  finally  calling  the
                                 C-language  main procedure  to start the main  part of  the operating system.  The C  code  also
                                 has  considerable  initialization  to  do,  but  this  is  more  logical  than  physical.  It  starts  out  by
                                 allocating a message buffer to help debug boot problems. As initialization proceeds, messages
                                 are written here about what is happening, so they can be fished out after a boot failure by a
                                 special diagnostic program. Think of this as the operating system’s cockpit flight recorder (the
                                 black box investigators look for after a plane crash). Next the kernel data structures are allocated.
                                 Most are fixed size, but a few, such as the page cache and certain page table structures, depend
                                 on the amount of RAM available.
                                 At this point the system begins autoconfiguration. Using configuration files telling what kinds of
                                 I/O devices might be present, it begins probing the devices to see which ones actually are present. If
                                 a probed device responds to the probe, it is added to a table of attached devices. If it fails to respond,
                                 it is assumed to be absent and ignored henceforth. Unlike traditional UNIX versions, Linux can device
                                 drivers do not need to be statically linked and may be loaded dynamically (as can all versions of
                                 MS-DOS  and  Windows,  incidentally).  The  arguments  for  and  against  dynamically  loading
                                 drivers  are  interesting  and  worth  stating  briefly.  The  main  argument  for  dynamic  loading
                                 is that a single binary can be shipped to customers with divergent configurations and have
                                 it automatically load the drivers it needs, possibly even over a network. The main argument
                                 against dynamic loading is security. If you are running a secure site, such as a bank’s database
                                 or a corporate Web server, you probably want to make it impossible for anyone to insert random
                                 code into the kernel. The system administrator may keep the operating system sources and
                                 object files on a secured machine, do all system builds there, and ship the kernel binary to
                                 other machines over a local area network. If drivers cannot be loaded dynamically, this scenario
                                 prevents machine operators and others who know the superuser password from injecting
                                 malicious or buggy code into the kernel. Furthermore, at large sites, the hardware configuration
                                 is known exactly at the time the system is compiled and linked. Changes are sufficiently rare
                                 having to relink the system when a new hardware device is added is not an issue.
                                 Once all the hardware has been configured, the next thing to do is to carefully handcraft process 0,
                                 set up its stack, and run it. Process 0 continues initialization, doing things like programming the
                                 real-time clock, mounting the root file system, and creating init (process 1) and the page daemon
                                 (process 2). Init checks its flags to see if it is supposed to come up single user or multiuser.
                                 In the former case, it forks off a process that execs the shell and waits for this process to exit.
                                 In the latter case, it forks off a process that executes the system initialization shell script, /etc/
                                 rc, which can do file system consistency checks, mount additional file systems, start daemon
                                 processes,  and  so  on.  Then  it  reads  /etc/ttys,  which  lists  the  terminals  and  some  of  their
                                 properties. For each enabled terminal, it forks off a copy of itself, which does some housekeeping
                                 and then execs a program called getty. Getty sets the line speed and other properties for each
                                 line (some of which may be modems, for example), and then types login: on the terminal’s screen
                                 and tries to read the user’s name from the keyboard. When someone sits down at the terminal
                                 and provides a login name, getty terminates by executing /bin/login, the login program. Login
                                 then asks for a password, encrypts it, and verifies it against the encrypted password stored in
                                 the password file, /etc/passwd. If it is correct, login replaces itself with the user’s shell, which
                                 then waits for the first command. If it is incorrect, login just asks for another user name. This
                                 mechanism is illustrated in Figure 14.11 for a system with three terminals.


        420                               LOVELY PROFESSIONAL UNIVERSITY
   422   423   424   425   426   427   428   429   430   431   432