ARM System Calls

来自osdev
跳到导航 跳到搜索

这个页面正在建设中! 此页面或部分内容仍在改进中,因此可能还不完整。 其内容可能会在不久的将来更改。

System Calls

swi 0x420000

这里向你介绍如何在ARM上做System Call。 指令 swi 跳转到预定义的地址,该地址又跳转到System Call处理程序。 System Call处理程序执行特定函数,并返回用户代码:

mov pc, lr

在大多数情况下,您无需担心从中断返回,因为GCC设置为针对ARM交叉编译,可以在C中编写中断处理程序:

void swi_handler () __attribute__((interrupt));

= 创建System Call =

interrupt_vector_table:
    b . @ Reset Handler
    b . @ Undefined
    b . @ SWI Handler
    b . @ Prefetch Abort
    b . @ Data Abort
    b . @ IRQ
    b . @ FIQ

这是相当于在x86上IDT的ARM版,它默认存储在地址0。 我们需要关心的唯一条目是SWI Handler。 要安装我们自己的SWI Handler,我们替换 b . 带有分支到我们的处理程序的指令:

interrupt_vector_table:
    b . @ Reset Handler
    b . @ Undefined
    b swi_handler @ Our new SWI Handler
    b . @ Prefetch Abort
    b . @ Data Abort
    b . @ IRQ
    b . @ FIQ

我们可以像这样编码中断处理程序:

void __attribute__ ((interrupt ("SWI"))) swi_handler (void) {}

ARM上函数的参数,在寄存器r0-r3中传递,如果遵循相同的约定的System Call,那么我们的中断处理程序也可以获取参数:

void __attribute__ ((interrupt ("SWI"))) swi_handler (int r0, int r1, int r2, int r3) {}

您可能已经注意到 swi 采用整数参数。 为了在C中得到这个参数,我们必须这样做:

uint8_t int_vector = 0;
asm volatile ("ldrb %0, [lr, #-2]" : "=r" (int_vector));

这会将参数的高8位 (16-23) 加载到 int_vector 中,使用Thumb加载完整的24位将不起作用。