Introduction to Linux kernel Interpretation

Source: Internet
Author: User
Tags intel pentium
Linux Kernel introduction-general Linux technology-Linux programming and kernel information. For more information, see the following section. For many Linux enthusiasts who are very interested in the kernel, this article aims to introduce an entry method for interpreting the Linux kernel source code,
Instead of explaining the complex linux kernel mechanism;
1. file organization of the core source program:
1. the Linux core source code is usually installed in/usr/src/linux, and it has a very simple numbering Convention: Any even
The core (for example, 2.0.30) is a stable distribution core, and any odd-number core (for example, 2.1.42) is a core in development.
This article is based on the stable 2.2.5 source code. The second part of the implementation platform is Redhat Linux 6.0.
2. The core source program files are organized in a tree structure. At the top of the source program tree, you will see the following directories:
● Arch: the arch sub-directory contains all core Code related to the architecture. Each of its subdirectories represents a supported system
Structure. For example, i386 is a subdirectory about the intel cpu and its compatible architecture. Generally, PCs are based on this directory;
● Include: The include sub-Directory includes most of the header files required for compiling the core. Platform-independent header files are in the include/linux subdirectory, intel cpu-related header files are in the include/asm-i386 subdirectory, And the include/scsi directory is the header file directory of the scsi device;
● Init: This directory contains the core initialization code (Note: it is not the System Boot Code). It contains two files: main. c and Version. c,
This is a very good starting point for studying how to work.
● Mm: This Directory includes all memory management code independent of the cpu architecture, such as page-based storage management memory allocation and release.
The Memory Management Code related to the architecture is located at arch/*/mm/, for example, arch/i386/mm/Fault. c.
● Kernel: the main core code. The files in this directory implement the Kernel functions of most linux systems. The most important file is
Sched. c; similarly, the architecture-related code is in arch/*/kernel;
● Drivers: Place all the device Drivers in the system. Each driver occupies a sub-directory, for example, block device Drivers under/block, such as ide. c ). If you want to view how all devices that may contain a file system are initialized, you can see
Device_setup () in drivers/block/genhd. c (). It not only initializes the hard disk, but also the network, because the network is required to install the nfs file system.
Others: for example, Lib stores the core library code; Net, core and network-related code; Ipc, which contains the code for inter-process communication between core processes;
Fs, all File System Code and various types of file operation code. Each subdirectory of Fs supports a file system, such as fat and ext2;
Scripts, which contains the script files used to configure the core.
Generally, there is. the depend file and a Makefile file are both auxiliary files used for compilation. reading these two files carefully is helpful for figuring out the relationship and dependency between each file. Moreover, there are also Readme files in some directories, which are descriptions of the files in this directory, which is also conducive to our understanding of the kernel source code;
2. interpreting practice: Add a system call for your Kernel
Although the Linux kernel source code is organized reasonably and scientifically in a tree structure, all files associated with functions are placed under the same subdirectory, which makes the program more readable. However, the Linux kernel source code is too large and complex. Even if a reasonable file organization method is adopted, there are still many associations between files under different directories, some code at the analysis core usually needs to view several other related files, and these files may not be in the same subdirectory.
The complexity of the system and the complexity of the association between documents may be the main reason why many people are afraid of it. Of course, the return of this daunting labor is also fascinating: You can not only learn a lot of underlying computer knowledge (such as the system guidance described below ), I realized that the entire operating system architecture is exquisite and the algorithm is clever when solving a specific problem in detail. More importantly, in the source code analysis process, you will be professionally specialized at 1.1 points. Even after analyzing the code in 10 million points, you will deeply understand what kind of code is written by a professional programmer, what kind of code is written by a hobbyist.
In order to allow readers to better understand this feature, the following describes a specific Kernel Analysis instance, this gives readers some specific understanding of the Linux kernel organization, from which they can also learn some kernel analysis methods.
The following is an analysis instance:
[1] operating platform:
Hardware: cpu intel Pentium II;
Software: Redhat Linux 6.0; kernel version 2.2.5
[2] kernel source code analysis:
1. System Boot and initialization: There are several boot methods for Linux systems: Lilo, Loadin, and Linux Bootstrap
(Bootsect-loader), and the latter corresponds to the source program is arch/i386/boot/bootsect. S, which is a real-mode assembler, limited
The length is not analyzed here. No matter which boot method is used, the page will jump to arch/i386/Kernel/setup. S. setup. S is mainly
During initialization, prepare for the system to enter the protection mode; after that, the system executes arch/i386/kernel/head. S (for compressed
The stored kernel must first execute arch/i386/boot/compressed/head. S); the Assembly program setup_idt defined in head. S,
It is responsible for creating an idt Table with 256 Items (Interrupt Descriptor Table), which stores all the entry addresses of Self-traps and interruptions.
Including the entry address of system_call of the system call General Control Program; of course, In addition, head. S also needs to perform some initialization work;
2. The first kernel program asmlinkage void _ init start_kernel (void) that runs after system initialization is defined in
In/usr/src/linux/init/main. c, it calls a function in usr/src/linux/arch/i386/kernel/traps. c.
Void _ init trap_init (void) sets the entry addresses of their respective traps and service interruption programs to the idt table, in which the system calls the general control program
System_cal is one of the interrupted services. The void _ init trap_init (void) function calls a macro
Set_system_gate (SYSCALL_VECTOR, & system_call); hangs the entry of the System Call Control Program on the interrupt 0x80;
SYSCALL_VECTOR is a constant 0x80 defined in/usr/src/linux/arch/i386/kernel/irq. h, while system_call
That is, the entry address of the interrupt control program. The interrupt control program is defined in/usr/src/linux/arch/i386/kernel/entry. S in assembly language;
3. the interrupt control program is mainly responsible for storing the status before the processor executes the system call, checking whether the current call is legal, and according to the system call vector, redirect the processor to the entry of the corresponding system service routine saved in the sys_call_table table; restore the processor status and return it to the user program after the system service routine returns;
The system call vector is defined in/usr/src/linux/include/asm-386/unistd. h; The sys_call_table table is defined in
/Usr/src/linux/arch/i386/kernel/entry. S; at the same time in/usr/src/linux/include/asm-386/unistd. h
User programming interfaces called by the system are also defined;
4. It can be seen that the linux system call is also like the dos system's int 21 h interrupt service, it takes 0x80 interrupt as the total entry, and then
Go to the entry addresses of various interrupt service routines stored in the sys_call_table table to form different interrupt services;
According to the source code analysis above, to add a system call, you must add an item to the sys_call_table table and save yourself in it.
And then re-compile the kernel. Of course, system service routines are essential.
We can see that the Linux kernel source program in this version is <2. 2. 5>, the source program files related to system calls include the following:
1. arch/i386/boot/bootsect. S
2. arch/i386/Kernel/setup. S
3. arch/i386/boot/compressed/head. S
4. arch/i386/kernel/head. S
5. init/main. c
6. arch/i386/kernel/traps. c
7. arch/i386/kernel/entry. S
8. arch/i386/kernel/irq. h
9. include/asm-386/unistd. h
Of course, this is only a few of the main files involved. And in fact, adding a system call really wants to modify the file only include/asm-386/unistd. h
And arch/i386/kernel/entry. S;
[3] modify the kernel source code:
1. Add the system service routine in kernel/sys. c as follows:
Asmlinkage int sys_addtotal (int numdata)
{
Int I = 0, enddata = 0;
While (I <= numdata)
Enddata + = I ++;
Return enddata;
}
This function has an int-type entry parameter numdata and returns the accumulated value from 0 to numdata. Of course, you can also place the system service routine
In a self-defined file or other files, only necessary instructions should be made in the corresponding file;
2. Add the entry address of asmlinkage int sys_addtotal (int) to the sys_call_table table:
The last few lines of source code in arch/i386/kernel/entry. S are changed:
......
. Long SYMBOL_NAME (sys_sendfile)
. Long SYMBOL_NAME (sys_ni_syscall)/* streams1 */
. Long SYMBOL_NAME (sys_ni_syscall)/* streams2 */
. Long SYMBOL_NAME (sys_vfork)/* 190 */
. Rept NR_syscalls-190
. Long SYMBOL_NAME (sys_ni_syscall)
. Endr
Modified :......
. Long SYMBOL_NAME (sys_sendfile)
. Long SYMBOL_NAME (sys_ni_syscall)/* streams1 */
. Long SYMBOL_NAME (sys_ni_syscall)/* streams2 */
. Long SYMBOL_NAME (sys_vfork)/* 190 */
/* Add by I */
. Long SYMBOL_NAME (sys_addtotal)
. Rept NR_syscalls-191
. Long SYMBOL_NAME (sys_ni_syscall)
. Endr
3. Make necessary declarations in include/asm-386/unistd. h for the vector corresponding to the added sys_call_table table item
Query or call user processes and other system processes:
The added part of the/usr/src/linux/include/asm-386/unistd. h file is as follows:
......
# Define _ NR_sendfile 187
# Define _ NR_getpmsg 188
# Define _ NR_putpmsg 189
# Define _ NR_vfork 190
/* Add by I */
# Define _ NR_addtotal 191
4. The test program (test. c) is as follows:
# Include
# Include
_ Syscall1 (int, addtotal, int, num)
Main ()
{
Int I, j;
Do
Printf ("Please input a number \ n ");
While (scanf ("% d", & I) = EOF );
If (j = addtotal (I) =-1)
Printf ("Error occurred in syscall-addtotal (); \ n ");
Printf ("Total from 0 to % d is % d \ n", I, j );
}
Compile the new kernel after modification and guide it as a new operating system. After running several programs, you can find that everything works normally.
Compile the Test Program (* Note: because the original kernel does not provide this system call, this test program is only available in the New Compiled kernel.
May be compiled). The running conditions are as follows:
$ Gcc-o test. c
$./Test
Please input a number
36
Total from 0 to 36 is 666
Visible, modification successful;
Further analysis of the source code shows that in the kernel of this version, from/usr/src/linux/arch/i386/kernel/entry. S
The settings of the sys_call_table table in the file show that several service routines called by the system are defined in
The same function in/usr/src/linux/kernel/sys. c:
Asmlinkage int sys_ni_syscall (void)
{
Return-ENOSYS;
}
For example, this is true for items 188th and 189th:
......
. Long SYMBOL_NAME (sys_sendfile)
. Long SYMBOL_NAME (sys_ni_syscall)/* streams1 */
. Long SYMBOL_NAME (sys_ni_syscall)/* streams2 */
. Long SYMBOL_NAME (sys_vfork)/* 190 */
......
The two items are declared in the file/usr/src/linux/include/asm-386/unistd. h as follows:
......
# Define _ NR_sendfile 187
# Define _ NR_getpmsg 188/* some people actually want streams */
# Define _ NR_putpmsg 189/* some people actually want streams */
# Define _ NR_vfork 190
In the kernel source code of this version, the asmlinkage int sys_ni_syscall (void) function does not perform any operations,
Therefore, several system calls, including getpmsg and putpmsg, do not perform any operations, that is, the air conditioners to be expanded.
It still occupies the sys_call_table table. It is estimated that this is arranged by the designers to facilitate the expansion of system calls. Therefore, you only need to add the corresponding
Service routines (such as adding service routines getmsg or putpmsg) can be used to increase system calls.
Conclusion: Of course, for a huge and complex linux kernel, an article is far from enough, and the Code related to system calls is only extremely
It is a tiny part, but it is important to have a method and a good grasp of the analysis method. Therefore, the above analysis is only a guiding role, and the readers still need to make their own efforts to analyze it.
Related Article

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.