[package] name = "rustbelt" version = "0.13.0" edition = "2024" [dependencies] # Bootloader 0.9.x: the version used by the 2nd edition of "Writing an OS in Rust". # `cargo bootimage` links it with our kernel into a bootable BIOS disk image. # `map_physical_memory`: the bootloader maps *all* physical RAM somewhere in # virtual memory and tells us where (BootInfo.physical_memory_offset), so we # can read/write page tables, which live at physical addresses. bootloader = { version = "0.9", features = ["map_physical_memory"] } volatile = "0.2.6" # stops the compiler optimising away VGA buffer writes spin = "0.5.2" # spinlock Mutex (no OS = no std::sync::Mutex) x86_64 = "0.15" # safe wrappers for x86 instructions/ports (hlt, outb, ...) uart_16550 = "0.3" # driver for the serial port (COM1) pic8259 = "0.11" # driver for the two chained 8259 interrupt controllers pc-keyboard = "0.7" # turns PS/2 scancodes into key events / characters linked_list_allocator = "0.9" # ready-made heap allocator (fallback for ours) # Async/await support without std (all with default features off): crossbeam-queue = { version = "0.3.11", default-features = false, features = ["alloc"] } # lock-free ArrayQueue conquer-once = { version = "0.4", default-features = false } # OnceCell: init a static at runtime, once futures-util = { version = "0.3.4", default-features = false, features = ["alloc"] } # Stream, AtomicWaker # FAT12/16/32 file system library. The crates.io release (0.3.6) needs the # abandoned `core_io` crate for no_std, so we use the git version, pinned to # an exact commit so builds are reproducible. Only `alloc` + long file names. fatfs = { git = "https://github.com/rafalh/rust-fatfs", rev = "38b3a7950bf0e765e34286d1dfe76c519ee347e2", default-features = false, features = ["alloc", "lfn"] } # Decompressors for btrfs's compressed extents (stage 10). Only decompression # is used; the btrfs driver itself is hand-written. Both work without std. miniz_oxide = { version = "0.8", default-features = false, features = ["with-alloc"] } # zlib (DEFLATE) ruzstd = { version = "0.8", default-features = false } # zstd # TCP/IP: Ethernet, ARP, IPv4, ICMP, UDP, TCP, DHCP and DNS, written for # kernels and microcontrollers (no_std, works without an OS). smoltcp = { version = "0.14", default-features = false, features = [ "alloc", "medium-ethernet", "proto-ipv4", "socket-tcp", "socket-udp", "socket-icmp", "socket-dhcpv4", "socket-dns", ] } [dependencies.lazy_static] version = "1.0" features = ["spin_no_std"] [features] # Build with `--features headless` to make the shell run the self-test # script (disk/scripts/selftest.sh) instead of reading the keyboard, and shut # QEMU down when it exits (used by scripts/run-headless.sh). headless = [] # Build with `--features demos` to see the earlier stages' demos at boot: # breakpoint, paging/heap printouts, threads A/B/C, async tasks and the # hello/evil/spin/demo programs (before the shell starts). demos = [] # Build with `--features stack-overflow` to deliberately overflow the kernel # stack after boot, to check the double-fault handler (GDT/TSS/IST) catches it. stack-overflow = [] # Build with `--features page-fault` to deliberately write to an unmapped # address after boot and watch the page-fault handler report it. page-fault = [] # The library (src/lib.rs) holds all kernel code so integration tests in # tests/ can use it; src/main.rs is the small binary that boots it. [lib] doctest = false # doc tests would need std; our tests run in QEMU instead [[bin]] name = "rustbelt" test = false # all tests live in the library and tests/ bench = false # These two tests replace the test framework with their own `_start`. [[test]] name = "should_panic" harness = false [[test]] name = "stack_overflow" harness = false # Note: no `panic = "abort"` profile settings: the target JSON already sets # "panic-strategy": "abort", and the profile setting breaks `cargo test` with # build-std ("duplicate lang item in crate core"). # Extra QEMU arguments used by `cargo run` (via `bootimage runner`). [package.metadata.bootimage] run-args = [ # Four CPU cores (smp.rs starts the other three). "-smp", "4", # Second disk: the FAT32 image build.rs makes (target/disk.img), as a # virtio-blk PCI device. snapshot=on: writes go to a temporary overlay, # so the image is the same at every boot (and tests can't corrupt it). "-drive", "file=target/disk.img,format=raw,if=virtio,snapshot=on", # Third disk: the ext2 image (target/ext2.img), also snapshot=on. "-drive", "file=target/ext2.img,format=raw,if=virtio,snapshot=on", # Fourth disk: the exFAT image (target/exfat.img), drive D:. "-drive", "file=target/exfat.img,format=raw,if=virtio,snapshot=on", # Fifth disk: the btrfs image (target/btrfs.img), drive E: (read-only). "-drive", "file=target/btrfs.img,format=raw,if=virtio,snapshot=on", # Network card: virtio-net on QEMU's user-mode network ("slirp"): a # built-in NAT router with DHCP (we get 10.0.2.15), the host as # 10.0.2.2 and a DNS forwarder at 10.0.2.3. No root or setup needed. # guestfwd: connections to 10.0.2.100:80 run scripts/http-reply.sh # (a test web server); 10.0.2.100:7 runs `cat` (an echo server). # hostfwd: the host's port 5580 reaches the guest's port 80, so # `httpd` in Rustbelt answers `curl http://127.0.0.1:5580/`. "-netdev", "user,id=net0,guestfwd=tcp:10.0.2.100:80-cmd:sh scripts/http-reply.sh,guestfwd=tcp:10.0.2.100:7-cmd:cat,hostfwd=tcp:127.0.0.1:5580-:80", "-device", "virtio-net-pci,netdev=net0", # Stage 13's virtual devices: # virtio-vga: virtio-gpu that also does the old VGA modes (so the # BIOS and the early VGA text console still work). -vga none drops # the default "std" VGA card it replaces. # virtio-rng-pci: random numbers from the host. # virtio-serial-pci + virtconsole: a second terminal (hvc0) on a unix # socket: `socat - UNIX-CONNECT:target/hvc0.sock` on the host, and # `getty /dev/hvc0 &` in Rustbelt to get a shell there. "-vga", "none", "-device", "virtio-vga", "-device", "virtio-rng-pci", "-device", "virtio-serial-pci", "-device", "virtconsole,chardev=hvc", "-chardev", "socket,id=hvc,path=target/hvc0.sock,server=on,wait=off", "-device", "isa-debug-exit,iobase=0xf4,iosize=0x04", # lets the kernel exit QEMU "-serial", "stdio", # serial port -> your terminal ] # Used by `cargo test`: headless, results on serial, exit code 33 = pass. test-args = [ "-smp", "4", # four CPU cores (tests that call init_smp use them all) # Second disk: the FAT32 image build.rs makes (target/disk.img), as a # virtio-blk PCI device. snapshot=on: writes go to a temporary overlay, # so the image is the same at every boot (and tests can't corrupt it). "-drive", "file=target/disk.img,format=raw,if=virtio,snapshot=on", "-drive", "file=target/ext2.img,format=raw,if=virtio,snapshot=on", "-drive", "file=target/exfat.img,format=raw,if=virtio,snapshot=on", "-drive", "file=target/btrfs.img,format=raw,if=virtio,snapshot=on", # More images just for the tests, after the ones `cargo run` has so the # drive letters B: to E: are the same in both: ext2 with 4 KiB blocks # (/mnt/disk4), ext2 revision 0 (/mnt/disk5), exFAT with 512-byte # clusters (/mnt/disk6), btrfs with lzo (/mnt/disk7), zstd (/mnt/disk8), # converted from ext2 (/mnt/disk9), and one with sha256 checksums that # must be refused (so it gets no /mnt/diskN). "-drive", "file=target/ext2-4k.img,format=raw,if=virtio,snapshot=on", "-drive", "file=target/ext2-rev0.img,format=raw,if=virtio,snapshot=on", "-drive", "file=target/exfat-512.img,format=raw,if=virtio,snapshot=on", "-drive", "file=target/btrfs-lzo.img,format=raw,if=virtio,snapshot=on", "-drive", "file=target/btrfs-zstd.img,format=raw,if=virtio,snapshot=on", "-drive", "file=target/btrfs-convert.img,format=raw,if=virtio,snapshot=on", "-drive", "file=target/btrfs-sha256.img,format=raw,if=virtio,snapshot=on", # Network (see run-args), plus slirp's TFTP server serving disk/ (a UDP # test). No hostfwd: tests must not depend on a free host port. "-netdev", "user,id=net0,tftp=disk,guestfwd=tcp:10.0.2.100:80-cmd:sh scripts/http-reply.sh,guestfwd=tcp:10.0.2.100:7-cmd:cat", "-device", "virtio-net-pci,netdev=net0", # The stage-13 devices (see run-args). The console's input comes from # tests/hvc0-input.txt and its output goes to target/hvc0-test.out. "-vga", "none", "-device", "virtio-vga", "-device", "virtio-rng-pci", "-device", "virtio-serial-pci", "-device", "virtconsole,chardev=hvc", "-chardev", "file,id=hvc,path=target/hvc0-test.out,input-path=tests/hvc0-input.txt", "-device", "isa-debug-exit,iobase=0xf4,iosize=0x04", "-serial", "stdio", "-display", "none", ] test-success-exit-code = 33 # (0x10 << 1) | 1 test-timeout = 120 # seconds