Proper VGA driver, just missing print! / println! support.
This commit is contained in:
parent
49d7c3e508
commit
5a528f7508
@ -1,5 +1,5 @@
|
||||
[build]
|
||||
target = "x86_64-D.TinctoriusAzureaus.json"
|
||||
target = "x86_64-D.TinctoriusAzureus.json"
|
||||
|
||||
[target.'cfg(target_os = "none")']
|
||||
runner = "bootimage runner"
|
3
.gitignore
vendored
3
.gitignore
vendored
@ -6,3 +6,6 @@
|
||||
#Cargo.lock
|
||||
# These are backup files generated by rustfmt
|
||||
**/*.rs.bk
|
||||
bootimage-kernel.iso
|
||||
kernel.sym
|
||||
bochsout.txt
|
@ -1,7 +1,23 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module type="CPP_MODULE" version="4">
|
||||
<component name="NewModuleRootManager">
|
||||
<content url="file://$MODULE_DIR$" />
|
||||
<content url="file://$MODULE_DIR$">
|
||||
<sourceFolder url="file://$MODULE_DIR$/kernel/src" isTestSource="false" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/kernel/examples" isTestSource="false" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/kernel/tests" isTestSource="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/kernel/benches" isTestSource="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/examples" isTestSource="false" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/tests" isTestSource="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/benches" isTestSource="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/vga_buffer/src" isTestSource="false" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/vga_buffer/examples" isTestSource="false" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/vga_buffer/tests" isTestSource="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/vga_buffer/benches" isTestSource="true" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/kernel/target" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/target" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vga_buffer/target" />
|
||||
</content>
|
||||
<orderEntry type="inheritedJdk" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
</component>
|
||||
|
@ -10,17 +10,23 @@
|
||||
</component>
|
||||
<component name="CargoProjects">
|
||||
<cargoProject FILE="$PROJECT_DIR$/Cargo.toml" />
|
||||
<cargoProject FILE="$PROJECT_DIR$/vga_buffer/Cargo.toml" />
|
||||
</component>
|
||||
<component name="ChangeListManager">
|
||||
<list default="true" id="7ddf063a-3554-4ac7-a5a5-6e243077d67d" name="Default Changelist" comment="">
|
||||
<change afterPath="$PROJECT_DIR$/.cargo/config" afterDir="false" />
|
||||
<change afterPath="$PROJECT_DIR$/rust-toolchain" afterDir="false" />
|
||||
<change afterPath="$PROJECT_DIR$/x86_64-D.TinctoriusAzureaus.json" afterDir="false" />
|
||||
<change afterPath="$PROJECT_DIR$/src/main.rs" afterDir="false" />
|
||||
<change afterPath="$PROJECT_DIR$/vga_buffer/Cargo.toml" afterDir="false" />
|
||||
<change afterPath="$PROJECT_DIR$/vga_buffer/src/lib.rs" afterDir="false" />
|
||||
<change afterPath="$PROJECT_DIR$/x86_64-D.TinctoriusAzureus.json" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/.cargo/config" beforeDir="false" afterPath="$PROJECT_DIR$/.cargo/config" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/.gitignore" beforeDir="false" afterPath="$PROJECT_DIR$/.gitignore" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/.idea/DendrobatesTinctoriusAzureus.iml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/DendrobatesTinctoriusAzureus.iml" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/Cargo.lock" beforeDir="false" afterPath="$PROJECT_DIR$/Cargo.lock" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/Cargo.toml" beforeDir="false" afterPath="$PROJECT_DIR$/Cargo.toml" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/kernel/Cargo.toml" beforeDir="false" afterPath="$PROJECT_DIR$/kernel/Cargo.toml" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/kernel/src/main.rs" beforeDir="false" afterPath="$PROJECT_DIR$/kernel/src/main.rs" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/kernel/Cargo.toml" beforeDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/kernel/src/main.rs" beforeDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/x86_64-D.TinctoriusAzureaus.json" beforeDir="false" />
|
||||
</list>
|
||||
<option name="EXCLUDED_CONVERTED_TO_IGNORED" value="true" />
|
||||
<option name="SHOW_DIALOG" value="false" />
|
||||
@ -31,6 +37,13 @@
|
||||
<component name="ClangdSettings">
|
||||
<option name="formatViaClangd" value="false" />
|
||||
</component>
|
||||
<component name="FileTemplateManagerImpl">
|
||||
<option name="RECENT_TEMPLATES">
|
||||
<list>
|
||||
<option value="Rust File" />
|
||||
</list>
|
||||
</option>
|
||||
</component>
|
||||
<component name="Git.Settings">
|
||||
<option name="RECENT_GIT_ROOT_PATH" value="$PROJECT_DIR$" />
|
||||
</component>
|
||||
@ -47,8 +60,16 @@
|
||||
<property name="node.js.path.for.package.tslint" value="project" />
|
||||
<property name="node.js.selected.package.eslint" value="(autodetect)" />
|
||||
<property name="node.js.selected.package.tslint" value="(autodetect)" />
|
||||
<property name="nodejs_package_manager_path" value="npm" />
|
||||
<property name="org.rust.cargo.project.model.PROJECT_DISCOVERY" value="true" />
|
||||
<property name="settings.editor.selected.configurable" value="language.rust.rustfmt" />
|
||||
<property name="org.rust.hideDetachedFileNotifications/Volumes/Pepins/Users/guillaumedidier/Documents/Etudes/PhD/CPUDissector/DendrobatesTinctoriusAzureus/vga_buffer/src/lib.rs" value="true" />
|
||||
<property name="settings.editor.selected.configurable" value="language.rust.cargo" />
|
||||
</component>
|
||||
<component name="RunAnythingCache">
|
||||
<option name="myCommands">
|
||||
<command value="cargo clippy" />
|
||||
<command value="cargo xclippy" />
|
||||
</option>
|
||||
</component>
|
||||
<component name="RunDashboard">
|
||||
<option name="ruleStates">
|
||||
@ -64,26 +85,65 @@
|
||||
</component>
|
||||
<component name="RunManager" selected="Cargo Command.Build kernel">
|
||||
<configuration name="Build kernel" type="CargoCommandRunConfiguration" factoryName="Cargo Command">
|
||||
<option name="channel" value="NIGHTLY" />
|
||||
<option name="channel" value="DEFAULT" />
|
||||
<option name="command" value="xbuild" />
|
||||
<option name="allFeatures" value="false" />
|
||||
<option name="nocapture" value="false" />
|
||||
<option name="emulateTerminal" value="true" />
|
||||
<option name="backtrace" value="SHORT" />
|
||||
<option name="workingDirectory" value="file://$PROJECT_DIR$/kernel" />
|
||||
<option name="workingDirectory" value="file://$PROJECT_DIR$" />
|
||||
<envs />
|
||||
<method v="2">
|
||||
<option name="CARGO.BUILD_TASK_PROVIDER" enabled="true" />
|
||||
</method>
|
||||
</configuration>
|
||||
<configuration name="Clean" type="CargoCommandRunConfiguration" factoryName="Cargo Command">
|
||||
<option name="channel" value="DEFAULT" />
|
||||
<option name="command" value="clean" />
|
||||
<option name="allFeatures" value="false" />
|
||||
<option name="nocapture" value="false" />
|
||||
<option name="emulateTerminal" value="true" />
|
||||
<option name="backtrace" value="SHORT" />
|
||||
<option name="workingDirectory" value="file://$PROJECT_DIR$" />
|
||||
<envs />
|
||||
<method v="2">
|
||||
<option name="CARGO.BUILD_TASK_PROVIDER" enabled="true" />
|
||||
</method>
|
||||
</configuration>
|
||||
<configuration name="Clippy" type="CargoCommandRunConfiguration" factoryName="Cargo Command">
|
||||
<option name="channel" value="DEFAULT" />
|
||||
<option name="command" value="xclippy" />
|
||||
<option name="allFeatures" value="false" />
|
||||
<option name="nocapture" value="false" />
|
||||
<option name="emulateTerminal" value="false" />
|
||||
<option name="backtrace" value="SHORT" />
|
||||
<option name="workingDirectory" value="file://$PROJECT_DIR$" />
|
||||
<envs />
|
||||
<method v="2">
|
||||
<option name="CARGO.BUILD_TASK_PROVIDER" enabled="true" />
|
||||
</method>
|
||||
</configuration>
|
||||
<configuration name="Expand dendrobates_tinctoreus_azureus" type="CargoCommandRunConfiguration" factoryName="Cargo Command" temporary="true">
|
||||
<option name="channel" value="DEFAULT" />
|
||||
<option name="command" value="expand --bin dendrobates_tinctoreus_azureus --color=always --theme=GitHub --tests" />
|
||||
<option name="allFeatures" value="false" />
|
||||
<option name="nocapture" value="false" />
|
||||
<option name="emulateTerminal" value="false" />
|
||||
<option name="backtrace" value="SHORT" />
|
||||
<option name="workingDirectory" value="file://$PROJECT_DIR$" />
|
||||
<envs />
|
||||
<method v="2">
|
||||
<option name="CARGO.BUILD_TASK_PROVIDER" enabled="true" />
|
||||
</method>
|
||||
</configuration>
|
||||
<configuration name="Run kernel" type="CargoCommandRunConfiguration" factoryName="Cargo Command" temporary="true">
|
||||
<option name="channel" value="NIGHTLY" />
|
||||
<option name="channel" value="DEFAULT" />
|
||||
<option name="command" value="xrun" />
|
||||
<option name="allFeatures" value="false" />
|
||||
<option name="nocapture" value="false" />
|
||||
<option name="emulateTerminal" value="true" />
|
||||
<option name="backtrace" value="SHORT" />
|
||||
<option name="workingDirectory" value="file://$PROJECT_DIR$/kernel" />
|
||||
<option name="workingDirectory" value="file://$PROJECT_DIR$" />
|
||||
<envs />
|
||||
<method v="2">
|
||||
<option name="CARGO.BUILD_TASK_PROVIDER" enabled="true" />
|
||||
@ -96,17 +156,22 @@
|
||||
<option name="nocapture" value="false" />
|
||||
<option name="emulateTerminal" value="true" />
|
||||
<option name="backtrace" value="SHORT" />
|
||||
<option name="workingDirectory" value="file://$PROJECT_DIR$" />
|
||||
<envs />
|
||||
<method v="2">
|
||||
<option name="CARGO.BUILD_TASK_PROVIDER" enabled="true" />
|
||||
</method>
|
||||
</configuration>
|
||||
<list>
|
||||
<item itemvalue="Cargo Command.Clippy" />
|
||||
<item itemvalue="Cargo Command.Build kernel" />
|
||||
<item itemvalue="Cargo Command.Clean" />
|
||||
<item itemvalue="Cargo Command.Run kernel" />
|
||||
<item itemvalue="Cargo Command.Expand dendrobates_tinctoreus_azureus" />
|
||||
</list>
|
||||
<recent_temporary>
|
||||
<list>
|
||||
<item itemvalue="Cargo Command.Expand dendrobates_tinctoreus_azureus" />
|
||||
<item itemvalue="Cargo Command.Run kernel" />
|
||||
</list>
|
||||
</recent_temporary>
|
||||
@ -116,6 +181,7 @@
|
||||
<option name="runExternalLinterOnTheFly" value="true" />
|
||||
<option name="runRustfmtOnSave" value="true" />
|
||||
<option name="toolchainHomeDirectory" value="$USER_HOME$/.cargo/bin" />
|
||||
<option name="version" value="2" />
|
||||
</component>
|
||||
<component name="SvnConfiguration">
|
||||
<configuration />
|
||||
@ -128,6 +194,10 @@
|
||||
<option name="presentableId" value="Default" />
|
||||
<updated>1569934487744</updated>
|
||||
<workItem from="1569934492535" duration="5355000" />
|
||||
<workItem from="1570003006617" duration="2487000" />
|
||||
<workItem from="1570093731306" duration="4682000" />
|
||||
<workItem from="1570347619224" duration="2476000" />
|
||||
<workItem from="1570370780740" duration="3966000" />
|
||||
</task>
|
||||
<task id="LOCAL-00001" summary="Add CLion config files">
|
||||
<created>1569934966982</created>
|
||||
@ -147,7 +217,9 @@
|
||||
<map>
|
||||
<entry key="MAIN">
|
||||
<value>
|
||||
<State />
|
||||
<State>
|
||||
<option name="COLUMN_ORDER" />
|
||||
</State>
|
||||
</value>
|
||||
</entry>
|
||||
</map>
|
||||
|
86
Cargo.lock
generated
86
Cargo.lock
generated
@ -1,10 +1,28 @@
|
||||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
[[package]]
|
||||
name = "array-init"
|
||||
version = "0.0.4"
|
||||
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]]
|
||||
name = "bit_field"
|
||||
version = "0.9.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "bit_field"
|
||||
version = "0.10.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "bitflags"
|
||||
version = "1.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "bootloader"
|
||||
version = "0.8.1"
|
||||
@ -14,12 +32,78 @@ dependencies = [
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "kernel"
|
||||
name = "cast"
|
||||
version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "dendrobates_tinctoreus_azureus"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"bootloader 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"vga_buffer 0.1.0",
|
||||
"x86_64 0.7.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "lazy_static"
|
||||
version = "1.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"spin 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "nodrop"
|
||||
version = "0.1.13"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "spin"
|
||||
version = "0.5.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "ux"
|
||||
version = "0.1.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "vga_buffer"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"spin 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"volatile 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "volatile"
|
||||
version = "0.2.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "x86_64"
|
||||
version = "0.7.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"array-init 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"bit_field 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"bitflags 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"cast 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"ux 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[metadata]
|
||||
"checksum array-init 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "23589ecb866b460d3a0f1278834750268c607e8e28a1b982c907219f3178cd72"
|
||||
"checksum bit_field 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a165d606cf084741d4ac3a28fb6e9b1eb0bd31f6cd999098cfddb0b2ab381dc0"
|
||||
"checksum bit_field 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ed8765909f9009617974ab6b7d332625b320b33c326b1e9321382ef1999b5d56"
|
||||
"checksum bitflags 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8a606a02debe2813760609f57a64a2ffd27d9fdf5b2f133eaca0b248dd92cdd2"
|
||||
"checksum bootloader 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "45dd858bd74a742ec0fe887722952c263abd0825aa8d33a3704917a97d7bd41e"
|
||||
"checksum cast 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "926013f2860c46252efceabb19f4a6b308197505082c609025aa6706c011d427"
|
||||
"checksum lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
|
||||
"checksum nodrop 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)" = "2f9667ddcc6cc8a43afc9b7917599d7216aa09c463919ea32c59ed6cac8bc945"
|
||||
"checksum spin 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d"
|
||||
"checksum ux 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "88dfeb711b61ce620c0cb6fd9f8e3e678622f0c971da2a63c4b3e25e88ed012f"
|
||||
"checksum volatile 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "6af0edf5b4faacc31fc51159244d78d65ec580f021afcef7bd53c04aeabc7f29"
|
||||
"checksum x86_64 0.7.5 (registry+https://github.com/rust-lang/crates.io-index)" = "997837f3913aac8f67164683258756d712376849906c8d609f844084bc03ef84"
|
||||
|
25
Cargo.toml
25
Cargo.toml
@ -1,6 +1,29 @@
|
||||
[workspace]
|
||||
|
||||
members = [
|
||||
"kernel",
|
||||
"vga_buffer",
|
||||
]
|
||||
|
||||
[package]
|
||||
name = "dendrobates_tinctoreus_azureus"
|
||||
version = "0.1.0"
|
||||
authors = ["Guillaume DIDIER <guillaume.didier.2014@polytechnique.org>"]
|
||||
edition = "2018"
|
||||
|
||||
[package.metadata.bootimage]
|
||||
run-command = ["./scripts/bochs.sh", "{}"]
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
x86_64 = "0.7.5"
|
||||
vga_buffer = { path = "vga_buffer" }
|
||||
|
||||
[dependencies.bootloader]
|
||||
version = "^0.8.1"
|
||||
features = ["sse"]
|
||||
|
||||
|
||||
[profile.dev]
|
||||
opt-level = 0
|
||||
debug = 2
|
||||
|
@ -1,28 +0,0 @@
|
||||
// main.rs
|
||||
// main file of the kernel
|
||||
|
||||
#![no_std]
|
||||
#![no_main]
|
||||
|
||||
use core::panic::PanicInfo;
|
||||
|
||||
#[panic_handler]
|
||||
fn panic(_info: &PanicInfo) -> ! {
|
||||
loop {}
|
||||
}
|
||||
|
||||
static HELLO: &[u8] = b"Hello Frog!";
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn _start() -> ! {
|
||||
let vga_buffer = 0xb8000 as *mut u8;
|
||||
|
||||
for (i, &byte) in HELLO.iter().enumerate() {
|
||||
unsafe {
|
||||
*vga_buffer.offset(i as isize * 2) = byte;
|
||||
*vga_buffer.offset(i as isize * 2 + 1) = 0xb;
|
||||
}
|
||||
}
|
||||
|
||||
loop {}
|
||||
}
|
7
scripts/bochs.sh
Executable file
7
scripts/bochs.sh
Executable file
@ -0,0 +1,7 @@
|
||||
#!/bin/sh
|
||||
set -e
|
||||
#bootimage build
|
||||
dd if=/dev/zero of=target/x86_64-D.TinctoriusAzureus/debug/bootimage-kernel.iso count=1008 bs=512
|
||||
dd if=$1 of=target/x86_64-D.TinctoriusAzureus/debug/bootimage-kernel.iso conv=notrunc
|
||||
./scripts/syms.sh target/x86_64-D.TinctoriusAzureus/debug/dendrobates_tinctoreus_azureus
|
||||
bochs -f scripts/bochsrc
|
1263
scripts/bochsrc
Normal file
1263
scripts/bochsrc
Normal file
File diff suppressed because it is too large
Load Diff
7
scripts/gdb.sh
Normal file
7
scripts/gdb.sh
Normal file
@ -0,0 +1,7 @@
|
||||
#!/bin/sh
|
||||
set -me
|
||||
bootimage build
|
||||
qemu-system-x86_64 -drive format=raw,file=target/x86_64-solstice/debug/bootimage-solstice.bin -no-reboot -S -s &
|
||||
sleep 0.5
|
||||
gdb target/x86_64-solstice/debug/solstice -ex "target remote :1234"
|
||||
pkill qemu
|
1
scripts/syms.sh
Executable file
1
scripts/syms.sh
Executable file
@ -0,0 +1 @@
|
||||
nm target/x86_64-D.TinctoriusAzureus/debug/dendrobates_tinctoreus_azureus | grep -i " T " | awk '{ print $1" "$3 }' > kernel.sym
|
86
src/main.rs
Normal file
86
src/main.rs
Normal file
@ -0,0 +1,86 @@
|
||||
// main.rs
|
||||
// main file of the kernel
|
||||
|
||||
#![no_std] // This is a free standing program
|
||||
#![no_main] // This has no crt0
|
||||
|
||||
use core::fmt::Write;
|
||||
use core::panic::PanicInfo; // required for custom panic handler
|
||||
|
||||
use x86_64;
|
||||
|
||||
use vga_buffer;
|
||||
|
||||
// Custom panic handler, required for freestanding program
|
||||
#[panic_handler]
|
||||
fn panic(_info: &PanicInfo) -> ! {
|
||||
loop {}
|
||||
}
|
||||
|
||||
// static greeting string, for hello world kernel
|
||||
static HELLO: &[u8] = b"Hello Blue Frog!";
|
||||
|
||||
static YES: &[u8] = b"yes";
|
||||
static NO: &[u8] = b"no";
|
||||
|
||||
static a: f64 = 420.0;
|
||||
static b: f64 = 42.0;
|
||||
|
||||
static d: f64 = 0.1;
|
||||
|
||||
// Kernel entry point
|
||||
#[no_mangle]
|
||||
pub extern "C" fn _start() -> ! {
|
||||
// TODO: Take care of cpuid stuff and set-up all floating point exetnsions
|
||||
// TODO: We may also need to enable debug registers ?
|
||||
|
||||
let vga_buffer = 0xb8000 as *mut u8;
|
||||
|
||||
for (i, &byte) in HELLO.iter().enumerate() {
|
||||
unsafe {
|
||||
*vga_buffer.offset(i as isize * 2) = byte;
|
||||
*vga_buffer.offset(i as isize * 2 + 1) = 0xb;
|
||||
}
|
||||
}
|
||||
// magic break ?
|
||||
x86_64::instructions::bochs_breakpoint();
|
||||
let c = a * d;
|
||||
x86_64::instructions::bochs_breakpoint();
|
||||
if b == c {
|
||||
for (i, &byte) in YES.iter().enumerate() {
|
||||
unsafe {
|
||||
*vga_buffer.offset(i as isize * 2) = byte;
|
||||
*vga_buffer.offset(i as isize * 2 + 1) = 0xb;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (i, &byte) in NO.iter().enumerate() {
|
||||
unsafe {
|
||||
*vga_buffer.offset(i as isize * 2) = byte;
|
||||
*vga_buffer.offset(i as isize * 2 + 1) = 0xb;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
x86_64::instructions::bochs_breakpoint();
|
||||
|
||||
writeln!(
|
||||
vga_buffer::WRITER.lock(),
|
||||
"The numbers are {} and {}",
|
||||
42,
|
||||
1.0 / 3.0
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
writeln!(
|
||||
vga_buffer::WRITER.lock(),
|
||||
"a is {}, b is {}, c is {}, d is {}",
|
||||
a,
|
||||
b,
|
||||
c,
|
||||
d
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
loop {}
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
[package]
|
||||
name = "kernel"
|
||||
name = "vga_buffer"
|
||||
version = "0.1.0"
|
||||
authors = ["Guillaume DIDIER <guillaume.didier.2014@polytechnique.org>"]
|
||||
edition = "2018"
|
||||
@ -7,7 +7,9 @@ edition = "2018"
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
volatile = "0.2.6"
|
||||
spin = "0.5.2"
|
||||
|
||||
[dependencies.bootloader]
|
||||
version = "^0.8.1"
|
||||
features = ["sse"]
|
||||
[dependencies.lazy_static]
|
||||
version = "1.0"
|
||||
features = ["spin_no_std"]
|
274
vga_buffer/src/lib.rs
Normal file
274
vga_buffer/src/lib.rs
Normal file
@ -0,0 +1,274 @@
|
||||
#![no_std] // This is a free standing program
|
||||
|
||||
use core::fmt;
|
||||
use core::intrinsics::transmute;
|
||||
use lazy_static::lazy_static;
|
||||
use spin::Mutex;
|
||||
use volatile::Volatile;
|
||||
|
||||
pub const BUFFER_HEIGHT: usize = 25;
|
||||
pub const BUFFER_WIDTH: usize = 80;
|
||||
|
||||
const BRIGHT_BIT: u8 = 0x4;
|
||||
const EMPTY_CHAR: u8 = b' ';
|
||||
const NEWLINE_CHAR: u8 = b'\n';
|
||||
const BACKSPACE_CHAR: u8 = 0x8;
|
||||
const UNPRINTABLE_CHAR: u8 = 0xfe;
|
||||
|
||||
const PRINTABLE_RANGE_START: u8 = 0x20;
|
||||
const PRINTABLE_RANGE_STOP: u8 = 0x7f;
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
#[test]
|
||||
fn it_works() {
|
||||
assert_eq!(2 + 2, 4);
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
#[repr(u8)]
|
||||
pub enum Color {
|
||||
Black = 0x0,
|
||||
Blue = 0x1,
|
||||
Green = 0x2,
|
||||
Cyan = 0x3,
|
||||
Red = 0x4,
|
||||
Magenta = 0x5,
|
||||
Brown = 0x6,
|
||||
LightGray = 0x7,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
#[repr(u8)]
|
||||
pub enum ForegroundColor {
|
||||
Black = 0x0,
|
||||
Blue = 0x1,
|
||||
Green = 0x2,
|
||||
Cyan = 0x3,
|
||||
Red = 0x4,
|
||||
Magenta = 0x5,
|
||||
Brown = 0x6,
|
||||
LightGray = 0x7,
|
||||
DarkGray = 0x8,
|
||||
LightBlue = 0x9,
|
||||
LightGreen = 0xa,
|
||||
LightCyan = 0xb,
|
||||
LightRed = 0xc,
|
||||
Pink = 0xd,
|
||||
Yellow = 0xe,
|
||||
White = 0xf,
|
||||
}
|
||||
|
||||
impl ForegroundColor {
|
||||
pub fn new(color: Color, bright: bool) -> ForegroundColor {
|
||||
if bright {
|
||||
unsafe { transmute(BRIGHT_BIT | (color as u8)) }
|
||||
} else {
|
||||
unsafe { transmute(color) }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Color> for ForegroundColor {
|
||||
fn from(color: Color) -> Self {
|
||||
unsafe { transmute(color) }
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
#[repr(transparent)]
|
||||
pub struct ColorCode(u8);
|
||||
|
||||
impl ColorCode {
|
||||
fn new_with_blink(foreground: ForegroundColor, background: Color, blink: bool) -> ColorCode {
|
||||
ColorCode((foreground as u8) | (blink as u8) << 7 | (background as u8) << 4)
|
||||
}
|
||||
|
||||
fn new(foreground: ForegroundColor, background: Color) -> ColorCode {
|
||||
ColorCode::new_with_blink(foreground, background, false)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
#[repr(C)]
|
||||
pub struct ScreenChar {
|
||||
ascii_char: u8,
|
||||
color_code: ColorCode,
|
||||
}
|
||||
|
||||
#[repr(transparent)]
|
||||
struct Buffer {
|
||||
chars: [[Volatile<ScreenChar>; BUFFER_WIDTH]; BUFFER_HEIGHT],
|
||||
}
|
||||
|
||||
// The writer could eventually also show the cursor
|
||||
|
||||
pub struct Writer {
|
||||
column_position: usize,
|
||||
row_position: usize,
|
||||
color_code: ColorCode,
|
||||
buffer: &'static mut Buffer,
|
||||
}
|
||||
|
||||
impl Writer {
|
||||
fn new(color_code: ColorCode, buffer: &'static mut Buffer) -> Writer {
|
||||
let mut w = Writer {
|
||||
column_position: 0,
|
||||
row_position: 0,
|
||||
color_code: color_code,
|
||||
buffer: buffer,
|
||||
};
|
||||
w.clear_screen();
|
||||
w
|
||||
}
|
||||
|
||||
fn clear_screen(&mut self) {
|
||||
for i in 0..BUFFER_HEIGHT {
|
||||
for j in 0..BUFFER_WIDTH {
|
||||
self.draw(
|
||||
i,
|
||||
j,
|
||||
ScreenChar {
|
||||
ascii_char: EMPTY_CHAR,
|
||||
color_code: self.color_code,
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn getchar(&self, row: usize, col: usize) -> ScreenChar {
|
||||
self.buffer.chars[row][col].read()
|
||||
}
|
||||
|
||||
fn draw(&mut self, row: usize, col: usize, sc: ScreenChar) {
|
||||
self.buffer.chars[row][col].write(sc);
|
||||
}
|
||||
|
||||
fn scroll(&mut self) {
|
||||
for i in 0..BUFFER_HEIGHT - 1 {
|
||||
for j in 0..BUFFER_WIDTH {
|
||||
let sc = self.getchar(i + 1, j);
|
||||
self.draw(i, j, sc);
|
||||
}
|
||||
}
|
||||
for j in 0..BUFFER_WIDTH {
|
||||
self.draw(
|
||||
BUFFER_HEIGHT - 1,
|
||||
j,
|
||||
ScreenChar {
|
||||
ascii_char: EMPTY_CHAR,
|
||||
color_code: self.color_code,
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
fn set_cursor_row(&mut self, row_position: usize) {
|
||||
assert!(row_position < BUFFER_HEIGHT);
|
||||
self.row_position = row_position;
|
||||
}
|
||||
|
||||
fn set_cursor_col(&mut self, column_position: usize) {
|
||||
assert!(column_position < BUFFER_WIDTH);
|
||||
self.column_position = column_position;
|
||||
}
|
||||
|
||||
fn cursor_offset(&mut self, offset: isize) {
|
||||
let mut line_pos: isize = offset + self.column_position as isize;
|
||||
let mut height_pos: isize = self.row_position as isize;
|
||||
while line_pos < 0 {
|
||||
height_pos -= 1;
|
||||
line_pos += BUFFER_WIDTH as isize;
|
||||
}
|
||||
|
||||
while line_pos >= BUFFER_WIDTH as isize {
|
||||
height_pos += 1;
|
||||
line_pos -= BUFFER_WIDTH as isize;
|
||||
}
|
||||
|
||||
while height_pos >= BUFFER_HEIGHT as isize {
|
||||
height_pos -= 1;
|
||||
self.scroll();
|
||||
}
|
||||
|
||||
if height_pos < 0 {
|
||||
height_pos = 0;
|
||||
line_pos = 0;
|
||||
}
|
||||
assert!(height_pos >= 0);
|
||||
assert!(line_pos >= 0);
|
||||
self.set_cursor_col(line_pos as usize);
|
||||
self.set_cursor_row(height_pos as usize);
|
||||
}
|
||||
|
||||
fn put_byte(&mut self, byte: u8) {
|
||||
match byte {
|
||||
NEWLINE_CHAR => {
|
||||
// Empty line
|
||||
for i in self.column_position..BUFFER_WIDTH {
|
||||
self.draw(
|
||||
self.row_position,
|
||||
i,
|
||||
ScreenChar {
|
||||
ascii_char: EMPTY_CHAR,
|
||||
color_code: self.color_code,
|
||||
},
|
||||
);
|
||||
}
|
||||
self.set_cursor_col(0);
|
||||
self.cursor_offset(BUFFER_WIDTH as isize)
|
||||
}
|
||||
BACKSPACE_CHAR => {
|
||||
self.draw(
|
||||
self.row_position,
|
||||
self.column_position,
|
||||
ScreenChar {
|
||||
ascii_char: EMPTY_CHAR,
|
||||
color_code: self.color_code,
|
||||
},
|
||||
);
|
||||
self.cursor_offset(-1);
|
||||
}
|
||||
byte => {
|
||||
self.draw(
|
||||
self.row_position,
|
||||
self.column_position,
|
||||
ScreenChar {
|
||||
ascii_char: byte,
|
||||
color_code: self.color_code,
|
||||
},
|
||||
);
|
||||
self.cursor_offset(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn put_bytes(&mut self, s: &str) {
|
||||
for byte in s.bytes() {
|
||||
match byte {
|
||||
// printable ASCII byte or newline
|
||||
PRINTABLE_RANGE_START..=PRINTABLE_RANGE_STOP | NEWLINE_CHAR | BACKSPACE_CHAR => {
|
||||
self.put_byte(byte)
|
||||
}
|
||||
// not part of printable ASCII range
|
||||
_ => self.put_byte(UNPRINTABLE_CHAR),
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Write for Writer {
|
||||
fn write_str(&mut self, s: &str) -> fmt::Result {
|
||||
self.put_bytes(s);
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
lazy_static! {
|
||||
pub static ref WRITER: Mutex<Writer> = Mutex::new(Writer::new(
|
||||
ColorCode::new(ForegroundColor::Yellow, Color::Blue),
|
||||
unsafe { &mut *(0xb8000 as *mut Buffer) },
|
||||
));
|
||||
}
|
Loading…
Reference in New Issue
Block a user