Add new system calls in Linux

Source: Internet
Author: User
A system call is a functional interface between an application and the operating system kernel. The main purpose is to allow users to use the functions provided by the operating system in terms of device management, input/input systems, file systems and process control, communication, and storage management, instead of having to understand the internal structure of the system program and related hardware details, it can reduce the burden on users, protect the system, and improve resource utilization.

As a representative of Free Software, the Linux operating system has become more and more widely used because of its excellent performance. It has not only been recognized by professionals, but also has been widely used in commercial applications. In Linux, most system calls are included in Linux's libc library, which can be called through standard C function call methods. So, for Linux enthusiasts, how can we add new system calls in Linux?

1. Linux System Call Mechanism

In Linux, system calling is implemented as an exception type. It will execute corresponding machine code commands to generate abnormal signals. An important effect of interruption or exception is that the system automatically switches the user State to the core State for processing. This means that when the system calls an abnormal command, the system is automatically switched to the core State and the exception handling program is executed.

The actual commands used by Linux to implement system call exceptions are:

Int $0x80

This command transfers control to the kernel using the interrupt/exception vector number 128 (that is, the hexadecimal 80. To enable programming without using machine commands when using system calls, a short subroutine is provided for each system call in the Standard C language library to complete programming of machine code. In fact, the machine code segment is very short. All it has to do is load the parameters sent to the system call to the CPU register, and then execute the int $0x80 command. Then run the system call. The return value of the system call is sent to a register of the CPU. The standard library subroutine obtains the return value and sends it back to the user program.

To make the execution of system calls a simple task, Linux provides a set of pre-processing macro commands. They can be used in programs. These macro commands take certain parameters and extend them to call the functions called by the specified system.

These macro commands have a name format similar to the following:

_ Syscalln (parameters)

N is the number of parameters required for system calls, while parameters is replaced by a set of parameters. These parameters enable macro commands to complete extensions suitable for specific system calls. For example, to create a function called by the setuid () system, use:

_ Syscall1 (INT, setuid, uid_t, UID)

The Int value of the 1st parameter in the syscalln () macro command indicates that the type of the returned value of the generated function is integer, And the setuid value indicates the name of the generated function. Each parameter required by the system call is followed. The macro command is followed by two parameters uid_t and uid respectively to specify the parameter type and name.

In addition, there is a limit on the data types used as system call parameters, and their capacity cannot exceed four bytes. This is because when the int $0x80 command is executed for system calling, all parameter values are stored in 32-bit CPU registers. Another restriction imposed by passing parameters using the CPU register is the number of parameters that can be transferred to the system. This limit allows up to five parameters to be passed. Therefore, Linux defines six different _ syscalln () macro commands, from _ syscall0 (), _ syscall1 () to _ syscall5 ().

Once the _ syscalln () macro command is extended with the corresponding parameters called by a specific system, the result is a function with the same name as the system call, it can execute this system call in the user program.

2. Add a new system call

If you add a new system call in Linux, follow these steps to add the system call. The following steps describe how to add the system call.

(1) Add source code

The first task is to compile the source program to be added to the kernel. A function to be added to a kernel file should be named by the Sys _ sign before the new system call name. If the newly added system call is mycall (INT number), add the source code to the/usr/src/Linux/kernel/sys. c file, as shown below:

Asmlinkage int sys_mycall (INT number)

{

Return number;

}

As a simple example, the newly added system call only returns an integer value.

(2) connect to a new system call

After a new system call is added, the next task is to let the rest of the Linux kernel know the existence of the program. To add a connection to a new function from an existing kernel program, you need to edit two files.

In our Linux kernel version (RedHat 6.0, the kernel is 2.2.5-15), the first file to be modified is:

/Usr/src/Linux/include/asm-i386/unistd. h

This file contains the system call list, which is used to assign a unique number to each system call. The format of each row in the file is as follows:

# DEFINE _ nr_name NNN

The name is replaced by the system call name, while the NNN is the number corresponding to the system call. Add the new system call name to the end of the list and assign it the next available system call number in the number sequence. Our system calls are as follows:

# DEFINE _ nr_mycall 191

The system call number is 191, the reason the system call number is 191, because the system call number of the Linux-2.2 kernel itself has used 190.

The second file to be modified is:

/Usr/src/Linux/ARCH/i386/kernel/entry. s

This file contains a list similar to the following:

. Long symbol_name ()

This list is used to initialize the sys_call_table [] array. This array contains pointers to each system call in the kernel. In this way, the new kernel function pointer is added to the array. Add a line at the end of the list:

. Long symbol_name (sys_mycall)

    

(3) Rebuilding the Linux Kernel

To make the new system call take effect, you need to re-build the Linux kernel. This requires Logon as a Super User.

# Pwd

/Usr/src/Linux

#

Super Users can reconstruct the kernel only in the current working directory (/usr/src/Linux.

# Make config

# Make Dep

# Make clearn

# Make bzimage

After compilation, the system generates a kernel image file that can be installed and compressed:

/Usr/src/Linux/ARCH/i386/boot/bzimage

(4) Start the system with a new kernel

To use a new system call, you must use a new kernel to reboot the system. To solve this problem, you need to modify the/etc/Lilo. conf file. In our system, the file content is as follows:

Boot =/dev/hda

Map =/boot/Map

Install =/boot. B

Prompt

Timeout = 50

Image =/boot/vmlinuz-2.2.5-15

Label = Linux

Root =/dev/hdb1

Read-Only

Other =/dev/hda1

Label = DoS

Table =/dev/had

First, edit the file and add a new boot kernel:

Image =/boot/bzimage-New

Label = Linux-New

Root =/dev/hdb1

Read-Only

After adding the file, the content of the file is as follows:

Boot =/dev/hda

Map =/boot/Map

Install =/boot. B

Prompt

Timeout = 50

Image =/boot/bzimage-New

Label = Linux-New

Root =/dev/hdb1

Read-Only

Image =/boot/vmlinuz-2.2.5-15

Label = Linux

Root =/dev/hdb1

Read-Only

Other =/dev/hda1

Label = DoS

Table =/dev/hda

In this way, the new kernel image bzimage-New becomes the default boot kernel.

To use the new Lilo. conf configuration file, run the following command:

# Cp/usr/src/Linux/ARCH/i386/boot/zimage/boot/bzimage-New

Configure lilo:

#/Sbin/lilo

Now, when you reboot the system, there are three options after the boot: Prompt: Linux-New, Linux, DOS, the new kernel becomes the default boot kernel.

Now, the new Linux kernel has been created, and the newly added system call has become part of the operating system. After Linux is restarted, you can use the system call in the application.

(5) use a new system call

Use the newly added system to call mycall in the application. For the same purpose, we wrote a simple example xtdy. C.

/* Xtdy. C */

# Include

_ Syscall1 (INT, mycall, Int, RET)

Main ()

{

Printf ("% d/N", mycall (100 ));

}

Compile the program:

# Cc-O xtdy. c

Run:

# Xtdy

Result:

#100

Note: because the system call is used, the user should be a Super User identity during program compilation and execution.

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.