<meter id="pryje"><nav id="pryje"><delect id="pryje"></delect></nav></meter>
          <label id="pryje"></label>

          新聞中心

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

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

          作者: 時間: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)核,該陷入動作由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

          舉一個例子來說:open系統(tǒng)調(diào)用,庫函數(shù)最終會調(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個
          ...
          將sys_call_table[5]中內(nèi)容傳給pc,系統(tǒng)進(jìn)入sys_open函數(shù),處理實質(zhì)的open動作

          注:用到的一些函數(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項為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)閉
          看屁屁www成人影院,亚洲人妻成人图片,亚洲精品成人午夜在线,日韩在线 欧美成人 (function(){ var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https') { bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })();