Skip to main content
\(\newcommand{\doubler}[1]{2#1} \newcommand{\binary}{\texttt} \newcommand{\hex}{\texttt} \newcommand{\octal}{\texttt} \newcommand{\prog}{\texttt} \newcommand{\lt}{ < } \newcommand{\gt}{ > } \newcommand{\amp}{ & } \)

Section17.2Supervisor Call

When the computer is first started, the operating system is at the EL1 exception level. This level allows the operating system kernel to access all the hardware components of the computing system. When a user launches an application, the operating system sets up the hardware resources required by the application, changes the CPU to exception level EL0 and transfers CPU control to the application.

Software executing at the EL0 level has fewer privileges with respect to accessing the hardware. For example, when preparing the hardware for running an application, the operating system allocates enough memory to load the machine code that has been marked as “.text”. The operating system can write to this area of memory because the CPU is at EL1. But when CPU control is transferred to the application, the CPU is switched to EL0, and the application is prevented from writing to any memory location that is within the .text segment.

Using exception level switching, the operating system can maintain control over all the hardware resources. This is especially important in multi-user environments, where several users can be using the same hardware resources. It is also useful to allow the operating system to make efficient use of the hardware. For example, if an application is waiting for input from the keyboard, the CPU can be used to perform another task until the user presses a key.

This raises the question of how an application can use something like the terminal window, since the operating system prevents direct access. This can be done by using an svc instruction, which generates an exception from the software that is running.

SVC

Generates an exception, often used for a supervisor call.

SVC{<c>}    <#imm>
  • <c> is the condition code, Table 9.2.1.

  • <imm> is the supervisor call number.

We can see how to use the svc instruction by rewriting the “Hello, World” program from Listing 10.3.1 to get the program in Listing 17.2.1.

@ helloWorld4.s
@ Hello World program, using system call.
@ Bob Plantz - 7 August 2016

@ Define my Raspberry Pi
        .cpu    cortex-a53
        .fpu    neon-fp-armv8
        .syntax unified         @ modern syntax

@ Useful source code constant
        .equ    STDOUT,1
        .equ    write,4

@ Constant program data
        .section  .rodata
        .align  2
helloMsg:
        .asciz	 "Hello, World!\n"
        .equ    helloLngth,.-helloMsg

@ Program code
        .text
        .align  2
        .global main
        .type   main, %function
main:
        stmfd   sp!, {r7, fp, lr}   @ save caller's info
        add     fp, sp, 8       @ our frame pointer
        sub     sp, sp, 4       @ 8-byte boundary

        mov     r0, STDOUT      @ file number to write to
        ldr     r1, helloMsgAddr   @ pointer to message
        mov     r2, helloLngth  @ number of bytes to write
        mov     r7, write       @ system call 'write'
        svc     0               @ write the message
        
        mov     r0, 0           @ return 0;
        ldmfd   sp!, {r7, fp, lr}   @ restore caller's info
        bx      lr              @ return
        
        .align  2
helloMsgAddr:
        .word   helloMsg
Listing17.2.1“Hello World” program using the svc supervisor call instruction. (prog asm)

The arguments passed to the write supervisor call are the same as the write C system call function. The write request is made with:

mov     r7, write       @ system call 'write'
swi     0               @ write the message

The “write” identifier is equated to \(4\text{.}\) The numbers for each supervisor call supported by Raspbian are found in the file /usr/include/arm-linux-gnueabihf/asm/unistd.h. The appropriate number is placed in r7, and then the request for service is made with the svc 0 instruction. As you surely can guess, the write C system function call is simply a C function “wrapper” for the write supervisor call.