rust-kernel
Rustbelt: a hobby x86_64 kernel written in Rust
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 | //! Stage 21: boot contract v2 -- which program becomes pid 1.
//!
//! If `fs::mount_disks` found a GPT "Linux root (x86-64)" partition with
//! ext2 and mounted it at "/" ([`fs::root_on_disk`]), the kernel starts the
//! first of [`INIT_PATHS`] that runs, the same order Linux tries, as pid 1:
//!
//! | program | argv |
//! |--------------|----------------------------------------|
//! | /sbin/init | `init` (+ `selftest` when headless) |
//! | /bin/init | `init` (+ `selftest` when headless) |
//! | /bin/sh | `sh` (+ `/scripts/selftest.sh` when headless) |
//!
//! The environment is [`V2_ENV`] (+ `RUSTBELT_HEADLESS=1` when headless).
//! There's no boot loader command line (bootloader 0.9 has none), so the
//! knobs are build time, like the `headless` feature itself:
//! * `cargo build --features headless`: the headless argv/env above;
//! * `RUSTBELT_INIT_ARGS="a b"`: extra arguments after those;
//! * `RUSTBELT_INIT_ENV="K=V K2=V2"`: extra environment variables (one
//! with a name already there replaces it, e.g. `PATH=...`).
//! (Both are read with `option_env!`, so changing them rebuilds the kernel.)
//!
//! The kernel does not restart pid 1. When it exits, its status ends the
//! QEMU run through isa-debug-exit: exit(n) writes 0x10 + n, so QEMU exits
//! with 33 + 2n (33 = exit 0 = the tests' "pass", 35 = exit 1, ...). A
//! status above 111 (it wouldn't fit in QEMU's 8-bit exit code) or death
//! by a signal writes 0x11 (35).
//!
//! Without a root partition nothing here is used: main.rs runs the old
//! shell supervisor (boot contract v1) exactly as before.
use crateErrno;
use cratefs;
use crate;
use ;
/// Tried in this order; the first that starts becomes pid 1.
pub const INIT_PATHS: = ;
/// pid 1's environment under contract v2.
pub const V2_ENV: = ;
/// argv and environment for `path` (one of [`INIT_PATHS`]).
/// Start pid 1: the first of [`INIT_PATHS`] that starts. Returns its path
/// and process, or the last error if none did. `log` gets a line for every
/// one that was tried and failed.
/// What to write to isa-debug-exit for pid 1's exit status (see above).
/// Shut down cleanly (stage 21.1, Clarke's K12): sync and unmount every
/// file system, newest mount first, so the disks are left the way a host
/// expects (no FAT "dirty bit"). Returns the log lines. This is the one
/// shutdown path: main.rs calls it when pid 1 exits, just before ending the
/// QEMU run, and a future `reboot(169)` POWER_OFF (K7) should call it too.
/// Don't use the file systems after it.
/// End the QEMU run with pid 1's exit status.
/// Run contract v2's pid 1 and wait for it. Returns its status (Err: no
/// init could be started).
/// Is contract v2 in use (a root partition was mounted at "/")?
|