zoukankan      html  css  js  c++  java
  • How to implement system call in ARM64?

     

    System calls

    Sometimes it is necessary for software to request a function from a more privileged entity. This might happen when, for example, an application requests that the OS opens a file.

    ARM275 Branding of Enabling Content Graphics ST1 V17

    In A64, there are special instructions for making such system calls. These instructions cause an exception, which allows controlled entry into a more privileged Exception level.

    • SVC - Supervisor call
      Causes an exception targeting EL1.
      Used by an application to call the OS.
    • HVC - Hypervisor call
      Causes an exception targeting EL2.
      Used by an OS to call the hypervisor, not available at EL0.
    • SMC - Secure monitor call
      Causes an exception targeting EL3.
      Used by an OS or hypervisor to call the EL3 firmware, not available at EL0.

    If an exception is executed from an Exception level higher than the target exception level, then the exception is taken to the current Exception level. This means that an SVC at EL2 would cause exception entry to EL2. Similarly, an HVC at EL3 causes exception entry to EL3. This is consistent with the rule that an exception can never cause the processor to lose privilege.

    Intro

    Hello world in ARM64 assembly for Linux and Macos. First example is how to compile hello world for raspberry pi 4, as its supports ARMv8 instruction set. Second example is how to run assembly on Apple M1 chip that also supports ARMv8 instruction set

    The two assembly examples are equivalent to C code

    int main() {
        char *s="Hello ARM64";
        write(1,s,strlen(s));
        exit(0);
    }
    

    Raspberry Pi 4

    Running 64bit linux. To detect with architecture and what bitness of os run command

    uname
    

    Architecture shown as aarch64 enoughs to indicate that os ir 64bit

    Linux raspberrypi 5.4.42-v8+ #1319 SMP PREEMPT Wed May 20 14:18:56 BST 2020 aarch64 GNU/Linux
    
    .data
    
    /* Data segment: define our message string and calculate its length. */
    helloworld:
        .ascii        "Hello, ARM64!\n"
    helloworld_len = . - helloworld
    
    .text
    
    /* Our application's entry point. */
    .globl _start
    _start:
        /* syscall write(int fd, const void *buf, size_t count) */
        mov     x0, #1              /* fd := STDOUT_FILENO */
        ldr     x1, =helloworld     /* buf := msg */
        ldr     x2, =helloworld_len /* count := len */
        mov     w8, #64             /* write is syscall #64 */
        svc     #0                  /* invoke syscall */
    
        /* syscall exit(int status) */
        mov     x0, #0               /* status := 0 */
        mov     w8, #93              /* exit is syscall #1 */
        svc     #0                   /* invoke syscall */
    

    Compile

    Too compile check if you have installed gnu gcc, other compilers such as clang also should work perfectly fine.

        as hello.s -o hello.o
        gcc hello.o -o hello
    

    Apple M1

    .global _start            // Provide program starting address to linker
    .align 2                  // Make sure everything is aligned properly
    
    /* syscall write(int fd, const void *buf, size_t count) */
    _start: 
        mov    X0, #1         // 1 = StdOut
        adr    X1, helloworld     // string to print
        mov    X2, helloworld_len // length of our string
        mov    X16, #4            // Unix write system call
        svc    #0x80              // Call kernel to output the string
    
    /* syscall exit(int status) */
        mov     X0, #0            // Use 0 return code
        mov     X16, #1           // System call number 1 terminates this program
        svc     #0x80             // Call kernel to terminate the program
    
    helloworld:      .ascii  "Hello, ARM64!\n"
    helloworld_len = . - helloworld
    

    Compile

    Install xcode tools before compilation

        as -o hello.o hello.s
        ld -macosx_version_min 11.0.0 -o hello hello.o -lSystem -syslibroot `xcrun -sdk macosx --show-sdk-path` -e _start -arch arm64

    svc指令

    [root@centos7 aarch64-bare-metal-qemu]# cat ans.s 
     .global _start
     _start:
     mov x0, #42
     mov x8, #93
     svc #0
    [root@centos7 aarch64-bare-metal-qemu]# as ans.s -o ans.o
    [root@centos7 aarch64-bare-metal-qemu]# ld  ans.o  -o ans
    [root@centos7 aarch64-bare-metal-qemu]# ./ans
    [root@centos7 aarch64-bare-metal-qemu]# echo $?
    42
    [root@centos7 aarch64-bare-metal-qemu]# 
    [root@centos7 aarch64-bare-metal-qemu]# cat sys.s
    .data
    
    /* Data segment: define our message string and calculate its length. */
    helloworld:
        .ascii        "Hello, ARM64!\n"
    helloworld_len = . - helloworld
    
    .text
    
    /* Our application's entry point. */
    .globl _start
    _start:
        /* syscall write(int fd, const void *buf, size_t count) */
        mov     x0, #1              /* fd := STDOUT_FILENO */
        ldr     x1, =helloworld     /* buf := msg */
        ldr     x2, =helloworld_len /* count := len */
        mov     w8, #64             /* write is syscall #64 */
        svc     #0                  /* invoke syscall */
    
        /* syscall exit(int status) */
        mov     x0, #0               /* status := 0 */
        mov     w8, #93              /* exit is syscall #1 */
        svc     #0                   /* invoke syscall */
    [root@centos7 aarch64-bare-metal-qemu]# as sys.s -o sys.o
    [root@centos7 aarch64-bare-metal-qemu]# ld sys.o -o sys
    [root@centos7 aarch64-bare-metal-qemu]# ./sys 
    Hello, ARM64!
  • 相关阅读:
    C#画K线图代码
    SQL查询效率:100w数据查询只需要1秒钟
    全程图解 手把手教你做RAID磁盘阵列
    炒股高手实战技巧
    数据库主键设计之思考
    如何做磁盘阵列和磁盘镜象
    股海心法—浓缩股市精华
    如何做磁盘阵列
    SQL Server 2005实现负载均衡的详细介绍!
    K线六种形态
  • 原文地址:https://www.cnblogs.com/dream397/p/15632453.html
Copyright © 2011-2022 走看看