33.5. Semihosting
Semihosting is a publicly documented interface specified by ARM Holdings that allows us to do some magic operations very useful in development, such as writting to the terminal or reading and writing host files.
It is documented at: https://developer.arm.com/docs/100863/latest/introduction
For example, all the following code make QEMU exit:
./run --arch arm --baremetal baremetal/arch/arm/semihost_exit.S ./run --arch arm --baremetal baremetal/arch/arm/no_bootloader/semihost_exit.S ./run --arch aarch64 --baremetal baremetal/arch/aarch64/semihost_exit.S ./run --arch aarch64 --baremetal baremetal/arch/aarch64/no_bootloader/semihost_exit.S
Sources:
That arm
program program contains the code:
mov r0, #0x18 ldr r1, =#0x20026 svc 0x00123456
and we can see from the docs that 0x18
stands for the SYS_EXIT
command.
This is also how we implement the exit(0)
system call in C for QEMU, which is used for example at userland/c/exit0.c through the Newlib via the _exit
function at baremetal/lib/syscalls.c.
Other magic operations we can do with semihosting besides exiting the on the host include:
-
read and write to host stdin and stdout
-
read and write to host files
Alternatives exist for some semihosting operations, e.g.:
The big advantage of semihosting is that it is standardized across all ARM boards, and therefore allows you to make a single image that does those magic operations instead of having to compile multiple images with different magic addresses.
The downside of semihosting is that it is ARM specific. TODO is it an open standard that other vendors can implement?
In QEMU, we enable semihosting with:
-semihosting
Newlib 9c84bfd47922aad4881f80243320422b621c95dc already has a semi-hosting implementation at:
newlib/libc/sys/arm/syscalls.c
TODO: how to use it? Possible through crosstool-NG? In the worst case we could just copy it.
Bibliography: