在线看毛片网站电影-亚洲国产欧美日韩精品一区二区三区,国产欧美乱夫不卡无乱码,国产精品欧美久久久天天影视,精品一区二区三区视频在线观看,亚洲国产精品人成乱码天天看,日韩久久久一区,91精品国产91免费

<menu id="6qfwx"><li id="6qfwx"></li></menu>
    1. <menu id="6qfwx"><dl id="6qfwx"></dl></menu>

      <label id="6qfwx"><ol id="6qfwx"></ol></label><menu id="6qfwx"></menu><object id="6qfwx"><strike id="6qfwx"><noscript id="6qfwx"></noscript></strike></object>
        1. <center id="6qfwx"><dl id="6qfwx"></dl></center>

            新聞中心

            EEPW首頁 > 嵌入式系統(tǒng) > 設(shè)計(jì)應(yīng)用 > 淺析Arm Linux操作系統(tǒng)調(diào)用流程詳細(xì)解析 .

            淺析Arm Linux操作系統(tǒng)調(diào)用流程詳細(xì)解析 .

            作者: 時(shí)間:2016-11-09 來源:網(wǎng)絡(luò) 收藏
            系統(tǒng)調(diào)用是os操作系統(tǒng)提供的服務(wù),用戶程序通過各種系統(tǒng)調(diào)用,來引用內(nèi)核提供的各種服務(wù),系統(tǒng)調(diào)用的執(zhí)行讓用戶程序陷入內(nèi)核,該陷入動(dòng)作由swi軟中斷完成.

            At91rm9200處理器對應(yīng)的linux2.4.19內(nèi)核系統(tǒng)調(diào)用對應(yīng)的軟中斷定義如下:

            #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運(yùn)算值
            #define __NR_open (__NR_SYSCALL_BASE+ 5) //0x900005

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

            __syscall_start:

            ...
            .long SYMBOL_NAME(sys_open) //第5個(gè)
            ...
            將sys_call_table[5]中內(nèi)容傳給pc,系統(tǒng)進(jìn)入sys_open函數(shù),處理實(shí)質(zhì)的open動(dòng)作

            注:用到的一些函數(shù)數(shù)據(jù)所在文件,如下所示
            arch/arm/kernel/calls.S聲明了系統(tǒng)調(diào)用函數(shù)
            include/asm-arm/unistd.h定義了系統(tǒng)調(diào)用的調(diào)用號規(guī)則

            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進(jìn)行了定義:
            .type sys_call_table, #object
            ENTRY(sys_call_table)
            #include "calls.S" //將calls.S中的內(nèi)容順序鏈接到這里

            源程序:

            ENTRY(vector_swi)
            save_user_regs
            zero_fp
            get_scno //將[lr,#-4]中的中斷號轉(zhuǎn)儲到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系統(tǒng)調(diào)用號scno=0x900005
            //eor scno,scno,#0x900000
            //之后scno=0x05
            eor scno, scno, #OS_NUMBER << 20 @ check OS number
            //sys_call_table項(xiàng)為calls.S的內(nèi)容
            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
            //執(zhí)行sys_open函數(shù)
            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
            //對應(yīng)反匯編:
            //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"


            評論


            技術(shù)專區(qū)

            關(guān)閉