浅析基于ARM的Linux下的系统调用的实现

发布者:心灵舞者最新更新时间:2020-02-16 来源: eefocus关键字:ARM  Linux下  系统调用 手机看文章 扫描二维码
随时随地手机看文章

在Linux下系统调用是用软中断实现的,下面以一个简单的open例子简要分析一下应用层的open是如何调用到内核中的sys_open的。


t8.c


   1:  #include

   2:  #include

   3:  #include

   4:  #include

   5:   

   6:  int main(int argc, const char *argv[])

   7:  {

   8:      int fd;

   9:   

  10:      fd = open(".", O_RDWR);

  11:   

  12:      close(fd);

  13:      return 0;

  14:  }


这里需要注意的是:open是C库提供的库函数,并不是系统调用,系统调用时在内核空间的,应用空间无法直接调用。在《Linux内核设计与实现》中说:要访问系统调用(在Linux中常称作syscall),通常通过C库中定义的函数调用来进行。


将t8.c进行静态编译,然后反汇编,看一下是如何调用open的?


   1:  arm-linux-gcc t8.c --static

   2:  arm-linux-objdump -D a.out >a.dis


下面我们截取a.dis中的一部分进行说明:


   1:  ......

   2:  00008228

:

   3:      8228:   e92d4800    push    {fp, lr}

   4:      822c:   e28db004    add fp, sp, #4  ; 0x4

   5:      8230:   e24dd010    sub sp, sp, #16 ; 0x10

   6:      8234:   e50b0010    str r0, [fp, #-16]

   7:      8238:   e50b1014    str r1, [fp, #-20]

   8:      823c:   e59f0028    ldr r0, [pc, #40]   ; 826c

   9:      8240:   e3a01002    mov r1, #2  ; 0x2   ;  #define  O_RDWR  00000002 

  10:      8244:   eb002e7d    bl  13c40 <__libc_open>

  11:      8248:   e1a03000    mov r3, r0

  12:      824c:   e50b3008    str r3, [fp, #-8]

  13:      8250:   e51b0008    ldr r0, [fp, #-8]

  14:      8254:   eb002e9d    bl  13cd0 <__libc_close>

  15:      8258:   e3a03000    mov r3, #0  ; 0x0

  16:      825c:   e1a00003    mov r0, r3

  17:      8260:   e24bd004    sub sp, fp, #4  ; 0x4

  18:      8264:   e8bd4800    pop {fp, lr}

  19:      8268:   e12fff1e    bx  lr

  20:      826c:   00064b8c    .word   0x00064b8c

  21:  ......

  22:  00013c40 <__libc_open>:

  23:     13c40:   e51fc028    ldr ip, [pc, #-40]  ; 13c20 <___fxstat64+0x50>

  24:     13c44:   e79fc00c    ldr ip, [pc, ip]

  25:     13c48:   e33c0000    teq ip, #0  ; 0x0

  26:     13c4c:   1a000006    bne 13c6c <__libc_open+0x2c>

  27:     13c50:   e1a0c007    mov ip, r7

  28:     13c54:   e3a07005    mov r7, #5  ; 0x5   

  #在arch/arm/include/asm/unistd.h中:#define __NR_open  (__NR_SYSCALL_BASE+5)

                    其中,__NR_OABI_SYSCALL_BASE是0

  29:     

13c58: ef000000 svc 0x00000000 #产生软中断

  30:     13c5c:   e1a0700c    mov r7, ip

  31:     13c60:   e3700a01    cmn r0, #4096   ; 0x1000

  32:     13c64:   312fff1e    bxcc    lr

  33:     13c68:   ea0008d4    b   15fc0 <__syscall_error>

  34:  ......


通过上面的代码注释,可以看到,系统调用sys_open的系统调用号是5,将系统调用号存放到寄存器R7当中,然后应用程序通过svc 0x00000000产生软中断,陷入内核空间。


也许会好奇,ARM软中断不是用SWI吗,这里怎么变成了SVC了,请看下面一段话,是从ARM官网copy的:


SVC


超级用户调用。 

语法


SVC{cond} #immed


其中:


cond


    是一个可选的条件代码(请参阅条件执行)。 

immed


    是一个表达式,其取值为以下范围内的一个整数:


        在 ARM 指令中为 0 到 224–1(24 位值)


        在 16 位 Thumb 指令中为 0-255(8 位值)。


用法


SVC 指令会引发一个异常。 这意味着处理器模式会更改为超级用户模式,CPSR 会保存到超级用户模式 SPSR,并且执行会跳转到 SVC 向量(请参阅《开发指南》中的第 6 章 处理处理器异常)。


处理器会忽略 immed。 但异常处理程序会获取它,借以确定所请求的服务。 

Note


作为 ARM 汇编语言开发成果的一部分,SWI 指令已重命名为 SVC。 在此版本的 RVCT 中,SWI 指令反汇编为 SVC,并提供注释以指明这是以前的 SWI。 

条件标记


此指令不更改标记。 

体系结构


此 ARM 指令可用于所有版本的 ARM 体系结构。


在基于ARM的Linux中,异常向量表已经被放置在了0xFFFF0000这个位置。这个过程的完成:


start_kernel ---> setup_arch ---> early_trap_init


   1:  void __init early_trap_init(void)

   2:  {

   3:      unsigned long vectors = CONFIG_VECTORS_BASE;  // 就是0xFFFF0000

   4:      extern char __stubs_start[], __stubs_end[];

   5:      extern char __vectors_start[], __vectors_end[];

   6:      extern char __kuser_helper_start[], __kuser_helper_end[];

   7:      int kuser_sz = __kuser_helper_end - __kuser_helper_start;

   8:   

   9:      /*

  10:       * Copy the vectors, stubs and kuser helpers (in entry-armv.S)

  11:       * into the vector page, mapped at 0xffff0000, and ensure these

  12:       * are visible to the instruction stream.

  13:       */

  14:      memcpy((void *)vectors, __vectors_start, __vectors_end - __vectors_start);

  15:      memcpy((void *)vectors + 0x200, __stubs_start, __stubs_end - __stubs_start);

  16:      memcpy((void *)vectors + 0x1000 - kuser_sz, __kuser_helper_start, kuser_sz);

  17:   

  18:      /*

  19:       * Copy signal return handlers into the vector page, and

  20:       * set sigreturn to be a pointer to these.

  21:       */

  22:      memcpy((void *)KERN_SIGRETURN_CODE, sigreturn_codes,

  23:             sizeof(sigreturn_codes));

  24:   

  25:      flush_icache_range(vectors, vectors + PAGE_SIZE);

  26:      modify_domain(DOMAIN_USER, DOMAIN_CLIENT);

  27:  }

关于上面这个函数的详细解释,参见:


http://www.cnblogs.com/pengdonglin137/p/3603549.html


把异常中断向量表的位置设置为0xffff0000的话,需要修改协处理器CP15的寄存器C1的第13位,将其设置为1。以Tq2440的提供的内核2.6.30.4为例看一下:


 arch/arm/kernel/head.S


   1:      adr    lr, __enable_mmu        @ return (PIC) address

   2:      add    pc, r10, #PROCINFO_INITFUNC

其中,PROCINFO_INITFUNC的值是16,r10的值是__arm920_proc_info的地址:


   1:  __arm920_proc_info:

   2:      .long    0x41009200

   3:      .long    0xff00fff0

   4:      .long   PMD_TYPE_SECT |

   5:          PMD_SECT_BUFFERABLE |

   6:          PMD_SECT_CACHEABLE |

   7:          PMD_BIT4 |

   8:          PMD_SECT_AP_WRITE |

   9:          PMD_SECT_AP_READ

  10:      .long   PMD_TYPE_SECT |

  11:          PMD_BIT4 |

  12:          PMD_SECT_AP_WRITE |

  13:          PMD_SECT_AP_READ

  14:      b    __arm920_setup

  15:      .long    cpu_arch_name

  16:      .long    cpu_elf_name

  17:       ......

  18:      .size    __arm920_proc_info, . - __arm920_proc_info

看一下__arm920_setup的实现(proc-arm920.S (archarmmm)):


   1:      .type    __arm920_setup, #function

   2:  __arm920_setup:

   3:      mov    r0, #0

   4:      mcr    p15, 0, r0, c7, c7        @ invalidate I,D caches on v4

   5:      mcr    p15, 0, r0, c7, c10, 4        @ drain write buffer on v4

   6:  #ifdef CONFIG_MMU

   7:      mcr    p15, 0, r0, c8, c7        @ invalidate I,D TLBs on v4

   8:  #endif

   9:      adr    r5, arm920_crval

  10:      ldmia    r5, {r5, r6}            @ 参看以下下面的arm920_crval的实现,本句话执行完后r5和r6分别为:0x3f3f和0x3135

  11:      mrc    p15, 0, r0, c1, c0        @ get control register v4   获取协处理器p15的寄存器才c1

  12:      

bic r0, r0, r5

  13:      

orr r0, r0, r6 @ 我们只关注第13位,这里将r0的第13位设置为了1

  14:      

mov pc, lr

  15:      .size    __arm920_setup, . - __arm920_setup

  16:   

  17:      /*

  18:       *  R

  19:       * .RVI ZFRS BLDP WCAM

  20:       * ..11 0001 ..11 0101

  21:       * 

  22:       */

  23:      .type    arm920_crval, #object

  24:  arm920_crval:

[1] [2] [3] [4]
关键字:ARM  Linux下  系统调用 引用地址:浅析基于ARM的Linux下的系统调用的实现

上一篇:三星S3C6410(ARM1176)平台Android资源获取与编译(RedHat AS5)
下一篇:Exynos4412的外部中断是如何安排的?

推荐阅读最新更新时间:2024-11-17 00:08

ARM7加速度数据采集系统设计
引言 加速度传感器一直是加速度测试中的重要元件。随着微加速度计的应用越来越广泛,对于微加速度计的数据信号采集和存储变得极为重要。传统的数据采集方法多数是采用单片机完成的,编程简单、控制灵活,但控制周期长、速度慢,特别是对高速转换的数据来说,单片机的速度极大地限制了数据传输速度。 目前,嵌入式系统的应用已经进入到一个高低并行发展的阶段。ARM处理器凭借体积小、功耗低、集成度高、硬件调试方便和操作系统可移植等优点,获得广泛的应用。本文采用基于ARM7TDMI-S核的32位微处理器AT91SAM7X256为控制核心,利用其内部自带的A/D转换器对采集到的加速度值进行转换。 本文应用Model 1221单轴MEMS加速度计,输
[单片机]
<font color='red'>ARM</font>7加速度数据采集<font color='red'>系统</font>设计
linux的各个目录的含义
路径名 内容 /bin 为得到最小的系统操作性所需要的那些命令 /boot 内核和加载内核所需的文件 /dev 终端、磁盘等设备项 /etc 关键的启动文件和配置文件 /lib c编译器的库和部分c编译器 /opt 可选,附加的应用软件包 /proc 所有正在运行进程的映象 /root 超级用户的主目录 /sbin 引导、修复或者恢复系统的命令 /tmp 每次重启就消失的临时文件 /usr 次要文件和命令层次结构 /ust/bin 大多数命令和可执行文件 /usr/include c程序的头文件 /usr/lib 库:供标准程序使用的支持文件 /usr/local 本地软件(用户所安装的软件) /usr/local/bin 本地的
[嵌入式]
基于ARM 的指纹识别门禁系统的设计
  1.概述   随着科学技术的不断进步,人们对现代化办公和生活场所提出了更高层次的安全管理需求,普通的门锁系统和手工出入管理已经不符合现代人的实际需求。由于安防业的智能化和网络化,为顺应智能楼宇、智能小区的发展,门禁系统也必须实现更可靠、更安全和更方便的智能系统。现代门禁系统综合利用了传感技术、数字信息处理、计算机技术、多媒体技术和网络技术,以实现门禁系统信息的采集、传输和处理。   目前智能门禁管理系统已广泛用于工厂、学校、写字楼宇、物业小区、商店、金融系统、电信系统、军事系统、宾馆等多种场合,大大提高了整体的工作效率、保障了系统安全,智能、安全和高效的现代化门禁系统已经成为社会发展的必然趋势,同时它也是现代化建筑的一个重
[单片机]
基于ARM的振动信号采集及文件存储系统
引言 在机械结构的振动过程中,许多微弱信号包含机械运动的丰富特征信息,如故障特征信息等,有必要提取出来加以分析。在微弱信号提取过程中,有时信号非常微弱,极易受到外界的干扰而淹没于强噪声之中,有时被测信号振幅变化范围又很大,会绐信号采集带来很大困难。放大电路本身的噪声性能和频率特性也将影响信号的提取精度。对振动信号的采集及处理,通常是用普通的数据采集系统去采集,然后用数字信号处理的方法来提取数据的特征信息。但是,一些由于采集系统的不足对信息造成的损失,是后期的数字信号处理无法补偿的。振动信号的检测是机械系统状态检测和早期故障诊断的关键,机械系统早期故障引起的异常振动信号有时很微弱,而且持续时间短、信噪比低,容易淹没于背景噪声中。
[单片机]
基于<font color='red'>ARM</font>的振动信号采集及文件存储<font color='red'>系统</font>
浅谈分析Arm linux 内核移植及系统初始化的过程一
学习嵌入式ARM linux ,主要想必三个方向发展: 1 、嵌入式linux 应用软件开发 2 、linux 内核的剪裁和移植 3 、嵌入式linux 底层驱动的开发 主 要介绍内核移植过程中涉及文件的分布及其用途,以及简单介绍系统的初始化过程。整个arm linux内核的启动可分为三个阶段:第一阶段主要是进行 cpu和体系结构的检查、cpu本身的初始化以及页表的建立等;第二阶段主要是对系统中的一些基础设施进行初始化;最后则是更高层次的初始化,如根设备和 外部设备的初始化。了解系统的初始化过程,有益于更好地移植内核。 1. 内核移植 2. 涉及文件分布介绍 2.1. 内核移植 2.2. 涉及的头文件 /linux-2.6.1
[单片机]
ARM中断向量设计方案
在32位ARM系统中,一般都是在中断向量表中放置一条分支指令或PC寄存器加载指令,实现程序跳转到中断服务例程的功能。例如: IRQEntry B HandleIRQ ;跳转范围较小 B HandleFIQ 或IRQEntry LDR PC,=HandleIRQ ;跳转的范围是任意32位地址空间 LDR PC,=HandleFIQ LDR伪指令等效生成1条存储读取指令和1条32位常数定义指令。32位常数存储在LDR指令附近的存储单元中,相对偏移小于4KB。该32位数据就是要跳转到的中断服务程序入口地址。 之所以使用LDR伪指令,是因为ARM的RISC指令为单字指令,不能装载32位的立即数(常数),无法直接把一个32位常数
[单片机]
一种ARM控制的逆变器的设计方案
  1.系统总体方案   1.1 总体设计框图   如图1 所示, 逆变器系统由升压电路、逆变电路、控制电路和反馈电路组成。低压直流电源DC12V经过升压电路升压、整流和滤波后得到约DC170V高压直流电,然后经全桥逆变电路DC/AC转换和LC滤波器滤波后得到AC110V的正弦交流电。   逆变器以ARM控制器为控制核心,输出电压和电流的反馈信号经反馈电路处理后进入ARM处理器的片内AD,经AD转换和数字PI运算后,生成相应的SPWM脉冲信号,改变SPWM的调制比就能改变输出电压的大小,从而完成整个逆变器的闭环控制。      1.2 SPWM方案选择   1.2.1 PWM电源芯片方案   采用普通的P W M电源
[单片机]
一种<font color='red'>ARM</font>控制的逆变器的设计方案
基于Linux操作系统ARM/DSP多机I2C通信设计方案
  引言   在很多嵌入式控制系统中,系统既要完成大量的信息采集和复杂的算法,又要实现精确的控制功能。采用运行有嵌入式Linux操作系统的ARM9微控制器完成信号采集及实现上层控制算法,并向DSP芯片发送上层算法得到控制参数,DSP芯片根据获得的参数和下层控制算法实现精确、可靠的闭环控制。   1 多机系统组成   该多机控制系统以ARM9微控制器s3c2440为核心,采用I2C总线挂载多个DSP芯片TMS320F28015作为协控制器,构成整个控制系统的核心。   1.1 S3C2440及TMS320F28015简介   Samsung公司的处理器S3C2440是内部集成了ARM公司ARM920T处理器内核的32位微控
[单片机]
基于<font color='red'>Linux</font>操作<font color='red'>系统</font>的<font color='red'>ARM</font>/DSP多机I2C通信设计方案
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
  • ARM裸机篇--按键中断
    先看看GPOI的输入实验:按键电路图:GPF1管教的功能:EINT1要使用GPF1作为EINT1的功能时,只要将GPFCON的3:2位配置成10就可以了!GPF1先配 ...
  • 网上下的--ARM入门笔记
    简单的介绍打今天起菜鸟的ARM笔记算是开张了,也算给我的这些笔记找个存的地方。为什么要发布出来?也许是大家感兴趣的,其实这些笔记之所 ...
  • 学习ARM开发(23)
    三个任务准备与运行结果下来看看创建任务和任运的栈空间怎么样的,以及运行输出。Made in china by UCSDN(caijunsheng)Lichee 1 0 0 ...
  • 学习ARM开发(22)
    关闭中断与打开中断中断是一种高效的对话机制,但有时并不想程序运行的过程中中断运行,比如正在打印东西,但程序突然中断了,又让另外一个 ...
  • 学习ARM开发(21)
    先要声明任务指针,因为后面需要使用。 任务指针 volatile TASK_TCB* volatile g_pCurrentTask = NULL;volatile TASK_TCB* vol ...
  • 学习ARM开发(20)
  • 学习ARM开发(19)
  • 学习ARM开发(14)
  • 学习ARM开发(15)
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved