微波EDA网,见证研发工程师的成长!
首页 > 硬件设计 > 嵌入式设计 > Arm Linux系统调用流程详细解析

Arm Linux系统调用流程详细解析

时间:11-09 来源:互联网 点击:

ABI)是通过跟随在swi指令中的调用号来进行的。同时这两种调用方式的系统调用号也是存在这区别的,在内核的文件arch/arm/inclue/asm/unistd.h中可以看到:

#define __NR_OABI_SYSCALL_BASE0x900#if defined(__thumb__)  defined(__ARM_EABI__)#define __NR_SYSCALL_BASE   0#else#define __NR_SYSCALL_BASE   __NR_OABI_SYSCALL_BASE#endif/** 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)……

接下来来看操作系统对系统调用的处理。我们回到ARM Linux的异常向量表,因为当执行swi时,会从异常向量表中取例程的地址从而跳转到相应的处理程序中。在文件arch/arm/kernel/entry-armv.S中:

/** We group all the following data together to optimise* for CPUs with separate I & D caches.*/.align    5.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_offsetW(ldr)    pc, .LCvswi + stubs_offsetW(b)    vector_pabt + stubs_offsetW(b)    vector_dabt + stubs_offsetW(b)    vector_addrexcptn + stubs_offsetW(b)    vector_irq + stubs_offsetW(b)    vector_fiq + stubs_offset.globl    __vectors_end__vectors_end:

而.LCvswi在同一个文件中定义为:

.LCvswi:.word vector_swi

也就是最终会执行例程vector_swi来完成对系统调用的处理,接下来我们来看下在arch/arm/kernel/entry-common.S中定义的vector_swi例程:

/*=============================================================================* SWI handler*--*//* If were optimising for StrongARM the resulting code wont run on an ARM7 and we can save a couple of instructions.  --pb */#ifdef CONFIG_CPU_ARM710#define A710(code...) code.Larm710bug:ldmia    sp, {r0 - lr}^            @ Get calling r0 - lrmov    r0, r0add    sp, sp, #S_FRAME_SIZEsubs    pc, lr, #4#else#define A710(code...)#endif.align    5ENTRY(vector_swi)sub    sp, sp, #S_FRAME_SIZEstmia    sp, {r0 - r12}            @ Calling r0 - r12ARM(    add    r8, sp, #S_PC        )ARM(    stmdb    r8, {sp, lr}^        )    @ Calling sp, lrTHUMB(    mov    r8, sp            )THUMB(    store_user_sp_lr r8, r10, S_SP    )    @ calling sp, lrmrs    r8, spsr            @ called from non-FIQ mode, so ok.str    lr, [sp, #S_PC]            @ Save calling PCstr    r8, [sp, #S_PSR]        @ Save CPSRstr    r0, [sp, #S_OLD_R0]        @ Save OLD_R0zero_fp/** Get 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_THUMBtst    r8, #PSR_T_BITmovne    r10, #0                @ no thumb OABI emulationldreq    r10, [lr, #-4]            @ get SWI instruction#elseldr    r10, [lr, #-4]            @ get SWI instructionA710(    and    ip, r10, #0x0f        @ check for SWI        )A710(    teq    ip, #0x0f                        )A710(    bne    .Larm710bug                        )#endif#ifdef CONFIG_CPU_ENDIAN_BE8rev    r10, r10            @ little endian instruction#endif#elif defined(CONFIG_AEABI)/** Pure EABI use

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top