Introduction to Linux kernel Interpretation

Source: Internet
Author: User
Tags intel pentium

Introduction to Linux kernel Interpretation

For many Linux enthusiasts who are very interested in the kernel, this article aims to introduce

Instead of explaining the complex Linux kernel mechanism.

1. file organization of the core source program

(1) Linux core source code is usually installed in/usr/src/Linux, and it has a very simple number

Convention: Any even core (for example, 2.0.30) is the core of a stable release, and any odd Core

(For example, 2.1.42) is the core of 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 files of the core source program are organized in a tree structure. You can see these contents at the top of the source program tree.

Recording:

● Arch: the arch sub-directory contains all core Code related to the architecture. Each of its subdirectories is replaced

Table is a supported architecture. For example, i386 is a subdirectory about 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

In the include/Linux subdirectory, Intel CPU-related header files are under the include/asm-i386 subdirectory

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) and contains two files.

Main. C and version. C, which is a very good starting point for studying how the core works;

● Mm: This Directory includes all memory management code independent of the CPU architecture, such as page-based storage management memory.

And the Memory Management Code related to the architecture is located in arch/*/mm/, such as arch/i38

6/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 Code related to the architecture is in arch/*/kernel;

● Drivers: Place all the device Drivers in the system. Each driver occupies a sub-directory, such as/bl.

Ock is a block Device Driver, such as ide (ide. c ). If you want to view all

How to initialize the device. You can see device_setup () in drivers/block/genhd. c (). It not only

Initialize the hard disk and network, because the network is required when installing the nfs file system.

For example, the library code that stores the core in Lib; Net, network-related core code; Ipc. This directory contains the core

Code for inter-process communication; Fs, all File System Code and various types of file operation code, each of its

Sub-directories support a file system, such as fat and ext2; Scripts. This directory contains Scripts used to configure the core.

Files.

Generally, each directory contains a. depend file and a Makefile file. Both files are compiled.

When using the auxiliary files, read these two files carefully to find out the relationship between each file and the dependency is very helpful

And there are Readme files in some directories. It is a description of the files in this directory, which is also advantageous.

In 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

In the same subdirectory, this makes the program more readable. However, the Linux kernel source code is too large and

Very complex. Even if a reasonable file organization method is used, there are still many files in different directories.

Association, analysis of a part of the core code usually needs to view several other related files, and may also

Not 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 from it

A lot of underlying computer knowledge (for example, the system guidance described below) can be used to understand the entire operating system.

The structure is exquisite and the algorithm is clever in solving a specific problem in detail, and more importantly, the analysis of the source code

In the process, you will be specialized by 1.1 points, imperceptible; or even, after analyzing 1/10 of the code, you will

I will deeply understand what kind of code is written by a professional programmer and what kind of code is an amateur

Written by fans.

In order to enable readers to better understand this feature, the following describes a specific Kernel Analysis instance.

This example allows readers to have some specific understanding of Linux kernel organization, from which they can also learn some internal

Core analysis method.

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

① System boot and initialization: There are several methods for Linux system boot, commonly referred to as Lilo and loadin

Bootsect-loader, which corresponds to the source program arch/i386/boot/bo.

Otsect. S, which is an assembly program in the real mode, is not analyzed here. No matter which mode of guidance, the most

And then jump to arch/i386/Kernel/setup. S. Setup. S is the initialization in the ongoing mode.

The system enters the protection mode to prepare. After that, the system executes arch/i386/kernel/head. S (

Run arch/i386/boot/compressed/head. S in the kernel.

The setup_idt program is used to create an idt Table (Interrupt Descriptor Table) with 256 Items.

Stores all inactive and inactive endpoints, including the endpoints for System Call Master Control system_call.

Address. Of course, in addition, head. S has to do some initialization work.

② The first kernel program asmlinkage void _ init start_kernel (void) that runs after system initialization)

Defined in/usr/src/linux/init/main. c. It calls usr/src/linux/arch/i386/kernel

Void _ init trap_init (void), a function in/traps. c, respectively traps and interrupts service programs.

Set the port address to the idt table. The system calls the general control program system_cal, which is one of the interrupted service programs; vo

The id _ init trap_init (void) function calls a macro set_system_gate (SYSCALL_VECTOR

, & System_call), and hangs the system call control program entry on the interrupt 0x80.

SYSCALL_VECTOR is a constant defined in/usr/src/linux/arch/i386/kernel/irq. h.

0x80, while system_call is the entry address of the interrupt control program. The interrupt control program is defined in assembly language.

In/usr/src/linux/arch/i386/kernel/entry. S.

③ The interrupt general control program is mainly responsible for saving the status before the processor executes the system call, checking whether the current call is legal, and

Redirect the processor to the corresponding system service routine saved in the sys_call_table table based on the system call vector.

From the system service routine to restore the processor status to the user program.

The system call vector is defined in/usr/src/linux/include/asm-386/unistd. h, sys_call_t

The able table is defined in/usr/src/linux/arch/i386/kernel/entry. S and in/usr/src/l

Inux/include/asm-386/unistd. h also defines user programming interfaces for system calls.

④ It can be seen that the Linux system calls are also like the dos system's int 21 h interrupt service, which interrupts 0x80

As the total entry, go to the entry address of various interrupt service routines saved in the sys_call_table table

To form a variety of service interruptions.

According to the source code analysis above, to add a system call, you must add one in the sys_call_table table.

And save the entry address of your system service routine in it, and then re-compile the kernel. Of course, the System Service

Routines are essential.

It can be seen that in the Linux kernel source program <2.2.5> of this version, the source program files related to system calls include the following

These:

* Arch/i386/boot/bootsect. S

* Arch/i386/Kernel/setup. S

* Arch/i386/boot/compressed/head. S

* Arch/i386/kernel/head. S

* Nit/main. c

* Rch/i386/kernel/traps. c

* Rch/i386/kernel/entry. S

* Rch/i386/kernel/irq. h

* Nclude/asm-386/unistd. h

Of course, this is only a few of the main files involved. In fact, only

Include/asm-386/unistd. h and arch/i386/kernel/entry. S.

(3) source code modification

① The System Service Routine added to kernel/sys. c is 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.

You can put the system service routine in a self-defined file or other files, but you must make the necessary

Description.

② Add the entry address of smlinkage 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

③ Add the vector corresponding to the sys_call_table table entry in include/asm-386/unistd. h.

Declarations are required for query or call by 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

④ Test. c is as follows:

# Include <linux/unistd. h>

# Include <stdio. h>

_ Syscall1 (int, addtotal, int, num)

Main ()

{

Int I, j;

Do

Printf ("Please input a number ");

While (scanf ("% d", & I) = EOF );

If (j = addtotal (I) =-1)

Printf ("Error occurred in syscall-addtotal ();");

Printf ("Total from 0 to % d is % d", 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. Compile the test program in the new system (Note: because the original kernel does not provide this system call

This test program can be compiled only in the new kernel after compilation. The running conditions are as follows:

$ GCC release test. c

$./Test

Please input a number

36

Total from 0 to 36 is 666

It can be seen that the modification is successful, and further analysis of the relevant source code shows that in the kernel of this version, from/usr/src/

The settings of the sys_call_table table in the Linux/ARCH/i386/kernel/entry. s file are as follows:

Several system-called service routines 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 operation, so several system calls, including getpmsg and putpmsg, do not perform any

Operation, that is, the air conditioners to be expanded. However, they still occupy the sys_call_table table.

To facilitate the expansion of system calls, you only need to add corresponding service routines (such as adding service routines ).

Getmsg or putpmsg) to increase the number of system calls.

3. Conclusion

Of course, for a large and complex Linux, an article is far from enough, and the Code related to system calls is only a tiny part of the kernel, and the most important thing is the method, therefore, the above analysis only plays a guiding role, and the real analysis still needs the reader's own efforts.

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.