mirror of
https://github.com/phil-opp/blog_os.git
synced 2025-12-16 14:27:49 +00:00
Merge branch 'post-06-new' into post-07-new-rebased
This commit is contained in:
@@ -55,8 +55,7 @@ install:
|
|||||||
- set PATH=%PATH%;%USERPROFILE%\.cargo\bin
|
- set PATH=%PATH%;%USERPROFILE%\.cargo\bin
|
||||||
- rustc -vV
|
- rustc -vV
|
||||||
- cargo -vV
|
- cargo -vV
|
||||||
|
# Install qemu
|
||||||
# Install qemu
|
|
||||||
- echo %cd%
|
- echo %cd%
|
||||||
- mkdir "C:\Program Files\qemu"
|
- mkdir "C:\Program Files\qemu"
|
||||||
- cd "C:\Program Files\qemu"
|
- cd "C:\Program Files\qemu"
|
||||||
@@ -85,7 +84,6 @@ before_test:
|
|||||||
- cargo install-latest cargo-xbuild bootimage
|
- cargo install-latest cargo-xbuild bootimage
|
||||||
|
|
||||||
test_script:
|
test_script:
|
||||||
- bootimage build
|
- cargo xbuild
|
||||||
- if %target%==x86_64-pc-windows-gnu cargo test
|
- cargo bootimage
|
||||||
- if %target%==x86_64-pc-windows-msvc cargo test
|
- cargo xtest
|
||||||
- bootimage test
|
|
||||||
|
|||||||
5
.cargo/config
Normal file
5
.cargo/config
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
[build]
|
||||||
|
target = "x86_64-blog_os.json"
|
||||||
|
|
||||||
|
[target.'cfg(target_os = "none")']
|
||||||
|
runner = "bootimage runner"
|
||||||
@@ -42,11 +42,10 @@ install:
|
|||||||
|
|
||||||
before_script:
|
before_script:
|
||||||
- rustup component add rust-src llvm-tools-preview
|
- rustup component add rust-src llvm-tools-preview
|
||||||
- (test -x $HOME/.cargo/bin/cargo-install-latest || cargo install cargo-install-latest)
|
- cargo install cargo-xbuild bootimage cargo-cache --debug -Z install-upgrade
|
||||||
- cargo install-latest cargo-xbuild bootimage cargo-cache
|
|
||||||
|
|
||||||
script:
|
script:
|
||||||
- bootimage build
|
- cargo xbuild
|
||||||
- cargo test
|
- cargo bootimage
|
||||||
- bootimage test
|
- cargo xtest
|
||||||
- cargo cache --autoclean
|
- cargo cache --autoclean
|
||||||
|
|||||||
49
Cargo.lock
generated
49
Cargo.lock
generated
@@ -1,13 +1,5 @@
|
|||||||
# This file is automatically @generated by Cargo.
|
# This file is automatically @generated by Cargo.
|
||||||
# It is not intended for manual editing.
|
# It is not intended for manual editing.
|
||||||
[[package]]
|
|
||||||
name = "array-init"
|
|
||||||
version = "0.0.3"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
dependencies = [
|
|
||||||
"nodrop 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "array-init"
|
name = "array-init"
|
||||||
version = "0.0.4"
|
version = "0.0.4"
|
||||||
@@ -30,20 +22,19 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
name = "blog_os"
|
name = "blog_os"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"array-init 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
"bootloader 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"bootloader 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"pc-keyboard 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"pc-keyboard 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"pic8259_simple 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"pic8259_simple 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"spin 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
"spin 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"uart_16550 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"uart_16550 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"volatile 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
"volatile 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"x86_64 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
"x86_64 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bootloader"
|
name = "bootloader"
|
||||||
version = "0.5.2"
|
version = "0.6.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"fixedvec 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
"fixedvec 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
@@ -56,7 +47,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cc"
|
name = "cc"
|
||||||
version = "1.0.34"
|
version = "1.0.35"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -170,7 +161,7 @@ version = "6.1.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
"bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"cc 1.0.34 (registry+https://github.com/rust-lang/crates.io-index)",
|
"cc 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
"rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -241,11 +232,11 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "uart_16550"
|
name = "uart_16550"
|
||||||
version = "0.1.0"
|
version = "0.2.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
"bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"x86_64 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)",
|
"x86_64 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -287,18 +278,6 @@ name = "winapi-x86_64-pc-windows-gnu"
|
|||||||
version = "0.4.0"
|
version = "0.4.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "x86_64"
|
|
||||||
version = "0.2.14"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
dependencies = [
|
|
||||||
"bit_field 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"os_bootinfo 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"usize_conversions 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"ux 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "x86_64"
|
name = "x86_64"
|
||||||
version = "0.3.6"
|
version = "0.3.6"
|
||||||
@@ -314,7 +293,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "x86_64"
|
name = "x86_64"
|
||||||
version = "0.5.3"
|
version = "0.5.4"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"array-init 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
"array-init 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
@@ -339,12 +318,11 @@ version = "0.1.2"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
[metadata]
|
[metadata]
|
||||||
"checksum array-init 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "c3cc8456d0ae81a8c76f59e384683a601548c38949a4bfcb65dd31ded5c75ff3"
|
|
||||||
"checksum array-init 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "23589ecb866b460d3a0f1278834750268c607e8e28a1b982c907219f3178cd72"
|
"checksum array-init 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "23589ecb866b460d3a0f1278834750268c607e8e28a1b982c907219f3178cd72"
|
||||||
"checksum bit_field 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ed8765909f9009617974ab6b7d332625b320b33c326b1e9321382ef1999b5d56"
|
"checksum bit_field 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ed8765909f9009617974ab6b7d332625b320b33c326b1e9321382ef1999b5d56"
|
||||||
"checksum bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "228047a76f468627ca71776ecdebd732a3423081fcf5125585bcd7c49886ce12"
|
"checksum bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "228047a76f468627ca71776ecdebd732a3423081fcf5125585bcd7c49886ce12"
|
||||||
"checksum bootloader 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "2735a1e3ddf16e6832fff86db617778dd3cecd5804fc8c2f20f448750d4c989c"
|
"checksum bootloader 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8654b1ebbd38d2a8687a451ad53466d01b5edc9d75ec63d676525a6103d77151"
|
||||||
"checksum cc 1.0.34 (registry+https://github.com/rust-lang/crates.io-index)" = "30f813bf45048a18eda9190fd3c6b78644146056740c43172a5a3699118588fd"
|
"checksum cc 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)" = "5e5f3fee5eeb60324c2781f1e41286bdee933850fff9b3c672587fed5ec58c83"
|
||||||
"checksum cpuio 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "22b8e308ccfc5acf3b82f79c0eac444cf6114cb2ac67a230ca6c177210068daa"
|
"checksum cpuio 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "22b8e308ccfc5acf3b82f79c0eac444cf6114cb2ac67a230ca6c177210068daa"
|
||||||
"checksum fixedvec 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "7c6c16d316ccdac21a4dd648e314e76facbbaf316e83ca137d0857a9c07419d0"
|
"checksum fixedvec 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "7c6c16d316ccdac21a4dd648e314e76facbbaf316e83ca137d0857a9c07419d0"
|
||||||
"checksum font8x8 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "b81d84c3c978af7d05d31a2198af4b9ba956d819d15d8f6d58fc150e33f8dc1f"
|
"checksum font8x8 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "b81d84c3c978af7d05d31a2198af4b9ba956d819d15d8f6d58fc150e33f8dc1f"
|
||||||
@@ -371,7 +349,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
"checksum spin 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)" = "ceac490aa12c567115b40b7b7fceca03a6c9d53d5defea066123debc83c5dc1f"
|
"checksum spin 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)" = "ceac490aa12c567115b40b7b7fceca03a6c9d53d5defea066123debc83c5dc1f"
|
||||||
"checksum spin 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "44363f6f51401c34e7be73db0db371c04705d35efbe9f7d6082e03a921a32c55"
|
"checksum spin 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "44363f6f51401c34e7be73db0db371c04705d35efbe9f7d6082e03a921a32c55"
|
||||||
"checksum tempdir 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)" = "15f2b5fb00ccdf689e0149d1b1b3c03fead81c2b37735d812fa8bddbbf41b6d8"
|
"checksum tempdir 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)" = "15f2b5fb00ccdf689e0149d1b1b3c03fead81c2b37735d812fa8bddbbf41b6d8"
|
||||||
"checksum uart_16550 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "269f953d8de3226f7c065c589c7b4a3e83d10a419c7c3b5e2e0f197e6acc966e"
|
"checksum uart_16550 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5b9392f60931fe3bf8f24e0a15ee4f51528770f1d64c48768ab66571334d95b0"
|
||||||
"checksum unicode-width 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "882386231c45df4700b275c7ff55b6f3698780a650026380e72dabe76fa46526"
|
"checksum unicode-width 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "882386231c45df4700b275c7ff55b6f3698780a650026380e72dabe76fa46526"
|
||||||
"checksum usize_conversions 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f70329e2cbe45d6c97a5112daad40c34cd9a4e18edb5a2a18fefeb584d8d25e5"
|
"checksum usize_conversions 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f70329e2cbe45d6c97a5112daad40c34cd9a4e18edb5a2a18fefeb584d8d25e5"
|
||||||
"checksum ux 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "88dfeb711b61ce620c0cb6fd9f8e3e678622f0c971da2a63c4b3e25e88ed012f"
|
"checksum ux 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "88dfeb711b61ce620c0cb6fd9f8e3e678622f0c971da2a63c4b3e25e88ed012f"
|
||||||
@@ -379,8 +357,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
"checksum winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)" = "f10e386af2b13e47c89e7236a7a14a086791a2b88ebad6df9bf42040195cf770"
|
"checksum winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)" = "f10e386af2b13e47c89e7236a7a14a086791a2b88ebad6df9bf42040195cf770"
|
||||||
"checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
|
"checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
|
||||||
"checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
"checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
||||||
"checksum x86_64 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)" = "2bd647af1614659e1febec1d681231aea4ebda4818bf55a578aff02f3e4db4b4"
|
|
||||||
"checksum x86_64 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "f9258d7e2dd25008d69e8c9e9ee37865887a5e1e3d06a62f1cb3f6c209e6f177"
|
"checksum x86_64 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "f9258d7e2dd25008d69e8c9e9ee37865887a5e1e3d06a62f1cb3f6c209e6f177"
|
||||||
"checksum x86_64 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "8f7e92e985f4052118fd69f2b366c67e91288c0f01f4ae52610dce236425dfa0"
|
"checksum x86_64 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)" = "1d0a8201f52d2c7b373c7243dcdfb27c0dd5012f221ef6a126f507ee82005204"
|
||||||
"checksum xmas-elf 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "22678df5df766e8d1e5d609da69f0c3132d794edf6ab5e75e7abcd2270d4cf58"
|
"checksum xmas-elf 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "22678df5df766e8d1e5d609da69f0c3132d794edf6ab5e75e7abcd2270d4cf58"
|
||||||
"checksum zero 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "5f1bc8a6b2005884962297587045002d8cfb8dcec9db332f4ca216ddc5de82c5"
|
"checksum zero 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "5f1bc8a6b2005884962297587045002d8cfb8dcec9db332f4ca216ddc5de82c5"
|
||||||
|
|||||||
20
Cargo.toml
20
Cargo.toml
@@ -4,12 +4,20 @@ version = "0.1.0"
|
|||||||
authors = ["Philipp Oppermann <dev@phil-opp.com>"]
|
authors = ["Philipp Oppermann <dev@phil-opp.com>"]
|
||||||
edition = "2018"
|
edition = "2018"
|
||||||
|
|
||||||
|
[[test]]
|
||||||
|
name = "panic_handler"
|
||||||
|
harness = false
|
||||||
|
|
||||||
|
[[test]]
|
||||||
|
name = "stack_overflow"
|
||||||
|
harness = false
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
bootloader = "0.5.1"
|
bootloader = "0.6.0"
|
||||||
volatile = "0.2.3"
|
volatile = "0.2.3"
|
||||||
spin = "0.4.9"
|
spin = "0.4.9"
|
||||||
uart_16550 = "0.1.0"
|
|
||||||
x86_64 = "0.5.2"
|
x86_64 = "0.5.2"
|
||||||
|
uart_16550 = "0.2.0"
|
||||||
pic8259_simple = "0.1.1"
|
pic8259_simple = "0.1.1"
|
||||||
pc-keyboard = "0.3.1"
|
pc-keyboard = "0.3.1"
|
||||||
|
|
||||||
@@ -17,9 +25,6 @@ pc-keyboard = "0.3.1"
|
|||||||
version = "1.0"
|
version = "1.0"
|
||||||
features = ["spin_no_std"]
|
features = ["spin_no_std"]
|
||||||
|
|
||||||
[dev-dependencies]
|
|
||||||
array-init = "0.0.3"
|
|
||||||
|
|
||||||
[profile.dev]
|
[profile.dev]
|
||||||
panic = "abort"
|
panic = "abort"
|
||||||
|
|
||||||
@@ -28,3 +33,8 @@ panic = "abort"
|
|||||||
|
|
||||||
[package.metadata.bootimage]
|
[package.metadata.bootimage]
|
||||||
default-target = "x86_64-blog_os.json"
|
default-target = "x86_64-blog_os.json"
|
||||||
|
test-args = [
|
||||||
|
"-device", "isa-debug-exit,iobase=0xf4,iosize=0x04", "-serial", "mon:stdio",
|
||||||
|
"-display", "none"
|
||||||
|
]
|
||||||
|
test-success-exit-code = 33 # (0x10 << 1) | 1
|
||||||
|
|||||||
14
README.md
14
README.md
@@ -1,6 +1,6 @@
|
|||||||
# Blog OS (Hardware Interrupts)
|
# Blog OS (Hardware Interrupts)
|
||||||
|
|
||||||
[](https://dev.azure.com/phil-opp/blog_os/_build?definitionId=1)
|
[](https://dev.azure.com/phil-opp/blog_os/_build?definitionId=1)
|
||||||
|
|
||||||
This repository contains the source code for the [Hardware Interrupts][post] post of the [Writing an OS in Rust](https://os.phil-opp.com) series.
|
This repository contains the source code for the [Hardware Interrupts][post] post of the [Writing an OS in Rust](https://os.phil-opp.com) series.
|
||||||
|
|
||||||
@@ -19,7 +19,13 @@ cargo install cargo-xbuild bootimage
|
|||||||
Then you can build the project by running:
|
Then you can build the project by running:
|
||||||
|
|
||||||
```
|
```
|
||||||
bootimage build
|
cargo xbuild
|
||||||
|
```
|
||||||
|
|
||||||
|
To create a bootable disk image, run:
|
||||||
|
|
||||||
|
```
|
||||||
|
cargo bootimage
|
||||||
```
|
```
|
||||||
|
|
||||||
This creates a bootable disk image in the `target/x86_64-blog_os/debug` directory.
|
This creates a bootable disk image in the `target/x86_64-blog_os/debug` directory.
|
||||||
@@ -33,7 +39,7 @@ You can run the disk image in [QEMU] through:
|
|||||||
[QEMU]: https://www.qemu.org/
|
[QEMU]: https://www.qemu.org/
|
||||||
|
|
||||||
```
|
```
|
||||||
bootimage run
|
cargo xrun
|
||||||
```
|
```
|
||||||
|
|
||||||
Of course [QEMU] needs to be installed for this.
|
Of course [QEMU] needs to be installed for this.
|
||||||
@@ -48,7 +54,7 @@ Where `sdX` is the device name of your USB stick. **Be careful** to choose the c
|
|||||||
|
|
||||||
## Testing
|
## Testing
|
||||||
|
|
||||||
To run the unit tests on the host system, execute `cargo test`. To run the integration tests in [QEMU], run `bootimage test`.
|
To run the unit and integration tests, execute `cargo xtest`.
|
||||||
|
|
||||||
## License
|
## License
|
||||||
The source code is dual-licensed under MIT or the Apache License (Version 2.0).
|
The source code is dual-licensed under MIT or the Apache License (Version 2.0).
|
||||||
|
|||||||
@@ -52,16 +52,14 @@ steps:
|
|||||||
- script: rustup component add rust-src llvm-tools-preview
|
- script: rustup component add rust-src llvm-tools-preview
|
||||||
displayName: 'Install Rustup Components'
|
displayName: 'Install Rustup Components'
|
||||||
|
|
||||||
- script: |
|
- script: cargo install cargo-xbuild bootimage --debug
|
||||||
cargo install cargo-xbuild --debug
|
|
||||||
cargo install bootimage --debug
|
|
||||||
displayName: 'Install cargo-xbuild and bootimage'
|
displayName: 'Install cargo-xbuild and bootimage'
|
||||||
|
|
||||||
- script: bootimage build
|
- script: cargo xbuild
|
||||||
displayName: 'Build'
|
displayName: 'Build'
|
||||||
|
|
||||||
- script: cargo test
|
- script: cargo bootimage
|
||||||
displayName: 'Unit Tests'
|
displayName: 'Create Bootimage'
|
||||||
|
|
||||||
- script: sudo apt update && sudo apt install qemu-system-x86
|
- script: sudo apt update && sudo apt install qemu-system-x86
|
||||||
condition: eq( variables['Agent.OS'], 'Linux' )
|
condition: eq( variables['Agent.OS'], 'Linux' )
|
||||||
@@ -83,8 +81,8 @@ steps:
|
|||||||
condition: eq( variables['Agent.OS'], 'Windows_NT' )
|
condition: eq( variables['Agent.OS'], 'Windows_NT' )
|
||||||
displayName: 'Install QEMU (Windows)'
|
displayName: 'Install QEMU (Windows)'
|
||||||
|
|
||||||
- script: bootimage test
|
- script: cargo xtest
|
||||||
displayName: 'Integration Tests'
|
displayName: 'Test'
|
||||||
|
|
||||||
- script: rustup component add rustfmt
|
- script: rustup component add rustfmt
|
||||||
displayName: 'Install Rustfmt'
|
displayName: 'Install Rustfmt'
|
||||||
|
|||||||
@@ -1,33 +0,0 @@
|
|||||||
#![cfg_attr(not(test), no_std)]
|
|
||||||
#![cfg_attr(not(test), no_main)] // disable all Rust-level entry points
|
|
||||||
#![cfg_attr(test, allow(unused_imports))]
|
|
||||||
|
|
||||||
use blog_os::{exit_qemu, serial_println};
|
|
||||||
use core::panic::PanicInfo;
|
|
||||||
|
|
||||||
/// This function is the entry point, since the linker looks for a function
|
|
||||||
/// named `_start` by default.
|
|
||||||
#[cfg(not(test))]
|
|
||||||
#[no_mangle] // don't mangle the name of this function
|
|
||||||
pub extern "C" fn _start() -> ! {
|
|
||||||
serial_println!("ok");
|
|
||||||
|
|
||||||
unsafe {
|
|
||||||
exit_qemu();
|
|
||||||
}
|
|
||||||
loop {}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// This function is called on panic.
|
|
||||||
#[cfg(not(test))]
|
|
||||||
#[panic_handler]
|
|
||||||
fn panic(info: &PanicInfo) -> ! {
|
|
||||||
serial_println!("failed");
|
|
||||||
|
|
||||||
serial_println!("{}", info);
|
|
||||||
|
|
||||||
unsafe {
|
|
||||||
exit_qemu();
|
|
||||||
}
|
|
||||||
loop {}
|
|
||||||
}
|
|
||||||
@@ -1,34 +0,0 @@
|
|||||||
#![no_std]
|
|
||||||
#![cfg_attr(not(test), no_main)]
|
|
||||||
#![cfg_attr(test, allow(dead_code, unused_macros, unused_imports))]
|
|
||||||
|
|
||||||
use blog_os::{exit_qemu, serial_println};
|
|
||||||
use core::panic::PanicInfo;
|
|
||||||
|
|
||||||
#[cfg(not(test))]
|
|
||||||
#[no_mangle]
|
|
||||||
pub extern "C" fn _start() -> ! {
|
|
||||||
blog_os::interrupts::init_idt();
|
|
||||||
|
|
||||||
x86_64::instructions::interrupts::int3();
|
|
||||||
|
|
||||||
serial_println!("ok");
|
|
||||||
|
|
||||||
unsafe {
|
|
||||||
exit_qemu();
|
|
||||||
}
|
|
||||||
loop {}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(not(test))]
|
|
||||||
#[panic_handler]
|
|
||||||
fn panic(info: &PanicInfo) -> ! {
|
|
||||||
serial_println!("failed");
|
|
||||||
|
|
||||||
serial_println!("{}", info);
|
|
||||||
|
|
||||||
unsafe {
|
|
||||||
exit_qemu();
|
|
||||||
}
|
|
||||||
loop {}
|
|
||||||
}
|
|
||||||
@@ -1,23 +0,0 @@
|
|||||||
#![cfg_attr(not(test), no_std)]
|
|
||||||
#![cfg_attr(not(test), no_main)]
|
|
||||||
#![cfg_attr(test, allow(unused_imports))]
|
|
||||||
|
|
||||||
use blog_os::{exit_qemu, serial_println};
|
|
||||||
use core::panic::PanicInfo;
|
|
||||||
|
|
||||||
#[cfg(not(test))]
|
|
||||||
#[no_mangle]
|
|
||||||
pub extern "C" fn _start() -> ! {
|
|
||||||
panic!();
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(not(test))]
|
|
||||||
#[panic_handler]
|
|
||||||
fn panic(_info: &PanicInfo) -> ! {
|
|
||||||
serial_println!("ok");
|
|
||||||
|
|
||||||
unsafe {
|
|
||||||
exit_qemu();
|
|
||||||
}
|
|
||||||
loop {}
|
|
||||||
}
|
|
||||||
@@ -100,3 +100,14 @@ extern "x86-interrupt" fn keyboard_interrupt_handler(_stack_frame: &mut Interrup
|
|||||||
.notify_end_of_interrupt(InterruptIndex::Keyboard.as_u8());
|
.notify_end_of_interrupt(InterruptIndex::Keyboard.as_u8());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
use crate::{serial_print, serial_println};
|
||||||
|
|
||||||
|
#[test_case]
|
||||||
|
fn test_breakpoint_exception() {
|
||||||
|
serial_print!("test_breakpoint_exception...");
|
||||||
|
// invoke a breakpoint exception
|
||||||
|
x86_64::instructions::interrupts::int3();
|
||||||
|
serial_println!("[ok]");
|
||||||
|
}
|
||||||
|
|||||||
58
src/lib.rs
58
src/lib.rs
@@ -1,16 +1,66 @@
|
|||||||
#![cfg_attr(not(test), no_std)]
|
#![no_std]
|
||||||
|
#![cfg_attr(test, no_main)]
|
||||||
|
#![feature(custom_test_frameworks)]
|
||||||
#![feature(abi_x86_interrupt)]
|
#![feature(abi_x86_interrupt)]
|
||||||
|
#![test_runner(crate::test_runner)]
|
||||||
|
#![reexport_test_harness_main = "test_main"]
|
||||||
|
|
||||||
|
use core::panic::PanicInfo;
|
||||||
|
|
||||||
pub mod gdt;
|
pub mod gdt;
|
||||||
pub mod interrupts;
|
pub mod interrupts;
|
||||||
pub mod serial;
|
pub mod serial;
|
||||||
pub mod vga_buffer;
|
pub mod vga_buffer;
|
||||||
|
|
||||||
pub unsafe fn exit_qemu() {
|
pub fn init() {
|
||||||
|
gdt::init();
|
||||||
|
interrupts::init_idt();
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn test_runner(tests: &[&dyn Fn()]) {
|
||||||
|
serial_println!("Running {} tests", tests.len());
|
||||||
|
for test in tests {
|
||||||
|
test();
|
||||||
|
}
|
||||||
|
exit_qemu(QemuExitCode::Success);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn test_panic_handler(info: &PanicInfo) -> ! {
|
||||||
|
serial_println!("[failed]\n");
|
||||||
|
serial_println!("Error: {}\n", info);
|
||||||
|
exit_qemu(QemuExitCode::Failed);
|
||||||
|
loop {}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||||
|
#[repr(u32)]
|
||||||
|
pub enum QemuExitCode {
|
||||||
|
Success = 0x10,
|
||||||
|
Failed = 0x11,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn exit_qemu(exit_code: QemuExitCode) {
|
||||||
use x86_64::instructions::port::Port;
|
use x86_64::instructions::port::Port;
|
||||||
|
|
||||||
let mut port = Port::<u32>::new(0xf4);
|
unsafe {
|
||||||
port.write(0);
|
let mut port = Port::new(0xf4);
|
||||||
|
port.write(exit_code as u32);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Entry point for `cargo xtest`
|
||||||
|
#[cfg(test)]
|
||||||
|
#[no_mangle]
|
||||||
|
pub extern "C" fn _start() -> ! {
|
||||||
|
init();
|
||||||
|
test_main();
|
||||||
|
loop {}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
#[panic_handler]
|
||||||
|
fn panic(info: &PanicInfo) -> ! {
|
||||||
|
test_panic_handler(info)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn hlt_loop() -> ! {
|
pub fn hlt_loop() -> ! {
|
||||||
|
|||||||
21
src/main.rs
21
src/main.rs
@@ -1,22 +1,25 @@
|
|||||||
#![cfg_attr(not(test), no_std)]
|
#![no_std]
|
||||||
#![cfg_attr(not(test), no_main)]
|
#![no_main]
|
||||||
#![cfg_attr(test, allow(unused_imports))]
|
#![feature(custom_test_frameworks)]
|
||||||
|
#![test_runner(blog_os::test_runner)]
|
||||||
|
#![reexport_test_harness_main = "test_main"]
|
||||||
|
|
||||||
use blog_os::println;
|
use blog_os::println;
|
||||||
use core::panic::PanicInfo;
|
use core::panic::PanicInfo;
|
||||||
|
|
||||||
#[cfg(not(test))]
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub extern "C" fn _start() -> ! {
|
pub extern "C" fn _start() -> ! {
|
||||||
use blog_os::interrupts::PICS;
|
use blog_os::interrupts::PICS;
|
||||||
|
|
||||||
println!("Hello World{}", "!");
|
println!("Hello World{}", "!");
|
||||||
|
|
||||||
blog_os::gdt::init();
|
blog_os::init();
|
||||||
blog_os::interrupts::init_idt();
|
|
||||||
unsafe { PICS.lock().initialize() };
|
unsafe { PICS.lock().initialize() };
|
||||||
x86_64::instructions::interrupts::enable();
|
x86_64::instructions::interrupts::enable();
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
test_main();
|
||||||
|
|
||||||
println!("It did not crash!");
|
println!("It did not crash!");
|
||||||
blog_os::hlt_loop();
|
blog_os::hlt_loop();
|
||||||
}
|
}
|
||||||
@@ -28,3 +31,9 @@ fn panic(info: &PanicInfo) -> ! {
|
|||||||
println!("{}", info);
|
println!("{}", info);
|
||||||
blog_os::hlt_loop();
|
blog_os::hlt_loop();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
#[panic_handler]
|
||||||
|
fn panic(info: &PanicInfo) -> ! {
|
||||||
|
blog_os::test_panic_handler(info)
|
||||||
|
}
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ use uart_16550::SerialPort;
|
|||||||
|
|
||||||
lazy_static! {
|
lazy_static! {
|
||||||
pub static ref SERIAL1: Mutex<SerialPort> = {
|
pub static ref SERIAL1: Mutex<SerialPort> = {
|
||||||
let mut serial_port = SerialPort::new(0x3F8);
|
let mut serial_port = unsafe { SerialPort::new(0x3F8) };
|
||||||
serial_port.init();
|
serial_port.init();
|
||||||
Mutex::new(serial_port)
|
Mutex::new(serial_port)
|
||||||
};
|
};
|
||||||
@@ -36,5 +36,6 @@ macro_rules! serial_print {
|
|||||||
macro_rules! serial_println {
|
macro_rules! serial_println {
|
||||||
() => ($crate::serial_print!("\n"));
|
() => ($crate::serial_print!("\n"));
|
||||||
($fmt:expr) => ($crate::serial_print!(concat!($fmt, "\n")));
|
($fmt:expr) => ($crate::serial_print!(concat!($fmt, "\n")));
|
||||||
($fmt:expr, $($arg:tt)*) => ($crate::serial_print!(concat!($fmt, "\n"), $($arg)*));
|
($fmt:expr, $($arg:tt)*) => ($crate::serial_print!(
|
||||||
|
concat!($fmt, "\n"), $($arg)*));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,9 @@ use lazy_static::lazy_static;
|
|||||||
use spin::Mutex;
|
use spin::Mutex;
|
||||||
use volatile::Volatile;
|
use volatile::Volatile;
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
use crate::{serial_print, serial_println};
|
||||||
|
|
||||||
lazy_static! {
|
lazy_static! {
|
||||||
/// A global `Writer` instance that can be used for printing to the VGA text buffer.
|
/// A global `Writer` instance that can be used for printing to the VGA text buffer.
|
||||||
///
|
///
|
||||||
@@ -175,85 +178,32 @@ pub fn _print(args: fmt::Arguments) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[test_case]
|
||||||
mod test {
|
fn test_println_simple() {
|
||||||
use super::*;
|
serial_print!("test_println... ");
|
||||||
|
println!("test_println_simple output");
|
||||||
fn construct_writer() -> Writer {
|
serial_println!("[ok]");
|
||||||
use std::boxed::Box;
|
}
|
||||||
|
|
||||||
let buffer = construct_buffer();
|
#[test_case]
|
||||||
Writer {
|
fn test_println_many() {
|
||||||
column_position: 0,
|
serial_print!("test_println_many... ");
|
||||||
color_code: ColorCode::new(Color::Blue, Color::Magenta),
|
for _ in 0..200 {
|
||||||
buffer: Box::leak(Box::new(buffer)),
|
println!("test_println_many output");
|
||||||
}
|
}
|
||||||
}
|
serial_println!("[ok]");
|
||||||
|
}
|
||||||
fn construct_buffer() -> Buffer {
|
|
||||||
use array_init::array_init;
|
#[test_case]
|
||||||
|
fn test_println_output() {
|
||||||
Buffer {
|
serial_print!("test_println_output... ");
|
||||||
chars: array_init(|_| array_init(|_| Volatile::new(empty_char()))),
|
|
||||||
}
|
let s = "Some test string that fits on a single line";
|
||||||
}
|
println!("{}", s);
|
||||||
|
for (i, c) in s.chars().enumerate() {
|
||||||
fn empty_char() -> ScreenChar {
|
let screen_char = WRITER.lock().buffer.chars[BUFFER_HEIGHT - 2][i].read();
|
||||||
ScreenChar {
|
assert_eq!(char::from(screen_char.ascii_character), c);
|
||||||
ascii_character: b' ',
|
}
|
||||||
color_code: ColorCode::new(Color::Green, Color::Brown),
|
|
||||||
}
|
serial_println!("[ok]");
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn write_byte() {
|
|
||||||
let mut writer = construct_writer();
|
|
||||||
writer.write_byte(b'X');
|
|
||||||
writer.write_byte(b'Y');
|
|
||||||
|
|
||||||
for (i, row) in writer.buffer.chars.iter().enumerate() {
|
|
||||||
for (j, screen_char) in row.iter().enumerate() {
|
|
||||||
let screen_char = screen_char.read();
|
|
||||||
if i == BUFFER_HEIGHT - 1 && j == 0 {
|
|
||||||
assert_eq!(screen_char.ascii_character, b'X');
|
|
||||||
assert_eq!(screen_char.color_code, writer.color_code);
|
|
||||||
} else if i == BUFFER_HEIGHT - 1 && j == 1 {
|
|
||||||
assert_eq!(screen_char.ascii_character, b'Y');
|
|
||||||
assert_eq!(screen_char.color_code, writer.color_code);
|
|
||||||
} else {
|
|
||||||
assert_eq!(screen_char, empty_char());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn write_formatted() {
|
|
||||||
use core::fmt::Write;
|
|
||||||
|
|
||||||
let mut writer = construct_writer();
|
|
||||||
writeln!(&mut writer, "a").unwrap();
|
|
||||||
writeln!(&mut writer, "b{}", "c").unwrap();
|
|
||||||
|
|
||||||
for (i, row) in writer.buffer.chars.iter().enumerate() {
|
|
||||||
for (j, screen_char) in row.iter().enumerate() {
|
|
||||||
let screen_char = screen_char.read();
|
|
||||||
if i == BUFFER_HEIGHT - 3 && j == 0 {
|
|
||||||
assert_eq!(screen_char.ascii_character, b'a');
|
|
||||||
assert_eq!(screen_char.color_code, writer.color_code);
|
|
||||||
} else if i == BUFFER_HEIGHT - 2 && j == 0 {
|
|
||||||
assert_eq!(screen_char.ascii_character, b'b');
|
|
||||||
assert_eq!(screen_char.color_code, writer.color_code);
|
|
||||||
} else if i == BUFFER_HEIGHT - 2 && j == 1 {
|
|
||||||
assert_eq!(screen_char.ascii_character, b'c');
|
|
||||||
assert_eq!(screen_char.color_code, writer.color_code);
|
|
||||||
} else if i >= BUFFER_HEIGHT - 2 {
|
|
||||||
assert_eq!(screen_char.ascii_character, b' ');
|
|
||||||
assert_eq!(screen_char.color_code, writer.color_code);
|
|
||||||
} else {
|
|
||||||
assert_eq!(screen_char, empty_char());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
27
tests/basic_boot.rs
Normal file
27
tests/basic_boot.rs
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
#![no_std]
|
||||||
|
#![no_main]
|
||||||
|
#![feature(custom_test_frameworks)]
|
||||||
|
#![test_runner(blog_os::test_runner)]
|
||||||
|
#![reexport_test_harness_main = "test_main"]
|
||||||
|
|
||||||
|
use blog_os::{println, serial_print, serial_println};
|
||||||
|
use core::panic::PanicInfo;
|
||||||
|
|
||||||
|
#[no_mangle] // don't mangle the name of this function
|
||||||
|
pub extern "C" fn _start() -> ! {
|
||||||
|
test_main();
|
||||||
|
|
||||||
|
loop {}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[panic_handler]
|
||||||
|
fn panic(info: &PanicInfo) -> ! {
|
||||||
|
blog_os::test_panic_handler(info)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test_case]
|
||||||
|
fn test_println() {
|
||||||
|
serial_print!("test_println... ");
|
||||||
|
println!("test_println output");
|
||||||
|
serial_println!("[ok]");
|
||||||
|
}
|
||||||
72
tests/panic_handler.rs
Normal file
72
tests/panic_handler.rs
Normal file
@@ -0,0 +1,72 @@
|
|||||||
|
#![no_std]
|
||||||
|
#![no_main]
|
||||||
|
#![feature(panic_info_message)]
|
||||||
|
|
||||||
|
use blog_os::{exit_qemu, serial_print, serial_println, QemuExitCode};
|
||||||
|
use core::{
|
||||||
|
fmt::{self, Write},
|
||||||
|
panic::PanicInfo,
|
||||||
|
};
|
||||||
|
|
||||||
|
const MESSAGE: &str = "Example panic message from panic_handler test";
|
||||||
|
const PANIC_LINE: u32 = 17; // adjust this when moving the `panic!` call
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub extern "C" fn _start() -> ! {
|
||||||
|
serial_print!("panic_handler... ");
|
||||||
|
panic!(MESSAGE); // must be in line `PANIC_LINE`
|
||||||
|
}
|
||||||
|
|
||||||
|
#[panic_handler]
|
||||||
|
fn panic(info: &PanicInfo) -> ! {
|
||||||
|
check_location(info);
|
||||||
|
check_message(info);
|
||||||
|
|
||||||
|
serial_println!("[ok]");
|
||||||
|
exit_qemu(QemuExitCode::Success);
|
||||||
|
loop {}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn fail(error: &str) -> ! {
|
||||||
|
serial_println!("[failed]");
|
||||||
|
serial_println!("{}", error);
|
||||||
|
exit_qemu(QemuExitCode::Failed);
|
||||||
|
loop {}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn check_location(info: &PanicInfo) {
|
||||||
|
let location = info.location().unwrap_or_else(|| fail("no location"));
|
||||||
|
if location.file() != file!() {
|
||||||
|
fail("file name wrong");
|
||||||
|
}
|
||||||
|
if location.line() != PANIC_LINE {
|
||||||
|
fail("file line wrong");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn check_message(info: &PanicInfo) {
|
||||||
|
let message = info.message().unwrap_or_else(|| fail("no message"));
|
||||||
|
let mut compare_message = CompareMessage { equals: false };
|
||||||
|
write!(&mut compare_message, "{}", message).unwrap_or_else(|_| fail("write failed"));
|
||||||
|
if !compare_message.equals {
|
||||||
|
fail("message not equal to expected message");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Compares a `fmt::Arguments` instance with the `MESSAGE` string
|
||||||
|
///
|
||||||
|
/// To use this type, write the `fmt::Arguments` instance to it using the
|
||||||
|
/// `write` macro. If a message component matches `MESSAGE`, the equals
|
||||||
|
/// field is set to true.
|
||||||
|
struct CompareMessage {
|
||||||
|
equals: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl fmt::Write for CompareMessage {
|
||||||
|
fn write_str(&mut self, s: &str) -> fmt::Result {
|
||||||
|
if s == MESSAGE {
|
||||||
|
self.equals = true;
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,58 +1,36 @@
|
|||||||
#![feature(abi_x86_interrupt)]
|
|
||||||
#![no_std]
|
#![no_std]
|
||||||
#![cfg_attr(not(test), no_main)]
|
#![no_main]
|
||||||
#![cfg_attr(test, allow(dead_code, unused_macros, unused_imports))]
|
#![feature(abi_x86_interrupt)]
|
||||||
|
|
||||||
use blog_os::{exit_qemu, serial_println};
|
use blog_os::{exit_qemu, serial_print, serial_println, QemuExitCode};
|
||||||
use core::panic::PanicInfo;
|
use core::panic::PanicInfo;
|
||||||
use lazy_static::lazy_static;
|
use lazy_static::lazy_static;
|
||||||
|
use x86_64::structures::idt::{InterruptDescriptorTable, InterruptStackFrame};
|
||||||
|
|
||||||
#[cfg(not(test))]
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
#[allow(unconditional_recursion)]
|
|
||||||
pub extern "C" fn _start() -> ! {
|
pub extern "C" fn _start() -> ! {
|
||||||
|
serial_print!("stack_overflow... ");
|
||||||
|
|
||||||
blog_os::gdt::init();
|
blog_os::gdt::init();
|
||||||
init_test_idt();
|
init_test_idt();
|
||||||
|
|
||||||
fn stack_overflow() {
|
|
||||||
stack_overflow(); // for each recursion, the return address is pushed
|
|
||||||
}
|
|
||||||
|
|
||||||
// trigger a stack overflow
|
// trigger a stack overflow
|
||||||
stack_overflow();
|
stack_overflow();
|
||||||
|
|
||||||
serial_println!("failed");
|
panic!("Execution continued after stack overflow");
|
||||||
serial_println!("No exception occured");
|
|
||||||
|
|
||||||
unsafe {
|
|
||||||
exit_qemu();
|
|
||||||
}
|
|
||||||
|
|
||||||
loop {}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// This function is called on panic.
|
#[allow(unconditional_recursion)]
|
||||||
#[cfg(not(test))]
|
fn stack_overflow() {
|
||||||
#[panic_handler]
|
stack_overflow(); // for each recursion, the return address is pushed
|
||||||
fn panic(info: &PanicInfo) -> ! {
|
|
||||||
serial_println!("failed");
|
|
||||||
serial_println!("{}", info);
|
|
||||||
|
|
||||||
unsafe {
|
|
||||||
exit_qemu();
|
|
||||||
}
|
|
||||||
|
|
||||||
loop {}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
use x86_64::structures::idt::{InterruptDescriptorTable, InterruptStackFrame};
|
|
||||||
|
|
||||||
lazy_static! {
|
lazy_static! {
|
||||||
static ref TEST_IDT: InterruptDescriptorTable = {
|
static ref TEST_IDT: InterruptDescriptorTable = {
|
||||||
let mut idt = InterruptDescriptorTable::new();
|
let mut idt = InterruptDescriptorTable::new();
|
||||||
unsafe {
|
unsafe {
|
||||||
idt.double_fault
|
idt.double_fault
|
||||||
.set_handler_fn(double_fault_handler)
|
.set_handler_fn(test_double_fault_handler)
|
||||||
.set_stack_index(blog_os::gdt::DOUBLE_FAULT_IST_INDEX);
|
.set_stack_index(blog_os::gdt::DOUBLE_FAULT_IST_INDEX);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -64,14 +42,16 @@ pub fn init_test_idt() {
|
|||||||
TEST_IDT.load();
|
TEST_IDT.load();
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "x86-interrupt" fn double_fault_handler(
|
extern "x86-interrupt" fn test_double_fault_handler(
|
||||||
_stack_frame: &mut InterruptStackFrame,
|
_stack_frame: &mut InterruptStackFrame,
|
||||||
_error_code: u64,
|
_error_code: u64,
|
||||||
) {
|
) {
|
||||||
serial_println!("ok");
|
serial_println!("[ok]");
|
||||||
|
exit_qemu(QemuExitCode::Success);
|
||||||
unsafe {
|
|
||||||
exit_qemu();
|
|
||||||
}
|
|
||||||
loop {}
|
loop {}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[panic_handler]
|
||||||
|
fn panic(info: &PanicInfo) -> ! {
|
||||||
|
blog_os::test_panic_handler(info)
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user