微波EDA网,见证研发工程师的成长! 2025濠电姷鏁告慨鐑藉极閸涘﹥鍙忛柟缁㈠枟閸庡顭块懜闈涘缂佺嫏鍥х閻庢稒蓱鐏忣厼霉濠婂懎浜惧ǎ鍥э躬婵″爼宕熼鐐差瀴闂備礁鎲¢悷銉ф崲濮椻偓瀵鏁愭径濠勵吅闂佹寧绻傚Λ顓炍涢崟顓犵<闁绘劦鍓欓崝銈嗙箾绾绡€鐎殿喖顭烽幃銏ゅ川婵犲嫮肖闂備礁鎲¢幐鍡涘川椤旂瓔鍟呯紓鍌氬€搁崐鐑芥嚄閼搁潧鍨旀い鎾卞灩閸ㄥ倿鏌涢锝嗙闁藉啰鍠栭弻鏇熺箾閻愵剚鐝曢梺绋款儏濡繈寮诲☉姘勃闁告挆鈧Σ鍫濐渻閵堝懘鐛滈柟鍑ゆ嫹04闂傚倸鍊搁崐鎼佸磹閹间礁纾归柟闂寸绾惧綊鏌熼梻瀵割槮缁惧墽鎳撻—鍐偓锝庝簼閹癸綁鏌i鐐搭棞闁靛棙甯掗~婵嬫晲閸涱剙顥氬┑掳鍊楁慨鐑藉磻閻愮儤鍋嬮柣妯荤湽閳ь兛绶氬鎾閳╁啯鐝曢梻浣藉Г閿氭い锔诲枤缁辨棃寮撮姀鈾€鎷绘繛杈剧秬濞咃絿鏁☉銏$厱闁哄啠鍋撴繛鑼枛閻涱噣寮介褎鏅濋梺闈涚墕濞诧絿绮径濠庢富闁靛牆妫涙晶閬嶆煕鐎n剙浠遍柟顕嗙節婵$兘鍩¢崒婊冨箺闂備礁鎼ú銊╁磻濞戙垹鐒垫い鎺嗗亾婵犫偓闁秴鐒垫い鎺嶈兌閸熸煡鏌熼崙銈嗗17闂傚倸鍊搁崐鎼佸磹閹间礁纾归柟闂寸绾惧綊鏌熼梻瀵割槮缁惧墽鎳撻—鍐偓锝庝簼閹癸綁鏌i鐐搭棞闁靛棙甯掗~婵嬫晲閸涱剙顥氬┑掳鍊楁慨鐑藉磻閻愮儤鍋嬮柣妯荤湽閳ь兛绶氬鎾閳╁啯鐝栭梻渚€鈧偛鑻晶鎵磼椤曞棛鍒伴摶鏍归敐鍫燁仩妞ゆ梹娲熷娲偡閹殿喗鎲奸梺鑽ゅ枂閸庣敻骞冨鈧崺锟犲礃椤忓棴绱查梻浣虹帛閻熴垽宕戦幘缁樼厱闁靛ǹ鍎抽崺锝団偓娈垮枛椤攱淇婇幖浣哥厸闁稿本鐭花浠嬫⒒娴e懙褰掑嫉椤掑倻鐭欓柟杈惧瘜閺佸倿鏌ㄩ悤鍌涘 闂傚倸鍊搁崐鎼佸磹閹间礁纾归柟闂寸绾惧綊鏌熼梻瀵割槮缁惧墽鎳撻—鍐偓锝庝簼閹癸綁鏌i鐐搭棞闁靛棙甯掗~婵嬫晲閸涱剙顥氬┑掳鍊楁慨鐑藉磻閻愮儤鍋嬮柣妯荤湽閳ь兛绶氬鎾閻樻爠鍥ㄧ厱閻忕偛澧介悡顖氼熆鐟欏嫭绀€闁宠鍨块、娆戠磼閹惧墎绐楅梻浣告啞椤棝宕橀敐鍡欌偓娲倵楠炲灝鍔氭繛鑼█瀹曟垿骞橀懜闈涙瀭闂佸憡娲﹂崜娑㈡晬濞戙垺鈷戦柛娑樷看濞堟洖鈹戦悙璇ц含闁诡喕鍗抽、姘跺焵椤掆偓閻g兘宕奸弴銊︽櫌婵犮垼娉涢鍡椻枍鐏炶В鏀介柣妯虹仛閺嗏晛鈹戦鑺ュ唉妤犵偛锕ュ鍕箛椤掑偊绱遍梻浣筋潐瀹曟﹢顢氳閺屻劑濡堕崱鏇犵畾闂侀潧鐗嗙€氼垶宕楀畝鍕厱婵炲棗绻戦ˉ銏℃叏婵犲懏顏犵紒杈ㄥ笒铻i柤濮愬€ゅΣ顒勬⒒娴e懙褰掓晝閵堝拑鑰块梺顒€绉撮悞鍨亜閹哄秷鍏岄柛鐔哥叀閺岀喖宕欓妶鍡楊伓闂傚倸鍊搁崐鎼佸磹閹间礁纾归柟闂寸绾惧綊鏌熼梻瀵割槮缁炬儳缍婇弻锝夊箣閿濆憛鎾绘煕婵犲倹鍋ラ柡灞诲姂瀵挳鎮欏ù瀣壕闁告縿鍎虫稉宥夋煛瀹ュ骸骞楅柣鎾存礃閵囧嫰骞囬崜浣荷戠紓浣插亾闁逞屽墰缁辨帡鎮欓鈧崝銈夋煟韫囨梻绠為柛鈺冨仱楠炲鏁傞挊澶夋睏闂佽楠稿﹢杈ㄦ叏閹绢啟澶娾攽閸垻锛濇繛杈剧到閹碱偊顢撳畝鍕厱闁靛ǹ鍎抽崺锝団偓娈垮枛椤攱淇婇幖浣哥厸闁稿本鐭花浠嬫⒒娴e懙褰掑嫉椤掑倻鐭欓柟杈惧瘜閺佸倿鏌ㄩ悤鍌涘
首页 > 硬件设计 > 嵌入式设计 > Arm Linux系统调用流程详细解析

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

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

ons have to be fixed up then non-zero is* returned and the operation has to be re-attempted.** *NOTE*: This is a ghost syscall private to the kernel. Only the* __kuser_cmpxchg code in entry-armv.S should be aware of its* existence. Dont ever use this from user code.*/case NR(cmpxchg):for (;;) {extern void do_DataAbort(unsigned long addr, unsigned int fsr,struct pt_regs *regs);unsigned long val;unsigned long addr = regs->ARM_r2;struct mm_struct *mm = current->mm;pgd_t *pgd; pmd_t *pmd; pte_t *pte;spinlock_t *ptl;regs->ARM_cpsr &= ~PSR_C_BIT;down_read(&mm->mmap_sem);pgd = pgd_offset(mm, addr);if (!pgd_present(*pgd))goto bad_access;pmd = pmd_offset(pgd, addr);if (!pmd_present(*pmd))goto bad_access;pte = pte_offset_map_lock(mm, pmd, addr, &ptl);if (!pte_present(*pte) !pte_dirty(*pte)) {pte_unmap_unlock(pte, ptl);goto bad_access;}val = *(unsigned long *)addr;val -= regs->ARM_r0;if (val == 0) {*(unsigned long *)addr = regs->ARM_r1;regs->ARM_cpsr = PSR_C_BIT;}pte_unmap_unlock(pte, ptl);up_read(&mm->mmap_sem);return val;bad_access:up_read(&mm->mmap_sem);/* simulate a write access fault */do_DataAbort(addr, 15 + (1 < 11), regs);}#endifdefault:/* Calls 9f00xx..9f07ff are defined to return -ENOSYSif not implemented, rather than raising SIGILL. Thisway the calling program can gracefully determine whethera feature is supported. */if ((no & 0xffff) <= 0x7ff)return -ENOSYS;break;}#ifdef CONFIG_DEBUG_USER/** experience shows that these seem to indicate that* something catastrophic has happened*/if (user_debug & UDBG_SYSCALL) {printk("[%d] %s: arm syscall %d\n",task_pid_nr(current), current->comm, no);dump_instr("", regs);if (user_mode(regs)) {__show_regs(regs);c_backtrace(regs->ARM_fp, processor_mode(regs));}}#endifinfo.si_signo = SIGILL;info.si_errno = 0;info.si_code = ILL_ILLTRP;info.si_addr = (void __user *)instruction_pointer(regs) -(thumb_mode(regs) ? 2 : 4);arm_notify_die("Oops - bad syscall(2)", regs, &info, no, 0);return 0;}

还有那个sys_ni_syscall,这个函数在kernel/sys_ni.c中定义,它的作用似乎也仅仅是要给用户空间返回错误码ENOSYS。

/*  we cant #include  here,but tell gcc to not warn with -Wmissing-prototypes  */asmlinkage long sys_ni_syscall(void);/** Non-implemented system calls get redirected here.*/asmlinkage long sys_ni_syscall(void){return -ENOSYS;}

系统调用号正确也好不正确也好,最终都是通过ret_fast_syscall例程来返回,同样在arch/arm/kernel/entry-common.S文件中:

.align    5/** This is the fast syscall return path.  We do as little as* possible here, and this includes saving r0 back into the SVC* stack.*/ret_fast_syscall:UNWIND(.fnstart    )UNWIND(.cantunwind    )disable_irq                @ disable interruptsldr    r1, [tsk, #TI_FLAGS]tst    r1, #_TIF_WORK_MASKbne    fast_work_pending#if defined(CONFIG_IRQSOFF_TRACER)asm_trace_hardirqs_on#endif/* perform architecture specific actions before user return */arch_ret_to_user r1, lrrestore_user_regs fast = 1, offset = S_OFFUNWIND(.fnend        )

四.声明系统调用的相关宏

linux下的系统调用函数定义接口:

1.SYSCALL_DEFINE1~6(include/linux/syscalls.h)

#define SYSCALL_DEFINE1(name, ...) SYSCALL_DEFINEx(1, _##name, __VA_ARGS__)#define SYSCALL_DEFINE2(name, ...) SYSCALL_DEFINEx(2, _##name, __VA_ARGS__)#define SYSCALL_DEFINE3(name, ...) SYSCALL_DEFINEx(3, _##name, __VA_ARGS__)#define SYSCALL_DEFINE4(name, ...) SYSCALL_DEFINEx(4, _##name, __VA_ARGS__)#define SYSCALL_DEFINE5(name, ...) SYSCALL_DEFINEx(5, _##name, __VA_ARGS__)#define SYSCALL_DEFINE6(name, ...) SYSCALL_DEFINEx(6, _##name, __VA_ARGS__)

2.SYSCALL_DEFINEx

#ifdef CONFIG_FTRACE_SYSCALLS#define SYSCALL_DEFINEx(x, sname, ...)                \static const char *types_##sname[] = {            \__SC_STR_TDECL##x(__VA_ARGS__)            \};                            \static const char *args_##sname[] = {            \__SC_STR_ADECL##x(__VA_ARGS__)            \};                            \SYSCALL_METADATA(sname, x);                \__SYSCALL_DEFINEx(x, sname, __VA_ARGS__)#else#define SYSCALL_DEFINEx(x, sname, ...)                \__SYSCALL_DEFINEx(x, sname, __VA_ARGS__)#endif

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

网站地图

Top