TinyEMU Data FlowHost-backed services

Host I/O supplies the outside world

VirtIO and device callbacks ultimately land in host implementations: local disk files, HTTP block cache, tap/slirp network, terminal stdin/stdout, local directories exposed through 9P, and optional SDL display refresh.

The run loop multiplexes host events and CPU slicesEach iteration computes sleep time, polls fds, handles ready host events, refreshes SDL, then executes guest instructions.
virt_machine_run(machine)
  delay = machine sleep duration
  FD_SET terminal if console queue can receive
  net->select_fill(...)
  fs_net_set_fdset(...)
  select(...)
  net->select_poll(...)
  terminal bytes -> virtio_console_write_data()
  sdl_refresh()
  virt_machine_interp(MAX_EXEC_CYCLE)
Local block devices are synchronous callbacksThe block backend exposes sector count, read, and write functions to VirtIO block.

Read-only and read-write modes operate directly on the disk image. Snapshot mode overlays writes in `sector_table`, so guest writes are visible to later reads without modifying the original image.

virtio block request
  -> bs->read_async / write_async
  -> local file fseek/fread/fwrite
  -> snapshot writes copy sectors into sector_table
  -> status byte returned through VirtIO descriptor
HTTP block devices cache split image chunksNetwork block data is fetched block-by-block or by prefetch group, with per-cluster write overlay support.
block_device_init_http(url)
  -> load blk.txt metadata
  -> read request enters bf_rw_async1()
  -> if cluster overlay exists: read modified cluster
  -> else find cached block
       loaded  -> copy from cache
       loading -> return async wait
       missing -> fs_wget(blkNNN.bin)
  -> onload updates cache and resumes request
Network packets cross an `EthernetDevice` bridgeTap uses a host fd; slirp routes through the user-mode network stack.

Guest TX starts in VirtIO net and calls `write_packet`. Host RX is polled through `select_fill`/`select_poll`; when a packet arrives, the backend calls `device_write_packet`, which copies it into the guest receive queue.

guest TX:
  virtio_net_recv_request(queue 1)
  -> EthernetDevice.write_packet()
  -> tap write(fd) or slirp_input()

host RX:
  select says backend readable
  -> backend reads packet
  -> EthernetDevice.device_write_packet()
  -> virtio_net_write_packet(queue 0)
Local 9P maps guest FIDs to host paths and file descriptorsThe VirtIO 9P layer owns protocol framing; `fs_disk.c` owns filesystem operations.
guest 9P request
  -> virtio_9p_recv_request()
  -> fid lookup or create
  -> FSDevice method
       attach -> root path
       walk   -> compose child path
       open   -> opendir/open
       read   -> readdir/read
       write  -> write
  -> marshal 9P reply
  -> virtio_consume_desc()