Created
November 20, 2025 13:19
-
-
Save edubart/21c04097af49b5ec3961ee5a38e4b2da to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| local cartesi = require("cartesi") | |
| local jsonrpc = require("cartesi.jsonrpc") | |
| local poll = require("posix.poll") | |
| local unistd = require("posix.unistd") | |
| local termio = require("posix.termio") | |
| local fcntl = require("posix.fcntl") | |
| -- set terminal to raw mode | |
| local ttyname = assert(unistd.ttyname()) | |
| local tty_fd = assert(fcntl.open(ttyname, fcntl.O_RDWR | fcntl.O_NOCTTY | fcntl.O_NONBLOCK)) | |
| local tty_size = assert(termio.tcgetwinsize(tty_fd)) | |
| local tty_old_mode = assert(termio.tcgetattr(tty_fd)) | |
| local tty_raw_mode = { | |
| lflag = tty_old_mode.lflag & ~(termio.ECHO | termio.ICANON | termio.ECHONL | termio.ISIG | termio.IEXTEN), | |
| iflag = tty_old_mode.iflag | |
| & ~( | |
| termio.IGNBRK | |
| | termio.BRKINT | |
| | termio.PARMRK | |
| | termio.ICRNL | |
| | termio.ISTRIP | |
| | termio.INLCR | |
| | termio.IGNCR | |
| | termio.IXON | |
| ), | |
| cflag = (tty_old_mode.cflag & ~(termio.CSIZE | termio.PARENB)) | termio.CS8, | |
| oflag = tty_old_mode.oflag | termio.OPOST, | |
| cc = { | |
| [termio.VTIME] = 0, | |
| [termio.VMIN] = 1, | |
| }, | |
| } | |
| assert(termio.tcsetattr(tty_fd, termio.TCSANOW, tty_raw_mode)) | |
| local _ = setmetatable({}, { | |
| __gc = function() -- reset terminal on exit | |
| termio.tcsetattr(tty_fd, termio.TCSANOW, tty_old_mode) | |
| unistd.close(tty_fd) | |
| end, | |
| }) | |
| -- interactive machine config with VirtIO console | |
| local config = { | |
| ram = { | |
| length = 128 * 1024 * 1024, | |
| backing_store = { | |
| data_filename = os.getenv("CARTESI_IMAGES_PATH") .. "/linux.bin", | |
| }, | |
| }, | |
| dtb = { | |
| bootargs = cartesi.machine:get_default_config().dtb.bootargs:gsub("console=hvc0", "console=hvc1"), | |
| entrypoint = "bash", | |
| }, | |
| flash_drive = { | |
| { | |
| backing_store = { | |
| data_filename = os.getenv("CARTESI_IMAGES_PATH") .. "/rootfs.ext2", | |
| }, | |
| }, | |
| }, | |
| virtio = { | |
| { type = "console" }, | |
| }, | |
| processor = { | |
| registers = { | |
| iunrep = 1, | |
| htif = { | |
| iconsole = cartesi.HTIF_CONSOLE_CMD_PUTCHAR_MASK | cartesi.HTIF_CONSOLE_CMD_GETCHAR_MASK, | |
| }, | |
| }, | |
| }, | |
| } | |
| -- machine runtime config will console buffering mode | |
| local runtime_config = { | |
| console = { | |
| output_destination = "to_buffer", | |
| output_flush_mode = "every_char", | |
| input_source = "from_buffer", | |
| tty_rows = tty_size.ws_row, | |
| tty_cols = tty_size.ws_col, | |
| }, | |
| } | |
| local machine <close> = jsonrpc.spawn_server():set_cleanup_call(jsonrpc.SHUTDOWN):create(config, runtime_config) | |
| -- To do use an existing server: | |
| -- local machine <close> = jsonrpc.connect_server("127.0.0.1:8888"):set_cleanup_call(jsonrpc.DESTROY):create(config, runtime_config) | |
| -- Main loop | |
| repeat | |
| local break_reason = machine:run() | |
| if break_reason == cartesi.BREAK_REASON_CONSOLE_INPUT then -- waiting for input | |
| if poll.rpoll(unistd.STDIN_FILENO, 0) ~= 0 then -- stdin has input characerters ready | |
| local avail_len = machine:write_console_input() | |
| local data = unistd.read(unistd.STDIN_FILENO, avail_len) | |
| if data then | |
| machine:write_console_input(data) | |
| else | |
| local EOF_CHAR = "\x04" | |
| machine:write_console_input(string.rep(EOF_CHAR, avail_len)) | |
| end | |
| end | |
| elseif break_reason == cartesi.BREAK_REASON_CONSOLE_OUTPUT then | |
| unistd.write(unistd.STDOUT_FILENO, machine:read_console_output()) | |
| end | |
| until break_reason == cartesi.BREAK_REASON_HALTED | |
| print("Halted") |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment