RustForge

rust-kernel

Rustbelt: a hobby x86_64 kernel written in Rust

rust-kernel / Cargo.toml
3369 bytes ยท raw
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
[package]
name = "rust_kernel"
version = "0.1.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

[dependencies.lazy_static]
version = "1.0"
features = ["spin_no_std"]

[features]
# Build with `--features headless` to make the kernel shut QEMU down after
# ~5 seconds of timer ticks (used by scripts/run-headless.sh). Without it the
# kernel just halts forever so you can look at the QEMU window.
headless = []
# 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 = "rust_kernel"
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 = [
    "-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 = [
    "-device", "isa-debug-exit,iobase=0xf4,iosize=0x04",
    "-serial", "stdio",
    "-display", "none",
]
test-success-exit-code = 33   # (0x10 << 1) | 1
test-timeout = 120            # seconds