Вся документация
С чего начать
Возможности
docs/features.mdОткрыть на GitHubЭта страница документации пока есть только на английском. Документация собирается прямо из каталога docs/ репозитория, поэтому всегда соответствует коду. По-русски написаны руководства.
Everything the kernel does today, by subsystem. For where the code lives see Project layout; for the interactive shell see Shell commands.
- virtio, entirely in Rust — the split virtqueue, the transport contract and both buses (virtio-pci modern and legacy, virtio-mmio v2) are
src/rust/virtio, and every device on them — blk, net, scsi, rng — is a Rust driver insrc/rust/drivers/. No virtio code is left in C++ - Two architectures — x86-64 (Multiboot2/GRUB, ISO or MBR disk boot, legacy BIOS and UEFI firmware) and arm64 (QEMU
virtboard, LinuxImageboot protocol); portable code goes through a HAL layer (src/cpp/hal/), arch backends live insrc/cpp/arch/ - SMP — up to 64 CPUs (20 exercised on real hardware); AP bootstrap via INIT/SIPI on x86-64, PSCI
CPU_ONon arm64, APs started one at a time,maxcpus=Nto cap them - Preemptive multitasking — per-CPU task queues, round-robin scheduling, load-balanced task placement
- Virtual memory — 4-level paging (4 KB pages), high-half kernel at
0xFFFF800001000000, TLB shootdown across CPUs via IPI - Page allocator — fixed-size block allocator (1–128 contiguous pages), pool allocator (32 B – 2 KB),
new/deletesupport - ACPI — RSDP, RSDT/XSDT, MADT, FADT, HPET and WDAT parsing: LAPIC/IOAPIC discovery, IRQ→GSI routing, the reset register, the century register, the HPET's base, a firmware-owned watchdog
- Interrupts — IDT with exception handlers, IOAPIC routing (edge + level-triggered), LAPIC IPI, PIC (remapped then disabled), round-robin IRQ balancing across CPUs once SMP is up (IOAPIC lines only over the apic ids a physical-mode redirection entry can name, MSI-X over all of them)
- arm64 port — GICv3 interrupt controller with ITS (PCIe MSI delivered as LPIs,
its=onby default), EL1 exception vectors, ARM generic timer (per-CPU), PL011 UART, FDT (device tree) parsing, PCIe ECAM, virtio-mmio transport, broadcast TLBI, semantic memory barriers (dmb) throughout; NVMe over ITS-delivered MSI works end-to-end - Drivers — serial (COM1), screen console (EGA text on BIOS, 8x16 font on the bootloader's pixel framebuffer under UEFI), PIT (10 ms tick, SeqLock-protected counters), RTC (CMOS wall clock), PS/2 keyboard (8042), USB HID keyboard over xHCI (BIOS/UEFI handoff, root-port and hub enumeration, boot-protocol reports), PCI bus scan, LAPIC, IOAPIC, virtio-blk, virtio-net, virtio-scsi, virtio-rng (Rust, on the Rust virtio foundation: legacy + modern virtio-pci, and virtio-mmio), NVMe (Rust, MSI-X interrupt-driven), Realtek RTL8168/RTL8125 and Intel 82576/I210 (igb) NICs (Rust)
- Block I/O — asynchronous, interrupt-driven block request queue with DMA slot pool,
BlockRequestsubmission withWaitGroupcompletion, direct DMA from caller buffers (page-aligned), virtqueue locking (RawSpinLock) for safe interrupt/task concurrency, early-boot polling fallback, SoftIrq-based retry for ring-full conditions, the block layer in Rust (src/rust/block): the device table a driver registers an ops table with — from C++ or from Rust alike — the claims that keep a mount, the disk log and a writer off each other's sectors, and the partition tables (MBR and GPT) each partition is registered from - Networking — virtio-net driver with asynchronous interrupt-driven TX/RX, software frame queues (256-entry TX/RX) in
NetDevicebase class, reference-countedNetFramedescriptors for zero-copy DMA, TX slot pool with bitmask allocation, SoftIrq-based TX retry and RX processing, IP routing (subnet mask + gateway from DHCP, off-subnet traffic forwarded to gateway), ARP (cache, request, reply, dump), IPv4/UDP transmit, ICMP echo (ping reply + send, per-type statistics), DHCP client that keeps its lease as RFC 2131 has one kept (sets IP, subnet mask, gateway, DNS server; renews from T1, rebinds from T2, and lets the address go when the lease runs out or a server refuses it; ignores offers of addresses no host may have), NAT (what is behind a virtual NIC -- the hypervisor's guests -- masqueraded out through the device the default route is on: TCP from its SYN, UDP and ICMP echo, ICMP errors translated back, address- and port-dependent filtering, 4096 mappings taken whole when it goes on, RFC 4787/5382 timeouts, checksums updated incrementally,natcommand), DNS resolver with 32-entry cache (A-record queries, name compression, DHCP-provided server), TCP (connection state machine, 3-way handshake, sequence/ack tracking, retransmission timers, MSS negotiation, send/receive ring buffers, graceful close with FIN exchange, RST handling, ephemeral port allocation, granular locking:Mutexfor ports,RawSpinLockfor pool and per-connection state, SoftIrq-driven timer processing), HTTP client (URL parsing, DNS resolution, TCP connection, request/response, chunked transfer decoding, redirect following for 301/302/303/307/308 with loop limit including http→https, URLs up to 2 KiB (a GitHub release download redirects to a ~900-character signed link) that are refused rather than truncated when longer, a streaming body sink so a 20 MB download costs one 16 KiB buffer instead of 20 MB of heap, an idle receive timeout,wgetshell command), HTTPS (TLS 1.3/1.2 through rustls inno_stdwith the RustCrypto provider, certificate chains verified against the compiled-in Mozilla root store and the RTC, entropy from the kernel's ChaCha20 pool, the socket staying on the C++ side), UDP remote shell (execute kernel commands over the network), network device abstraction with per-protocol packet counters,MacAddress/IpAddressstructs (IPv6-ready tagged union) - Filesystem — VFS with mount points, path resolution and a file API (open/read/write/seek, append, truncate, rename, stat, readdir; open files pin their vnode), one filesystem call at a time; ext2 read-write (rev 1, 1–4 KiB blocks, direct/indirect/doubly-indirect blocks, sparse files, lazy directory loading, e2fsck-clean write ordering,
validstate kept like Linux; refuses ext3/ext4 features, mountsgdt_csumimages read-only); a root filesystem on disk chosen byroot=auto|<dev>|LABEL=|UUID=, made withscripts/mkrootfs.sh/scripts/build-disk.sh(no root privileges), and a self-test (fstest) run at boot by the smoke tests; ramfs (in-memory), nanofs (the kernel's own checksummed 64 MiB filesystem, copy-on-write, files up to 1 MiB), procfs - Randomness — a ChaCha20 CSPRNG (
src/rust/random: fast key erasure for output, absorb for seeding, RFC 8439 block function checked at boot against the RFC's vector) seeded from every entropy source the machine has: the CPU's own instruction behind a HAL seam (RDSEED/RDRAND on x86-64, RNDR/RNDRRS on arm64, with a self-test that refuses an instruction answering the same value every time), virtio-rng, and a timing-jitter collector with von Neumann debiasing as the last resort on a machine with neither. a source implementsrandom::Sourceand registers with the pool, which reseeds from all of them;randomandentropyshell commands,hwrng=offto exercise the fallback - Power management — ACPI S5 shutdown, keyboard controller reset/reboot
- Interactive shell — trace output suppressed during shell session (dmesg only), restored on shutdown; commands:
ps,top,profile,stacks,cpu,lscpu,bt <pid>,dmesg [lines] [filter],loglevel [N],uptime,date,memusage,meminfo,memcheck,pci,disks,diskread,diskwrite,irqstat,net,arp,netpool,icmpstat,tcpstat,udpsend,ping,nslookup,dnsflush,dhcp,wget,random,entropy,format,mount,umount,ls,cat,cp,write,append,mkdir,touch,rm,mv,stat,sync,fstest,crc32,sha256,grubenv,panic,version,cls,help,poweroff,reboot— see Shell commands - Timekeeping — TSC calibration via PIT channel 2 (multi-round median), KVM paravirt clock (
kvmclock) for accurate VM time, RTC wall clock, layered clock source selection (kvmclock → calibrated TSC → PIT fallback),GetBootTime()/GetWallTimeSecs()API - All of the machine's RAM, up to 512 GiB — the bootstrap linear map
covers the first 4 GiB at 2 MiB granularity, then one 1 GiB block per GiB
of RAM above it (x86-64: needs CPUID PDPE1GB, which everything since
Nehalem/Barcelona has; arm64: an L1 block, always available at a 4 KiB
granule). 512 GiB is where one PDPT/L1 table runs out. Blocks with no
usable RAM in them are left unmapped. Where the hardware cannot do it the
kernel falls back to 4 GiB and says so;
meminfoand twomm:lines at boot always report RAM reported vs. RAM reachable, so the difference is never silent. The page-descriptor array that comes with all that RAM (one 32-bytePageper 4 KiB frame, so 512 MiB on a 64 GiB box) gets a contiguous carve-out of its own and is mapped with 2 MiB pages, since every free-list walk touches it at random. Cost: building the free list still touches every page twice, about 0.6 µs in total each, so a 64 GiB machine spends around ten seconds of its boot there. - Per-CPU tick — each CPU runs its own timer (x86-64: the local APIC timer, calibrated once against the established clock; arm64: the generic timer), rather than one HPET interrupt on one CPU fanned out to every other by IPI. One-shot: armed for the next tick, or sooner for a task asleep until a deadline, so a sleep of a millisecond takes one and not the tick's ten (the local timer). That removes a write to the interrupt command register per CPU per tick, and removes the single point of failure: a CPU that stops answering interrupts now stops only its own tick, while the others keep ticking and the watchdog notices it. The HPET stays as the timekeeper.
- Kernel infrastructure — spinlocks, mutexes, SeqLock (single-writer/multi-reader), atomics, wait groups, SoftIrq deferred processing, IPI tasks, timers, watchdog, stack traces with symbol resolution, dmesg ring buffer (512 KB, 2048 messages, recycled lines counted and reported), panic handler with backtrace and CPU/task context, per-device interrupt statistics, AP startup diagnostics, virtual-to-physical address translation (4-level page table walk), byte-order helpers (
Htons/Htonl/Ntohs/Ntohl) - Optimized stdlib —
MemSet,MemCpy,MemCmp,StrLen,StrCmp,StrStrimplemented in x86-64 assembly usingrep stosq/rep movsq/repe cmpsb/repne scasb(portable C versions on arm64) - Rust support —
#![no_std]Rust crates linked into the kernel viastaticlib, FFI bridge (rust_ffi.cpp) exposing kernel services to Rust: spinlocks, mutexes, wait groups, timers, SoftIRQ, MSI-X interrupts, legacy interrupts, DMA allocation, MMIO mapping, PCI config space, block device and network device registration, CPU/IPI/task APIs. kcore library provides safe Rust wrappers around kernel primitives. NVMe driver written entirely in Rust — PCI BAR mapping, admin + I/O queue pairs, MSI-X interrupt-driven completion, WaitGroup-based synchronous I/O, multi-device support, proper RAII cleanup on shutdown - Loadable kernel modules — kernel services written in Rust, each a crate built into a position-independent ELF
.koand loaded into the running kernel withinsmod(listed withlsmod, removed withrmmod), on both architectures. The loader maps each segment into pages of its own, binds the module's imports by name against an export table generated from thefficrate's declarations, applies its dynamic relocations, gives every segment the permissions its program header asks for (never writable and executable at once), and refuses a module built against another kernel interface. A module can add shell commands;insmodandrmmodeach run in a task of their own, so an unload waiting out a module command still running holds up neither the shell norlsmod. Images up to 16 MiB. Backtraces — the panic report,bt, the profiler — name a module's functions, from a demangled table the build puts in the.ko.blkload, a module in the tree, load-tests a disk or a partition from the shell: IOPS, bandwidth, latency percentiles;netloadload-tests the network from either end -- a UDP target that echoes from the receive softirq, a batch of replies to the NIC at a time, and a source that sends to an address and port as fast as the NIC takes them or at a rate, counts what comes back, and leaves room in the transmit queue so that the shell goes on answering under it. Tagged releases carry every module, built for both architectures, forwgetfrom a running kernel. The boot self-test loads, exercises and unloads a module embedded in the kernel image - netblk — a module that serves an NVMe disk, or a partition of one, as a block device over UDP, zero-copy both ways: the disk DMAs a read straight into the frame the NIC transmits, and a write straight out of the frame the NIC received, which then goes back as the reply. Requests pass from the receive softirq to a pinned worker and back from the disk's interrupt through the kernel's lockless rings; the worker rings the disk's doorbell and the NIC's once a batch, polls while completions are due and blocks on an event otherwise. It stands on a UDP listener that is handed the frame itself, batched transmit, virtio-net receiving into pool frames, and an asynchronous block path (
kcore::block::Disk::submit) the NVMe driver implements.scripts/netblk.pyis its client,scripts/netblk-test.pyits end-to-end test on both architectures - sshd — an SSH server in a module: an OpenSSH client logs in with an Ed25519 key and gets the kernel's shell, with a line editor and history on a terminal, or runs one command (
ssh host dmesg). curve25519-sha256 with OpenSSH's strict key exchange, ssh-ed25519 host and user keys, chacha20-poly1305@openssh.com, client-started rekeying followed even mid-output, flow control both ways; the protocol lives in a crate of its own (src/rust/ssh) over the vendored RustCrypto and dalek crates, the module supplies TCP, the files and the shell. The host key is made on the first start and kept in OpenSSH's own format, the authorized keys in an OpenSSHauthorized_keys; 8 connections, at most 4 of them logging in, a 30-second login grace, keepalives./etc/rc-- shell commands the shell runs once at boot, edited withrc-- loads and starts it on a machine whose only console is the network. It was the first user of the TCP stack's passive side, which gained anAcceptthat times out and notices its listener closed, and resets for connections a closed listener never accepted - The hypervisor — stage 3, as Rust crates and a module that can be taken back out:
hvarchis the CPU's virtualization extension and almost all of the hypervisor'sunsafe(128 sites),hvis everything above it and has four, and neither is compiled into a kernel that does not load the module. Under AMD-V and Intel VT-x it runs guests: guest memory behind a nested page table that maps nothing but pages the memory owns, accessed by copies only -- but for its devices' rings, mapped while a queue is up and still reached a value at a time; a VMCB whose host-critical intercepts and controls the entry sets every time whatever the policy above wrote;vmsave/vmloadof the host's segment state aroundvmrun, with GIF clear throughout; the exits decoded; and a software check of the VMCB that names the rulevmrunwould refuse it for. Six built-in long-mode guests (hv run) show port I/O and CPUID, memory above 4 GiB and every register across a hypercall, a write past its memory stopped at the nested table, a triple fault, a refused VMCB, andcli; jmp $stopped by the host. Today it finds what the machine has and reports it a feature a line -- AMD-V or Intel VT-x, nested paging, next-RIP save, ASIDs, x2APIC, 1 GiB pages; on arm64, the exception level and what stage-2 would offer -- and turns the extension on and off for named CPUs or all of them, allocating each CPU's host-save-area or VMXON region before the IPI that hands it over and freeing it only after that CPU says it is done.hvreports which CPUs have it on by asking the CPUs, not its own table, so anrmmodthat left one on is visible on the nextinsmod:scripts/hv-test.pyis that round trip. AMD-V is the backend written first because QEMU's TCG emulates it, nested paging included, and emulates no VMX at all; Intel VT-x is a full second backend now -- a VMCS synced from the same AMD-shaped guest-state shadow, EPT, avmlaunchstub and the exits decoded -- brought up and gated under nested KVM, with every built-in guest running under it too. It boots Linux:hv bootloads an unmodified 64-bitbzImageand initramfs by the boot protocol, with a CPU cut down to what is emulated (CPUID and MSR policy), an 8250, an 8254 PIT, an RTC and a pair of 8259 PICs, and a vCPU that sleeps while its guest halts -- a tinyconfig Linux 6.18 reaches a BusyBox shell and runs what is typed at it, under TCG and on the AX41's real AMD-V;hv startleaves such a guest running on a vCPU task of its own, reached from the shell withhv list,console,send,exec,wait,restartandstop, or live and typed at over ssh withhv attach(Guests that stay up); and gives it disks, virtio over legacy PCI on files of nos's, served while the guest runs on by a task of the disk's own, which a guest mounts ext4 from (A disk), and a NIC on a switch with the other guests and nos, whose end of it is a virtual NIC in its own stack (hv0) -- a guest's server reached from outside throughhv forward, and the world reached from a guest through NAT, the switch answering its DHCP with its port's address and nos's DNS server, and the NIC's checksums and TCP's sends of up to 64 KiB offloaded both ways, a send carried whole from one guest to another (A network). A distribution boots as it ships: Alpine'svirtISO, its own kernel and initramfs, the ISO a read-only disk, to a login prompt, rebooting and on the switch, its own sshd installed from the ISO and logged into from outside; and Debian 13's cloud image under systemd, provisioned by credentials on its command line, its root the guest's writable disk and kept across a reboot (A distribution). A Linux guest has as many CPUs ascpus=gives it, up to 16, each a task on a host CPU of its own with an emulated x2APIC -- its timer, IPIs, and INIT and the start-up IPI into real mode -- found by the guest through an MP table, its disks and NICs interrupting it by MSI-X through its local APICs -- the vector table a page of its own memory, so no MMIO is decoded -- and gated under AMD-V and Intel VT-x (More than one CPU). Every Linux guest is given ACPI's tables -- an XSDT, a FADT, a MADT, and a DSDT in AML with S5 and the PCI host bridge its kernel finds its disks and NICs through -- and the fixed hardware they describe on ports, the PM timer, the SCI on IRQ 9, the reset register;hv stoppresses the guest's power button and gives it time to shut itself down, as a distribution does (ACPI). MMIO is emulated: the instruction that faulted on a device's page is fetched by the guest's own paging, decoded -- the forms ofmovLinux's accessors are, checked against clang's encodings -- and performed, with nounsafe; its first device is the local APIC's xAPIC mode, which a guest toldnox2apicor givenxapicreaches through the page (MMIO), and its second an IO-APIC, whichioapicgives a guest of more than one CPU -- its timer, serial port, SCI and virtio INTx routed through it to any CPU, as edges and levels (The IO-APIC). Each CPU hands out ASIDs by generation, so an entry flushes the TLB only when they run out, not every time;hv benchmeasures what an exit costs (Address space identifiers). - Boot tests — allocator, ring buffer, stack trace, multitasking, contiguous page alloc (up to 128 pages), parsing helpers, block device table, memset, memcpy, memcmp, strlen, strcmp, strstr; the lockless ring with producers and consumers on several CPUs at once