Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

How to implement Linux system call

2025-03-28 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >

Share

Shulou(Shulou.com)06/01 Report--

Today, I would like to share with you how to achieve Linux system call related knowledge points, detailed content, clear logic, I believe that most people still know too much about this knowledge, so share this article for your reference, I hope you can learn something after reading this article, let's take a look at it.

System call (system call) is a set of interfaces provided by the operating system for processes running in user mode to interact with hardware devices such as cpu, disk, printer, etc. When the user process needs to make a system call, cpu switches to the kernel state through the soft interrupt and starts to execute the kernel system call function. Here are three ways to make system calls under linux:

1. Through the library functions provided by glibc

Glibc is the open source standard c library used under linux. It is the libc library released by gnu, that is, the runtime library. Glibc provides programmers with rich api (application programming interface). In addition to user-state services such as string processing and mathematical operations, the most important thing is to encapsulate the system services provided by the operating system, that is, the encapsulation of system calls. So what is the relationship between the system calls api provided by glibc and kernel-specific system calls?

Usually, each specific system call corresponds to at least one library function encapsulated by glibc. For example, the open file system call sys_open provided by the system corresponds to the open function in glibc.

Secondly, a single api of glibc may call multiple system calls, such as sys_open, sys_mmap, sys_write, sys_close, etc., if the printf function provided by glibc calls.

In addition, multiple api may only correspond to the same system call. For example, malloc, calloc, free and other functions implemented under glibc are used to allocate and release memory, all of which make use of the system call of sys_brk in the kernel.

For example, we use the chmod function provided by glibc to change the file etc/passwd property to 444:

# include # include int main () {int rc; rc = chmod ("/ etc/passwd", 0444); if (rc =-1) fprintf (stderr, "chmod failed, errno =% d\ n", errno); else printf ("chmod success!\ n"); return 0;}

Compiled and used by ordinary users, the output is as follows:

Chmod failed, errno = 1

The value returned by the above system call is-1, indicating that the system call failed, and the error code is 1. The error code is described as follows in the / usr/include/asm-generic/errno-base.h file:

# define eperm 1 / * operation not permitted * /

That is, we do not have the permission to do this operation, we cannot modify the properties of the / etc/passwd file with ordinary user permissions, and the result is correct.

Second, call directly using syscall

There are many benefits to using the above method, first of all, you do not need to know more details, such as chmod system call number, you only need to know the prototype of api provided by glibc; secondly, this method has a better portability, you can easily port the program to other platforms, or replace the glibc library with other libraries, the program only needs to make a few changes.

But the drawback is that if glibc doesn't encapsulate a system call provided by a kernel, I won't be able to call that system call through the method above. For example, if I add a system call by compiling the kernel, it is impossible for glibc to have the wrapper api of your new system call, at this time we can use the syscall function provided by glibc to call directly. The function is defined in the unistd.h header file. The function prototype is as follows:

Long int syscall (long int sysno,...)

Sysno is the system call number, and each system call is identified by a unique system call number. Macro definition of all possible system call numbers in sys/syscall.h.

... For the remaining parameters with variable length, the parameters taken by the system call can be different from 0 to 5 according to the different system calls. if the parameters exceed the parameters that a specific system call can take, the extra parameters will be ignored.

The return value of this function is the return value of a specific system call. You can convert the return value to a specific type after the system call is successful, and return-1 if the system call fails. The error code is stored in errno.

Also take the above modification of the properties of the / etc/passwd file as an example, this time using syscall to directly call:

# include # include int main () {int rc; rc = syscall (sys_chmod, "/ etc/passwd", 0444); if (rc =-1) fprintf (stderr, "chmod failed, errno =% d\ n", errno); else printf ("chmod succeess!\ n"); return 0;}

Compiled and executed under ordinary users, the output is the same as the above example.

Third, fall into through the int instruction

If we know the whole process of the system call, we should know that the user program falls into the kernel state through the soft interrupt instruction int 0x80 (the sysenter instruction is also introduced in intel pentium ii), the parameters are transferred through registers, eax passes the system call number, ebx, ecx, edx, esi and edi pass up to five parameters in turn, and when the system call returns, the return value is stored in eax.

Still take the above modified file properties as an example, write the calling system call into inline assembly code:

# include # include int main () {long rc; char * file_name = "/ etc/passwd"; unsigned short mode = 0444; asm ("int $0x80": "= a" (rc): "0" (sys_chmod), "b" ((long) file_name), "c" ((long) mode); if ((unsigned long) rc > = (unsigned long)-132) {errno =-rc; rc =-1 } if (rc = =-1) fprintf (stderr, "chmode failed, errno =% d\ n", errno); else printf ("success!\ n"); return 0;}

If the return value stored in the eax register (stored in the variable rc) is between-1 eax 132, it must be interpreted as an error code (the maximum error code defined in the / usr/include/asm-generic/errno.h file is 132). At this time, the error code is written into errno and the system call return value is-1; otherwise, the value returned is the error code. The above program is compiled and run under 32-bit linux with ordinary user rights, and the result is the same as the previous two!

These are all the contents of the article "how to implement Linux system calls". Thank you for reading! I believe you will gain a lot after reading this article. The editor will update different knowledge for you every day. If you want to learn more knowledge, please pay attention to the industry information channel.

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Development

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report