The necessity and implementation of system call in operating system

Source: Internet
Author: User

before remember <?xml:namespace prefix = o ns = "Urn:schemas-microsoft-com:office:office"/>

This period of time is really too busy, there is a long time did not write a report, this time Pyos development is basically and half stagnant state, the first two days just built a pyos CVS (http://pyos.binghua.com), Hope has been the development can be a little more efficient a little ~ ~ ~ :)

Recently did not do anything, only completed a system call experiment, to get back to the bottom, I would still introduce my experiment.

Experimental Review the need for system calls in the operating system

Each operating system has a very important component, which is the system call. The operating system provides services to the processes through system calls, and processes also obtain operating system services through appropriate system calls. System call is a bridge between the application and the operating system, which is the interface between them, and also has a direct influence on the compilation link of the program. One of the most common system calls is a memory allocation function (such as the malloc of C), which returns a pointer to a memory to the application. A simple look, as if the system call is not the same as the normal function, but if you look closely, you will find that there is a significant difference between them.

Let's take a look at another example of a system call, a screen output function (such as printf in C), to illustrate how a system call differs from a normal function.

Let's take a look at how the general functions are written:

void Myprint (char ch)

{

static int x_pos = 0; Record the x position of the current cursor, initially equal to 0

static int y_pos = y; Record the y position of the current cursor, initially equal to 0

Output (X_pos, Y_pos, ch); In the screen of X_pos with y_pos output character ch,

Output is a virtual function, and in our discussion it can be

To be used for output, as to how it is implemented internally, we do not

With care

++x_pos; Because a character is output, the cursor should automatically move down one position to print a new

To the character of the time, will not overwrite the original character

}

The above code seems completely fine, but let's consider that there are two programs A and B, all of which use this common function, so that when they are loaded into memory, they appear as shown in the following illustration:


From the above we can see clearly that in this case both A and B contain a separate copy of the function of myprintf, and that both A and B use their own x_pos and y_pos to locate the current cursor position. So there's this question:

Suppose a runs first, X_pos and Y_pos are initialized to 0, this is a printed five characters, then, the X_pos value should be 5, and then the B run, because B is using its own x_pos and Y_pos, so for B, X_pos and Y_pos value is still 0, B will then print its characters at the (0,0) position, that is, the results of the B run will overwrite the results of the previous a run. So let's think again, in systems such as DOS or Linux, you run a program, run the second program, and the second program overwrites the results of the first program.

The reason for this improper problem is that there are two parts of X_pos and Y_pos in the system memory space, which means that there are two cursors, in fact the system has only one cursor, therefore, because there should be a copy of X_pos and Y_pos, they are shared by all processes.

So if we can change the system's configuration, only provide a copy of the myprintf function, and different processes through a function like a pointer to call it, then in the memory space will only appear a x_pos and y_pos, so that will not produce the above problems. So which process is going to keep the only myprintf? Is it a process or a B process?

It is clear that both A and B processes are incapable of assuming this responsibility, because a process that retains this unique myprintf must always be present in memory so that different processes can be used, and a and b are likely to be paged out at any time, and second, such processes must exist in the system as soon as the system is started. Or the first one to be transferred into the system memory, so that you can save the myprintf when other processes are being transferred into memory. Because the process that contains this myprintf copy needs to have these characteristics, so it is not difficult for us to think of it directly into the kernel, let it become a part of the system, is undoubtedly the most convenient. Thus, when we reconstruct our system with this pattern, the distribution of memory space may be as follows:

In this way, because there is only one myprintf in the system, so there is only one copy of X_pos and Y_pos, so there is no such situation. Since myprintf is currently in the system, we can call it a system call, which means that A and B use the screen output provided by the system to output information on the screen by myprintf this system call.

We can also see from the above description that the system call differs from the general function in that it is not actually linked to the process, but in each process it simply holds a pointer that can call it, which exists only in the system and only one copy.

So how do each process or get the call to this system call the portal. How to implement this system call inside the system. This is the problem that the experiment will solve. In this experiment we implemented a screen output system call, of course, we will continue to use Pyos as an example of our experiments.

Call Door

As we can see from the above description, to make myprintf capable of being invoked by all processes, the pointer to it, or the address of the system call must be fixed, so that there is a question as to where the pointer should be placed, This will allow the operating system kernel to change, the address of this system call has not changed. Careful analysis will find that this seems to be an impossible task, because once the operating system changes, it is difficult to control its internal parts in the memory of the layout that the storage location in memory does not change, then how to solve this problem. We can think of a space in the system to store the pointer to the system call, so no matter how the system changes, as long as the program can find the space, it can get the system call the pointer, so it can call the system call. So the question now is, in what space can we find the program to locate it exactly? This time, we think of the "descriptive chart" (note, the contents of the description chart are described in detail in the "Guide to the operating system", because when the system starts, the descriptor is loaded into memory and its address is told to the CPU, so the CPU is aware of its address and if we are in " Description chart, specifically specify a location, such as "second descriptor" to hold the myprintf pointer, so that each time the program only told the CPU to use the "second number descriptor", then the CPU can get myprintf address, so the change can be invoked myprintf run. As a result, the system's memory layout is no longer limited to the inability to change, and only by keeping the "second number descriptor" in the descriptor table pointing to myprintf, the original application does not need to be changed after the operating system has been upgraded. and to maintain the above point, for the system, is an easy thing.

The descriptor is stored in a descriptor, and if a descriptor holds the address of a function, then we call it a "call gate", meaning that it allows you to invoke a function. Let's take a look at the structure of the calling door:


The diagram above is the structure of the calling door, which is the offset of the function in memory that the calling door points to. The segment selector is the segment selector used by the function to which this call door refers, and the double word count is when a call door is used between different privileged poles, which throws a privilege-level conversion, and because different privilege levels use their own separate stacks, So in order for a stack switch to occur, when a stack switch occurs, you need to indicate how much of the two-byte bytes are to be copied from the previous stack to the new stack (because the function's invocation parameters are passed through the stack, so you need to copy the parameters from the original stack to the new stack) The double word count indicates the number of copies to be copied, but it is in two-word units. The Type field needs to be specified as 1100 (0xC) to indicate that this is a call door. DT is the type that describes this description system, and 0 indicates that it is a gate descriptor (the door descriptor not only refers to the calling door, but also to the interrupt door, the trap door, etc.). P is a bit that indicates whether the descriptor is available.

From the structure of the door descriptor that calls the door, we can see that the call Gate provides enough information, so we can call the door, not only between the same privilege level, but also between different privilege levels, calling between different privilege poles, which is a great feature for the operating system, This allows us to put the application at the user's privileged level and place the system call at the kernel privilege level.

Well, about the knowledge used in this experiment has been introduced, let's take a look at our experiment.

Pyos Implementation of system call in

Let's take a look at the real system call functions that are chained to the kernel:

/* This function is a system function that really handles the system call * *

void Class_pyos_systemlib_video::P rint (int x_pos, int y_pos, char ch, char style)

{

if (x_pos >= 0) {//If < 0 means print at current position

Cursor_x_pos = X_pos;

}

if (y_pos >= 0) {

Cursor_y_pos = Y_pos;

}

Switch (CH) {

Case '/n '://return character

Cursor_x_pos = 0;

++cursor_y_pos;

break;

Default://printable character

/* Through the cursor position, calculate the offset * *

unsigned short offset = Cursor_y_pos * + cursor_x_pos;

/* Display Character * *

char* video = (char*) 0xb8000 + offset * 2; Because one character Fu Jian two bytes, the offset is *2

*video++ = ch;

*video = style;

Move the cursor to the next position

++cursor_x_pos;

break;

}

/* Reset Cursor Position * *

SetCursor (Cursor_x_pos, Cursor_y_pos);

}

This function completes the output of the specified character on the screen, which is a function called by the system. The problem now is that we need to give the call door a pointer to this function, and now this function is a C + + function, its pointer in memory is not easy to get, so we can not use its pointer directly, but need to use a C language function to help, because for the C language function, its function name is its pointer, The function name is known (the C + + compiler extends the function name of the C + + function. So we can't know its true function name L), so we can provide to the call door is this C language function rather than C + + function pointers, the following is our C language wrapper function:

/* Real system call interface function, which is called by the call gate, and this function calls the real system function to handle the system call.

extern "C" void pyos_true_invoke_video_print (unsigned int x_pos, unsigned int y_pos, char ch, char color)

{

Class_pyos_systemlib_video::P rint (X_pos, Y_pos, ch, color);

}

This C language function is very simple, it is actually directly called the front of the individual C + + language function. So is it right to use the C-language function directly? Because of the offset, the ordinary

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.