在线看毛片网站电影-亚洲国产欧美日韩精品一区二区三区,国产欧美乱夫不卡无乱码,国产精品欧美久久久天天影视,精品一区二区三区视频在线观看,亚洲国产精品人成乱码天天看,日韩久久久一区,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首頁(yè) > 嵌入式系統(tǒng) > 設(shè)計(jì)應(yīng)用 > Arm linux 系統(tǒng)調(diào)用分析

            Arm linux 系統(tǒng)調(diào)用分析

            作者: 時(shí)間:2016-11-09 來源:網(wǎng)絡(luò) 收藏
            Armlinux系統(tǒng)調(diào)用分析
            概述

            操作系統(tǒng)為在用戶態(tài)運(yùn)行的進(jìn)程與硬件設(shè)備進(jìn)行交互,提供操作系統(tǒng)的系統(tǒng)服務(wù),提供了一組接口。在應(yīng)用程序和硬件之間,內(nèi)核提供的系統(tǒng)服務(wù)設(shè)置一個(gè)額外層具有很多優(yōu)點(diǎn)。

            本文引用地址:http://www.biyoush.com/article/201611/318014.htm

            首先,這使得編程更加容易,把用戶從學(xué)習(xí)硬件設(shè)備的低級(jí)編程特性中解放出來。

            其次,這極大地提高了系統(tǒng)的安全性,因?yàn)閮?nèi)核在試圖滿足某個(gè)請(qǐng)求之前在接口級(jí)就可以檢查這種請(qǐng)求的正確性。

            最后,更重要的是這些接口使得程序具有可移植性,因?yàn)橹灰獌?nèi)核所提供的一組接口相同,那么在任一內(nèi)核之上就可以正確地編譯和執(zhí)行程序。


            ARMLinux系統(tǒng)利用SWI指令來從用戶空間進(jìn)入內(nèi)核空間,還是先讓我們了解下這個(gè)SWI指令吧。SWI指令用于產(chǎn)生軟件中斷,從而實(shí)現(xiàn)從用戶模式到管理模式的變換,CPSR保存到管理模式的SPSR,執(zhí)行轉(zhuǎn)移到SWI向量。在其他模式下也可使用SWI指令,處理器同樣地切換到管理模式。指令格式如下:

            SWI{cond}immed_24

            其中:

            immed_2424位立即數(shù),值為從0——16777215之間的整數(shù)。

            使用SWI指令時(shí),通常使用以下兩種方法進(jìn)行參數(shù)傳遞,SWI異常處理程序可以提供相關(guān)的服務(wù),這兩種方法均是用戶軟件協(xié)定。

            1)指令中24位的立即數(shù)指定了用戶請(qǐng)求的服務(wù)類型,參數(shù)通過通用寄存器傳遞。SWI異常處理程序要通過讀取引起軟件中斷的SWI指令,以取得24為立即數(shù)。如:

            MOVR0,#34

            SWI12

            2)指令中的24位立即數(shù)被忽略,用戶請(qǐng)求的服務(wù)類型由寄存器R0的值決定,參數(shù)通過其他的通用寄存器傳遞。如:

            MOVR0,#12

            MOVR1,#34

            SWI0

            ArmLinux內(nèi)核處理系統(tǒng)調(diào)用

            1. 在分析arm中斷處理過程中我們提到過arm架構(gòu)中的異常處理向量表,其中有一個(gè)地址就是處理swi軟件中斷的入口。
            2. .globl __vectors_start
            3. __vectors_start:
            4. swi SYS_ERROR0:
            5. b vector_und + stubs_offset
            6. ldr pc, .LCvswi + stubs_offset
            7. b vector_pabt + stubs_offset
            8. b vector_dabt + stubs_offset
            9. b vector_addrexcptn + stubs_offset
            10. b vector_irq + stubs_offset
            11. b vector_fiq + stubs_offset
            12. .globl __vectors_end:
            13. __vectors_end:
            14. Cpu執(zhí)行上面紅色指令之后跳轉(zhuǎn)到entry-common.s執(zhí)行vector_swi處的指令,該函數(shù)就是內(nèi)核中處理系統(tǒng)調(diào)用的入口。

            1. 在用戶態(tài)調(diào)用swi指令,cpu從user狀態(tài)切換到svc狀態(tài)。首先需要執(zhí)行的就是保存cpu現(xiàn)場(chǎng),這樣才能在陷入內(nèi)核態(tài)執(zhí)行了相應(yīng)的系統(tǒng)調(diào)用處理過程之后,恢復(fù)cpu用戶態(tài)的狀態(tài),重新執(zhí)行用戶態(tài)進(jìn)程。
            2. ENTRY(vector_swi)
            3. sub sp, sp, #S_FRAME_SIZE
            4. stmia sp, {r0 - r12} @ Calling r0 - r12
            5. add r8, sp, #S_PC
            6. stmdb r8, {sp, lr}^ @ Calling sp, lr
            7. mrs r8, spsr @ called from non-FIQ mode, so ok.
            8. str lr, [sp, #S_PC] @ Save calling PC
            9. str r8, [sp, #S_PSR] @ Save CPSR
            10. str r0, [sp, #S_OLD_R0] @ Save OLD_R0
            11. zero_fp
            12. BLANK();
            13. DEFINE(S_R0, offsetof(struct pt_regs, ARM_r0));
            14. DEFINE(S_R1, offsetof(struct pt_regs, ARM_r1));
            15. DEFINE(S_R2, offsetof(struct pt_regs, ARM_r2));
            16. DEFINE(S_R3, offsetof(struct pt_regs, ARM_r3));
            17. DEFINE(S_R4, offsetof(struct pt_regs, ARM_r4));
            18. DEFINE(S_R5, offsetof(struct pt_regs, ARM_r5));
            19. DEFINE(S_R6, offsetof(struct pt_regs, ARM_r6));
            20. DEFINE(S_R7, offsetof(struct pt_regs, ARM_r7));
            21. DEFINE(S_R8, offsetof(struct pt_regs, ARM_r8));
            22. DEFINE(S_R9, offsetof(struct pt_regs, ARM_r9));
            23. DEFINE(S_R10, offsetof(struct pt_regs, ARM_r10));
            24. DEFINE(S_FP, offsetof(struct pt_regs, ARM_fp));
            25. DEFINE(S_IP, offsetof(struct pt_regs, ARM_ip));
            26. DEFINE(S_SP, offsetof(struct pt_regs, ARM_sp));
            27. DEFINE(S_LR, offsetof(struct pt_regs, ARM_lr));
            28. DEFINE(S_PC, offsetof(struct pt_regs, ARM_pc));
            29. DEFINE(S_PSR, offsetof(struct pt_regs, ARM_cpsr));
            30. DEFINE(S_OLD_R0, offsetof(struct pt_regs, ARM_ORIG_r0));
            31. DEFINE(S_FRAME_SIZE, sizeof(struct pt_regs));
            32. BLANK();

            1. ldr r10, [lr, #-4] @ get SWI instruction
            2. 之后,將swi指令保存在r10寄存器中
            3. enable_irq
            4. get_thread_info tsk
            5. adr tbl, sys_call_table @ load syscall table pointer
            6. ldr ip, [tsk, #TI_FLAGS] @ check for syscall tracing
            7. 開啟中斷,將thread info結(jié)構(gòu)的指針保存在tsk,將sys_call_table的地址保存在tbl中,將thread info結(jié)構(gòu)中的flag保存ip中。
            8. scno .req r7 @ syscall number
            9. tbl .req r8 @ syscall table pointer
            10. why .req r8 @ Linux syscall (!= 0)
            11. tsk .req r9 @ current thread_info

            1. bics r10, r10, #0xff000000
            2. eorne scno, r10, #__NR_OABI_SYSCALL_BASE
            3. ldrne tbl, =sys_oabi_call_table
            4. #elif !defined(CONFIG_AEABI)
            5. bic scno, scno, #0xff000000 @ mask off SWI op-code
            6. eor scno, scno, #__NR_SYSCALL_BASE @ check OS number
            7. #endif
            8. 檢查swi命令中帶的中斷號(hào)是不是為0,如果不等于零說明是是old ABI方式調(diào)用的系統(tǒng)調(diào)用,這時(shí)將sys_oabi_call_table的地址載入到tbl中,同時(shí)得到系統(tǒng)調(diào)用的中斷號(hào),保存在scno中。如果swi指令中帶點(diǎn)中斷號(hào)為0,說明系統(tǒng)調(diào)用是利用scno寄存器傳遞中斷號(hào)的。利用異或指令,將__NR_SYSCALL_BASE清除掉,得到實(shí)際的系統(tǒng)請(qǐng)求號(hào)(系統(tǒng)調(diào)用號(hào)定義為__NR_SYSCALL_BASE+x)。

            1. stmdb sp!, {r4, r5} @ push fifth and sixth args
            2. tst ip, #_TIF_SYSCALL_TRACE @ are we tracing syscalls?
            3. bne __sys_trace
            4. 如果進(jìn)程帶有syscall trace標(biāo)志就調(diào)用sys_trace,這處應(yīng)該是作為調(diào)試用的。
            5. cmp scno, #NR_syscalls @ check upper syscall limit
            6. adr lr, ret_fast_syscall @ return address
            7. ldrcc pc, [tbl, scno, lsl #2] @ call sys_* routine
            8. 如果系統(tǒng)調(diào)用號(hào),不大于NR_syscalls,就跳轉(zhuǎn)到系統(tǒng)調(diào)用函數(shù)去執(zhí)行l(wèi)drcc pc, [tbl, scno, lsl #2]

            總結(jié)

            Arm系統(tǒng)調(diào)用的簡(jiǎn)單概述。首先是用戶態(tài)執(zhí)行swi指令,swi指令使得cpu陷入svc狀態(tài),并跳轉(zhuǎn)到固定地址去執(zhí)行系統(tǒng)調(diào)用處理過程。用戶態(tài)通過兩種方法傳遞給內(nèi)核執(zhí)行系統(tǒng)調(diào)用的系統(tǒng)調(diào)用號(hào)。內(nèi)核執(zhí)行系統(tǒng)調(diào)用處理過程,首先保存cpu現(xiàn)場(chǎng),之后會(huì)獲取到系統(tǒng)調(diào)用號(hào),以系統(tǒng)調(diào)用地址表的基地址,加系統(tǒng)調(diào)用號(hào)做偏移,跳轉(zhuǎn)到相應(yīng)的系統(tǒng)調(diào)用例程做相應(yīng)的處理。



            關(guān)鍵詞: Armlinux系統(tǒng)調(diào)

            評(píng)論


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

            關(guān)閉