Skip to content

Trap guestOS to run SDL-oriented applications #551

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Feb 1, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,12 @@ $ make ENABLE_SYSTEM=1
$ build/rv32emu -k <kernel_img_path> -i <rootfs_img_path>
```

Build with a larger INITRD_SIZE (e.g., 64 MiB) to run SDL-oriented application because the default 8 MiB is insufficient for SDL-oriented application artifacts:
```shell
$ make system ENABLE_SYSTEM=1 ENABLE_SDL=1 INITRD_SIZE=64
```
Once login the guestOS, run `doom-riscv` or `quake` or `smolnes`. To terminate SDL-oriented applications, use the built-in exit utility, ctrl-c or the SDL window close button(X).

#### Build Linux image
An automated build script is provided to compile the RISC-V cross-compiler, Busybox, and Linux kernel from source. Please note that it only supports the Linux host environment. It can be found at tools/build-linux-image.sh.
```
Expand Down
15 changes: 13 additions & 2 deletions src/devices/uart.c
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@
#include <unistd.h>

#include "uart.h"

/* Emulate 8250 (plain, without loopback mode support) */

#define U8250_INTR_THRE 1
Expand Down Expand Up @@ -66,10 +65,22 @@ static uint8_t u8250_handle_in(u8250_state_t *uart)
if (value == 1) { /* start of heading (Ctrl-a) */
if (getchar() == 120) { /* keyboard x */
printf("\n"); /* end emulator with newline */
exit(0);
exit(EXIT_SUCCESS);
}
}

#if RV32_HAS(SDL) && RV32_HAS(SYSTEM) && !RV32_HAS(ELF_LOADER)
/*
* The guestOS may repeatedly open and close the SDL window,
* and the user could close the application by pressing the ctrl-c key.
* Need to trap the ctrl-c key and ensure the SDL window and
* SDL mixer are destroyed properly.
*/
extern void sdl_video_audio_cleanup();
if (value == 3) /* ctrl-c */
sdl_video_audio_cleanup();
#endif

return value;
}

Expand Down
17 changes: 16 additions & 1 deletion src/emulate.c
Original file line number Diff line number Diff line change
Expand Up @@ -1299,7 +1299,22 @@ void ecall_handler(riscv_t *rv)
syscall_handler(rv);
#elif RV32_HAS(SYSTEM)
if (rv->priv_mode == RV_PRIV_U_MODE) {
SET_CAUSE_AND_TVAL_THEN_TRAP(rv, ECALL_U, 0);
switch (rv_get_reg(
rv,
rv_reg_a7)) { /* trap guestOS's SDL-oriented application syscall */
case 0xBEEF:
case 0xC0DE:
case 0xFEED:
case 0xBABE:
case 0xD00D:
case 93:
syscall_handler(rv);
rv->PC += 4;
break;
default:
SET_CAUSE_AND_TVAL_THEN_TRAP(rv, ECALL_U, 0);
break;
}
} else if (rv->priv_mode ==
RV_PRIV_S_MODE) { /* trap to SBI syscall handler */
rv->PC += 4;
Expand Down
13 changes: 12 additions & 1 deletion src/syscall.c
Original file line number Diff line number Diff line change
Expand Up @@ -132,9 +132,20 @@ static void syscall_write(riscv_t *rv)
rv_set_reg(rv, rv_reg_a0, -1);
}


static void syscall_exit(riscv_t *rv)
{
#if RV32_HAS(SDL) && RV32_HAS(SYSTEM) && !RV32_HAS(ELF_LOADER)
/*
* The guestOS may repeatedly open and close the SDL window,
* and the user could close the application using the application’s
* built-in exit function. Need to trap the built-in exit and
* ensure the SDL window and SDL mixer are destroyed properly.
*/
extern void sdl_video_audio_cleanup();
sdl_video_audio_cleanup();
return;
#endif

/* simply halt cpu and save exit code.
* the application decides the usage of exit code
*/
Expand Down
Loading