Analysis of Linux system calls based on arm

Publisher:SereneHarmonyLatest update time:2022-05-27 Source: eefocusKeywords:arm  linux Reading articles on mobile phones Scan QR code
Read articles on your mobile phone anytime, anywhere

1 The role of system calls

The Linux kernel has a set of subroutines for implementing various system functions, called system calls, such as read, write, open, etc. Users can call them in their own applications through system call commands. From a certain perspective, system calls and ordinary function calls are very similar. The difference is that system calls are provided by the operating system core and run in kernel mode, while ordinary function calls are provided by function libraries or users themselves and run in user mode. In fact, many standard C language functions that we are accustomed to are implemented on the Linux platform through system calls. Therefore, if you want to have a deep understanding of the underlying principles of the system, you must master the preliminary requirements for various system calls.


2 How system calls work

We know that general processes cannot access the kernel. System calls are the only legal way for user space to access kernel space. In the early days, Linux used the OABI method to pass the system call number. Now Linux uses the new EABI (Embedded) method to pass the system call number. We mainly understand the EABI method, and will not talk about the OABI method here. The current Android compiler arm-linux-androideabi-gcc uses the EABI method. The process of this new system call method is as follows:

1. Store the syscall number in the r7 register.

2. Execute the swi instruction to jump to the soft interrupt and get the syscall number from r7.

Note that the soft interrupt mentioned here is supervisor call exception (svc). Since its original name was software interrupt (swi), the term soft interrupt has been used.

If there is a read function in the application and there is also a read function in the system call, how to find the read function in the kernel space from the application? You need to use the swi instruction. There are many system call functions in the kernel, such as read, write, open, etc. How does the kernel know which function is called? Here we need to use a register r7, which we will talk about later.

In the kernel source code, there is a file entry-common.S assembly code in archarmkernel. This code is the interface for the application to access the kernel. Some of the code is given below.


ENTRY(vector_swi)

    sub sp, sp, #S_FRAME_SIZE

    stmia   sp, {r0 - r12}          @ Calling r0 - r12

 ARM(   add r8, sp, #S_PC       )

 ARM(   stmdb   r8, {sp, lr}^       )   @ Calling sp, lr

 THUMB( mov r8, sp          )

 THUMB( store_user_sp_lr r8, r10, S_SP  )   @ calling sp, lr

    mrs r8, spsr            @ called from non-FIQ mode, so ok.

    str lr, [sp, #S_PC]         @ Save calling PC

    str r8, [sp, #S_PSR]        @ Save CPSR

    str r0, [sp, #S_OLD_R0]     @ Save OLD_R0

    zero_fp

    /*

     * Get the system call number.

     */


#if defined(CONFIG_OABI_COMPAT)

    /*The OABI method is used here

     * If we have CONFIG_OABI_COMPAT then we need to look at the swi

     * value to determine if it is an EABI or an old ABI call.

     */

#ifdef CONFIG_ARM_THUMB

    tst r8, #PSR_T_BIT

    movne   r10, #0             @ no thumb OABI emulation

    ldreq   r10, [lr, #-4]          @ get SWI instruction

#else

    ldr r10, [lr, #-4]          @ get SWI instruction

  A710( and ip, r10, #0x0f000000        @ check for SWI     )

  A710( ip teq, #0x0f000000 )

  A710( bne .Larm710bug                     )

#endif

#ifdef CONFIG_CPU_ENDIAN_BE8

    rev r10, r10            @ little endian instruction

#endif


#elif defined(CONFIG_AEABI)

    /*Here we use the EABI method

     * Pure EABI user space always put syscall number into scno (r7).

     */

  A710( ldr ip, [lr, #-4]           @ get SWI instruction   )

  A710( and ip, ip, #0x0f000000     @ check for SWI     )

  A710( ip teq, #0x0f000000 )

  A710( bne .Larm710bug                     )


#elif defined(CONFIG_ARM_THUMB)


    /* Legacy ABI only, possibly thumb mode. */

    tst r8, #PSR_T_BIT          @ this is SPSR from save_user_regs

    addne   scno, r7, #__NR_SYSCALL_BASE    @ put OS number in

    ldreq   scno, [lr, #-4]


#else


    /* Legacy ABI only. */

    ldr scno, [lr, #-4]         @ get SWI instruction

  A710( and ip, scno, #0x0f000000       @ check for SWI     )

  A710( ip teq, #0x0f000000 )

  A710( bne .Larm710bug                     )


#endif


In the EABI method, we can see that the application system space puts the system call number in the r7 register, as shown below

Write the picture description here

The kernel needs to get this number, take the value of register r7 and put it into scno.

There is a sentence ldrcc pc, [tbl, scno, lsl #2] in the program. We will not look at other code parts for now.

This sentence indicates that the kernel takes out the syscall number in the r7 register through scno.

1 This instruction logically shifts scno left by 2 bits and adds it to tbl, and assigns the value stored at the result position to PC. PC = * (tbl + (scno << 2)).

2 tbl is the entry address of the system call table, and tbl can be regarded as a char array header. char tbl[] = {…….};

3 Because scno only means the number of the system call, not the actual address or relative address of the system call.

4 The actual address of each system call (that is, the function name) is .long x 32 bits, which requires four bytes to store.

5 scno logically shifts left by 2 bits, which means that the entry address of the required system call function is stored at the position offset by scno<<2 bytes on tbl. tbl[scno<<2] stores the entry address of the required system call function.


In entry-common.S, sys_call_table is called, which is actually the assembly code of calls.S. It stores the numbers of various system calls. The kernel code uses this number as an offset to find the corresponding system call. The code of calls.S is as follows. The system call starts from 0. The first system call is sys_reatart_syscall, and the second is sys_exit. Of course, these codes are specially defined by the Linux kernel writers. If we want to add our own system call functions, we can add them one by one at the end of these codes. The format is generally the same (sys_function name). For example, when you write a function named mem, when updating calls.S, just add CALL(sys_mem) in the code in sequence.


/* 0 */     CALL(sys_restart_syscall)

        CALL(sys_exit)

        CALL(sys_fork_wrapper)

        CALL(sys_read)

        CALL(sys_write)

/* 5 */     CALL(sys_open)

        CALL(sys_close)

        CALL(sys_ni_syscall)        /* was sys_waitpid */

        CALL(sys_creat)

        CALL(sys_link)


In the unistd.h file, the system call program is basically written based on this header file. Every time a system call function is added, the unistd.h and calls.S files must be updated. The system call number also corresponds to the number in call.S. The code part is as follows. The function names we want to add are also added in the order in the code. Generally speaking, the format is —_NR function name.

Here you need to manually add #define __NR_mem at the end.


/*

 * This file contains the system call numbers.

 */


#define __NR_restart_syscall        (__NR_SYSCALL_BASE+  0)

#define __NR_exit           (__NR_SYSCALL_BASE+  1)

#define __NR_fork           (__NR_SYSCALL_BASE+  2)

#define __NR_read           (__NR_SYSCALL_BASE+  3)

#define __NR_write          (__NR_SYSCALL_BASE+  4)

#define __NR_open           (__NR_SYSCALL_BASE+  5)

#define __NR_close          (__NR_SYSCALL_BASE+  6)


So far, the general process of Linux system calls is like this. The author has not gone into detail, but it is enough to understand this much for now, and then continue to work hard as you learn more.

Keywords:arm  linux Reference address:Analysis of Linux system calls based on arm

Previous article:Character device driver (I)
Next article:DMA mechanism (based on S3C6410)

Recommended ReadingLatest update time:2024-11-16 13:03

ARM chip learning (S5PV210 development) - code relocation
What is code relocation? Code relocation is the copying or moving of code, copying a copy of the code stored at address A to address B. As for the addresses A and B, programmers know them in advance and can find them out through the chip data sheet. And due to certain restrictions, sometimes the code cannot be downloa
[Microcontroller]
Linux 2.6.22 port based on 3c2410 (3)
4、 生成第一阶段gcc: $root@host:/home/arm/build-tools/# tar xvjf gcc-4.2.1.tar.bz2 打补丁: $root@host:/home/arm/build-tools/# cd gcc-4.2.1 $root@host:/home/arm/build-tools/gcc-4.2.1#   patch –Np1 –i /home/arm/build-tools/patch/gcc-4.2.1-* $root@host:/home/arm/build-tools/ gcc-4.2.1# cd .. $root@host:/home/arm/build-too
[Microcontroller]
Let’s talk about ARM embedded things
1 Introduction With the rapid development of high-tech technologies such as big data and AI technology, embedded systems have been widely used in scientific research, military technology, engineering design, business culture and art, entertainment industry, daily life and other aspects. Embedded systems are based on c
[Microcontroller]
Quickly learn Arm (31)--Memory addressing (4)
In order to be compatible with future devices, the entire Boot ROM is mapped to the top of the on-chip memory space. In this way, using a larger or smaller on-chip Flash block will not affect the address of the Boot ROM. The very first byte of the Boot ROM is the exception interrupt vector table. In this way, it can b
[Microcontroller]
Quickly learn Arm (31)--Memory addressing (4)
What can arm bring to NVIDIA?
Since Arm was put on the shelf by SoftBank, Apple and Samsung have become the protagonists of the rumors. After both companies expressed their interest, a new potential buyer, Nvidia, surfaced. Moreover, as the reports deepened, the biggest marriage in the semiconductor industry seemed to be close to taking shape.   
[Semiconductor design/manufacturing]
What can arm bring to NVIDIA?
Common ARM assembly instructions
In embedded development, assemblers are often used in very critical places, such as initialization at system startup, environmental protection when entering and exiting interrupts, recovery, and other places that require performance.   The ARM instruction set can be divided into six categories, namely data processin
[Microcontroller]
Linux-2.6.38 to tiny6410 porting manual (serial 4) __USB devices (U disk, camera, wifi)
Today, let's talk about some USB device drivers (U disk, camera, wifi). Its characteristic is that the kernel already has very complete drivers. All we need is configuration and few modifications. First, the U disk must be supported. 1、vi arch/arm/mach-s3c64xx/mach-mini6410.c 124行增加 /* Initi
[Microcontroller]
Linux-2.6.38 to tiny6410 porting manual (serial 4) __USB devices (U disk, camera, wifi)
LED display system based on AT91 M42800A
Recently, the author found in a logistics call system project based on fieldbus on a large production line in a factory that due to the large amount of information flow to be displayed, the existing LED display screen control system based on AT89C51 chip is limited by the processing speed, system architecture, addre
[Microcontroller]
LED display system based on AT91 M42800A
Latest Microcontroller Articles
  • Download from the Internet--ARM Getting Started Notes
    A brief introduction: From today on, the ARM notebook of the rookie is open, and it can be regarded as a place to store these notes. Why publish it? Maybe you are interested in it. In fact, the reason for these notes is ...
  • Learn ARM development(22)
    Turning off and on interrupts Interrupts are an efficient dialogue mechanism, but sometimes you don't want to interrupt the program while it is running. For example, when you are printing something, the program suddenly interrupts and another ...
  • Learn ARM development(21)
    First, declare the task pointer, because it will be used later. Task pointer volatile TASK_TCB* volatile g_pCurrentTask = NULL;volatile TASK_TCB* vol ...
  • Learn ARM development(20)
    With the previous Tick interrupt, the basic task switching conditions are ready. However, this "easterly" is also difficult to understand. Only through continuous practice can we understand it. ...
  • Learn ARM development(19)
    After many days of hard work, I finally got the interrupt working. But in order to allow RTOS to use timer interrupts, what kind of interrupts can be implemented in S3C44B0? There are two methods in S3C44B0. ...
  • Learn ARM development(14)
  • Learn ARM development(15)
  • Learn ARM development(16)
  • Learn ARM development(17)
Change More Related Popular Components

EEWorld
subscription
account

EEWorld
service
account

Automotive
development
circle

About Us Customer Service Contact Information Datasheet Sitemap LatestNews


Room 1530, 15th Floor, Building B, No.18 Zhongguancun Street, Haidian District, Beijing, Postal Code: 100190 China Telephone: 008610 8235 0740

Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号