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 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 | #!/usr/bin/env bash
# Build the kernel with the `headless` feature and boot it in QEMU with no
# window. Serial output goes to this terminal; the kernel powers QEMU off via
# the isa-debug-exit device when done. A timeout guards against hangs.
#
# A normal boot runs the shell self-test (disk/scripts/selftest.sh); the
# shell's exit code decides success, and this script then also checks that
# the expected lines appear in the output.
#
# Usage: ./scripts/run-headless.sh # boot + shell self-test
# ./scripts/run-headless.sh stack-overflow # extra cargo features, comma separated
# EXT2_IMG=copy.img ./scripts/run-headless.sh
# use copy.img as the ext2 disk *without* snapshot=on, so the
# self-test's writes land in that file (scripts/ext2-check.sh
# then runs e2fsck on it)
# EXFAT_IMG=copy.img ./scripts/run-headless.sh
# the same for the exFAT disk (scripts/exfat-check.sh runs
# fsck.exfat on it)
# BTRFS_IMG=other.img ./scripts/run-headless.sh
# use other.img as drive E: (read-only, so always snapshot=on)
# Force bootimage to repack the disk image (see scripts/runner.sh for why).
IMG=target/x86_64-rust_kernel/debug/bootimage-rustbelt.bin
if [; then
EXT2_DRIVE="file=,format=raw,if=virtio"
else
EXT2_DRIVE="file=target/ext2.img,format=raw,if=virtio,snapshot=on"
fi
if [; then
EXFAT_DRIVE="file=,format=raw,if=virtio"
else
EXFAT_DRIVE="file=target/exfat.img,format=raw,if=virtio,snapshot=on"
fi
BTRFS_DRIVE="file=,format=raw,if=virtio,snapshot=on"
LOG=target/headless-serial.log
|
code=
# Lines the shell self-test must have printed (only for a plain boot).
if [ && [; then
expect=(
"Rustbelt 0.11.0 (stage 11: core polish) x86_64" # ver
"[smp] 4 CPUs online" # smp.rs started 3 more cores
"B: /mnt/disk0 fat32" # drives
"C: /mnt/disk1 ext2"
"D: /mnt/disk2 exfat"
"E: /mnt/disk3 btrfs"
"B:/ $ ls" # cd B: changed the prompt
"readme.txt scripts/" # ls in columns
"In the Rustbelt shell this disk is drive B:" # type B:/readme.txt
"second line" # >> and <
" 125 todo.txt" # cp + ls -l
'[trace 18] open("/mnt/disk0/notes/todo.txt", 0o0) = 3' # run --trace
"sleep started in the background" # start
"[done] pid 19 (start sleep 1), exit code 0" # wait
"C:/ $ ls" # the ext2 disk
"Hello from the ext2 disk!" # cat through a symlink
"big.txt line 12345" # double-indirect block
"written by Rustbelt" # mkdir + create on ext2
"-rw-r--r-- 125 todo.txt" # cp B: -> C:, ls -l
"lrwxrwxrwx hello-link -> hello.txt"
"drwxr-xr-x <DIR> made-here/"
"D:/ $ ls" # the exFAT disk
"This file has a long name with spaces in it." # quoted name, other case
"MixedCase.TXT: exFAT keeps the case" # cp D: -> C:, cat
"hi from exFAT" # md + echo >, other case
" 125 todo.txt" # cp B: -> D:, ls -l D:/
" <DIR> New Folder/"
" 340000 numbers.txt"
"E:/ $ ls -l" # the btrfs disk
"lrwxrwxrwx hello-link -> hello.txt"
"Hello from btrfs! (an inline extent" # inline, through a symlink
"btrfs never overwrites a block in place" # compressed inline extent
" 120000 360000 2160000 big.txt" # 17 zlib extents
"btrfs line 119999"
"Stage 10: a read-only btrfs driver" # inside subvolume projects
"sh: new.txt: Read-only file system" # writes refused
"rm: hello.txt: Read-only file system"
"mkdir: newdir: Read-only file system"
"[exit code 139]" # run evil
"(overflow) killed: stack overflow" # user stack guard zone
"4 CPUs online (this program ran on CPU" # sysinfo
" CPU3 ["
"sh: nosuchprogram: command not found"
"cd: there is no drive Q:"
"A:/tmp $ pwd"
)
missing=0
for; do
|| { ; missing=1; }
done
# Pipe results: `... | grep -i EXT | wc -l` -> 1, `dir bin | wc -l` -> 17,
# `cat C:/chunks.txt | wc -l` (copied from E:) -> 3, and
# `type D:/COW.TXT | wc -l` (copied from E:) -> 4.
for; do
|| { ; missing=1; }
done
# No memory leaks: once the shell and all ~60 programs it ran have
# exited, exactly as many frames must be in use as before it started.
if ; then
else
; missing=1
fi
[ && || code=35
fi
# isa-debug-exit: QEMU exit status = (value << 1) | 1, so Success(0x10) -> 33.
case in
33) ; ;;
35) ; ;;
124) ; ;;
*) ; ;;
esac
|