Operating System Concepts

Most operating systems provide specific basic concepts and abstractions, such as processes, address Spaces, files, and so on, that are the core to understand. We will briefly introduce some of the basic concepts below. To illustrate these concepts, we will present examples from UNIX from time to time, and the same examples will also exist on other systems, which we will cover later.

process

A key concept in operating systems is processes. The essence of a process is a program executed by the operating system. Associated with each process is the Address space, which is a list of storage locations from some minimum value (usually zero) to some maximum value. In this address space, processes can read and write. The address space holds the executable program, the data the program needs, and its stack. Associated with each process is a set of resources, usually including registers (registers typically include program counter and stack pointer), a list of open files, emergent alarms, a list of related processes, and other information about programs that need to be executed. You can think of a process as a container for all the information that runs a program.

One way to get a sense of process is to think about building a multi-program system. Consider the situation where a user starts a video editing program, instructs it to convert the video to a certain format, and then goes to the web. At the same time, a background process that checks E-mail is woken up and running, so we now have three active processes: a video editor, a Web browser, and an E-mail receiver. The operating system periodically suspends one process and then starts another, probably because the program has run out of CPU time in the last second or two, and the CPU has moved on to another program.

After temporarily interrupting the process like this, the next time an application starts here, it has to be restored to the same state as it was at the time of the interruption, something that we users seem to take for granted, but inside the operating system is doing a huge thing. It’s like playing football, a perfect game can be played without the referee. This also means that all information about the process is saved when it is suspended. For example, a process may have multiple files open for reading. Associated with each file is a pointer that provides the current location (that is, the number of the next byte or record to read). When the process is suspended, these Pointers must be saved so that the read call after the process is restarted will read the data correctly. In many operating systems, all information related to a process, except the contents of the process’s own address space, is stored in a table in the operating system, called the Process Table. The process table is an array or linked list structure, and each process currently occupies one item in the table.

So, a suspended process consists of the process’s address space (often called core image, core image, memory of the past) and the corresponding process table items (which contain registers and much other information needed to start the process later).

The most critical system calls related to process management are often those that determine the creation and termination of a process. Consider a typical example where a process called a Command interpreter, or shell, reads commands from a terminal. At this point, the user has just typed a command to compile a program. The shell must first create a new process to execute the compiler, and when the compiler is finished, it makes a system call to terminate its own process.

If a process can create one or more processes (called child processes), and those processes can create child processes, it is easy to find the number of processes, as shown below

The diagram above shows A tree of processes. Process A creates two child processes B and C, and child process B creates three child processes D, E, and F.

Related processes that cooperate to complete certain jobs often need to communicate with each other to complete the job. This communication is called interprocess communication. We’ll talk about interprocess communication later.

Other available process system calls include requesting more memory (or freeing memory that is no longer needed), waiting for a child process to terminate, and overwriting that program with another program.

Sometimes, you need to pass information to a running process that is not waiting to receive it. For example, a process communicates over a network by sending messages to a process on another machine. To ensure that a message or reply to a message is not lost. The sender asks its operating system to send a notification after a specified number of seconds so that it can resend if it has not received an acknowledgement. After setting this timer, the program can continue to do other work.

The operating system sends an alarm signal to the process when a specified time has elapsed. This signal causes the process to suspend temporarily, no matter what the process is doing, and the system saves the values of its registers to the stack and starts restarting a special signal handler, such as resending messages that might have been lost. These signals are software-simulated hardware interrupts that can be generated for a variety of reasons in addition to timer expiration. Many traps detected by the hardware, such as executing an illegal instruction or using an invalid address, are also translated into this signal and handed to the process.

The system manager authorizes each process to use a given UID(User IDentification). Each started process has an operating system-assigned UID, and the child process has the same UID as its parent. A user can be a member of a Group, and each Group has a GID(Group IDentification).

In UNIX, there is a UID that is a superuser, or an administrator in Windows, with special rights to violate some protection rules. In large systems, only the system administrator controls which users can be called superusers.

Address space

Every computer has some main memory where programs are being executed. In a very simple operating system, there is only one application running in memory. In order to run the second application, you need to remove the first application to load the second into memory.

More complex operating systems allow multiple applications to run in memory at the same time. To prevent applications from interfering with each other, including the operating system, you need some kind of protection mechanism. Although this mechanism is implemented in the hardware, it is controlled by the operating system.

The above views relate to the management and protection of computer main memory. An equally important and storage-related aspect is managing the address space of the process. In general, each process has a set of addresses available, typically starting at 0 up to a maximum. The maximum address space a process can have is less than main memory. In this case, there is enough memory to run the process even if it runs out of address space.

However, on many computers with 32-bit or 64-bit addresses, there are 2^32 or 2^64 bytes of address space, respectively. What if a process has an address space larger than the main memory the computer has, and the process wants to use all the memory? In the early days of computers it was impossible to process. But now there is a virtual memory technology, and as mentioned earlier, the operating system can put part of the address space into main memory and part of it on disk, and swap it back and forth as needed.

file

Another key concept supported by almost all operating systems is the file system. As mentioned earlier, one of the main functions of the operating system is to mask the details of disks and other I/O devices, giving the programmer a good, clear, abstract file model that is device-independent. System calls are required to create files, delete files, read files, and write files. The file must be located and opened on disk before it can be read, and it should be closed after it has been read. The related system calls are used to do this.

To provide a place to keep files, most personal computer operating systems have the concept of directory, which allows you to group files. For example, students could create a directory for each course to hold resources for that subject, another directory for E-mail, and another directory for world Wide Web home pages. This requires system calls to create and delete directories, put existing files into directories, delete files from directories, and so on. Directory entries can be files or directories, and directories can be nested within each other, resulting in a file system

Both process and file hierarchies are organized in a tree-like structure, but there are some differences between the two tree-like structures. While a typical process has a small tree (rarely more than three levels), a file system has a deeper tree, usually four or even five levels. Process tree hierarchies are transient and usually exist for a few minutes at most, whereas directory hierarchies can exist for a long time. Processes and files are also different in terms of permission protection. In general, the parent process can control and access the child process, and there is usually a mechanism in files and directories to make the file accessible to users other than the file owner.

Each file in the directory layer structure can be identified by the path name starting at the top of the directory, the Root directory. Absolute path name contains everything from the root directory to the file directory listing, separated by slashes separators between them, in the above university departments file system, file the CS101 path name is/Faculty/initial Brown/Courses/the CS101. The initial slash delimiter represents the root directory /, the absolute path to the file system.

For historical reasons, file systems under Windows use \ as the delimiter, but Linux uses/as the delimiter.

On the above system, each process would have a working directory that would look for paths that do not start with a slash and give absolute addresses. If /Faculty/ prof.brown is the working directory, then /Courses/CS101 represents the same file as the absolute pathname given above. A process can change its working directory by specifying a new working directory using a system call.

Before reading or writing a file, you need to open the file and check its access rights. If permission permits, the system returns a small integer, called a file descriptor, for subsequent operations. If access is forbidden, the system returns an error code.

Another important concept in UNIX is special files. Special files are provided to make the I/O device look like a file. In this way, I/O devices can read and write through the same system calls as they can read and write files using system calls. There are two types of special files: block special files and character special files. Block special files refer to devices, such as disks, that are made up of randomly accessible blocks. For example, by opening a block-specific file and then reading block 4, the program can directly access block 4 of the device regardless of the file system structure in which the file is stored. Similarly, character special files are used in printers, modulation and demodulation transmitters, and other devices that accept or output character streams. By convention, special files are stored in the /dev directory. For example, /devv/lp is a printer.

Another feature related to processes and files is pipes, which are virtual files that can connect two processes

If A and B want to talk through pipes, they must set up pipes in advance. When process A sends data to process B, it writes the data to the pipe, which is the output file. Thus, communication between two processes in UNIX is very similar to reading and writing ordinary files.

To protect the

Computers contain a large amount of information, and users want to be able to protect useful and important information, such as E-mail, business plans and so on. The security of managing these information depends entirely on the operating system. For example, files provide authorized user access.

For example, the UNIX operating system protects files in UNIX by assigning a 9-bit binary protection code to each file. The protection code has three segments, one for the owner, one for other members of the owner’s group (users are grouped by the system administrator), and one for others. Each field has one for read access, one for write access, and one for execution access. These bits are known as RWX bits. For example, the guard code rwxr-x–x means that the owner can read, write, or execute the file, other group members can read or execute (but not write) the file, and others can execute (but not read or write) the file.

shell

The operating system is the code that makes the system calls. Editors, compilers, assemblers, linkers, users, and command interpreters, while important and useful, are not really part of the operating system. Let’s focus on the UNIX command prompt, the shell. The shell is useful, but it is not part of the operating system. However, it is a good illustration of many features of the operating system.

There are many kinds of shells, such as sh, CSH, KSH, and bash, all of which support these functions. The earliest shells can be traced back to sh

When the user logs in, a shell starts at the same time, which takes the terminal as standard input and standard output. First, a prompt, which may be a dollar sign ($), is displayed to tell the user that the shell is waiting to receive a command if the user enters

date
Copy the code

The shell creates a child process and runs Date as the child process. While the child process is running, the shell waits for it to finish. When the child process completes, the shell displays a prompt and waits for the next line of input.

The user can redirect standard output to a file, for example

date > file
Copy the code

Similarly, standard input can be used as a redirect

sort <file1> file2
Copy the code

This calls sort to receive the contents of file1 and output the results to file2.

The output of one application can be piped as the input of another, so there are

cat file1 file2 file3 | sort > /dev/lp
Copy the code

The CAT application is called to merge the three files, feeding the results into sort and sorting them by dictionary. The sort application is redirected to /dev/lp, which is obviously a print operation.

The system calls

We can already see that operating systems provide two functions: application abstraction for users and management of computer resources. For the most part, the interactions between the application and the operating system are primarily application abstractions, such as creating, writing, reading, and deleting files. Computer resource management is basically transparent to users. Thus, the interface between the user program and the operating system is primarily about dealing with abstractions. To truly understand the behavior of the operating system, we must carefully analyze this interface.

Most modern operating systems have identical but different system calls that depend on the machine’s own mechanisms and must be expressed in assembly code. Any single CPU computer executes one instruction at a time. If a process is running a user program in user mode, such as reading data from a file. If you want to transfer control to the operating system, you must execute an exception instruction or system call instruction. The operating system then needs to check the parameters to find out which calling process is needed. The operating system then checks the parameters to find the required calling process. The system call is then executed, passing control to the instructions below the system call. Roughly speaking, a system call is like a special procedure call, but only system calls can enter kernel state and procedure calls cannot.

To get an idea of how this is done, let’s take a look at the call using the read method as an example. As mentioned above, there are three arguments, the first to specify the file, the second to point to the buffer, and the third to give the number of bytes to read. Like almost all system calls, it calls from a C program by calling a library of functions with the same name as the system call: read.

count = read(fd,buffer,nbytes);
Copy the code

The system call returns the number of bytes actually read in count. This value is usually the same as nbytes, but may be smaller. For example, the end of a file is encountered in the process of reading.

If the system call cannot be executed, whether because of invalid arguments or disk errors, the value of count is set to -1 and an error signal is placed in the global variable errno. The program should go in and check the results of the system call to see if anything went wrong.

A system call is implemented in a series of steps. To illustrate this concept more clearly, we also take the example of a read call, where arguments are pushed onto the stack before preparing the system call, as shown below

C and C++ compilers use reverse order (the first argument must be assigned to printf(format string), placed at the top of the stack). The first and third arguments are both value calls, but the second argument is passed by reference, that is, the address of the buffer (indicated by &), not the contents of the buffer. C then calls the system library’s read function, which is also the fourth step.

In a library written in assembly language, system call numbers are typically placed where the operating system expects them to be, such as registers (step 5). A TRAP instruction is then executed to switch from user to kernel mode, and step 6 begins at a fixed address in the kernel. TRAP instructions are actually very similar to procedure call instructions in that they are followed by an instruction from a distant location and a return address stored on the stack for later use.

TRAP directives differ from procedure call directives in two ways

  • TRAP instructions change the state of the operating system from user mode to kernel mode, while procedure calls do not change the mode
  • Second, TRAP instructions cannot jump to arbitrary addresses. Depending on the architecture of the machine, either a jump to a single fixed address or an 8-bit field in the instruction is given the index of a table in memory that contains the jump address and then the jump to the specified address.

The kernel code following the TRAP instruction begins checking the system call number and dispatches it to the correct system call handler, usually through step 7 with a table of Pointers to the system call handler referenced by the system call number. At this point, the system call processor runs step 8, and once the system call processor has finished its work, control is returned to the function call library step 9 according to the instructions following the TRAP instruction. This procedure then returns to the client application in the usual way that a procedure call returns, which is step 10. Then, after the call completes, the operating system must also clear the user stack and increment the stackpointer to clear the arguments pushed in before the call to read. This completes the entire read call.

In step 9 above, we said that control might return to the instruction after the TRAP instruction, handing control back to the caller and blocking the system call, preventing the application from continuing. There’s a reason for that. For example, if you try to read the keyboard and there is no input at this point, the caller must block. In this case, the operating system checks to see if there are other processes that can run. This way, when there is user input, the process will alert the operating system and return to step 9 to continue.

Below, we’ll list some of the commonly used POSIX system calls. There are more than 100 POSIX system calls, and the most important ones are listed in the table below

Process management

call instructions
pid = fork() Creates a child that is the same as the parent
pid = waitpid(pid, &statloc,options) Wait for a child process to terminate
s = execve(name,argv,environp) Replace the core image of a process
exit(status) Terminates process execution and returns status

File management

call instructions
fd = open(file, how,…) Open a file using read and write
s = close(fd) Close an open file
n = read(fd,buffer,nbytes) To read data from a file into a buffer
n = write(fd,buffer,nbytes) Write data from a buffer to a file
position = iseek(fd,offset,whence) Moving file pointer
s = stat(name,&buf) Gets file status information

Directory and file system management

call instructions
s = mkdir(nname,mode) Create a new directory
s = rmdir(name) Delete an empty directory
s = link(name1,name2) Create a new directory entry name2 and point to name1
s = unlink(name) Delete a directory entry
s = mount(special,name,flag) Install a file system
s = umount(special) Unmount a file system

other

call instructions
s = chdir(dirname) Change working directory
s = chmod(name,mode) Change the protection bit of a file
s = kill(pid, signal) Sends a signal to the process
seconds = time(&seconds) Gets the time from January 1, 1970 to the present

The system call parameters above have some common parts, such as PID system process ID, fd is the file descriptor, n is the number of bytes, position is the offset in the file, and seconds is the elapsed time.

From a macro perspective, the services provided by these system calls define the functionality that most operating systems should have, and the different system calls are explained below

System calls for process management

In UNIX, fork is the only way to create a process in POSIX by creating a copy of the original process, including all file descriptors, registers, and so on. After fork, the original process and copies (parent and child) are separated. During fork, all variables have the same value, and while the parent process’s data is copied to the child process, subsequent changes to either process do not affect the other. The fork call returns a value that is 0 in the child and equal to the child’s Process identifier (Process IDentified (PID)) in the parent. Using the returned PID, you can see which is the parent and which is the child.

In most cases, after fork, the child needs to execute different code than the parent. Read commands from a terminal, create a subprocess, wait for the subprocess to execute the command, and then read the next input instruction after the subprocess finishes. To wait for the child to complete, the parent needs to execute the WaitPID system call, and the parent waits until the child terminates (or any child terminates if there are more than one). Waitpid can wait for a specific child process, or for any older child process by setting the first parameter to -1. When waitPID is complete, the address pointed to by the second parameter statloc is set to the exit status (normal or abnormal termination and exit value) of the child process. There are various options available, which are determined by the third parameter. For example, return immediately if there are no child processes that have exited.

So how does a shell use fork? After typing a command, the shell invokes fork to create a new process. This child process will execute the user’s instructions. System execution is achieved by using the execve system call, which causes the entire core image to be replaced by a file given by the first parameter. Here is a simplified example of fork, Waitpid, and execve

#define TRUE 1While (TRUE){/* keep looping */ type_prompt(); /* Display prompt on screen */ read_command(command,parameters) /* Read input from terminal */ if(fork()! = 0) {/ * fork the child * / * / / * parent code waitpid (1, & status, 0). Execve (command,parameters,0) execve(command,parameters,0) execve(execve,parameters,0) execve(execve,parameters,0) execve(execve,parameters,0) execve(execve,parameters,0) execve(execve,parameters,0) execveCopy the code

Typically, execve takes three parameters: the name of the file to execute, a pointer to an array of variables, and a pointer to an array of environments. Here is a brief description of these parameters.

Let’s start with a shell directive

cp file1 file2
Copy the code

This command copies file1 into file2, and after the shell forks, the child processes locate and perform the file copy, passing it the names of the source and destination files.

The main program of CP (and the main program that contains most other C programs) contains declarations

main(argc,argv,envp)
Copy the code

Where argc is a count of the number of arguments on the command line, including the program name. For the above example, argc is 3. The second argument, argv, is a pointer to the array. The element I of the array is a pointer to the i-th string on the command line. In the above example, argv[0] points to the string cp, argv[1] to the string file1, and argv[2] to the string file2. The third argument to main is a pointer to the environment, which is an array with an assignment of name = value to pass information to the program, such as the terminal type and root directory. These variables are often used to determine how the user wants to accomplish a particular task (for example, using the default printer). In the example above, no environment parameters are passed to execve, so the environment variable is 0, so the third parameter to execve is 0.

Execve is probably the most complex of all POSIX system calls. The rest are relatively simple. As a simple example, let’s look again at exit, which is the system call that the process should make after execution is complete. This system call has one parameter with an exit status between 0 and 255, which is returned to the parent via statloc in the WaitPID system call.

UNIX processes divide memory into three parts: text segment, such as program code, data segment, such as variables, stack segment, and stack segment. The data grows up and the stack grows down, as shown in the figure below

In the middle is the free area, or unallocated area, which the stack automatically squeezes as needed, but the expansion of the data segment is explicitly done through the system call BRK, which points to a new address after the expansion. However, this call is not defined in the POSIX standard, encouraging programmers to use malloc functions for dynamic allocation of memory, and the internal implementation of Malloc is not a suitable topic for standardization, since few programmers use it directly.

System calls for file management

Many system calls are related to the file system, and to read or write a file, you must first open it. The system call specifies the name of the file to open by either an absolute pathname or a relative pathname pointing to the working directory, and the code O_RDONLY, O_WRONLY, or O_RDWR means read only, write only, or both, respectively. To create a new file, use the O_CREATE parameter. You can then read and write using the returned file descriptor. The file can then be closed with close, and this call causes the file descriptor to be used again in subsequent open.

The most common calls are read and write, which we discussed earlier. Write takes the same arguments as read.

While most programs read and write files frequently, some applications need to be able to randomly access any part of a file. Associated with each file is a pointer to the current location of the file. In sequential reads and writes, this pointer usually points to the next byte to be read (written). The Iseek call can change the value of the position pointer so that subsequent read or write calls can start anywhere in the file.

Iseek has three parameters: position = Iseek (fd,offset,whence). The first parameter is the file descriptor. The second parameter is the file location. After modifying the pointer, Iseek returns the absolute location in the file.

UNIX stores the type (normal, special, directory, and so on), size, last modification time, and other information for each file, which the program can view through the STAT system call. S = stat(name,&buf), the first parameter specifies the file to be checked; The second argument is a pointer to the structure that holds the information. For an open file, the fstat call does the same job.

System calls for directory management

Next we’ll look at system calls to directories and the entire file system, above for a particular file. Create s = mkdir(nname,mode) and delete s = rmdir(name). The next call is s = link(name1,name2). This allows the same file to have two or more names. Most of the time link is used in different directories. How does link work

There are two users, the AST and Jim, each with his own directory and files if the AST wants to execute an application containing the following system calls

link("/usr/jim/memo", "/usr/ast/note");
Copy the code

The Memo file in Jim will now go into the ast directory under the Note name. After that, /usr/jim/memo and /usr/ast/note will have the same name.

Whether the user directory is stored in /usr, /user, /home, or any other location is up to the local system administrator.

To understand how Link works, you need to know what Link does. Every file in UNIX has a unique version, also known as an i-number, which identifies the version of the different file. This i-number is the index of the i-Nodes table. Each file indicates who owns the file, where the disk block is located, and so on. A directory is simply a file containing a set of (I number, ASCII name) corresponding files. In the first versions of UNIX, each directory entry had 16 bytes, two bytes for its I-number and 14 bytes for its name. Now a more complex structure is needed to support long file names, but conceptually a directory is still a collection of series (i-numbered, ASCII names). In the figure above, mail’s I-number is 16, and so on. Link simply takes the I-number of an existing file and creates a new directory entry (perhaps with a new name). In figure B, you can see that there are two files with the same 70 I-number, so they need to have the same file. If one of them uses an Unlink system call, one of them will be removed and the other will remain. If both files are removed, UNIX finds that the file does not have any non-directory entries (a field in the I-node records directory entries pointing to the file) and removes the file from disk.

As we mentioned above, the mount system s = mount(Special,name,flag) call merges the two file systems into one. It is common to distribute the root file system, which contains binary (executable) versions of commonly used commands and other frequently used files, on the hard disk (subpartition) and the user files on another (subpartition). The user then inserts a readable USB hard drive.

The USB file system can be added to the root file system by executing the mount system call,

That’s true if it’s executed in C

mount("/dev/sdb0"."/mnt".0)
Copy the code

Here, the first parameter is the block-specific file name for USB drive 0, the second parameter is the location in the tree to be installed, and the third parameter indicates whether the file system to be installed is read-write or read-only.

When a file system is no longer needed, you can use umount to remove it.

Other system calls

In addition to process, file, and directory system calls, there are other system calls, which we’ll explore. We can see that there are only four other system calls above. First look at the first chdir, chdir call changes the current working directory, in the call

chdir("/usr/ast/test");
Copy the code

After the xyz file is opened, the /usr/ast/test/xyz file is opened. The working directory concept eliminates the need to always enter a long file name.

On UNIX systems, every file has a protected mode, which has a read-read-execute bit that distinguishes owner, group, and other members. The chmod system call provides operations to change file modes. For example, to make a file readable to users other than the owner, you can perform

chmod("file",0644);	
Copy the code

The kill system call is how users and user processes send signals, and if a process is ready to catch a particular signal, a signal handler is run before the signal is caught. If the process is not ready to catch a particular signal, the arrival of the signal kills the process (hence the name).

POSIX defines several processes for time processing. For example, time returns the current time in seconds, with 0 corresponding to January 1, 1970. On a 32-bit computer, the maximum value of time is (2^32) -1 second, which corresponds to a little more than 136 years. So in 2106, 32-bit UNIX systems will be on the run. If you have a 32-bit UNIX system now, you are advised to switch to a 64-bit operating system in 2106.

Win 32 API

All of the above are UNIX system calls. Now let’s talk about system calls in Win 32. Windows and UNIX are fundamentally different in the way they program. UNIX programs consist of code that performs some operations or others, making system calls to perform some services. Windows systems are different. Windows applications are usually event-driven. The main program waits for some event to happen and then calls the program to handle it. The simplest event handling is keystrokes and mouse slides, or mouse clicks, or the insertion of a USB drive, and then the operating system calls the processor to handle the event, update the screen and update the internal state of the program. This is a different design style from UNIX.

Of course, Windows also has system calls. In UNIX, there is an almost one-to-one relationship between a system call (such as read) and the call library that the system call uses (such as read). In Windows, things are quite different. First, there is little correspondence between library calls and actual system calls. Microsoft defines a set of procedures, called the Win32 Application Programming Interface, through which programmers implement system calls. This interface supports all versions of Windows from Windows 95 onwards.

The number of Win32 API calls is very large, there are thousands more. However, not all of these calls are run in kernel-mode, some are run in user-mode. The Win32 API has numerous calls to manage Windows, geometry, text, fonts, scroll bars, dialogs, menus, and other GUI functions. In order for the graphics subsystem to run in kernel mode, system calls are required; otherwise, only library calls are required.

Focusing on Win32 system calls, we can take a quick look at how system calls in Win32 APIS differ from those in UNIX (not all system calls).

UNIX Win32 instructions
fork CreateProcess Create a new process
waitpid WaitForSingleObject Wait for a process to exit
execve none CraeteProcess = fork + servvice
exit ExitProcess To terminate execution
open CreateFile Create a file or open an existing file
close CloseHandle Close the file
read ReadFile Reads data from a single file
write WriteFile Write data to a single file
lseek SetFilePointer Moving file pointer
stat GetFileAttributesEx Get different file properties
mkdir CreateDirectory Create a new directory
rmdir RemoveDirectory Remove an empty directory
link none Win32 does not support link
unlink DeleteFile Destroy an existing file
mount none Win32 does not support mount
umount none Win32 does not support mount, so it does not support mount
chdir SetCurrentDirectory Switch the current working directory
chmod none Win32 does not support security
kill none Win32 does not support signals
time GetLocalTime Get the current time

In the table above, UNIX calls roughly correspond to Win32 API system calls. CreateProcess Creates a new process that combines the UNIX commands fork and execve into one. It has a number of parameters that specify the nature of the newly created process. There is no UNIX process hierarchy in Windows, so there is no concept of parent and child processes. After a process is created, the creator and the created are equal. The WaitForSingleObject is used to wait for an event, which can be any number of possible events. If a process is specified with an argument, the caller waits for the specified process to exit, which is done through ExitProcess.

Then there are the six file operations, similar in function to UNIX calls, but different in parameters and details. As in UNIX, files can be opened, read, written, and closed. SetFilePointer and GetFileAttributesEx set the location of the file and get the file’s attributes.

Windows has directories that are created and removed using the CreateDirectory and RemoveDirectory API calls, respectively. There is also a tag for the current directory, which can be set by SetCurrentDirectory. Use GetLocalTime to get the current time.

Win32 interface does not have file linking, file system mount, umount and stat, of course, Win32 also has a lot of UNIX does not have system calls, especially for GUI management and call.

Operating system architecture

We will explore several operating system architectures, including singleton architectures, layered systems, microkernels, client-server systems, virtual machines, and outer cores. Let’s take a look at this

Monomer system

On most systems so far, the entire system runs as a single program in kernel mode. The entire operating system is written as a collection of programs, linked together to form a large binary executable program. With this technique, the system is free to call any other procedure if each procedure in the system provides some useful computation required by the former. In the monomer system, call any needed by a program is very efficient, but tend to thousands of unlimited call each other very bloated and clumsy, and monomer system must exist problem, that is as long as the system fails, then any system and the application will not be available, this is often disastrous.

When the actual object program is constructed in a singleton system, all the individual procedures (or files containing them) are first compiled and then bound together into an executable using the system linker

For unitary systems, there are often several recommendations

  • There needs to be a main program that invokes the requesting server
  • You need a set of service procedures to perform system calls
  • A set of service routines is required to assist service procedure calls

In a singleton system, there is a service to secure and run each system call. A set of utilities is required to compensate for the functionality required by the service, such as fetching data from the user program. Processes can be divided into a three-tier model

Many operating systems support additional extensions in addition to the core operating system that is loaded when the computer is first booted up. Such as I/O device drivers and file systems. These parts can be loaded on demand. They are called shared libraries in UNIX and Dynamic Link Libraries (DLLS) in Windows. Their extension is.dll, and there are more than 1000 DLL files in C:\Windows\ System32, so don’t delete the FILES on drive C easily, or they might explode.

Layered system

Layered systems use layers to separate different functional units. Each layer communicates only with the upper and lower layers of that layer. Each layer uses the layer below to perform its functions. Communication between layers is via predefined fixed interfaces.

THE layered system is THE system developed by E.W.Dijkstar and his students at THE Netherlands Institute of Technology.

The above monomer system is further generalized, it becomes a hierarchical structure of the operating system, its upper software is built on the basis of the lower software. The system is divided into six layers, as shown below

Layer no. function
5 The operator
4 The user program
3 Input/output management
2 Operator-process communication
1 Storage and drum management
0 Processor allocation and multiprogramming

The processor runs at layer 0. When an interrupt occurs or the timer expires, the process switch is completed at this layer. Above layer 0, the system consists of sequential processes that can be written without considering the details of running multiple processes on a single processor. Memory management is at layer 1, which allocates main memory for processes. Layer 1 software ensures that whenever a page needs to be accessed, it must already be in memory and removed when the page is no longer needed.

Layer 2 handles the communication between the process and the operator console (that is, the user). Layer 3 manages the I/O devices and the associated information flow buffers. The fourth layer is the user program layer, which does not worry about details such as process, memory, console, or I/O device management. The system operator is on level 5.

The microkernel

In the layered approach, the designer determines where to divide the kernel-user boundary. Traditionally, all layers are in the kernel, but this is not necessary. In fact, it’s probably better to minimize the functionality in kernel mode. Because errors in the kernel are difficult to handle, errors in the kernel state can drag down the entire system.

Therefore, to achieve high reliability, it is necessary to divide the operating system into small, hierarchical modules, with only one module – the microkernel – running in kernel mode and the rest running as normal user processes. Because each device driver and file system is treated separately as a normal user process, errors in these modules can crash the modules, but not the entire system.

MINIX 3 is a masterpiece of the microkernel, and its structure is as follows

Outside the kernel, the system is constructed with three layers, all of which run in user mode, with the device driver at the bottom. Because they run in user mode, they cannot physically access the I/O port space or issue I/O commands directly. Instead, to be able to program the I/O device, the driver completes a call by building a structure that specifies which parameter values are written to which I/O port and claiming a kernel call.

Above the user-mode drivers is the server layer, which contains the servers that do most of the work of the operating system. File systems are managed by one or more file servers, and processes are created, destroyed, and managed by process managers. There is a special server in the server called reincarnation Server, whose job is to check that the server and the driver function correctly, and when errors are detected, it fixes them without user intervention. In this way, the system has recoverability and high reliability.

The kernel in the microkernel also has the idea of separating mechanism from policy. For example, system scheduling, a relatively simple scheduling algorithm is to assign a priority to each process and let the kernel execute the process with the highest priority. Here, the kernel mechanism is to find the highest priority process and run it. The policy (giving priority to the process) can be completed by the process in user mode. In this pattern, policies and mechanisms are separated, making the kernel smaller.

Client-server mode

The microkernel strategy is to divide processes into two types: servers, each used to provide services; Clients, using these services. This pattern is called the client-server pattern.

Client-server mode will have two carriers, one case is a computer is both client and server, in this way, the operating system will have some optimization; But it is common for the client and server to be on different machines, connected over a local area network or wan.

The client communicates with the server by sending messages that the client does not need to know whether the messages are being processed on the local machine or sent over the network to a remote machine. For the client, both situations are the same: you send a request and get a response.

More and more systems, including the PC in your home, are becoming clients, and large machines running somewhere are becoming servers. Much of the Web works this way. A PC asks a server for a Web page, and the server returns the Web page to the client. This is a typical customer-server pattern

Article Reference:

Modern operating systems, fourth edition

baike.baidu.com/item/ Operating system /1…

Modern Operating System Forth Edition

Faculty.cs.niu.edu/~hutchins/c…

www.computerhope.com/jargon/c/cl…

Station B – Operating System

www.bilibili.com/video/av955…

En.wikipedia.org/wiki/System…

C.biancheng.net/cpp/html/23…

www.dossier-andreas.net/software_ar…