Skip to content
Draft
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
44 changes: 36 additions & 8 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 5 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,12 @@ members = [
"build/root",
"kernel",
"kernel/amdvi",
"kernel/dma",
"kernel/gicv3",
"kernel/its",
"kernel/loom",
"kernel/pci",
"kernel/phys",
"kernel/register",
"kernel/sim",
"kernel/smmu",
"lib/acpi",
Expand Down Expand Up @@ -77,6 +77,8 @@ members = [
"lib/userbound",
"lib/vdagent",
"lib/virtio",
"lib/virtio-serial",
"lib/virtio-serial/claim",
"lib/wallclock",
"loader",
"sdk/abi",
Expand Down Expand Up @@ -141,6 +143,7 @@ members = [
"system/usbd",
"system/usbd/xhci",
"system/vdagent",
"system/virtio-console",
"system/vdagent/bridge",
"tests/guest/hangupholder",
"tests/guest/kernelprobe",
Expand Down Expand Up @@ -254,6 +257,7 @@ toyos-session = { path = "lib/session" }
# QEMU's clipboard channel's port name, id and port count, so the launch reads
# the declaration the guest's agent drives.
toyos-vdagent = { path = "lib/vdagent" }
toyos-virtio-serial = { path = "lib/virtio-serial" }
# The watchdog's parameter name, so the gate over `kernel/src/params.rs` reads
# the same constant the kernel and the bootloader do.
toyos-tco = { path = "lib/tco" }
Expand Down
8 changes: 7 additions & 1 deletion build/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -653,7 +653,8 @@ const SUPERVISOR_SERVED: &[&str] = &[toyos_swap::PORT, "power", toyos_manifest::
/// clipboard port, whose holder is sent every copy made in the session, the
/// display port, whose holder sets the mode and the scale every window is
/// drawn at, and the session-admin port, whose holder signs its user's
/// sessions out.
/// sessions out, and the log's carrier port, for whose holder the console
/// UART goes quiet.
const HELD_ALONE: &[(&str, &[&str])] = &[
(toyos_swap::PORT, &[toyos_swap::HOLDER]),
(toyos_manifest::grants::PORT, &[toyos_manifest::grants::HOLDER]),
Expand All @@ -662,6 +663,7 @@ const HELD_ALONE: &[(&str, &[&str])] = &[
(toyos_manifest::clipboard::PORT, &[toyos_manifest::clipboard::HOLDER]),
(toyos_manifest::display::PORT, &[toyos_manifest::display::HOLDER]),
(toyos_session::ADMIN_PORT, &[toyos_session::ADMIN_HOLDER]),
(toyos_logstream::CARRIER, &[toyos_logstream::CARRIER_HOLDER]),
];

/// Rows, as a refusal names them.
Expand Down Expand Up @@ -3290,6 +3292,10 @@ mod tests {
assert!(held_by_their_holders_alone(&vdagent).is_ok());
let editor: SystemConfig = toml::from_str("[programs.editor]\nreceives = [\"clipboard\"]\n").unwrap();
assert!(held_by_their_holders_alone(&editor).is_err());
let console: SystemConfig = toml::from_str("[programs.virtio-console]\nreceives = [\"log-carrier\"]\n").unwrap();
assert!(held_by_their_holders_alone(&console).is_ok());
let agent: SystemConfig = toml::from_str("[programs.vdagent]\nreceives = [\"clipboard\", \"log-carrier\"]\n").unwrap();
assert!(held_by_their_holders_alone(&agent).unwrap_err().contains("only `virtio-console`"));
}

/// The prompt port reaches its server alone, and the consent port no row,
Expand Down
2 changes: 1 addition & 1 deletion build/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ pub mod flags;
pub mod hostws;
pub mod identity;
pub mod image;
pub mod kernelconsole;
pub mod signing;
/// Which kernel containers may be hashed, and by whose keys; read by nothing
/// but its own tests.
Expand All @@ -52,6 +51,7 @@ pub mod tether;
pub mod toolchain;
pub mod userlandhost;
pub mod vdagent;
pub mod vmconsole;
pub mod wallpaper;

use std::path::{Path, PathBuf};
Expand Down
23 changes: 8 additions & 15 deletions build/qemu.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ use std::path::PathBuf;
use std::process::{Command, Stdio};

use toyos_build::arch::{Accel, Arch};
use toyos_build::kernelconsole;
use toyos_build::vmconsole;

/// The hardware shape QEMU presents to the guest.
///
Expand All @@ -61,7 +61,7 @@ use toyos_build::kernelconsole;
/// virtio device, which changes the console, the network, and audio too.
#[derive(Clone, Copy, PartialEq)]
pub enum Profile {
/// virtio-gpu for the display, virtio-console for the console, plus
/// virtio-gpu for the display, a virtio-serial port for the console, plus
/// virtio-net and virtio-sound.
Virtio,
/// `-vga std`, so firmware publishes a GOP and the kernel takes the
Expand Down Expand Up @@ -256,24 +256,17 @@ pub fn launch(opts: &Options) {
qemu.arg("-device")
.arg(format!("virtio-sound-pci,audiodev=audio0,streams=1{platform}"));

// The clipboard's channel, just before the console's function, so it
// enumerates first and the kernel's console rule runs.
qemu.args(toyos_build::vdagent::args(platform));

// Console wiring: virtio-console on stdio is the primary I/O channel
// (the kernel switches to it once virtio-console init completes —
// see drivers/virtio_console.rs). UART stays on a file so early-boot
// logs (before virtio is up) and panic fallback are still captured.
// The console's port on stdio, where `/system/bin/virtio-console`
// carries the log once userland runs; the UART on a file, which keeps
// the loader, the early boot, the stop and a fatal path's report, and
// the whole log again if the console's carrier goes.
qemu.arg("-serial")
.arg("file:/tmp/toyos-uart-early.log")
.arg("-chardev")
.arg("stdio,id=cs0,signal=off")
.arg("-device")
.arg(format!(
"virtio-serial-pci-non-transitional,id=virtio-serial0,max_ports=1{platform}"
))
.arg("-device")
.arg("virtconsole,chardev=cs0,id=console0");
.args(toyos_build::vmconsole::args("cs0", platform));
} else if opts.mute {
eprintln!("metal-sim: no 16550 — the framebuffer is the only channel out");
qemu.arg("-serial").arg("none");
Expand Down Expand Up @@ -320,7 +313,7 @@ pub fn launch(opts: &Options) {
let console = child.stdout.take().expect("QEMU's stdout is piped");
// The console ends when QEMU does; a relay that fails first ends QEMU, which
// would otherwise run on into a pipe nobody reads.
if let Err(relay) = kernelconsole::relay(console, &mut terminal) {
if let Err(relay) = vmconsole::relay(console, &mut terminal) {
// SIGTERM, not `Child::kill`'s SIGKILL: QEMU gives the terminal back its
// modes only on its own exit path.
let pid = libc::pid_t::try_from(child.id()).expect("a pid is a pid_t");
Expand Down
8 changes: 2 additions & 6 deletions build/sourcegate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -88,18 +88,15 @@ const LOG_PRODUCERS: &[&str] = &["log!(", "alert!(", "boot_phase!(", "log::emit(
const NMI_SILENT: &[&str] =
&["kernel/src/arch/x86_64/idt/nmi.rs", "kernel/src/hardlockup/mod.rs"];

/// Every `enable_bus_master(` site `kernel/src` holds, by file and count.
/// No kernel site leaves a device it declined mastering the bus: virtio
/// parses its capability chain first, and switches mastering off on a refusal
/// that comes after arming.
/// Every `enable_bus_master(` site `kernel/src` holds, by file and count:
/// its definition, and the AMD-Vi unit's own function.
///
/// A function handed to a *process* takes the other path: `pcidev` arms bus
/// mastering with `start_bus_mastering`, after the address space that bounds it
/// exists, so `enable_bus_master` stays what a kernel driver calls and the
/// count below stays the census of drivers this kernel has.
const BUS_MASTER_SITES: &[(&str, usize)] = &[
("kernel/src/drivers/pci.rs", 1),
("kernel/src/drivers/virtio.rs", 1),
("kernel/src/arch/x86_64/amdvi/mod.rs", 1),
];

Expand Down Expand Up @@ -137,7 +134,6 @@ const SENTINEL_ALLOWED: &[(&str, usize)] = &[
/// reds beside a permitted one and a deleted one reds its own stale row.
const AUTO_TRAIT_IMPLS: &[(&str, usize)] = &[
("kernel/src/drivers/panic_console/mod.rs", 3),
("kernel/src/drivers/virtio_console.rs", 1),
("kernel/src/arch/x86_64/hw.rs", 1),
("kernel/src/mm/mmio.rs", 2),
("kernel/src/mm/region.rs", 2),
Expand Down
11 changes: 4 additions & 7 deletions build/vdagent.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,7 @@
//! QEMU's clipboard channel at the launch: its `qemu-vdagent` chardev, the
//! virtio-serial function of its own it is on, and the agent's port, from the
//! one declaration the guest's agent reads (`toyos-vdagent`).
//!
//! **A function of its own**, created just before the console's: the console's
//! function is the kernel's log channel from early boot, and the agent's
//! enumerates first, so every virtio boot runs the kernel's choice of console
//! (`toyos_pci::console`).
//! declarations the guest's agent reads (`toyos-vdagent`,
//! `toyos-virtio-serial`).
//!
//! **The chardev exists only in a QEMU built with spice-protocol** (QEMU's
//! `qapi/char.json`, `'if': 'CONFIG_SPICE_PROTOCOL'`), so a launch asks QEMU
Expand All @@ -14,7 +10,8 @@
use std::process::Command;
use std::sync::OnceLock;

use toyos_vdagent::{MAX_PORTS, PORT_ID, PORT_NAME};
use toyos_vdagent::PORT_NAME;
use toyos_virtio_serial::{MAX_PORTS, PORT_ID};

use crate::arch::Arch;

Expand Down
Loading