Home PC Games Linux Windows Database Network Programming Server Mobile  
           
  Home \ Linux \ ARM Linux system call     - Automated Password Generator: Linux under a special password generator (Linux)

- VMware installed Linux system and JDK deployment (Linux)

- Security implementation of disk data protection under Linux (Linux)

- ssh using scp: / directory: Permission denied (Server)

- shell script error dirname: invalid option - b (Database)

- LMMS 1.03 install on Ubuntu 14.04 (Linux)

- How to enable curl command HTTP2 support (Linux)

- Ubuntu treated with cue file to ape and wav files automatically track points (Linux)

- Teach you self-built Linux firewall free (Linux)

- MySQL Data Types (Database)

- CentOS 6.0 system security level (Linux)

- Linux Network Programming - raw socket programming (Programming)

- Python Dir find a folder several files (Programming)

- Nginx + ownCloud + PHP + MySQL to build personal private cloud under CentOS7 (Server)

- Python exception summary (Programming)

- Inxi: Get Linux system and hardware information (Linux)

- Ubuntu 12.04 installation OpenCV2.4.1 and compile test (Linux)

- Use Vagrant up a local development environment tutorials (Server)

- Linux startup and logon security settings (Linux)

- UUID in Java (Programming)

 
         
  ARM Linux system call
     
  Add Date : 2018-11-21      
         
         
         
  System call is the operating system available to the user (application) of a set of interfaces, each system call has a corresponding system call functions to complete the work. The interface to the user through the operating system, application services, such as access to the hardware, management processes, and so on. However, because the user program is running in user space, and system calls runs in kernel space, so that the user program can not call the system functions are called directly, we often see such as fork, open, write, and so the function is not actually true system calls they are just the c library, these functions will be executed in a soft interrupt swi instruction generates a software interrupt, the CPU into the kernel mode, followed by a series of judgments in the kernel, it is determined which system call, then go the real function of the system call, complete the corresponding function. The following give a simple example from user mode to call a "system call" to the kernel handles the entire execution process.

User programs are as follows:

      void pk ()

{

__asm __ (

"Ldr r7 = 365 \ n"

"Swi \ n"

:

:

:

);

}

int main ()

{

PK ();

retrun 0;

}

The code above, I have implemented a new system call, specifically how to do, and then described in detail later. pk () can be analogous to the fact that we usually open call in user program () function, this function only did a simple thing: the system call number passed r7 ,, then generates a software interrupt. Then CPU core into

Kernel mode:

After the CPU corresponding soft interrupt, PC pointer to the interrupt vector table fetch the interrupt vector table in the kernel code: Defining arch / arm / kernel / entry-armv.S in

.LCvswi:
 .word vector_swi

 .globl __stubs_end
__stubs_end:

 .equ stubs_offset, __vectors_start + 0x200 - __stubs_start

 .globl __vectors_start
__vectors_start:
 ARM (swi SYS_ERROR0)
 THUMB (svc # 0)
 THUMB (nop)
 W (b) vector_und + stubs_offset
 pc point here after W (ldr) pc, .LCvswi + stubs_offset # interrupt
 W (b) vector_pabt + stubs_offset
 W (b) vector_dabt + stubs_offset
 W (b) vector_addrexcptn + stubs_offset
 W (b) vector_irq + stubs_offset
 W (b) vector_fiq + stubs_offset

 .globl __vectors_end
__vectors_end:

When the pc fetched as instruction, it will jump to vector_swi this label, the label is defined in arch / arm / kernel / entry-commen.S in.

 .align 5
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. # Remove the system call number
  * /

#if defined (CONFIG_OABI_COMPAT)

 / *
  * 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 (teq ip, # 0x0f000000)
  A710 (bne .Larm710bug)
#endif
#ifdef CONFIG_CPU_ENDIAN_BE8
 rev r10, r10 @ little endian instruction
#endif

#elif defined (CONFIG_AEABI)


 / *
  * 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 (teq ip, # 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 (teq ip, # 0x0f000000)
  A710 (bne .Larm710bug)

#endif

#ifdef CONFIG_ALIGNMENT_TRAP
 ldr ip, __cr_alignment
 ldr ip, [ip]
 mcr p15, 0, ip, c1, c0 @ update control register
#endif
 enable_irq

 get_thread_info tsk

 adr tbl, sys_call_table @ load syscall table pointer # to obtain the base address of the system call table
 ldr ip, [tsk, #TI_FLAGS] @ check for syscall tracing

#if defined (CONFIG_OABI_COMPAT)
 / *
  * If the swi argument is zero, this is an EABI call and we do nothing.
  *
  * If this is an old ABI call, get the syscall number into scno and
  * Get the old ABI syscall table address.
  * /
 bics r10, r10, # 0xff000000
 eorne scno, r10, #__NR_OABI_SYSCALL_BASE
 ldrne tbl, = sys_oabi_call_table
#elif! defined (CONFIG_AEABI)
 bic scno, scno, # 0xff000000 @ mask off SWI op-code
 eor scno, scno, #__NR_SYSCALL_BASE @ check OS number
#endif

 stmdb sp !, {r4, r5} @ push fifth and sixth args
 tst ip, #_TIF_SYSCALL_TRACE @ are we tracing syscalls?
 bne __sys_trace

 cmp scno, #NR_syscalls @ check upper syscall limit
 adr lr, BSYM (ret_fast_syscall) @ return address
 ldrcc pc, [tbl, scno, lsl # 2] @ call sys_ * routine # skip system calls

 add r1, sp, #S_OFF
2: mov why, # 0 @ no longer a real syscall
 cmp scno, # (__ ARM_NR_BASE - __NR_SYSCALL_BASE)
 eor r0, scno, #__NR_SYSCALL_BASE @ put OS number back
 bcs arm_syscall
 b sys_ni_syscall @ not private func

As can be seen from the above, when the CPU from the interrupt vector to vector_swi after the completion of several things: 1. Remove the system call number 2. Remove the system calls the system call number in accordance with the base address of the system call table, get a system function pointer call functions 3. the system call table base address and the system call number to give this system call table entries, each entry is a pointer to a function, the function pointer is assigned to this PC, it is to achieve a jump Go to the system call function.

System call table is defined in: arch / arm / kernel / Calls.S

* This program is free software; you can redistribute it and / or modify
 * It under the terms of the GNU General Public License version 2 as
 * Published by the Free Software Foundation.
 *
 * This file is included thrice in entry-common.S
 * /
/ * 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)
/ * 10 * / CALL (sys_unlink)
  CALL (sys_execve_wrapper)
  CALL (sys_chdir)
  CALL (OBSOLETE (sys_time)) / * used by libc4 * /
  CALL (sys_mknod)
/ * 15 * / CALL (sys_chmod)
  CALL (sys_lchown16)
  CALL (sys_ni_syscall) / * was sys_break * /
  CALL (sys_ni_syscall) / * was sys_stat * /
  CALL (sys_lseek)
/ * 20 * / CALL (sys_getpid)
  CALL (sys_mount)
  CALL (OBSOLETE (sys_oldumount)) / * used by libc4 * /
  CALL (sys_setuid16)
  CALL (sys_getuid16)
/ * 25 * / CALL (OBSOLETE (sys_stime))
  CALL (sys_ptrace)
  CALL (OBSOLETE (sys_alarm)) / * used by libc4 * /
  CALL (sys_ni_syscall) / * was sys_fstat * /
  CALL (sys_pause)
/ * 30 * / CALL (OBSOLETE (sys_utime)) / * used by libc4 * /
  CALL (sys_ni_syscall) / * was sys_stty * /
  CALL (sys_ni_syscall) / * was sys_getty * /
  CALL (sys_access)
  CALL (sys_nice)
/ * 35 * / CALL (sys_ni_syscall) / * was sys_ftime * /
  CALL (sys_sync)
  CALL (sys_kill)
  CALL (sys_rename)
  CALL (sys_mkdir)
/ * 40 * / CALL (sys_rmdir)
  CALL (sys_dup)
  CALL (sys_pipe)
  CALL (sys_times)
  CALL (sys_ni_syscall) / * was sys_prof * /
/ * 45 * / CALL (sys_brk)
  CALL (sys_setgid16)
  CALL (sys_getgid16)
  CALL (sys_ni_syscall) / * was sys_signal * /
  CALL (sys_geteuid16)
/ * 50 * / CALL (sys_getegid16)
  CALL (sys_acct)
  CALL (sys_umount)
  CALL (sys_ni_syscall) / * was sys_lock * /
  CALL (sys_ioctl)
/ * 55 * / CALL (sys_fcntl)
.......

  CALL (sys_eventfd2)
  CALL (sys_epoll_create1)
  CALL (sys_dup3)
  CALL (sys_pipe2)
/ * 360 * / CALL (sys_inotify_init1)
  CALL (sys_preadv)
  CALL (sys_pwritev)
  CALL (sys_rt_tgsigqueueinfo)
  CALL (sys_perf_event_open)
  CALL (sys_pk) # add my own system calls

 Learn the execution of a system call can try to add its own system calls:

Kernel:

1. In the kernel code to implement a system call function, namely sys_xxx () function, as I added in kernel / printk.c in

void pk ()

{

printk (KERN_WARNING "this is my first sys call \ n!");

}

 

2. Add the system call number in arch / arm / include / asm / Unistd.h

Add #define __NR_pk (__NR_SYSCALL_BASE + 365)

 

3. Add a list of pointers to call a function in arch / arm / keenel / Calls.S

Add CALL (sys_pk)

 

4. Declare your system calling functions in include / linux / syscall.h

Add asmlinkage long sys_pk ()

 

User space:

 

      void pk ()

{

__asm __ (

"Ldr r7 = 365 \ n"

"Swi \ n"

:

:

:

);

}

int main ()

{

PK ();

 retrun 0;

}

After completion of the above preparation can compile the kernel and application.

The resulting file is running arm development board can print out: This is my first sys call!

I added the system call instructions can use.

So far, the implementation mechanism described system call and add a new system call is complete.
     
         
         
         
  More:      
 
- Nginx Keepalived Nginx monitoring scripts (Server)
- Compiling source code Nginx module installation subs_filter (Server)
- How to use Aptik to backup and restore Apps/PPAs under ubuntu (Linux)
- Ruby and Python simple comparison (Programming)
- Linux System Getting Started Learning: Statistical process a number of threads in Linux (Linux)
- Java abstract class instantiation (Programming)
- Ubuntu Locale configuration problem solving Can not set LC_CTYPE (Linux)
- ORA-38856: Unable instance UNNAMED_INSTANCE_2 (redo thread 2) marked enabled (Database)
- CentOS 5.3 under broadcom NIC dual activation issues (Linux)
- C ++ why we chose to use the smart pointer (Programming)
- The hashcode method of Java (Programming)
- C language binary tree (Programming)
- How the program is executed (Programming)
- Postgres-X2 deployment steps (Database)
- REDO LOG records management (Database)
- Django how to generate content in non-HTML formats (Programming)
- How to set up HTTPS policies for older browsers (Server)
- Custom Android UI template Comments (Programming)
- Java by Spy Memcached to cache data (Programming)
- Spacewalk Linux system configuration and installation (Linux)
     
           
     
  CopyRight 2002-2020 newfreesoft.com, All Rights Reserved.