新聞中心

        EEPW首頁 > 嵌入式系統 > 設計應用 > 淺析Arm Linux操作系統調用流程詳細解析 .

        淺析Arm Linux操作系統調用流程詳細解析 .

        作者: 時間:2016-11-09 來源:網絡 收藏
        系統調用是os操作系統提供的服務,用戶程序通過各種系統調用,來引用內核提供的各種服務,系統調用的執行讓用戶程序陷入內核,該陷入動作由swi軟中斷完成.

        At91rm9200處理器對應的linux2.4.19內核系統調用對應的軟中斷定義如下:

        #if defined(__thumb__) //thumb模式
        #define __syscall(name)/
        "push {r7}/n/t" /
        "mov r7, #" __sys1(__NR_##name) "/n/t" /
        "swi 0/n/t" /
        "pop {r7}"
        #else //arm模式
        #define __syscall(name) "swi/t" __sys1(__NR_##name) "/n/t"
        #endif

        #define __sys2(x) #x
        #define __sys1(x) __sys2(x)
        #define __NR_SYSCALL_BASE 0x900000 //此為OS_NUMBER << 20運算值
        #define __NR_open (__NR_SYSCALL_BASE+ 5) //0x900005

        舉一個例子來說:open系統調用,庫函數最終會調用__syscall (open),宏展開之后為swi #__NR_open,即,swi #0x900005觸發中斷,中斷號0x900005存放在[lr,#-4]地址中,處理器跳轉到arch/arm/kernel/entry- common.S中vector_swi讀取[lr,#-4]地址中的中斷號,之后查詢arch/arm/kernel/entry-common.S中的sys_call_table系統調用表,該表內容在arch/arm/kernel/calls.S中定義,__NR_open在表中對應的順序號為

        __syscall_start:

        ...
        .long SYMBOL_NAME(sys_open) //第5個
        ...
        將sys_call_table[5]中內容傳給pc,系統進入sys_open函數,處理實質的open動作

        注:用到的一些函數數據所在文件,如下所示
        arch/arm/kernel/calls.S聲明了系統調用函數
        include/asm-arm/unistd.h定義了系統調用的調用號規則

        vector_swi定義在arch/arm/kernel/entry-common.S
        vector_IRQ定義在arch/arm/kernel/entry-armv.S
        vector_FIQ定義在arch/arm/kernel/entry-armv.S

        arch/arm/kernel/entry-common.S中對sys_call_table進行了定義:
        .type sys_call_table, #object
        ENTRY(sys_call_table)
        #include "calls.S" //將calls.S中的內容順序鏈接到這里

        源程序:

        ENTRY(vector_swi)
        save_user_regs
        zero_fp
        get_scno //將[lr,#-4]中的中斷號轉儲到scno(r7)
        arm710_bug_check scno, ip
        #ifdef CONFIG_ALIGNMENT_TRAP
        ldr ip, __cr_alignment
        ldr ip, [ip]
        mcr p15, 0, ip, c1, c0 @ update control register
        #endif
        enable_irq ip

        str r4, [sp, #-S_OFF]! @ push fifth arg

        get_current_task tsk
        ldr ip, [tsk, #TSK_PTRACE] @ check for syscall tracing
        bic scno, scno, #0xff000000 @ mask off SWI op-code
        //#define OS_NUMBER 9[entry-header.S]
        //所以對于上面示例中open系統調用號scno=0x900005
        //eor scno,scno,#0x900000
        //之后scno=0x05
        eor scno, scno, #OS_NUMBER << 20 @ check OS number
        //sys_call_table項為calls.S的內容
        adr tbl, sys_call_table @ load syscall table pointer
        tst ip, #PT_TRACESYS @ are we tracing syscalls?
        bne __sys_trace

        adrsvc al, lr, ret_fast_syscall @ return address
        cmp scno, #NR_syscalls @ check upper syscall limit
        //執行sys_open函數
        ldrcc pc, [tbl, scno, lsl #2] @ call sys_* routine
        add r1, sp, #S_OFF
        2: mov why, #0 @ no longer a real syscall
        cmp scno, #ARMSWI_OFFSET
        eor r0, scno, #OS_NUMBER << 20 @ put OS number back
        bcs SYMBOL_NAME(arm_syscall)
        b SYMBOL_NAME(sys_ni_syscall) @ not private func
        /*
        * This is the really slow path. Were going to be doing
        * context switches, and waiting for our parent to respond.
        */
        __sys_trace:
        add r1, sp, #S_OFF
        mov r0, #0 @ trace entry [IP = 0]
        bl SYMBOL_NAME(syscall_trace)
        /*
        //2007-07-01 gliethttp [entry-header.S]
        //Like adr, but force SVC mode (if required)
        .macro adrsvc, cond, reg, label
        adr/cond /reg, /label
        .endm
        //對應反匯編:
        //add lr, pc, #16 ; lr = __sys_trace_return
        */
        adrsvc al, lr, __sys_trace_return @ return address
        add r1, sp, #S_R0 + S_OFF @ pointer to regs
        cmp scno, #NR_syscalls @ check upper syscall limit
        ldmccia r1, {r0 - r3} @ have to reload r0 - r3
        ldrcc pc, [tbl, scno, lsl #2] @ call sys_* routine
        b 2b

        __sys_trace_return:
        str r0, [sp, #S_R0 + S_OFF]! @ save returned r0
        mov r1, sp
        mov r0, #1 @ trace exit [IP = 1]
        bl SYMBOL_NAME(syscall_trace)
        b ret_disable_irq

        .align 5
        #ifdef CONFIG_ALIGNMENT_TRAP
        .type __cr_alignment, #object
        __cr_alignment:
        .word SYMBOL_NAME(cr_alignment)
        #endif

        .type sys_call_table, #object
        ENTRY(sys_call_table)
        #include "calls.S"


        評論


        技術專區

        關閉
        主站蜘蛛池模板: 东辽县| 沾化县| 琼结县| 济宁市| 仙游县| 蒲城县| 灌云县| 板桥市| 洞头县| 泰和县| 黔江区| 定襄县| 安陆市| 高州市| 田阳县| 卢氏县| 安龙县| 南漳县| 景德镇市| 全南县| 灯塔市| 昔阳县| 岳普湖县| 资源县| 利辛县| 永年县| 都江堰市| 五华县| 黄骅市| 奎屯市| 南汇区| 镇康县| 桐城市| 纳雍县| 昭苏县| 五常市| 吴江市| 鹤山市| 泸溪县| 灵川县| 新兴县|