Skip to content
Snippets Groups Projects
Commit b21393cc authored by Eemeli Lehtonen's avatar Eemeli Lehtonen
Browse files

framebuffer logger + some ansi escapes

parent 8c51bd1a
No related branches found
No related tags found
No related merge requests found
......@@ -41,6 +41,7 @@ target/limine/limine-deploy $KERNEL.iso
if [ "$(basename $KERNEL)" = "hyperion" ]; then
# Run the created image with QEMU.
qemu-system-x86_64 \
-enable-kvm \
-machine q35 \
-cpu qemu64 \
-M smm=off \
......@@ -55,6 +56,7 @@ else
set +e
# Run the created image with QEMU.
qemu-system-x86_64 \
-enable-kvm \
-machine q35 \
-cpu qemu64 \
-M smm=off \
......
......@@ -2,6 +2,12 @@
# It is not intended for manual editing.
version = 3
[[package]]
name = "adler"
version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe"
[[package]]
name = "autocfg"
version = "1.1.0"
......@@ -20,10 +26,196 @@ version = "1.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
[[package]]
name = "bumpalo"
version = "3.11.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "572f695136211188308f16ad2ca5c851a712c464060ae6974944458eb83880ba"
[[package]]
name = "bytemuck"
version = "1.12.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "aaa3a8d9a1ca92e282c96a32d6511b695d7d994d1d102ba85d279f9b2756947f"
[[package]]
name = "byteorder"
version = "1.4.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610"
[[package]]
name = "cfg-if"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "color_quant"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3d7b894f5411737b7867f4827955924d7c254fc9f4d91a6aad6b097804b1018b"
[[package]]
name = "crc32fast"
version = "1.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d"
dependencies = [
"cfg-if",
]
[[package]]
name = "crossbeam-channel"
version = "0.5.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c2dd04ddaf88237dc3b8d8f9a3c1004b506b54b3313403944054d23c0870c521"
dependencies = [
"cfg-if",
"crossbeam-utils",
]
[[package]]
name = "crossbeam-deque"
version = "0.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "715e8152b692bba2d374b53d4875445368fdf21a94751410af607a5ac677d1fc"
dependencies = [
"cfg-if",
"crossbeam-epoch",
"crossbeam-utils",
]
[[package]]
name = "crossbeam-epoch"
version = "0.9.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "01a9af1f4c2ef74bb8aa1f7e19706bc72d03598c8a570bb5de72243c7a9d9d5a"
dependencies = [
"autocfg",
"cfg-if",
"crossbeam-utils",
"memoffset",
"scopeguard",
]
[[package]]
name = "crossbeam-utils"
version = "0.8.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4fb766fa798726286dbbb842f174001dab8abc7b627a1dd86e0b7222a95d929f"
dependencies = [
"cfg-if",
]
[[package]]
name = "crunchy"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7"
[[package]]
name = "either"
version = "1.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "90e5c1c8368803113bf0c9584fc495a58b86dc8a29edbf8fe877d21d9507e797"
[[package]]
name = "exr"
version = "1.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8eb5f255b5980bb0c8cf676b675d1a99be40f316881444f44e0462eaf5df5ded"
dependencies = [
"bit_field",
"flume",
"half",
"lebe",
"miniz_oxide",
"smallvec",
"threadpool",
]
[[package]]
name = "flate2"
version = "1.0.25"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a8a2db397cb1c8772f31494cb8917e48cd1e64f0fa7efac59fbd741a0a8ce841"
dependencies = [
"crc32fast",
"miniz_oxide",
]
[[package]]
name = "flume"
version = "0.10.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1657b4441c3403d9f7b3409e47575237dac27b1b5726df654a6ecbf92f0f7577"
dependencies = [
"futures-core",
"futures-sink",
"nanorand",
"pin-project",
"spin",
]
[[package]]
name = "futures-core"
version = "0.3.25"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "04909a7a7e4633ae6c4a9ab280aeb86da1236243a77b694a49eacd659a4bd3ac"
[[package]]
name = "futures-sink"
version = "0.3.25"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "39c15cf1a4aa79df40f1bb462fb39676d0ad9e366c2a33b590d7c66f4f81fcf9"
[[package]]
name = "getrandom"
version = "0.2.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c05aeb6a22b8f62540c194aac980f2115af067bfe15a0734d7277a768d396b31"
dependencies = [
"cfg-if",
"js-sys",
"libc",
"wasi",
"wasm-bindgen",
]
[[package]]
name = "gif"
version = "0.11.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3edd93c6756b4dfaf2709eafcc345ba2636565295c198a9cfbf75fa5e3e00b06"
dependencies = [
"color_quant",
"weezl",
]
[[package]]
name = "half"
version = "2.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "02b4af3693f1b705df946e9fe5631932443781d0aabb423b62fcd4d73f6d2fd0"
dependencies = [
"crunchy",
]
[[package]]
name = "hermit-abi"
version = "0.2.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ee512640fe35acbfb4bb779db6f0d80704c2cacfa2e39b601ef3e3f47d1ae4c7"
dependencies = [
"libc",
]
[[package]]
name = "hyperion"
version = "0.1.0"
dependencies = [
"image",
"limine",
"spin",
"uart_16550",
......@@ -31,6 +223,55 @@ dependencies = [
"x86_64",
]
[[package]]
name = "image"
version = "0.24.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "69b7ea949b537b0fd0af141fff8c77690f2ce96f4f41f042ccb6c69c6c965945"
dependencies = [
"bytemuck",
"byteorder",
"color_quant",
"exr",
"gif",
"jpeg-decoder",
"num-rational",
"num-traits",
"png",
"scoped_threadpool",
"tiff",
]
[[package]]
name = "jpeg-decoder"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bc0000e42512c92e31c2252315bda326620a4e034105e900c98ec492fa077b3e"
dependencies = [
"rayon",
]
[[package]]
name = "js-sys"
version = "0.3.60"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "49409df3e3bf0856b916e2ceaca09ee28e6871cf7d9ce97a692cacfdb2a25a47"
dependencies = [
"wasm-bindgen",
]
[[package]]
name = "lebe"
version = "0.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "03087c2bad5e1034e8cace5926dec053fb3790248370865f5117a7d0213354c8"
[[package]]
name = "libc"
version = "0.2.139"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "201de327520df007757c1f0adce6e827fe8562fbc28bfd9c15571c66ca1f5f79"
[[package]]
name = "limine"
version = "0.1.9"
......@@ -47,18 +288,184 @@ dependencies = [
"scopeguard",
]
[[package]]
name = "log"
version = "0.4.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e"
dependencies = [
"cfg-if",
]
[[package]]
name = "memoffset"
version = "0.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5de893c32cde5f383baa4c04c5d6dbdd735cfd4a794b0debdb2bb1b421da5ff4"
dependencies = [
"autocfg",
]
[[package]]
name = "miniz_oxide"
version = "0.6.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b275950c28b37e794e8c55d88aeb5e139d0ce23fdbbeda68f8d7174abdf9e8fa"
dependencies = [
"adler",
]
[[package]]
name = "nanorand"
version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6a51313c5820b0b02bd422f4b44776fbf47961755c74ce64afc73bfad10226c3"
dependencies = [
"getrandom",
]
[[package]]
name = "num-integer"
version = "0.1.45"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "225d3389fb3509a24c93f5c29eb6bde2586b98d9f016636dff58d7c6f7569cd9"
dependencies = [
"autocfg",
"num-traits",
]
[[package]]
name = "num-rational"
version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0638a1c9d0a3c0914158145bc76cff373a75a627e6ecbfb71cbe6f453a5a19b0"
dependencies = [
"autocfg",
"num-integer",
"num-traits",
]
[[package]]
name = "num-traits"
version = "0.2.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "578ede34cf02f8924ab9447f50c28075b4d3e5b269972345e7e0372b38c6cdcd"
dependencies = [
"autocfg",
]
[[package]]
name = "num_cpus"
version = "1.15.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0fac9e2da13b5eb447a6ce3d392f23a29d8694bff781bf03a16cd9ac8697593b"
dependencies = [
"hermit-abi",
"libc",
]
[[package]]
name = "once_cell"
version = "1.17.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6f61fba1741ea2b3d6a1e3178721804bb716a68a6aeba1149b5d52e3d464ea66"
[[package]]
name = "pin-project"
version = "1.0.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ad29a609b6bcd67fee905812e544992d216af9d755757c05ed2d0e15a74c6ecc"
dependencies = [
"pin-project-internal",
]
[[package]]
name = "pin-project-internal"
version = "1.0.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "069bdb1e05adc7a8990dce9cc75370895fbe4e3d58b9b73bf1aee56359344a55"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "png"
version = "0.17.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5d708eaf860a19b19ce538740d2b4bdeeb8337fa53f7738455e706623ad5c638"
dependencies = [
"bitflags",
"crc32fast",
"flate2",
"miniz_oxide",
]
[[package]]
name = "proc-macro2"
version = "1.0.49"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "57a8eca9f9c4ffde41714334dee777596264c7825420f521abc92b5b5deb63a5"
dependencies = [
"unicode-ident",
]
[[package]]
name = "quote"
version = "1.0.23"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8856d8364d252a14d474036ea1358d63c9e6965c8e5c1885c18f73d70bff9c7b"
dependencies = [
"proc-macro2",
]
[[package]]
name = "rayon"
version = "1.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6db3a213adf02b3bcfd2d3846bb41cb22857d131789e01df434fb7e7bc0759b7"
dependencies = [
"either",
"rayon-core",
]
[[package]]
name = "rayon-core"
version = "1.10.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cac410af5d00ab6884528b4ab69d1e8e146e8d471201800fa1b4524126de6ad3"
dependencies = [
"crossbeam-channel",
"crossbeam-deque",
"crossbeam-utils",
"num_cpus",
]
[[package]]
name = "rustversion"
version = "1.0.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5583e89e108996506031660fe09baa5011b9dd0341b89029313006d1fb508d70"
[[package]]
name = "scoped_threadpool"
version = "0.1.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1d51f5df5af43ab3f1360b429fa5e0152ac5ce8c0bd6485cae490332e96846a8"
[[package]]
name = "scopeguard"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
[[package]]
name = "smallvec"
version = "1.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a507befe795404456341dfab10cef66ead4c041f62b8b11bbb92bffe5d0953e0"
[[package]]
name = "spin"
version = "0.9.4"
......@@ -68,6 +475,37 @@ dependencies = [
"lock_api",
]
[[package]]
name = "syn"
version = "1.0.107"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1f4064b5b16e03ae50984a5a8ed5d4f8803e6bc1fd170a3cda91a1be4b18e3f5"
dependencies = [
"proc-macro2",
"quote",
"unicode-ident",
]
[[package]]
name = "threadpool"
version = "1.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d050e60b33d41c19108b32cea32164033a9013fe3b46cbd4457559bfbf77afaa"
dependencies = [
"num_cpus",
]
[[package]]
name = "tiff"
version = "0.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7449334f9ff2baf290d55d73983a7d6fa15e01198faef72af07e2a8db851e471"
dependencies = [
"flate2",
"jpeg-decoder",
"weezl",
]
[[package]]
name = "uart_16550"
version = "0.2.18"
......@@ -79,12 +517,84 @@ dependencies = [
"x86_64",
]
[[package]]
name = "unicode-ident"
version = "1.0.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "84a22b9f218b40614adcb3f4ff08b703773ad44fa9423e4e0d346d5db86e4ebc"
[[package]]
name = "volatile"
version = "0.4.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e3ca98349dda8a60ae74e04fd90c7fb4d6a4fbe01e6d3be095478aa0b76f6c0c"
[[package]]
name = "wasi"
version = "0.11.0+wasi-snapshot-preview1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
[[package]]
name = "wasm-bindgen"
version = "0.2.83"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "eaf9f5aceeec8be17c128b2e93e031fb8a4d469bb9c4ae2d7dc1888b26887268"
dependencies = [
"cfg-if",
"wasm-bindgen-macro",
]
[[package]]
name = "wasm-bindgen-backend"
version = "0.2.83"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4c8ffb332579b0557b52d268b91feab8df3615f265d5270fec2a8c95b17c1142"
dependencies = [
"bumpalo",
"log",
"once_cell",
"proc-macro2",
"quote",
"syn",
"wasm-bindgen-shared",
]
[[package]]
name = "wasm-bindgen-macro"
version = "0.2.83"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "052be0f94026e6cbc75cdefc9bae13fd6052cdcaf532fa6c45e7ae33a1e6c810"
dependencies = [
"quote",
"wasm-bindgen-macro-support",
]
[[package]]
name = "wasm-bindgen-macro-support"
version = "0.2.83"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "07bc0c051dc5f23e307b13285f9d75df86bfdf816c5721e573dec1f9b8aa193c"
dependencies = [
"proc-macro2",
"quote",
"syn",
"wasm-bindgen-backend",
"wasm-bindgen-shared",
]
[[package]]
name = "wasm-bindgen-shared"
version = "0.2.83"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1c38c045535d93ec4f0b4defec448e4291638ee608530863b1e2ba115d4fff7f"
[[package]]
name = "weezl"
version = "0.1.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9193164d4de03a926d909d3bc7c30543cecb35400c02114792c2cae20d5e2dbb"
[[package]]
name = "x86_64"
version = "0.14.10"
......
......@@ -23,3 +23,6 @@ x86_64 = "0.14.10"
uart_16550 = "0.2.18"
limine = { version = "0.1.9", optional = true }
#tracing = { version = "0.1.37", default-features = false }
[build-dependencies]
image = "0.24.5"
use std::{
env::var,
error::Error,
fs::{self, File, OpenOptions},
io::Read,
fs::{self, File},
io::Write,
path::PathBuf,
process::Command,
};
//
......@@ -43,30 +40,56 @@ fn main() -> Result<(), Box<dyn Error>> {
panic!();
};
let unifont_path = "target/hyperion/unifont.bmp";
let read_unifont = || {
let mut file = OpenOptions::new()
.read(true)
.create(false)
.write(false)
.open(unifont_path)?;
// generate kernel font from the bitmap image
let mut buf = Vec::new();
file.read_to_end(buf)?;
Ok::<_, Box<dyn Error>>(buf)
};
let unifont = if let Ok(file) = read_unifont() {
file
} else {
Command::new("wget")
.arg("http://unifoundry.com/pub/unifont/unifont-15.0.01/unifont-15.0.01.bmp")
.args(["-O", unifont_path])
.spawn()
let bmp_date = fs::metadata("./src/video/font.bmp")
.unwrap()
.modified()
.unwrap();
let rs_date = fs::metadata("./src/video/font.rs")
.unwrap()
.modified()
.unwrap();
// panic!("{bmp_date:?} {rs_date:?}");
if bmp_date > rs_date {
let mut generated_rs = File::options()
.write(true)
.truncate(true)
.open("./src/video/font.rs")
.unwrap();
read_unifont().unwrap()
};
let bmp = image::open("./src/video/font.bmp").unwrap().to_luma8();
assert_eq!(bmp.width(), 4096);
assert_eq!(bmp.height(), 16);
write!(
generated_rs,
"pub static FONT: [([u16; 16], bool); 256] = ["
)
.unwrap();
for i in 0..=255_u8 {
let mut byte = ([0u16; 16], false);
bmp.chunks(16)
.skip(i as usize)
.step_by(256)
.enumerate()
.for_each(|(i, s)| {
s.iter().enumerate().for_each(|(j, b)| {
if *b != 255 {
byte.0[i] |= 1 << j
}
})
});
// set the flag if the character is 16 wide instead of 8 wide
byte.1 = !byte.0.iter().all(|c| *c < 0x100);
write!(generated_rs, "\n\t{byte:?},").unwrap();
}
write!(generated_rs, "\n];").unwrap();
}
Ok(())
}
......@@ -27,7 +27,43 @@ extern "x86-interrupt" fn double_fault(stack: InterruptStackFrame, ec: u64) -> !
// TODO: This won't be safe when multiple CPUs are running
crate::qemu::unlock();
}
panic!("INT: Double fault ({ec})\n{stack:#?}")
crate::qemu::_print(format_args_nl!("INT: Double fault ({ec})\n{stack:#?}"));
let mut sp = stack.stack_pointer.as_ptr() as *const [u8; 8];
for i in 0isize..256 {
let sp = unsafe { sp.offset(i) };
let bytes: [u8; 8] = unsafe { *sp };
let graphic = |c: u8| {
if c.is_ascii_graphic() {
c as char
} else {
'.'
}
};
crate::qemu::_print(format_args_nl!(
"{:#x}: {:02x} {:02x} {:02x} {:02x} {:02x} {:02x} {:02x} {:02x} {}{}{}{}{}{}{}{}",
sp as usize,
bytes[0],
bytes[1],
bytes[2],
bytes[3],
bytes[4],
bytes[5],
bytes[6],
bytes[7],
graphic(bytes[0]),
graphic(bytes[1]),
graphic(bytes[2]),
graphic(bytes[3]),
graphic(bytes[4]),
graphic(bytes[5]),
graphic(bytes[6]),
graphic(bytes[7]),
));
}
panic!();
}
//
......
use crate::{
println,
video::framebuffer::{Framebuffer, FBO},
video::framebuffer::{get_fbo, Framebuffer, FramebufferInfo, FBO},
};
use core::slice;
use limine::LimineFramebufferRequest;
......@@ -24,14 +24,17 @@ pub fn init() {
let buf = unsafe { slice::from_raw_parts_mut(fb.address.as_ptr()?, fb.size()) };
Some(Framebuffer {
buf,
width: fb.width as _,
height: fb.height as _,
pitch: fb.pitch as _,
info: FramebufferInfo {
width: fb.width as _,
height: fb.height as _,
pitch: fb.pitch as _,
},
})
});
if let Some(fbo) = fbo {
if let Some(mut fbo) = fbo {
fbo.clear();
FBO.call_once(|| Mutex::new(fbo));
}
println!("Global framebuffer {:#?}", FBO.get())
println!("Global framebuffer: {:#?}", get_fbo().map(|f| f.info))
}
......@@ -18,9 +18,6 @@ pub extern "C" fn _start() -> ! {
framebuffer::init();
// the initial terminal logger crashes if used after initializing GDT and IDT
crate::log::disable_term();
gdt::init();
idt::init();
......
......@@ -19,12 +19,20 @@ macro_rules! println {
//
pub fn enable_term() {
LOGGER.term.store(true, Ordering::SeqCst);
// pub fn enable_term() {
// LOGGER.term.store(true, Ordering::SeqCst);
// }
//
// pub fn disable_term() {
// LOGGER.term.store(false, Ordering::SeqCst);
// }
pub fn enable_fbo() {
LOGGER.fbo.store(true, Ordering::SeqCst);
}
pub fn disable_term() {
LOGGER.term.store(false, Ordering::SeqCst);
pub fn disable_fbo() {
LOGGER.fbo.store(false, Ordering::SeqCst);
}
pub fn enable_qemu() {
......@@ -40,24 +48,34 @@ pub fn disable_qemu() {
static LOGGER: Lazy<Logger> = Lazy::new(Logger::init);
struct Logger {
term: AtomicBool,
// Log to a bootloader given terminal
// term: AtomicBool,
// Log to a framebuffer
fbo: AtomicBool,
// Log to a QEMU serial
qemu: AtomicBool,
}
impl Logger {
fn init() -> Self {
Logger {
term: true.into(),
// term: false.into(),
fbo: true.into(),
qemu: true.into(),
}
}
fn print(&self, args: Arguments) {
// if self.term.load(Ordering::SeqCst) {
// crate::arch::boot::_print(args);
// }
if self.qemu.load(Ordering::SeqCst) {
crate::qemu::_print(args);
}
if self.term.load(Ordering::SeqCst) {
crate::arch::boot::_print(args);
if self.fbo.load(Ordering::SeqCst) {
crate::video::logger::_print(args);
}
}
}
......
......@@ -11,7 +11,10 @@
use spin::Mutex;
use crate::video::framebuffer::{Color, FBO};
use crate::{
term::escape::encode::EscapeEncoder,
video::framebuffer::{get_fbo, Color, FBO},
};
//
......@@ -20,6 +23,7 @@ pub mod arch;
pub mod log;
pub mod panic;
pub mod qemu;
pub mod term;
#[cfg(test)]
pub mod testfw;
pub mod video;
......@@ -39,8 +43,8 @@ pub static BOOTLOADER: Mutex<&'static str> = Mutex::new(KERNEL);
//
fn kernel_main() -> ! {
println!("Hello from {KERNEL}");
println!(" - {KERNEL} was booted with {}", BOOTLOADER.lock());
println!("Hello from {}", KERNEL.cyan());
println!(" - {} was booted with {}", KERNEL.cyan(), BOOTLOADER.lock());
// error handling test
// stack_overflow(79999999);
......@@ -48,13 +52,10 @@ fn kernel_main() -> ! {
// *(0xFFFFFFFFDEADC0DE as *mut u8) = 42;
// }
if let Some(fbo) = FBO.get() {
let mut fbo = fbo.lock();
fbo.fill(40, 40, 40, 40, Color::RED);
fbo.fill(50, 50, 60, 40, Color::GREEN);
fbo.fill(5, 15, 80, 20, Color::BLUE);
fbo.put_bytes(100, 100, b"ABABABAB\0", Color::WHITE, Color::BLACK);
if let Some(mut fbo) = get_fbo() {
fbo.fill(240, 240, 40, 40, Color::RED);
fbo.fill(250, 250, 60, 40, Color::GREEN);
fbo.fill(205, 215, 80, 20, Color::BLUE);
}
#[cfg(test)]
......
......@@ -13,9 +13,6 @@ pub fn _print(args: Arguments) {
}
/// Unlocks the COM1 writer IF it is locked by this exact thread
///
/// SAFETY: this is unsafe unless called from the same thread, this is intended for double fault
/// handling
pub unsafe fn unlock() {
// TODO: SMP
// if COM1_LOCKER.load(Ordering::SeqCst) != crate::THREAD {
......
This diff is collapsed.
use super::font::FONT;
use core::fmt;
use spin::{Mutex, Once};
use core::{
fmt,
ops::{Deref, DerefMut},
};
use spin::{Lazy, Mutex, MutexGuard, Once};
//
......@@ -8,9 +11,20 @@ pub static FBO: Once<Mutex<Framebuffer>> = Once::new();
//
pub fn get_fbo() -> Option<MutexGuard<'static, Framebuffer>> {
FBO.get().map(|mtx| mtx.lock())
}
//
pub struct Framebuffer {
pub buf: &'static mut [u8],
pub info: FramebufferInfo,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
pub struct FramebufferInfo {
pub width: usize, // not the pixels to the next row
pub height: usize,
pub pitch: usize, // pixels to the next row
......@@ -39,24 +53,51 @@ impl Framebuffer {
}
}
pub fn put_byte(&mut self, x: usize, y: usize, ch: u8, fg: Color, bg: Color) {
let map = FONT[ch as usize];
pub fn put_byte(&mut self, x: usize, y: usize, ch: u8, fg: Color, bg: Color) -> bool {
let (map, double_wide) = FONT[ch as usize];
for (yd, row) in map.into_iter().enumerate() {
for xd in 0..8 {
self.set(
x + xd,
y + yd,
if (row & 1 << (7 - xd)) != 0 { fg } else { bg },
);
for xd in 0..if double_wide { 16 } else { 8 } {
self.set(x + xd, y + yd, if (row & 1 << xd) != 0 { fg } else { bg });
}
}
double_wide
}
pub fn put_bytes(&mut self, x: usize, y: usize, s: &[u8], fg: Color, bg: Color) {
for (offs, ch) in s.iter().enumerate() {
self.put_byte(x + 12 * offs, y, *ch, fg, bg)
pub fn scroll(&mut self, h: usize) {
for y in h..self.height {
let two_rows = &mut self.buf[(y - 1) * self.info.pitch..(y + 1) * self.info.pitch];
self.buf.copy_within(
y * self.info.pitch..(y + 1) * self.info.pitch,
(y - h) * self.info.pitch,
);
}
self.buf[(self.info.height - h) * self.info.pitch..].fill(0);
}
pub fn clear(&mut self) {
self.buf.fill(0);
}
pub fn info(&self) -> FramebufferInfo {
self.info
}
}
impl Deref for Framebuffer {
type Target = FramebufferInfo;
fn deref(&self) -> &Self::Target {
&self.info
}
}
impl DerefMut for Framebuffer {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.info
}
}
......@@ -72,21 +113,56 @@ impl Color {
Self { r, g, b }
}
pub const fn as_u32(&self) -> u32 {
u32::from_ne_bytes([self.r, self.g, self.b, 0])
pub const fn from_u32(code: u32) -> Self {
let [r, g, b, _] = code.to_ne_bytes();
Self::new(r, g, b)
}
pub const fn as_arr(&self) -> [u8; 4] {
[self.r, self.g, self.b, 0]
pub const fn from_hex(hex_code: &str) -> Self {
Self::from_hex_bytes(hex_code.as_bytes())
}
pub const fn from_hex_bytes(hex_code: &[u8]) -> Self {
match hex_code {
[r0, r1, g0, g1, b0, b1, _, _]
| [r0, r1, g0, g1, b0, b1]
| [b'#', r0, r1, g0, g1, b0, b1, _, _]
| [b'#', r0, r1, g0, g1, b0, b1] => {
Self::from_hex_bytes_2([*r0, *r1, *g0, *g1, *b0, *b1])
}
_ => {
panic!("Invalid color hex code")
}
}
}
pub const fn from_hex_bytes_2(hex_code: [u8; 6]) -> Self {
const fn parse_hex_char(c: u8) -> u8 {
match c {
b'0'..=b'9' => c - b'0',
b'a'..=b'f' => c - b'a' + 0xa,
_ => c,
}
}
const fn parse_byte(str_byte: [u8; 2]) -> u8 {
parse_hex_char(str_byte[0]) | parse_hex_char(str_byte[1]) << 4
}
let r = parse_byte([hex_code[0], hex_code[1]]);
let g = parse_byte([hex_code[2], hex_code[3]]);
let b = parse_byte([hex_code[4], hex_code[5]]);
Self::new(r, g, b)
}
}
impl fmt::Debug for Framebuffer {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("Framebuffer")
.field("width", &self.width)
.field("height", &self.height)
.field("pitch", &self.pitch)
.finish_non_exhaustive()
pub const fn as_u32(&self) -> u32 {
// self.b as u32 | (self.g as u32) << 8 | (self.r as u32) << 16
u32::from_le_bytes([self.b, self.g, self.r, 0])
}
pub const fn as_arr(&self) -> [u8; 4] {
self.as_u32().to_ne_bytes()
// [self.r, self.g, self.b, 0]
}
}
pub mod font;
pub mod framebuffer;
pub mod logger;
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment