• trusty系统调用


    trusty中,可以通过系统调用陷入kernel,获取kernel服务。

    这里记录一下trusty的系统调用框架结构,代码基于google trusty源码

    1、应用程序接口
    在文件lib/include/trusty_syscalls.h中,申明了上层调用的syscall接口。如:

    1 // send_msg()系统调用的号码是0x23
    2 #define __NR_send_msg 0x23
    3 // send_msg()系统调用原型申明
    4 long send_msg (uint32_t handle, ipc_msg_t *msg);

    这样,应用层程序可以调用这些接口获取系统服务了。

    2、陷入内核
    在lib/lib/libc-trusty/arch/arm/trusty_syscall.S文件中,
    // 各个系统调用函数对应的汇编代码

    .section .text.send_msg
    FUNCTION(send_msg)
        ldr r12, =__NR_send_msg // 系统调用号置入r12寄存器
        swi #0    // 通过swi陷入内核,执行内核代码
        bx lr    // 返回lr寄存器位置

    用户空间的这些代码是通过脚本解析生成的,看注释。具体生成方式方法需要在明确要再明确一下。

    3、内核中系统调用服务函数申明
    lk/trusty/lib/syscall目录定好了trusty内核处理系统调用的框架。
    在lk/trusty/lib/trusty/include/syscall_table.h定义了一系列宏,其余用户空间的syscall号码一一对应。

    形如:DEF_SYSCALL(0x23, send_msg, long, 2, uint32_t handle, ipc_msg_t *msg)

    在lk/trusty/lib/syscall/syscall.c文件中其进行展开,得到系统调用函数数组:
    #define DEF_SYSCALL(nr, fn, rtype, nr_args, ...) rtype sys_##fn (void);
    =》long sys_send_msg(void);
    #define DEF_SYSCALL(nr, fn, rtype, nr_args, ...) [(nr)] = (unsigned long) (sys_##fn),
    =》[0x23] = (unsigned long) sys_send_msg,
    前一个做函数原型申明,后一个定义了函数指针数组,

    1 long sys_send_msg(void);
    2 
    3 const unsigned long syscall_table [] = {
    4 ……
    5 [0x23] = (unsigned long) sys_send_msg,
    6 ……
    7 };

    这些sys_***类似的函数要在kernel中实现功能。

    4、系统调用过程
    用户调用到swi指令,这是arm软中断指令,此时CPU会强制从系统异常向量表的软中断异常处开始执行(可能为0x00000008),
    trusty中这里安排了一条跳转指令,直接跳到arm_syscall符号处。
    external/lk/arch/arm/arm/start.S

     1 .section ".text.boot"
     2 .globl _start
     3 _start:
     4     b platform_reset
     5     b arm_undefined
     6     b arm_syscall
     7     b arm_prefetch_abort
     8     b arm_data_abort
     9     b arm_reserved
    10     b arm_irq
    11     b arm_fiq
    12 #if WITH_SMP
    13     b arm_reset
    14 #endif

    该标号在

    lk/trusty/lib/syscall/arch/arm/syscall.S中有定义:

     1 /* ARM syscall ABI
     2  * ===============
     3  * Only syscalls with 4 args (max) are currently supported
     4  * r0-r3 = args
     5  * r0-r1 = return value (r0 only if 32-bit retval)
     6  * r12   = syscall number, expected to be trashed.
     7  * syscalls run with interrupts enabled
     8  */
     9 FUNCTION (arm_syscall)
    10         srsdb   sp!, #MODE_SVC
    11         sub     sp, sp, #8
    12         stmia   sp, { r13-r14 }^
    13         // 保存r13、r14、spsr相关寄存器
    14 
    15         cpsie   iaf
    16         // 开中断,cpsr中相关位
    17 
    18         ldr     r14, =nr_syscalls
    19         ldr     r14, [r14]
    20         // 将nr_syscalls的值放入r14,nr_syscalls是当前系统支持的系统调用个数
    21         cmp     r12, r14
    22         // 比较r12与r14,如r12保存的是中断请求号
    23 
    24         ldrlo   r14, =syscall_table
    25         // ldrlo是条件加载,如果r12<r14,将syscall_table地址置入r14,
    26         // syscall_table就是syscall服务函数数组的地址
    27         ldrlo   r14, [r14, r12, lsl#2]
    28         // 将r14 + r12 * 4的值放入r14寄存器,该值即为对应系统调用号的服务函数地址
    29         rsblos  r12, r14, #1    /* This will set the same flags as the cmp above */
    30         // rsb逆向减法指令,r12 = 1 - r14,结果影响cpsr
    31         ldrhs   r14,=sys_undefined
    32         // r14置入sys_undefined函数的地址(如果1 >= r14?)
    33         blx     r14
    34         // 跳转执行r14指示的syscall程序
    35 
    36         cpsid   iaf
    37         // 关中断
    38 
    39         ldmia   sp, { r13-r14 }^
    40         add     sp, sp, #8
    41         rfeia   sp!
    42         // 恢复之前的r13、r14等寄存器

    这样上层请求的系统调用最终会进入内核中对应的服务函数中执行

  • 相关阅读:
    华为全联接大会2019,共创智能新高度
    CTDC2019首席技术官领袖峰会,AI赋能 智享5G
    2019全球体验设计峰会:体验赋能商业,创造更好体验
    全球闪存峰会旨在深化技术创新,增进闪存产业链上下游
    PyCon 2019火热来袭,与大数据、人工智能等专家一起探讨Python语言
    PHPConChina 2019 PHP开发者大会将于8月在上海举办!
    2019腾讯Live开发者大会(TLC),引领技术新趋势
    2019 HTML5深度应用开发实践
    2019年5G物联网关键技术与应用培训,了解5G网络发展现状及进展
    2019第二届企业云服务大会 -- 企业智变,云化未来
  • 原文地址:https://www.cnblogs.com/caidi/p/13620331.html
Copyright © 2020-2023  润新知