add basic script repl

This commit is contained in:
Matthieu Jolimaitre 2024-10-25 01:44:27 +02:00
parent 0d1a12202f
commit a2cca0be4e
15 changed files with 1041 additions and 61 deletions

View file

@ -3,7 +3,7 @@
target = ["x86_64-nulfos.json"] target = ["x86_64-nulfos.json"]
[unstable] [unstable]
build-std = ["core", "compiler_builtins"] build-std = ["core", "compiler_builtins", "alloc"]
build-std-features = ["compiler-builtins-mem"] build-std-features = ["compiler-builtins-mem"]
[target.'cfg(target_os = "none")'] [target.'cfg(target_os = "none")']

516
Cargo.lock generated
View file

@ -2,6 +2,33 @@
# It is not intended for manual editing. # It is not intended for manual editing.
version = 4 version = 4
[[package]]
name = "ahash"
version = "0.8.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011"
dependencies = [
"cfg-if",
"once_cell",
"version_check",
"zerocopy",
]
[[package]]
name = "aho-corasick"
version = "1.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916"
dependencies = [
"memchr",
]
[[package]]
name = "allocator-api2"
version = "0.2.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5c6cb57a04249c6480766f7f7cef5467412af1490f8d1e243141daddada3264f"
[[package]] [[package]]
name = "autocfg" name = "autocfg"
version = "1.4.0" version = "1.4.0"
@ -20,12 +47,74 @@ version = "2.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de"
[[package]]
name = "blinkcast"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "87be723831f9bfa47f0bc5b28edd97cbd8002726289d8bfd6dfdc1cd895e06d9"
dependencies = [
"loom",
]
[[package]] [[package]]
name = "bootloader" name = "bootloader"
version = "0.9.29" version = "0.9.29"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "365861702868e2a37b4247aaecc7bd8f4389baec8d025497ad8ba7ff37ee9440" checksum = "365861702868e2a37b4247aaecc7bd8f4389baec8d025497ad8ba7ff37ee9440"
[[package]]
name = "cfg-if"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "chumsky"
version = "0.9.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8eebd66744a15ded14960ab4ccdbfb51ad3b81f51f3f04a80adac98c985396c9"
dependencies = [
"hashbrown 0.14.5",
]
[[package]]
name = "foldhash"
version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f81ec6369c545a7d40e4589b5597581fa1c441fe1cce96dd1de43159910a36a2"
[[package]]
name = "generator"
version = "0.8.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dbb949699c3e4df3a183b1d2142cb24277057055ed23c68ed58894f76c517223"
dependencies = [
"cfg-if",
"libc",
"log",
"rustversion",
"windows",
]
[[package]]
name = "hashbrown"
version = "0.14.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1"
dependencies = [
"ahash",
"allocator-api2",
]
[[package]]
name = "hashbrown"
version = "0.15.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1e087f84d4f86bf4b218b927129862374b72199ae7d8657835f1e89000eea4fb"
dependencies = [
"foldhash",
]
[[package]] [[package]]
name = "lazy_static" name = "lazy_static"
version = "1.5.0" version = "1.5.0"
@ -35,6 +124,18 @@ dependencies = [
"spin", "spin",
] ]
[[package]]
name = "libc"
version = "0.2.161"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8e9489c2807c139ffd9c1794f4af0ebe86a828db53ecdc7fea2111d0fed085d1"
[[package]]
name = "libm"
version = "0.2.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4ec2a862134d2a7d32d7983ddcdd1c4923530833c9f2ea1a44fc5fa473989058"
[[package]] [[package]]
name = "linked_list_allocator" name = "linked_list_allocator"
version = "0.10.5" version = "0.10.5"
@ -54,18 +155,86 @@ dependencies = [
"scopeguard", "scopeguard",
] ]
[[package]]
name = "log"
version = "0.4.22"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24"
[[package]]
name = "loom"
version = "0.7.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "419e0dc8046cb947daa77eb95ae174acfbddb7673b4151f56d1eed8e93fbfaca"
dependencies = [
"cfg-if",
"generator",
"scoped-tls",
"tracing",
"tracing-subscriber",
]
[[package]]
name = "matchers"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8263075bb86c5a1b1427b5ae862e8889656f126e9f77c484496e8b47cf5c5558"
dependencies = [
"regex-automata 0.1.10",
]
[[package]]
name = "memchr"
version = "2.7.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3"
[[package]]
name = "microlang"
version = "0.1.0"
source = "git+https://git.barnulf.net/mb/microlang.git#3868298f006b58dd1df2c4d615e044d5698846f7"
dependencies = [
"chumsky",
"hashbrown 0.15.0",
"libm",
]
[[package]]
name = "nu-ansi-term"
version = "0.46.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "77a8165726e8236064dbb45459242600304b42a5ea24ee2948e18e023bf7ba84"
dependencies = [
"overload",
"winapi",
]
[[package]] [[package]]
name = "nulfos" name = "nulfos"
version = "0.1.0" version = "0.1.0"
dependencies = [ dependencies = [
"blinkcast",
"bootloader", "bootloader",
"lazy_static", "lazy_static",
"linked_list_allocator", "linked_list_allocator",
"microlang",
"pic8259", "pic8259",
"spin", "spin",
"x86_64", "x86_64",
] ]
[[package]]
name = "once_cell"
version = "1.20.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775"
[[package]]
name = "overload"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39"
[[package]] [[package]]
name = "pic8259" name = "pic8259"
version = "0.11.0" version = "0.11.0"
@ -75,18 +244,107 @@ dependencies = [
"x86_64", "x86_64",
] ]
[[package]]
name = "pin-project-lite"
version = "0.2.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "915a1e146535de9163f3987b8944ed8cf49a18bb0056bcebcdcece385cece4ff"
[[package]]
name = "proc-macro2"
version = "1.0.89"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f139b0662de085916d1fb67d2b4169d1addddda1919e696f3252b740b629986e"
dependencies = [
"unicode-ident",
]
[[package]]
name = "quote"
version = "1.0.37"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af"
dependencies = [
"proc-macro2",
]
[[package]]
name = "regex"
version = "1.11.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191"
dependencies = [
"aho-corasick",
"memchr",
"regex-automata 0.4.8",
"regex-syntax 0.8.5",
]
[[package]]
name = "regex-automata"
version = "0.1.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132"
dependencies = [
"regex-syntax 0.6.29",
]
[[package]]
name = "regex-automata"
version = "0.4.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "368758f23274712b504848e9d5a6f010445cc8b87a7cdb4d7cbee666c1288da3"
dependencies = [
"aho-corasick",
"memchr",
"regex-syntax 0.8.5",
]
[[package]]
name = "regex-syntax"
version = "0.6.29"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1"
[[package]]
name = "regex-syntax"
version = "0.8.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c"
[[package]] [[package]]
name = "rustversion" name = "rustversion"
version = "1.0.18" version = "1.0.18"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0e819f2bc632f285be6d7cd36e25940d45b2391dd6d9b939e79de557f7014248" checksum = "0e819f2bc632f285be6d7cd36e25940d45b2391dd6d9b939e79de557f7014248"
[[package]]
name = "scoped-tls"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e1cf6437eb19a8f4a6cc0f7dca544973b0b78843adbfeb3683d1a94a0024a294"
[[package]] [[package]]
name = "scopeguard" name = "scopeguard"
version = "1.2.0" version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
[[package]]
name = "sharded-slab"
version = "0.1.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6"
dependencies = [
"lazy_static",
]
[[package]]
name = "smallvec"
version = "1.13.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67"
[[package]] [[package]]
name = "spin" name = "spin"
version = "0.9.8" version = "0.9.8"
@ -105,12 +363,250 @@ dependencies = [
"lock_api", "lock_api",
] ]
[[package]]
name = "syn"
version = "2.0.85"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5023162dfcd14ef8f32034d8bcd4cc5ddc61ef7a247c024a33e24e1f24d21b56"
dependencies = [
"proc-macro2",
"quote",
"unicode-ident",
]
[[package]]
name = "thread_local"
version = "1.1.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8b9ef9bad013ada3808854ceac7b46812a6465ba368859a37e2100283d2d719c"
dependencies = [
"cfg-if",
"once_cell",
]
[[package]]
name = "tracing"
version = "0.1.40"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef"
dependencies = [
"pin-project-lite",
"tracing-core",
]
[[package]]
name = "tracing-core"
version = "0.1.32"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54"
dependencies = [
"once_cell",
"valuable",
]
[[package]]
name = "tracing-log"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ee855f1f400bd0e5c02d150ae5de3840039a3f54b025156404e34c23c03f47c3"
dependencies = [
"log",
"once_cell",
"tracing-core",
]
[[package]]
name = "tracing-subscriber"
version = "0.3.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ad0f048c97dbd9faa9b7df56362b8ebcaa52adb06b498c050d2f4e32f90a7a8b"
dependencies = [
"matchers",
"nu-ansi-term",
"once_cell",
"regex",
"sharded-slab",
"smallvec",
"thread_local",
"tracing",
"tracing-core",
"tracing-log",
]
[[package]]
name = "unicode-ident"
version = "1.0.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e91b56cd4cadaeb79bbf1a5645f6b4f8dc5bde8834ad5894a8db35fda9efa1fe"
[[package]]
name = "valuable"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d"
[[package]]
name = "version_check"
version = "0.9.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a"
[[package]] [[package]]
name = "volatile" name = "volatile"
version = "0.4.6" version = "0.4.6"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "442887c63f2c839b346c192d047a7c87e73d0689c9157b00b53dcc27dd5ea793" checksum = "442887c63f2c839b346c192d047a7c87e73d0689c9157b00b53dcc27dd5ea793"
[[package]]
name = "winapi"
version = "0.3.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
dependencies = [
"winapi-i686-pc-windows-gnu",
"winapi-x86_64-pc-windows-gnu",
]
[[package]]
name = "winapi-i686-pc-windows-gnu"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
[[package]]
name = "winapi-x86_64-pc-windows-gnu"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
[[package]]
name = "windows"
version = "0.58.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dd04d41d93c4992d421894c18c8b43496aa748dd4c081bac0dc93eb0489272b6"
dependencies = [
"windows-core",
"windows-targets",
]
[[package]]
name = "windows-core"
version = "0.58.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6ba6d44ec8c2591c134257ce647b7ea6b20335bf6379a27dac5f1641fcf59f99"
dependencies = [
"windows-implement",
"windows-interface",
"windows-result",
"windows-strings",
"windows-targets",
]
[[package]]
name = "windows-implement"
version = "0.58.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2bbd5b46c938e506ecbce286b6628a02171d56153ba733b6c741fc627ec9579b"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "windows-interface"
version = "0.58.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "053c4c462dc91d3b1504c6fe5a726dd15e216ba718e84a0e46a88fbe5ded3515"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "windows-result"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1d1043d8214f791817bab27572aaa8af63732e11bf84aa21a45a78d6c317ae0e"
dependencies = [
"windows-targets",
]
[[package]]
name = "windows-strings"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4cd9b125c486025df0eabcb585e62173c6c9eddcec5d117d3b6e8c30e2ee4d10"
dependencies = [
"windows-result",
"windows-targets",
]
[[package]]
name = "windows-targets"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973"
dependencies = [
"windows_aarch64_gnullvm",
"windows_aarch64_msvc",
"windows_i686_gnu",
"windows_i686_gnullvm",
"windows_i686_msvc",
"windows_x86_64_gnu",
"windows_x86_64_gnullvm",
"windows_x86_64_msvc",
]
[[package]]
name = "windows_aarch64_gnullvm"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3"
[[package]]
name = "windows_aarch64_msvc"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469"
[[package]]
name = "windows_i686_gnu"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b"
[[package]]
name = "windows_i686_gnullvm"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66"
[[package]]
name = "windows_i686_msvc"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66"
[[package]]
name = "windows_x86_64_gnu"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78"
[[package]]
name = "windows_x86_64_gnullvm"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d"
[[package]]
name = "windows_x86_64_msvc"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
[[package]] [[package]]
name = "x86_64" name = "x86_64"
version = "0.15.1" version = "0.15.1"
@ -122,3 +618,23 @@ dependencies = [
"rustversion", "rustversion",
"volatile", "volatile",
] ]
[[package]]
name = "zerocopy"
version = "0.7.35"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0"
dependencies = [
"zerocopy-derive",
]
[[package]]
name = "zerocopy-derive"
version = "0.7.35"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e"
dependencies = [
"proc-macro2",
"quote",
"syn",
]

View file

@ -10,6 +10,8 @@ linked_list_allocator = "0.10.5"
pic8259 = "0.11.0" pic8259 = "0.11.0"
spin = "0.9.8" spin = "0.9.8"
x86_64 = "0.15.1" x86_64 = "0.15.1"
microlang = { git = "https://git.barnulf.net/mb/microlang.git" }
blinkcast = "0.2.0"
# artefact configuration # artefact configuration

9
setup
View file

@ -4,3 +4,12 @@ set -e
rustup target add x86_64-unknown-none rustup target add x86_64-unknown-none
rustup component add rust-src rustup component add rust-src
rustup component add llvm-tools-preview rustup component add llvm-tools-preview
if ! cargo bootimage --help > /dev/null 2>&1
then echo "
WARNING cargo-bootimage is not installed.
Get it from your package manager or run :
cargo install cargo-bootimage
" && exit 1
fi

View file

@ -1,6 +0,0 @@
use crate::println;
pub fn init() {
println!("Initializing Allocator.");
// TODO
}

View file

@ -1,7 +1,7 @@
use core::fmt; use core::fmt;
use lazy_static::lazy_static; use lazy_static::lazy_static;
use spin::Mutex; use spin::{Mutex, MutexGuard};
use crate::hard::vga::{self, Vga}; use crate::hard::vga::{self, Vga};
@ -17,12 +17,16 @@ macro_rules! println {
} }
lazy_static! { lazy_static! {
static ref Out: Mutex<Console> = Mutex::new(Console::init()); static ref OUT: Mutex<Console> = Mutex::new(Console::init());
}
pub fn out<'r>() -> MutexGuard<'r, Console> {
OUT.lock()
} }
pub struct Console { pub struct Console {
cursor: Cursor, pub cursor: Cursor,
vga: Vga, pub vga: Vga,
} }
impl Console { impl Console {
@ -44,6 +48,11 @@ impl Console {
} }
} }
} }
pub fn correct(&mut self) {
self.cursor.set_col((self.cursor.col().max(1) - 1));
self.vga.write_at(self.cursor.pos(), ' ');
}
} }
struct Cursor { struct Cursor {
@ -67,14 +76,6 @@ impl Cursor {
(self.column, self.line) (self.column, self.line)
} }
pub fn set_line(&mut self, line: usize) {
self.line = line;
}
pub fn set_col(&mut self, col: usize) {
self.column = col;
}
pub fn line(&self) -> usize { pub fn line(&self) -> usize {
self.line self.line
} }
@ -83,6 +84,18 @@ impl Cursor {
self.column self.column
} }
pub fn set_pos(&mut self, pos: (usize, usize)) {
(self.column, self.line) = pos;
}
pub fn set_line(&mut self, line: usize) {
self.line = line;
}
pub fn set_col(&mut self, col: usize) {
self.column = col;
}
pub fn progress(&mut self) { pub fn progress(&mut self) {
self.column += 1; self.column += 1;
if self.column < self.width { if self.column < self.width {
@ -113,6 +126,6 @@ pub fn print_args(args: fmt::Arguments) {
use core::fmt::Write; use core::fmt::Write;
use x86_64::instructions::interrupts; use x86_64::instructions::interrupts;
interrupts::without_interrupts(|| { interrupts::without_interrupts(|| {
Out.lock().write_fmt(args).unwrap(); OUT.lock().write_fmt(args).unwrap();
}); });
} }

View file

@ -1,23 +1,23 @@
use lazy_static::lazy_static; // use lazy_static::lazy_static;
use spin::Mutex; // use spin::Mutex;
use crate::hard::keyboard::Keyboard; // use crate::hard::keyboard::Keyboard;
lazy_static! { // lazy_static! {
static ref In: Mutex<Input> = Mutex::new(Input::init()); // static ref In: Mutex<Input> = Mutex::new(Input::init());
} // }
pub struct Input { // pub struct Input {
keyboard: Keyboard, // keyboard: Keyboard,
} // }
impl Input { // impl Input {
pub fn init() -> Self { // pub fn init() -> Self {
let keyboard = Keyboard; // let keyboard = Keyboard;
Self { keyboard } // Self { keyboard }
} // }
pub fn read(out: &mut [char]) -> usize { // pub fn read(out: &mut [char]) -> usize {
0 // 0
} // }
} // }

116
src/dev/memory.rs Normal file
View file

@ -0,0 +1,116 @@
use bootloader::bootinfo::{MemoryMap, MemoryRegionType};
use x86_64::{
registers::control::Cr3,
structures::paging::{
mapper::MapToError, page_table::FrameError, FrameAllocator, Mapper, OffsetPageTable, Page, PageTable,
PageTableFlags, PhysFrame, Size4KiB,
},
PhysAddr, VirtAddr,
};
use crate::println;
pub fn init(physical_memory_start: u64, mapping: &'static MemoryMap) {
let mut mapper = unsafe { init_mapper(physical_memory_start) };
let mut frame_allocator = unsafe { BootInfoFrameAllocator::new(mapping) };
init_heap(&mut mapper, &mut frame_allocator).unwrap();
}
pub unsafe fn init_mapper(physical_memory_start: u64) -> OffsetPageTable<'static> {
println!("Initializing Mapper.");
let physical_memory_start = VirtAddr::new(physical_memory_start);
let level_4_table = active_level_4_table(physical_memory_start);
OffsetPageTable::new(level_4_table, physical_memory_start)
}
unsafe fn active_level_4_table(physical_memory_start: VirtAddr) -> &'static mut PageTable {
let (l4_table, _flags) = Cr3::read();
let l4_start = l4_table.start_address();
let virt = physical_memory_start + l4_start.as_u64();
let page_table_ptr = virt.as_mut_ptr::<PageTable>();
&mut *page_table_ptr
}
pub struct BootInfoFrameAllocator {
memory_map: &'static MemoryMap,
next: usize,
}
impl BootInfoFrameAllocator {
pub unsafe fn new(memory_map: &'static MemoryMap) -> Self {
println!("Initializing Frame Allocator.");
BootInfoFrameAllocator { memory_map, next: 0 }
}
fn usable_frames(&self) -> impl Iterator<Item = PhysFrame> {
let regions = self.memory_map.iter();
let usable_regions = regions.filter(|r| r.region_type == MemoryRegionType::Usable);
let addr_ranges = usable_regions.map(|r| r.range.start_addr()..r.range.end_addr());
let frame_addresses = addr_ranges.flat_map(|r| r.step_by(4096));
frame_addresses.map(|addr| PhysFrame::containing_address(PhysAddr::new(addr)))
}
}
unsafe impl FrameAllocator<Size4KiB> for BootInfoFrameAllocator {
fn allocate_frame(&mut self) -> Option<PhysFrame> {
let frame = self.usable_frames().nth(self.next);
self.next += 1;
frame
}
}
pub const HEAP_START: usize = 0x_4444_4444_0000;
pub const HEAP_SIZE: usize = 500 * 1024; // 500 KiB
pub fn init_heap(
mapper: &mut impl Mapper<Size4KiB>,
frame_allocator: &mut impl FrameAllocator<Size4KiB>,
) -> Result<(), MapToError<Size4KiB>> {
println!("Initializing Heap.");
let page_range = {
let heap_start = VirtAddr::new(HEAP_START as u64);
let heap_end = heap_start + HEAP_SIZE as u64 - 1u64;
let heap_start_page = Page::containing_address(heap_start);
let heap_end_page = Page::containing_address(heap_end);
Page::range_inclusive(heap_start_page, heap_end_page)
};
for page in page_range {
let frame = frame_allocator
.allocate_frame()
.ok_or(MapToError::FrameAllocationFailed)?;
let flags = PageTableFlags::PRESENT | PageTableFlags::WRITABLE;
unsafe { mapper.map_to(page, frame, flags, frame_allocator)?.flush() };
}
unsafe { ALLOCATOR.lock().init(HEAP_START as _, HEAP_SIZE) };
Ok(())
}
use linked_list_allocator::LockedHeap;
#[global_allocator]
static ALLOCATOR: LockedHeap = LockedHeap::empty();
pub unsafe fn translate_addr(addr: VirtAddr, physical_memory_start: VirtAddr) -> Option<PhysAddr> {
translate_addr_inner(addr, physical_memory_start)
}
fn translate_addr_inner(addr: VirtAddr, physical_memory_start: VirtAddr) -> Option<PhysAddr> {
let (level_4_table_frame, _) = Cr3::read();
let table_indexes = [addr.p4_index(), addr.p3_index(), addr.p2_index(), addr.p1_index()];
let mut frame = level_4_table_frame;
for &index in &table_indexes {
let virt = physical_memory_start + frame.start_address().as_u64();
let table_ptr: *const PageTable = virt.as_ptr();
let table = unsafe { &*table_ptr };
let entry = &table[index];
frame = match entry.frame() {
Ok(frame) => frame,
Err(FrameError::FrameNotPresent) => return None,
Err(FrameError::HugeFrame) => panic!("huge pages not supported."),
};
}
Some(frame.start_address() + u64::from(addr.page_offset()))
}

View file

@ -1,3 +1,3 @@
pub mod alloc;
pub mod console; pub mod console;
pub mod input; pub mod input;
pub mod memory;

View file

@ -6,7 +6,7 @@ use x86_64::{
structures::idt::{InterruptDescriptorTable, InterruptStackFrame}, structures::idt::{InterruptDescriptorTable, InterruptStackFrame},
}; };
use crate::{print, println}; use crate::{hard::keyboard::keyboard, println};
pub fn init() { pub fn init() {
println!("Initializing interrupt handler."); println!("Initializing interrupt handler.");
@ -33,17 +33,12 @@ static PICS: Mutex<ChainedPics> = Mutex::new(unsafe { ChainedPics::new(0x20, 0x2
extern "x86-interrupt" fn keyboard_handler(_stack_frame: InterruptStackFrame) { extern "x86-interrupt" fn keyboard_handler(_stack_frame: InterruptStackFrame) {
let mut port = Port::new(0x60); let mut port = Port::new(0x60);
let _scancode: u8 = unsafe { port.read() }; let scan_code = unsafe { port.read() };
// crate::task::keyboard::add_scancode(scancode); keyboard().record(scan_code);
println!("keyboard got scancode"); unsafe { PICS.lock().notify_end_of_interrupt(INT_IDX_KEYBOARD) };
unsafe {
PICS.lock().notify_end_of_interrupt(INT_IDX_KEYBOARD);
}
} }
extern "x86-interrupt" fn timer_handler(_stack_frame: InterruptStackFrame) { extern "x86-interrupt" fn timer_handler(_stack_frame: InterruptStackFrame) {
print!("."); // print!(".");
unsafe { unsafe { PICS.lock().notify_end_of_interrupt(INT_IDX_TIMER) };
PICS.lock().notify_end_of_interrupt(INT_IDX_TIMER);
}
} }

View file

@ -1,7 +1,278 @@
pub struct Keyboard; use alloc::boxed::Box;
use lazy_static::lazy_static;
use spin::{Mutex, MutexGuard};
use crate::println;
pub fn keyboard<'r>() -> MutexGuard<'r, Keyboard> {
KEYBOARD.lock()
}
lazy_static! {
static ref KEYBOARD: Mutex<Keyboard> = Mutex::new(Keyboard::init());
}
pub struct Keyboard {
on_code: Option<Box<dyn FnMut(Code) + Send>>,
last: Option<Code>,
}
impl Keyboard { impl Keyboard {
pub fn record(key_code: u8) { pub fn init() -> Self {
// todo!() let on_code = None;
let last = None;
Self { on_code, last }
}
pub fn on_code(&mut self, op: impl FnMut(Code) + Send + 'static) {
self.on_code = Some(Box::new(op) as _);
}
pub fn record(&mut self, scan_code: u8) {
let code = self.parse(scan_code);
match code {
Err(err) => println!("Failed to record key : {err:?}"),
Ok(Code::Control) => self.last = Some(Code::Control),
Ok(c) if let Some(op) = self.on_code.as_mut() => op(c),
Ok(c) => println!("Ignoring {c:?}"),
};
}
pub fn parse(&mut self, scan_code: u8) -> Result<Code, KeyParseErr> {
let code = match (self.last, scan_code) {
(None, 0xE0) => Code::Control,
(None, 0x1E) => Code::Down(Key::Char('a')),
(None, 0x30) => Code::Down(Key::Char('b')),
(None, 0x2E) => Code::Down(Key::Char('c')),
(None, 0x20) => Code::Down(Key::Char('d')),
(None, 0x12) => Code::Down(Key::Char('e')),
(None, 0x21) => Code::Down(Key::Char('f')),
(None, 0x22) => Code::Down(Key::Char('g')),
(None, 0x23) => Code::Down(Key::Char('h')),
(None, 0x17) => Code::Down(Key::Char('i')),
(None, 0x24) => Code::Down(Key::Char('j')),
(None, 0x25) => Code::Down(Key::Char('k')),
(None, 0x26) => Code::Down(Key::Char('l')),
(None, 0x32) => Code::Down(Key::Char('m')),
(None, 0x31) => Code::Down(Key::Char('n')),
(None, 0x18) => Code::Down(Key::Char('o')),
(None, 0x19) => Code::Down(Key::Char('p')),
(None, 0x10) => Code::Down(Key::Char('q')),
(None, 0x13) => Code::Down(Key::Char('r')),
(None, 0x1F) => Code::Down(Key::Char('s')),
(None, 0x14) => Code::Down(Key::Char('t')),
(None, 0x16) => Code::Down(Key::Char('u')),
(None, 0x2F) => Code::Down(Key::Char('v')),
(None, 0x11) => Code::Down(Key::Char('w')),
(None, 0x2D) => Code::Down(Key::Char('x')),
(None, 0x15) => Code::Down(Key::Char('y')),
(None, 0x2C) => Code::Down(Key::Char('z')),
(None, 0x0B) => Code::Down(Key::Char('0')),
(None, 0x02) => Code::Down(Key::Char('1')),
(None, 0x03) => Code::Down(Key::Char('2')),
(None, 0x04) => Code::Down(Key::Char('3')),
(None, 0x05) => Code::Down(Key::Char('4')),
(None, 0x06) => Code::Down(Key::Char('5')),
(None, 0x07) => Code::Down(Key::Char('6')),
(None, 0x08) => Code::Down(Key::Char('7')),
(None, 0x09) => Code::Down(Key::Char('8')),
(None, 0x0A) => Code::Down(Key::Char('9')),
(None, 0x29) => Code::Down(Key::Char('`')),
(None, 0x0C) => Code::Down(Key::Char('-')),
(None, 0x0D) => Code::Down(Key::Char('=')),
(None, 0x2B) => Code::Down(Key::Char('\\')),
(None, 0x1A) => Code::Down(Key::Char('[')),
(None, 0x34) => Code::Down(Key::Char('.')),
(None, 0x35) => Code::Down(Key::Char('/')),
(None, 0x1B) => Code::Down(Key::Char(']')),
(None, 0x27) => Code::Down(Key::Char(';')),
(None, 0x28) => Code::Down(Key::Char('\'')),
(None, 0x33) => Code::Down(Key::Char(',')),
(None, 0x1C) => Code::Down(Key::Char('\n')),
(None, 0x39) => Code::Down(Key::Char(' ')),
(None, 0x0F) => Code::Down(Key::Char('\t')),
(None, 0x0E) => Code::Down(Key::BackSpace),
(None, 0x9E) => Code::Up(Key::Char('a')),
(None, 0xB0) => Code::Up(Key::Char('b')),
(None, 0xAE) => Code::Up(Key::Char('c')),
(None, 0xA0) => Code::Up(Key::Char('d')),
(None, 0x92) => Code::Up(Key::Char('e')),
(None, 0xA1) => Code::Up(Key::Char('f')),
(None, 0xA2) => Code::Up(Key::Char('g')),
(None, 0xA3) => Code::Up(Key::Char('h')),
(None, 0x97) => Code::Up(Key::Char('i')),
(None, 0xA4) => Code::Up(Key::Char('j')),
(None, 0xA5) => Code::Up(Key::Char('k')),
(None, 0xA6) => Code::Up(Key::Char('l')),
(None, 0xB2) => Code::Up(Key::Char('m')),
(None, 0xB1) => Code::Up(Key::Char('n')),
(None, 0x98) => Code::Up(Key::Char('o')),
(None, 0x99) => Code::Up(Key::Char('p')),
(None, 0x90) => Code::Up(Key::Char('q')),
(None, 0x93) => Code::Up(Key::Char('r')),
(None, 0x9F) => Code::Up(Key::Char('s')),
(None, 0x94) => Code::Up(Key::Char('t')),
(None, 0x96) => Code::Up(Key::Char('u')),
(None, 0xAF) => Code::Up(Key::Char('v')),
(None, 0x91) => Code::Up(Key::Char('w')),
(None, 0xAD) => Code::Up(Key::Char('x')),
(None, 0x95) => Code::Up(Key::Char('y')),
(None, 0xAC) => Code::Up(Key::Char('z')),
(None, 0x8B) => Code::Up(Key::Char('0')),
(None, 0x82) => Code::Up(Key::Char('1')),
(None, 0x83) => Code::Up(Key::Char('2')),
(None, 0x84) => Code::Up(Key::Char('3')),
(None, 0x85) => Code::Up(Key::Char('4')),
(None, 0x86) => Code::Up(Key::Char('5')),
(None, 0x87) => Code::Up(Key::Char('6')),
(None, 0x88) => Code::Up(Key::Char('7')),
(None, 0x89) => Code::Up(Key::Char('8')),
(None, 0x8A) => Code::Up(Key::Char('9')),
(None, 0xA9) => Code::Up(Key::Char('`')),
(None, 0x8C) => Code::Up(Key::Char('-')),
(None, 0x8D) => Code::Up(Key::Char('=')),
(None, 0xAB) => Code::Up(Key::Char('\\')),
(None, 0x9A) => Code::Up(Key::Char('[')),
(None, 0xB4) => Code::Up(Key::Char('.')),
(None, 0xB5) => Code::Up(Key::Char('/')),
(None, 0x9B) => Code::Up(Key::Char(']')),
(None, 0xA7) => Code::Up(Key::Char(';')),
(None, 0xA8) => Code::Up(Key::Char('\'')),
(None, 0xB3) => Code::Up(Key::Char(',')),
(None, 0x9C) => Code::Up(Key::Char('\n')),
(None, 0xB9) => Code::Up(Key::Char(' ')),
(None, 0x8F) => Code::Up(Key::Char('\t')),
(None, 0x8E) => Code::Up(Key::BackSpace),
_ => Err(KeyParseErr::UnknownCode(scan_code))?,
};
Ok(code)
} }
} }
#[derive(Debug, Clone, Copy)]
pub enum Code {
Down(Key),
Up(Key),
Control,
}
#[derive(Debug, Clone, Copy)]
pub enum Key {
Char(char),
BackSpace,
}
#[derive(Debug, Clone, Copy)]
pub enum KeyParseErr {
UnknownCode(u8),
}
/*
char table
A 1E 9E
B 30 B0
C 2E AE
D 20 A0
E 12 92
F 21 A1
G 22 A2
H 23 A3
I 17 97
J 24 A4
K 25 A5
L 26 A6
M 32 B2
N 31 B1
O 18 98
P 19 99
Q 10 90
R 13 93
S 1F 9F
T 14 94
U 16 96
V 2F AF
W 11 91
X 2D AD
Y 15 95
Z 2C AC
0 0B 8B
1 02 82
2 03 83
3 04 84
4 05 85
5 06 86
6 07 87
7 08 88
8 09 89
9 0A 8A
` 29 89
- 0C 8C
= 0D 8D
\ 2B AB
[ 1A 9A
. 34 B4
/ 35 B5
] 1B 9B
; 27 A7
' 28 A8
, 33 B3
ENTER 1C 9C
SPACE 39 B9
TAB 0F 8F
BKSP 0E 8E
ESC 01 81
CAPS 3A BA
L_SHFT 2A AA
L_CTRL 1D 9D
INSERT E0,52 E0,D2
HOME E0,47 E0,97
PG_UP E0,49 E0,C9
DELETE E0,53 E0,D3
END E0,4F E0,CF
PG_DN E0,51 E0,D1
U_ARROW E0,48 E0,C8
L_ARROW E0,4B E0,CB
D_ARROW E0,50 E0,D0
R_ARROW E0,4D E0,CD
L_GUI E0,5B E0,DB
L_ALT 38 B8
R_SHFT 36 B6
R_CTRL E0,1D E0,9D
R_GUI E0,5C E0,DC
R_ALT E0,38 E0,B8
APPS E0,5D E0,DD
F1 3B BB
F2 3C BC
F3 3D BD
F4 3E BE
F5 3F BF
F6 40 C0
F7 41 C1
F8 42 C2
F9 43 C3
F10 44 C4
F11 57 D7
F12 58 D8
SCROLL 46 C6
KP_2 50 D0
KP_3 51 D1
KP_4 4B CB
KP_5 4C CC
KP_6 4D CD
KP_7 47 C7
KP_8 48 C8
KP_9 49 C9
NUM 45 C5
KP_/ E0,35 E0,B5
KP_* 37 B7
KP_- 4A CA
KP_+ 4E CE
KP_EN E0,1C E0,9C
KP_. 53 D3
KP_0 52 D2
KP_1 4F CF
*/

View file

@ -1,26 +1,34 @@
#![no_std] #![no_std]
#![no_main] #![no_main]
#![feature(abi_x86_interrupt)] #![feature(abi_x86_interrupt)]
#![feature(if_let_guard)]
extern crate alloc;
mod dev; mod dev;
mod hard; mod hard;
mod program;
mod util;
use core::panic::PanicInfo; use core::panic::PanicInfo;
use program::shell;
use dev::alloc; use bootloader::{entry_point, BootInfo};
use dev::memory;
use hard::int; use hard::int;
#[no_mangle] entry_point!(kernel_main);
pub extern "C" fn _start() -> ! {
fn kernel_main(boot_info: &'static BootInfo) -> ! {
println!("Starting."); println!("Starting.");
int::init(); int::init();
alloc::init(); memory::init(boot_info.physical_memory_offset, &boot_info.memory_map);
println!("Finished initializations."); println!("Finished initializations.");
loop {} shell::main();
panic!("Exiting.")
} }
#[panic_handler] #[panic_handler]
fn panic(_info: &PanicInfo) -> ! { fn panic(info: &PanicInfo) -> ! {
println!("Paniced."); println!("Panicked : {info:?}");
loop {} util::spin();
} }

1
src/program/mod.rs Normal file
View file

@ -0,0 +1 @@
pub mod shell;

51
src/program/shell.rs Normal file
View file

@ -0,0 +1,51 @@
use core::mem;
use alloc::{string::String, sync::Arc};
use blinkcast::alloc::channel;
use microlang::Context;
use spin::Mutex;
use crate::{
dev::console::out,
hard::keyboard::{keyboard, Code, Key},
print, println,
};
pub fn main() {
let (tx, mut rx) = channel(1024);
let buff = Arc::new(Mutex::new(String::new()));
keyboard().on_code(move |c| {
let mut buff = buff.lock();
match c {
Code::Down(Key::Char(c)) => {
print!("{c}");
if c == '\n' {
let mut new = String::new();
mem::swap(&mut new, &mut buff);
tx.send(new);
} else {
buff.push(c);
}
}
Code::Down(Key::BackSpace) => {
out().correct();
buff.pop();
}
_ => (),
}
});
let mut context = Context::empty();
print!("> ");
loop {
if let Some(line) = rx.recv() {
match context.eval(line) {
Ok((_, value)) => println!("{}", value.serialize()),
Err(err) => println!("Error: {err:?}"),
}
print!("> ");
}
}
}

4
src/util.rs Normal file
View file

@ -0,0 +1,4 @@
#[allow(clippy::empty_loop)]
pub fn spin() -> ! {
loop {}
}