mirror of
https://github.com/cirosantilli/linux-kernel-module-cheat.git
synced 2026-01-23 02:05:57 +01:00
baremetal: aarch64 semihosting exit
This commit is contained in:
@@ -819,6 +819,11 @@ auto_reset_addr_64 = True
|
|||||||
|
|
||||||
That patch breaks `--arch arm`, so don't forget to remove it if you want to go back to it.
|
That patch breaks `--arch arm`, so don't forget to remove it if you want to go back to it.
|
||||||
|
|
||||||
|
When doing bare metal programming, it is likely that you will want to learn assembly language basics. Have a look at these tutorials for the userland part:
|
||||||
|
|
||||||
|
* https://github.com/cirosantilli/x86-assembly-cheat
|
||||||
|
* https://github.com/cirosantilli/arm-assembly-cheat
|
||||||
|
|
||||||
For more information on baremetal, see the section: <<baremetal>>. The following subjects are particularly important:
|
For more information on baremetal, see the section: <<baremetal>>. The following subjects are particularly important:
|
||||||
|
|
||||||
* <<tracing>>
|
* <<tracing>>
|
||||||
|
|||||||
20
baremetal/arch/aarch64/semihost_exit.S
Normal file
20
baremetal/arch/aarch64/semihost_exit.S
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
.global main
|
||||||
|
main:
|
||||||
|
/* 0x20026 == ADP_Stopped_ApplicationExit */
|
||||||
|
mov x1, #0x26
|
||||||
|
movk x1, #2, lsl #16
|
||||||
|
str x1, [sp,#0]
|
||||||
|
|
||||||
|
/* Exit status code. Host QEMU process exits with that status. */
|
||||||
|
mov x0, #0
|
||||||
|
str x0, [sp,#8]
|
||||||
|
|
||||||
|
/* x1 contains the address of parameter block.
|
||||||
|
* Any memory address could be used. */
|
||||||
|
mov x1, sp
|
||||||
|
|
||||||
|
/* SYS_EXIT */
|
||||||
|
mov w0, #0x18
|
||||||
|
|
||||||
|
/* Do the semihosting call on A64. */
|
||||||
|
hlt 0xf000
|
||||||
@@ -1,5 +1,8 @@
|
|||||||
.global main
|
.global main
|
||||||
main:
|
main:
|
||||||
|
/* SYS_EXIT */
|
||||||
mov r0, #0x18
|
mov r0, #0x18
|
||||||
|
/* ADP_Stopped_ApplicationExit */
|
||||||
ldr r1, =#0x20026
|
ldr r1, =#0x20026
|
||||||
|
/* Do the semihosting call on A32. */
|
||||||
svc 0x00123456
|
svc 0x00123456
|
||||||
|
|||||||
@@ -58,8 +58,21 @@ int _write(int file, char *ptr, int len) {
|
|||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Only 0 is supported for now, arm semihosting cannot handle it. */
|
||||||
void _exit(int status) {
|
void _exit(int status) {
|
||||||
#if defined(__arm__)
|
#if defined(__arm__)
|
||||||
__asm__ __volatile__ ("mov r0, #0x18; ldr r1, =#0x20026; svc 0x00123456");
|
__asm__ __volatile__ ("mov r0, #0x18; ldr r1, =#0x20026; svc 0x00123456");
|
||||||
|
#elif defined(__aarch64__)
|
||||||
|
/* TODO actually use the exit value here, just for fun. */
|
||||||
|
__asm__ __volatile__ (
|
||||||
|
"mov x1, #0x26\n" \
|
||||||
|
"movk x1, #2, lsl #16\n" \
|
||||||
|
"str x1, [sp,#0]\n" \
|
||||||
|
"mov x0, #0\n" \
|
||||||
|
"str x0, [sp,#8]\n" \
|
||||||
|
"mov x1, sp\n" \
|
||||||
|
"mov w0, #0x18\n" \
|
||||||
|
"hlt 0xf000\n"
|
||||||
|
);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ for arch in $archs; do
|
|||||||
if [ ! "$arch" = x86_64 ]; then
|
if [ ! "$arch" = x86_64 ]; then
|
||||||
./build-crosstool-ng --arch "$arch"
|
./build-crosstool-ng --arch "$arch"
|
||||||
./build-baremetal --arch "$arch"
|
./build-baremetal --arch "$arch"
|
||||||
./build-baremetal --arch "$arch" -g
|
./build-baremetal --arch "$arch" --gem5
|
||||||
./build-baremetal --arch "$arch" -g --machine RealViewPBX
|
./build-baremetal --arch "$arch" --gem5 --machine RealViewPBX
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
|
|||||||
@@ -119,23 +119,27 @@ def main(args, extra_args=None):
|
|||||||
bootloader_obj=bootloader_obj,
|
bootloader_obj=bootloader_obj,
|
||||||
common_obj=common_obj,
|
common_obj=common_obj,
|
||||||
)
|
)
|
||||||
build_dir(
|
arch_dir = os.path.join('arch', args.arch)
|
||||||
os.path.join('arch', args.arch),
|
if os.path.isdir(os.path.join(common.baremetal_src_dir, arch_dir)):
|
||||||
gcc=gcc,
|
build_dir(
|
||||||
cflags=cflags,
|
arch_dir,
|
||||||
entry_address=entry_address,
|
gcc=gcc,
|
||||||
bootloader_obj=bootloader_obj,
|
cflags=cflags,
|
||||||
common_obj=common_obj,
|
entry_address=entry_address,
|
||||||
)
|
bootloader_obj=bootloader_obj,
|
||||||
build_dir(
|
common_obj=common_obj,
|
||||||
os.path.join('arch', args.arch, 'no_bootloader'),
|
)
|
||||||
gcc=gcc,
|
arch_dir = os.path.join('arch', args.arch, 'no_bootloader')
|
||||||
cflags=cflags,
|
if os.path.isdir(os.path.join(common.baremetal_src_dir, arch_dir)):
|
||||||
entry_address=entry_address,
|
build_dir(
|
||||||
bootloader_obj=bootloader_obj,
|
arch_dir,
|
||||||
common_obj=common_obj,
|
gcc=gcc,
|
||||||
bootloader=False,
|
cflags=cflags,
|
||||||
)
|
entry_address=entry_address,
|
||||||
|
bootloader_obj=bootloader_obj,
|
||||||
|
common_obj=common_obj,
|
||||||
|
bootloader=False,
|
||||||
|
)
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
|
|||||||
2
run
2
run
@@ -271,7 +271,7 @@ def main(args, extra_args=None):
|
|||||||
'-device', 'edu',
|
'-device', 'edu',
|
||||||
])
|
])
|
||||||
elif args.arch == 'arm' or args.arch == 'aarch64':
|
elif args.arch == 'arm' or args.arch == 'aarch64':
|
||||||
extra_qemu_args.append('-semihosting')
|
extra_emulator_args.append('-semihosting')
|
||||||
if args.kgdb:
|
if args.kgdb:
|
||||||
kernel_cli += ' kgdboc=ttyAMA0,115200'
|
kernel_cli += ' kgdboc=ttyAMA0,115200'
|
||||||
if args.arch == 'arm':
|
if args.arch == 'arm':
|
||||||
|
|||||||
Reference in New Issue
Block a user