`
cjc
  • 浏览: 680987 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

ARM linux系统调用的实现原理

阅读更多
<script>function StorePage(){d=document;t=d.selection?(d.selection.type!='None'?d.selection.createRange().text:''):(d.getSelection?d.getSelection():'');void(keyit=window.open('http://www.365key.com/storeit.aspx?t='+escape(d.title)+'&u='+escape(d.location.href)+'&c='+escape(t),'keyit','scrollbars=no,width=475,height=575,left=75,top=20,status=no,resizable=yes'));keyit.focus();}</script>

作者:刘洪涛,华清远见嵌入式培训中心讲师。

大家都知道linux的应用程序要想访问内核必须使用系统调用从而实现从usr模式转到svc模式。下面咱们看看它的实现过程。

系统调用是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. We're 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"

分享到:
评论

相关推荐

    arm linux系统调用分析

    ### ARM Linux系统调用分析 #### 一、系统调用概览 系统调用作为操作系统提供的核心机制之一,是用户态程序与内核态交互的关键途径...了解ARM Linux系统调用的具体实现细节对于深入理解操作系统的工作原理至关重要。

    ARM linux系統調用的實現原理

    以下是关于"ARM Linux系统调用实现原理"的详细解释: 1. **模式切换**: - 在ARM处理器中,有两种主要的执行模式:用户模式(usr)和系统模式(svc)。当应用程序执行系统调用时,它需要从用户模式切换到系统模式...

    Linux下的系统调用和进程

    在ARMLinux系统中,原子操作主要通过硬件支持实现,其API和原子类型的定义存储在内核源码树的`include/asm/atomic.h`文件中。原子操作通常用于实现资源计数,例如,引用计数(`refcnt`)的管理,保证了在并发环境下的...

    嵌入式系统/ARM技术中的ARM linux系统调用的实现原理

     大家都知道linux的应用程序要想访问内核必须使用系统调用从而实现从usr模式转到svc模式。下面咱们看看它的实现过程。  系统调用是os操作系统提供的服务,用户程序通过各种系统调用,来引用内核提供的各种服务,...

    arm linux 技术详解 光盘

    这些基础知识是理解ARM Linux系统运行原理的关键,有助于开发者编写高效的底层代码。 其次,光盘可能会讲解Linux内核的移植过程,包括交叉编译环境的建立、内核配置、编译和裁剪,以及如何将编译好的内核映像烧录到...

    ARM-Linux系统移植

    ### ARM-Linux系统移植知识点概览 #### 第一部分:前言 **1. 硬件环境** - **1.1 主机硬件环境** - 需要明确主机(开发机)的具体硬件配置,包括处理器类型、内存大小等。 - **1.2 目标板硬件环境** - 描述目标板...

    ARM嵌入式Linux系统开发技术详解-基于ARM pdf

    在ARM平台上开发应用程序需要了解Linux编程接口,如系统调用、标准库函数、多线程编程、网络编程等。书籍将提供实践指导,帮助读者编写高效且稳定的嵌入式应用程序。 七、调试与性能优化 调试技巧和性能优化是任何...

    ARM嵌入式Linux系统开发详解源代码

    - 在嵌入式Linux系统中,网络编程涉及到TCP/IP协议栈、socket编程以及网络服务的实现,是许多物联网应用的基础。 8. **电源管理** - 在ARM设备中,有效的电源管理可以延长电池寿命,涉及CPU频率调整、休眠模式...

    ARM Linux启动过程分析

    ARM Linux启动过程分析 1. ARM Linux 启动过程概述 ARM Linux 启动过程可以分为四个部分:引导加载程序...了解 ARM Linux 启动过程可以帮助开发者更好地理解嵌入式系统的工作原理,并提高嵌入式系统的开发效率。

    ARM Linux Ubuntu 虚拟键盘配置文件及配置说明

    在嵌入式开发领域,尤其是基于ARM架构的Linux系统中,使用虚拟键盘是常见的需求,尤其是在没有物理输入设备或者输入设备有限的情况下。本资源提供的"ARM Linux Ubuntu 虚拟键盘配置文件及配置说明"正是为了解决这个...

    精通ARM嵌入式Linux系统开发

    通过阅读《精通ARM嵌入式Linux系统开发》,读者不仅可以掌握ARM处理器的工作原理,还能全面了解嵌入式Linux系统的设计与开发流程,从而具备在实际项目中应用这些技术的能力。无论是对硬件工程师还是软件开发者,这都...

    ARM嵌入式linux系统开发视频教程

    学习者将了解如何在Linux环境下进行系统调用、创建守护进程、实现网络通信,以及如何有效地管理系统的内存资源。这对于开发高效且稳定的嵌入式应用至关重要。 此外,教程还会涉及嵌入式开发中的实际问题,如电源...

    ArmLinux BOOTLOADER全程详解

    在构建ArmLinux Bootloader时,采用的是Redhat Linux操作系统作为开发主机,使用armgcc工具链编译代码,并以Armlinux Kernel作为目标平台。具体的地址分配如下: - **0x4000_0000**:片内DRAM,用于存放4KB以内的...

    Arm+Linux系统移植(非常好的移植文档很详细)

    ### Arm+Linux系统移植知识点详解 #### 一、前言 **Arm+Linux系统移植**是将Linux操作系统适配到基于ARM架构的目标硬件平台上的一项技术工作。这项工作不仅包括了软件层面的操作系统移植,还涉及到了硬件环境的...

    arm linux内核源码剖析0

    Linux内核是操作系统的核心,负责管理系统的硬件资源,提供系统调用接口,以及调度进程等核心功能。对于嵌入式系统,如基于ARM架构的设备,理解和分析Linux内核源码对于优化性能、调试和定制化系统至关重要。 "0...

    建立Arm Linux 开发环境

    ### 建立Arm Linux开发环境:在Ubuntu上的详尽指南 ...遵循上述步骤,开发者不仅能够顺利搭建起Arm Linux开发环境,还能在此过程中深化对嵌入式系统原理的理解,为后续的项目开发打下坚实的基础。

    一个小的ARM操作系统.rar_ARM 源码_arm 操作系统_arm-linux_operating system_操作系统

    这个操作系统可能是一个简化版或教育用途的实现,旨在帮助开发者和学习者理解ARM处理器上的操作系统是如何工作的。ARM架构广泛应用于移动设备、嵌入式系统以及物联网(IoT)设备。 描述中的“一个小的ARM源码”暗示了...

    Lab 6:Linux系统调用1

    在本实验“Lab 6:Linux系统调用1”中,我们将深入理解Linux操作系统的核心机制,特别是如何实现自定义的系统调用。这个过程涉及到多个步骤,包括获取源码、配置内核、编译以及安装系统调用。以下是对整个流程的详细...

Global site tag (gtag.js) - Google Analytics