feat: Can start normally
This commit is contained in:
parent
ae5b398d30
commit
920f7f5fc8
@ -1,10 +1,2 @@
|
||||
[unstable]
|
||||
build-std = ["core", "compiler_builtins"]
|
||||
build-std-features = ["compiler-builtins-mem"]
|
||||
|
||||
[build]
|
||||
target = "i686-unknown-linux-gnu"
|
||||
|
||||
[target.i686-unknown-linux-gnu]
|
||||
linker = "i686-elf-ld"
|
||||
ar = "i686-elf-ar"
|
||||
bindeps = true
|
||||
580
Cargo.lock
generated
580
Cargo.lock
generated
@ -3,10 +3,25 @@
|
||||
version = 4
|
||||
|
||||
[[package]]
|
||||
name = "bit_field"
|
||||
version = "0.10.2"
|
||||
name = "anyhow"
|
||||
version = "1.0.100"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dc827186963e592360843fb5ba4b973e145841266c1357f7180c43526f2e5b61"
|
||||
checksum = "a23eb6b1614318a8071c9b2521f36b424b2c83db5eb3a0fead4a6c0809af6e61"
|
||||
|
||||
[[package]]
|
||||
name = "bincode"
|
||||
version = "1.3.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b1f45e9417d87227c7a56d22e471c6206462cba514c7590c09aff4cf6d1ddcad"
|
||||
dependencies = [
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bit_field"
|
||||
version = "0.10.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1e4b40c7323adcfc0a41c4b88143ed58346ff65a288fc144329c5c45e05d70c6"
|
||||
|
||||
[[package]]
|
||||
name = "bitflags"
|
||||
@ -15,28 +30,571 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
|
||||
|
||||
[[package]]
|
||||
name = "cure"
|
||||
name = "bitflags"
|
||||
version = "2.9.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2261d10cca569e4643e526d8dc2e62e433cc8aba21ab764233731f8d369bf394"
|
||||
|
||||
[[package]]
|
||||
name = "bitvec"
|
||||
version = "1.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1bc2832c24239b0141d5674bb9174f9d68a8b5b3f2753311927c172ca46f7e9c"
|
||||
dependencies = [
|
||||
"funty",
|
||||
"radium",
|
||||
"tap",
|
||||
"wyz",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bootloader"
|
||||
version = "0.11.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "61e418d2f8952e4a6d935d23ea038daed2fe7707b0118923f91e83bf1fbe64b3"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"bootloader-boot-config",
|
||||
"fatfs",
|
||||
"gpt",
|
||||
"llvm-tools",
|
||||
"mbrman",
|
||||
"serde_json",
|
||||
"tempfile",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bootloader-boot-config"
|
||||
version = "0.11.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6cfbe7f4a5d9843a9a310712e64691f3c474546f02bed7a53ed81775a681d18e"
|
||||
dependencies = [
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bootloader_api"
|
||||
version = "0.11.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ba1a4adcd36a49a08c4fb8c13c132fb1ea01a59681b305b46625095318328455"
|
||||
|
||||
[[package]]
|
||||
name = "bumpalo"
|
||||
version = "3.19.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "46c5e41b57b8bba42a04676d81cb89e9ee8e859a1a66f80a5a72e1cb76b34d43"
|
||||
|
||||
[[package]]
|
||||
name = "byteorder"
|
||||
version = "1.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
version = "1.0.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2fd1289c04a9ea8cb22300a459a72a385d7c73d3259e2ed7dcb2af674838cfa9"
|
||||
|
||||
[[package]]
|
||||
name = "crc"
|
||||
version = "3.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9710d3b3739c2e349eb44fe848ad0b7c8cb1e42bd87ee49371df2f7acaf3e675"
|
||||
dependencies = [
|
||||
"crc-catalog",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crc-catalog"
|
||||
version = "2.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "19d374276b40fb8bbdee95aef7c7fa6b5316ec764510eb64b8dd0e2ed0d7e7f5"
|
||||
|
||||
[[package]]
|
||||
name = "cure-builder"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"x86",
|
||||
"bootloader",
|
||||
"cure-kernel",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cure-kernel"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"bootloader_api",
|
||||
"lazy_static",
|
||||
"raw-cpuid",
|
||||
"spin 0.10.0",
|
||||
"x86_64",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "errno"
|
||||
version = "0.3.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"windows-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fastrand"
|
||||
version = "2.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be"
|
||||
|
||||
[[package]]
|
||||
name = "fatfs"
|
||||
version = "0.3.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "05669f8e7e2d7badc545c513710f0eba09c2fbef683eb859fd79c46c355048e0"
|
||||
dependencies = [
|
||||
"bitflags 1.3.2",
|
||||
"byteorder",
|
||||
"log",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "funty"
|
||||
version = "2.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c"
|
||||
|
||||
[[package]]
|
||||
name = "getrandom"
|
||||
version = "0.3.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "26145e563e54f2cadc477553f1ec5ee650b00862f0a58bcd12cbdc5f0ea2d2f4"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"libc",
|
||||
"r-efi",
|
||||
"wasi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "gpt"
|
||||
version = "3.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8283e7331b8c93b9756e0cfdbcfb90312852f953c6faf9bf741e684cc3b6ad69"
|
||||
dependencies = [
|
||||
"bitflags 2.9.4",
|
||||
"crc",
|
||||
"log",
|
||||
"uuid",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "itoa"
|
||||
version = "1.0.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c"
|
||||
|
||||
[[package]]
|
||||
name = "js-sys"
|
||||
version = "0.3.81"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ec48937a97411dcb524a265206ccd4c90bb711fca92b2792c407f268825b9305"
|
||||
dependencies = [
|
||||
"once_cell",
|
||||
"wasm-bindgen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "lazy_static"
|
||||
version = "1.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe"
|
||||
dependencies = [
|
||||
"spin 0.9.8",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.177"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2874a2af47a2325c2001a6e6fad9b16a53b802102b528163885171cf92b15976"
|
||||
|
||||
[[package]]
|
||||
name = "linux-raw-sys"
|
||||
version = "0.11.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "df1d3c3b53da64cf5760482273a98e575c651a67eec7f77df96b5b642de8f039"
|
||||
|
||||
[[package]]
|
||||
name = "llvm-tools"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "955be5d0ca0465caf127165acb47964f911e2bc26073e865deb8be7189302faf"
|
||||
|
||||
[[package]]
|
||||
name = "lock_api"
|
||||
version = "0.4.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "224399e74b87b5f3557511d98dff8b14089b3dadafcab6bb93eab67d3aace965"
|
||||
dependencies = [
|
||||
"scopeguard",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "log"
|
||||
version = "0.4.28"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "34080505efa8e45a4b816c349525ebe327ceaa8559756f0356cba97ef3bf7432"
|
||||
|
||||
[[package]]
|
||||
name = "mbrman"
|
||||
version = "0.5.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b1fc3bff63c208d4a14301c6cb807af2d1a0760052584ce3f9a737b55fb85498"
|
||||
dependencies = [
|
||||
"bincode",
|
||||
"bitvec",
|
||||
"serde",
|
||||
"serde-big-array",
|
||||
"thiserror",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "memchr"
|
||||
version = "2.7.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f52b00d39961fc5b2736ea853c9cc86238e165017a493d1d5c8eac6bdc4cc273"
|
||||
|
||||
[[package]]
|
||||
name = "once_cell"
|
||||
version = "1.21.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d"
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.101"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "89ae43fd86e4158d6db51ad8e2b80f313af9cc74f5c0e03ccb87de09998732de"
|
||||
dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.41"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ce25767e7b499d1b604768e7cde645d14cc8584231ea6b295e9c9eb22c02e1d1"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "r-efi"
|
||||
version = "5.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f"
|
||||
|
||||
[[package]]
|
||||
name = "radium"
|
||||
version = "0.7.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09"
|
||||
|
||||
[[package]]
|
||||
name = "raw-cpuid"
|
||||
version = "10.7.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6c297679cb867470fa8c9f67dbba74a78d78e3e98d7cf2b08d6d71540f797332"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"bitflags 1.3.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "x86"
|
||||
version = "0.52.0"
|
||||
name = "rustix"
|
||||
version = "1.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2781db97787217ad2a2845c396a5efe286f87467a5810836db6d74926e94a385"
|
||||
checksum = "cd15f8a2c5551a84d56efdc1cd049089e409ac19a3072d5037a17fd70719ff3e"
|
||||
dependencies = [
|
||||
"bitflags 2.9.4",
|
||||
"errno",
|
||||
"libc",
|
||||
"linux-raw-sys",
|
||||
"windows-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustversion"
|
||||
version = "1.0.22"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d"
|
||||
|
||||
[[package]]
|
||||
name = "ryu"
|
||||
version = "1.0.20"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f"
|
||||
|
||||
[[package]]
|
||||
name = "scopeguard"
|
||||
version = "1.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
|
||||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.228"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e"
|
||||
dependencies = [
|
||||
"serde_core",
|
||||
"serde_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde-big-array"
|
||||
version = "0.5.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "11fc7cc2c76d73e0f27ee52abbd64eec84d46f370c88371120433196934e4b7f"
|
||||
dependencies = [
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_core"
|
||||
version = "1.0.228"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad"
|
||||
dependencies = [
|
||||
"serde_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_derive"
|
||||
version = "1.0.228"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_json"
|
||||
version = "1.0.145"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "402a6f66d8c709116cf22f558eab210f5a50187f702eb4d7e5ef38d9a7f1c79c"
|
||||
dependencies = [
|
||||
"itoa",
|
||||
"memchr",
|
||||
"ryu",
|
||||
"serde",
|
||||
"serde_core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "spin"
|
||||
version = "0.9.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67"
|
||||
|
||||
[[package]]
|
||||
name = "spin"
|
||||
version = "0.10.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d5fe4ccb98d9c292d56fec89a5e07da7fc4cf0dc11e156b41793132775d3e591"
|
||||
dependencies = [
|
||||
"lock_api",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "2.0.106"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ede7c438028d4436d71104916910f5bb611972c5cfd7f89b8300a8186e6fada6"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tap"
|
||||
version = "1.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369"
|
||||
|
||||
[[package]]
|
||||
name = "tempfile"
|
||||
version = "3.23.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2d31c77bdf42a745371d260a26ca7163f1e0924b64afa0b688e61b5a9fa02f16"
|
||||
dependencies = [
|
||||
"fastrand",
|
||||
"getrandom",
|
||||
"once_cell",
|
||||
"rustix",
|
||||
"windows-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thiserror"
|
||||
version = "1.0.69"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52"
|
||||
dependencies = [
|
||||
"thiserror-impl",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thiserror-impl"
|
||||
version = "1.0.69"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unicode-ident"
|
||||
version = "1.0.19"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f63a545481291138910575129486daeaf8ac54aee4387fe7906919f7830c7d9d"
|
||||
|
||||
[[package]]
|
||||
name = "uuid"
|
||||
version = "1.18.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2f87b8aa10b915a06587d0dec516c282ff295b475d94abf425d62b57710070a2"
|
||||
dependencies = [
|
||||
"getrandom",
|
||||
"js-sys",
|
||||
"wasm-bindgen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "volatile"
|
||||
version = "0.4.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "442887c63f2c839b346c192d047a7c87e73d0689c9157b00b53dcc27dd5ea793"
|
||||
|
||||
[[package]]
|
||||
name = "wasi"
|
||||
version = "0.14.7+wasi-0.2.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "883478de20367e224c0090af9cf5f9fa85bed63a95c1abf3afc5c083ebc06e8c"
|
||||
dependencies = [
|
||||
"wasip2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasip2"
|
||||
version = "1.0.1+wasi-0.2.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0562428422c63773dad2c345a1882263bbf4d65cf3f42e90921f787ef5ad58e7"
|
||||
dependencies = [
|
||||
"wit-bindgen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen"
|
||||
version = "0.2.104"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c1da10c01ae9f1ae40cbfac0bac3b1e724b320abfcf52229f80b547c0d250e2d"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"once_cell",
|
||||
"rustversion",
|
||||
"wasm-bindgen-macro",
|
||||
"wasm-bindgen-shared",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-backend"
|
||||
version = "0.2.104"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "671c9a5a66f49d8a47345ab942e2cb93c7d1d0339065d4f8139c486121b43b19"
|
||||
dependencies = [
|
||||
"bumpalo",
|
||||
"log",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"wasm-bindgen-shared",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-macro"
|
||||
version = "0.2.104"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7ca60477e4c59f5f2986c50191cd972e3a50d8a95603bc9434501cf156a9a119"
|
||||
dependencies = [
|
||||
"quote",
|
||||
"wasm-bindgen-macro-support",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-macro-support"
|
||||
version = "0.2.104"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9f07d2f20d4da7b26400c9f4a0511e6e0345b040694e8a75bd41d578fa4421d7"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"wasm-bindgen-backend",
|
||||
"wasm-bindgen-shared",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-shared"
|
||||
version = "0.2.104"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bad67dc8b2a1a6e5448428adec4c3e84c43e561d8c9ee8a9e5aabeb193ec41d1"
|
||||
dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-link"
|
||||
version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5"
|
||||
|
||||
[[package]]
|
||||
name = "windows-sys"
|
||||
version = "0.61.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc"
|
||||
dependencies = [
|
||||
"windows-link",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wit-bindgen"
|
||||
version = "0.46.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f17a85883d4e6d00e8a97c586de764dabcc06133f7f1d55dce5cdc070ad7fe59"
|
||||
|
||||
[[package]]
|
||||
name = "wyz"
|
||||
version = "0.5.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "05f360fc0b24296329c78fda852a1e9ae82de9cf7b27dae4b7f62f118f77b9ed"
|
||||
dependencies = [
|
||||
"tap",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "x86_64"
|
||||
version = "0.15.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0f042214de98141e9c8706e8192b73f56494087cc55ebec28ce10f26c5c364ae"
|
||||
dependencies = [
|
||||
"bit_field",
|
||||
"bitflags",
|
||||
"raw-cpuid",
|
||||
"bitflags 2.9.4",
|
||||
"rustversion",
|
||||
"volatile",
|
||||
]
|
||||
|
||||
26
Cargo.toml
26
Cargo.toml
@ -1,27 +1,9 @@
|
||||
[package]
|
||||
name = "cure"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
[lib]
|
||||
crate-type = ["staticlib"]
|
||||
path = "src/lib.rs"
|
||||
[workspace]
|
||||
resolver = "2"
|
||||
members = ["kernel", "builder"]
|
||||
|
||||
[profile.dev]
|
||||
panic = "abort"
|
||||
opt-level = 0
|
||||
|
||||
[profile.release]
|
||||
panic = "abort"
|
||||
opt-level = 2
|
||||
|
||||
[package.metadata.bootimage]
|
||||
test-args = ["-device", "isa-debug-exit,iobase=0xf4,iosize=0x04", "-serial", "stdio", "-display", "none"]
|
||||
test-success-exit-code = 33
|
||||
|
||||
[features]
|
||||
default = []
|
||||
debug = []
|
||||
|
||||
[dependencies]
|
||||
x86 = "0.52.0"
|
||||
panic = "abort"
|
||||
@ -1,6 +0,0 @@
|
||||
default=0
|
||||
timeout=3
|
||||
|
||||
menuentry "$_OS_NAME" {
|
||||
multiboot /boot/$_OS_NAME.bin
|
||||
}
|
||||
@ -1,10 +1,10 @@
|
||||
# -- 基本設定 --
|
||||
romimage: file=/usr/local/share/bochs/BIOS-bochs-latest, address=0xfffe0000
|
||||
vgaromimage: file=/usr/local/share/bochs/VGABIOS-lgpl-latest
|
||||
# romimage: file=/usr/local/share/bochs/BIOS-bochs-latest, address=0xfffe0000
|
||||
# vgaromimage: file=/usr/local/share/bochs/VGABIOS-lgpl-latest
|
||||
|
||||
boot: cdrom
|
||||
boot: disk
|
||||
ata0-master: type=disk, path="build/cure-bios.img", mode=flat
|
||||
|
||||
ata0-master: type=cdrom, path="build/cure.iso", status=inserted
|
||||
|
||||
memory: guest=1024, host=1024
|
||||
|
||||
|
||||
@ -1,5 +0,0 @@
|
||||
#!/usr/bin/bash
|
||||
|
||||
export _OS_NAME=$1
|
||||
|
||||
cat GRUB_TEMPLATE | envsubst > "$2"
|
||||
23
linker.ld
23
linker.ld
@ -1,23 +0,0 @@
|
||||
ENTRY(start_)
|
||||
|
||||
SECTIONS {
|
||||
. = 0x100000;
|
||||
|
||||
.text BLOCK(4K): {
|
||||
* (.multiboot) /* boot.o (.multiboot) */
|
||||
* (.text)
|
||||
}
|
||||
|
||||
.bss BLOCK(4K): {
|
||||
* (COMMON)
|
||||
* (.bss)
|
||||
}
|
||||
|
||||
.data BLOCK(4K): {
|
||||
* (.data)
|
||||
}
|
||||
|
||||
.rodata BLOCK(4k): {
|
||||
* (.rodata)
|
||||
}
|
||||
}
|
||||
225
makefile
225
makefile
@ -3,75 +3,188 @@ include config/make-os
|
||||
include config/make-cc
|
||||
include config/make-debug-tool
|
||||
|
||||
# Rust 構建配置
|
||||
BUILD_MODE := release
|
||||
CARGO_FLAGS :=
|
||||
RUST_TARGET := i686-unknown-linux-gnu
|
||||
CARGO_FLAGS := --release
|
||||
ifeq ($(BUILD_MODE),debug)
|
||||
CARGO_FLAGS :=
|
||||
endif
|
||||
|
||||
INCLUDES := $(patsubst %, -I%, $(INCLUDES_DIR))
|
||||
SOURCE_FILES := $(shell find -name "*.[cS]")
|
||||
SRC := $(patsubst ./%, $(OBJECT_DIR)/%.o, $(SOURCE_FILES))
|
||||
# 目標和輸出
|
||||
RUST_TARGET := x86_64-unknown-none
|
||||
BUILDER_PKG := cure-builder
|
||||
DISK_IMAGE := cure-os.img
|
||||
|
||||
$(OBJECT_DIR):
|
||||
@mkdir -p $(OBJECT_DIR)
|
||||
# 顏色輸出
|
||||
COLOR_RESET := \033[0m
|
||||
COLOR_GREEN := \033[32m
|
||||
COLOR_YELLOW := \033[33m
|
||||
COLOR_BLUE := \033[34m
|
||||
COLOR_RED := \033[31m
|
||||
|
||||
.PHONY: all rust-build run clean debug-bochs debug-qemu help all-debug
|
||||
|
||||
# 創建目錄(先清理)
|
||||
$(BUILD_DIR):
|
||||
@rm -rf $(BUILD_DIR)
|
||||
@mkdir -p $(BUILD_DIR)
|
||||
|
||||
$(BIN_DIR):
|
||||
@mkdir -p $(BIN_DIR)
|
||||
|
||||
$(ISO_DIR):
|
||||
@mkdir -p $(ISO_DIR)
|
||||
@mkdir -p $(ISO_BOOT_DIR)
|
||||
@mkdir -p $(ISO_GRUB_DIR)
|
||||
# 默認目標
|
||||
all: clean-build rust-build copy-artifacts
|
||||
|
||||
rust-kernel:
|
||||
@echo "Building Rust kernel..."
|
||||
@cargo build $(CARGO_FLAGS)
|
||||
|
||||
$(OBJECT_DIR)/%.S.o: %.S
|
||||
@mkdir -p $(@D)
|
||||
@echo "Compiling: $< -> $@"
|
||||
@$(CC) $(INCLUDES) -c $< -o $@
|
||||
|
||||
$(OBJECT_DIR)/%.c.o: %.c
|
||||
@mkdir -p $(@D)
|
||||
@echo "Compiling: $< -> $@"
|
||||
@$(CC) $(INCLUDES) -c $< -o $@ $(CFLAGS)
|
||||
|
||||
$(BIN_DIR)/$(OS_BIN): $(OBJECT_DIR) $(BIN_DIR) rust-kernel $(SRC)
|
||||
@echo "Linking..."
|
||||
@cp target/$(RUST_TARGET)/$(BUILD_MODE)/libcure.a $(OBJECT_DIR)/
|
||||
@$(CC) -T linker.ld -o $(BIN_DIR)/$(OS_BIN) $(SRC) $(OBJECT_DIR)/libcure.a $(LDFLAGS)
|
||||
|
||||
$(BUILD_DIR)/$(OS_ISO): $(ISO_DIR) $(BIN_DIR)/$(OS_BIN) GRUB_TEMPLATE
|
||||
@./config-grub.sh ${OS_NAME} $(ISO_GRUB_DIR)/grub.cfg
|
||||
@cp $(BIN_DIR)/$(OS_BIN) $(ISO_BOOT_DIR)
|
||||
@grub-mkrescue -o $(BUILD_DIR)/$(OS_ISO) $(ISO_DIR)
|
||||
|
||||
all: clean $(BUILD_DIR)/$(OS_ISO)
|
||||
|
||||
all-debug: BUILD_MODE := debug
|
||||
all-debug: CARGO_FLAGS := --features debug
|
||||
all-debug: O := -Og
|
||||
all-debug: CFLAGS := -g -std=gnu99 -ffreestanding $(O) $(W) $(ARCH_OPT)
|
||||
all-debug: LDFLAGS := -g -ffreestanding $(O) -nostdlib -lgcc
|
||||
all-debug: clean $(BUILD_DIR)/$(OS_ISO)
|
||||
@echo "Dumping the disassembled kernel code to $(BUILD_DIR)/dump.txt"
|
||||
@$(OBJDUMP) -D $(BIN_DIR)/$(OS_BIN) > $(BUILD_DIR)/dump.txt
|
||||
|
||||
clean:
|
||||
# 清理 build 目錄
|
||||
clean-build:
|
||||
@echo "$(COLOR_YELLOW)Cleaning build directory...$(COLOR_RESET)"
|
||||
@rm -rf $(BUILD_DIR)
|
||||
|
||||
# 構建內核
|
||||
rust-build:
|
||||
@echo "$(COLOR_BLUE)Building CureOS...$(COLOR_RESET)"
|
||||
@cargo build -p $(BUILDER_PKG) $(CARGO_FLAGS)
|
||||
@echo "$(COLOR_GREEN)✓ Build complete$(COLOR_RESET)"
|
||||
|
||||
# 複製構建產物到 build/ 目錄
|
||||
copy-artifacts: $(BUILD_DIR) $(BIN_DIR)
|
||||
@echo "$(COLOR_BLUE)Copying build artifacts...$(COLOR_RESET)"
|
||||
@BIOS_IMG=$$(find target -name "cure-bios.img" -type f | head -1); \
|
||||
UEFI_IMG=$$(find target -name "cure-uefi.img" -type f | head -1); \
|
||||
KERNEL_BIN=$$(find target/$(RUST_TARGET)/$(BUILD_MODE) -name "cure-kernel" -type f | head -1); \
|
||||
if [ -n "$$BIOS_IMG" ]; then \
|
||||
echo "$(COLOR_YELLOW) → $(BUILD_DIR)/cure-bios.img$(COLOR_RESET)"; \
|
||||
cp "$$BIOS_IMG" $(BUILD_DIR)/cure-bios.img; \
|
||||
fi; \
|
||||
if [ -n "$$UEFI_IMG" ]; then \
|
||||
echo "$(COLOR_YELLOW) → $(BUILD_DIR)/cure-uefi.img$(COLOR_RESET)"; \
|
||||
cp "$$UEFI_IMG" $(BUILD_DIR)/cure-uefi.img; \
|
||||
fi; \
|
||||
if [ -n "$$KERNEL_BIN" ]; then \
|
||||
echo "$(COLOR_YELLOW) → $(BIN_DIR)/$(OS_BIN)$(COLOR_RESET)"; \
|
||||
cp "$$KERNEL_BIN" $(BIN_DIR)/$(OS_BIN); \
|
||||
fi
|
||||
|
||||
@echo "$(COLOR_GREEN)✓ Artifacts copied$(COLOR_RESET)"
|
||||
|
||||
# Debug 構建(包含 dump)
|
||||
all-debug: BUILD_MODE := debug
|
||||
all-debug: CARGO_FLAGS :=
|
||||
all-debug: clean-build rust-build copy-artifacts dump
|
||||
|
||||
# 生成反彙編 dump
|
||||
dump:
|
||||
@echo "$(COLOR_BLUE)Generating disassembly dump...$(COLOR_RESET)"
|
||||
@if [ -f "$(BIN_DIR)/$(OS_BIN)" ]; then \
|
||||
echo "$(COLOR_YELLOW)Dumping to $(BUILD_DIR)/dump.txt$(COLOR_RESET)"; \
|
||||
objdump -D $(BIN_DIR)/$(OS_BIN) > $(BUILD_DIR)/dump.txt; \
|
||||
echo "$(COLOR_GREEN)✓ Dump complete$(COLOR_RESET)"; \
|
||||
else \
|
||||
echo "$(COLOR_RED)Error: Kernel binary not found$(COLOR_RESET)"; \
|
||||
exit 1; \
|
||||
fi
|
||||
|
||||
# 完全清理
|
||||
clean:
|
||||
@echo "$(COLOR_YELLOW)Cleaning all build artifacts...$(COLOR_RESET)"
|
||||
@cargo clean
|
||||
@rm -rf $(BUILD_DIR)
|
||||
@rm -f $(DISK_IMAGE) bochs.log serial.log serial-debug.log bochs-debug.log
|
||||
@echo "$(COLOR_GREEN)✓ Clean complete$(COLOR_RESET)"
|
||||
|
||||
run: $(BUILD_DIR)/$(OS_ISO)
|
||||
@qemu-system-i386 -smp 1 -m 1G -rtc base=utc -cdrom $(BUILD_DIR)/$(OS_ISO) -monitor telnet::$(QEMU_MON_PORT),server,nowait &
|
||||
@sleep 1
|
||||
@telnet 127.0.0.1 $(QEMU_MON_PORT)
|
||||
# 使用 QEMU 運行
|
||||
run: all
|
||||
@echo "$(COLOR_BLUE)Running with QEMU...$(COLOR_RESET)"
|
||||
@qemu-system-x86_64 -drive format=raw,file=$(BUILD_DIR)/cure-bios.img \
|
||||
-m 128M \
|
||||
-serial stdio
|
||||
|
||||
# 使用 Bochs 運行
|
||||
run-bochs: all
|
||||
@echo "$(COLOR_BLUE)Running with Bochs...$(COLOR_RESET)"
|
||||
@bochs -q -f bochs.cfg
|
||||
|
||||
# QEMU 調試模式
|
||||
debug-qemu: all-debug
|
||||
@$(OBJCOPY) --only-keep-debug $(BIN_DIR)/$(OS_BIN) $(BUILD_DIR)/kernel.dbg
|
||||
@qemu-system-i386 -smp 1 -m 1G -rtc base=utc -s -S -cdrom $(BUILD_DIR)/$(OS_ISO) -monitor telnet::$(QEMU_MON_PORT),server,nowait &
|
||||
@echo "$(COLOR_BLUE)Starting QEMU in debug mode...$(COLOR_RESET)"
|
||||
@qemu-system-x86_64 -drive format=raw,file=$(BUILD_DIR)/cure-bios.img \
|
||||
-m 128M \
|
||||
-serial stdio \
|
||||
-s -S &
|
||||
@sleep 1
|
||||
@$(QEMU_MON_TERM) -e "telnet 127.0.0.1 $(QEMU_MON_PORT)"
|
||||
@gdb -s $(BUILD_DIR)/kernel.dbg -ex "target remote localhost:1234"
|
||||
@echo ""
|
||||
@echo "$(COLOR_YELLOW)QEMU waiting for debugger...$(COLOR_RESET)"
|
||||
@echo "$(COLOR_YELLOW)Run in another terminal:$(COLOR_RESET)"
|
||||
@echo " gdb $(BIN_DIR)/$(OS_BIN)"
|
||||
@echo " (gdb) target remote :1234"
|
||||
@echo " (gdb) continue"
|
||||
@echo ""
|
||||
|
||||
# Bochs 調試模式
|
||||
debug-bochs: all-debug
|
||||
@bochs -q -f bochs.cfg
|
||||
@echo "$(COLOR_BLUE)Running Bochs in debug mode...$(COLOR_RESET)"
|
||||
@echo "$(COLOR_YELLOW)Dump file available at: $(BUILD_DIR)/dump.txt$(COLOR_RESET)"
|
||||
@bochs -q -f bochs.cfg
|
||||
|
||||
# 顯示構建產物位置
|
||||
show-artifacts:
|
||||
@echo "$(COLOR_BLUE)Build artifacts:$(COLOR_RESET)"
|
||||
@echo " Build directory: $(BUILD_DIR)/"
|
||||
@echo " Binary directory: $(BIN_DIR)/"
|
||||
@echo ""
|
||||
@if [ -d $(BUILD_DIR) ]; then \
|
||||
echo "$(COLOR_GREEN)Files in $(BUILD_DIR):$(COLOR_RESET)"; \
|
||||
ls -lh $(BUILD_DIR)/ 2>/dev/null || echo " (empty)"; \
|
||||
else \
|
||||
echo "$(COLOR_YELLOW) (directory doesn't exist)$(COLOR_RESET)"; \
|
||||
fi
|
||||
@echo ""
|
||||
@if [ -d $(BIN_DIR) ]; then \
|
||||
echo "$(COLOR_GREEN)Files in $(BIN_DIR):$(COLOR_RESET)"; \
|
||||
ls -lh $(BIN_DIR)/ 2>/dev/null || echo " (empty)"; \
|
||||
else \
|
||||
echo "$(COLOR_YELLOW) (directory doesn't exist)$(COLOR_RESET)"; \
|
||||
fi
|
||||
|
||||
# 檢查構建
|
||||
check:
|
||||
@echo "$(COLOR_BLUE)Checking code...$(COLOR_RESET)"
|
||||
@cargo check -p cure-kernel
|
||||
@cargo check -p $(BUILDER_PKG)
|
||||
@echo "$(COLOR_GREEN)✓ Check complete$(COLOR_RESET)"
|
||||
|
||||
# 格式化代碼
|
||||
fmt:
|
||||
@echo "$(COLOR_BLUE)Formatting code...$(COLOR_RESET)"
|
||||
@cargo fmt
|
||||
@echo "$(COLOR_GREEN)✓ Format complete$(COLOR_RESET)"
|
||||
|
||||
# Clippy 檢查
|
||||
clippy:
|
||||
@echo "$(COLOR_BLUE)Running clippy...$(COLOR_RESET)"
|
||||
@cargo clippy
|
||||
@echo "$(COLOR_GREEN)✓ Clippy complete$(COLOR_RESET)"
|
||||
|
||||
# 幫助信息
|
||||
help:
|
||||
@echo "$(COLOR_BLUE)CureOS Makefile Commands:$(COLOR_RESET)"
|
||||
@echo ""
|
||||
@echo " $(COLOR_GREEN)make all$(COLOR_RESET) - Clean build/ then build (release)"
|
||||
@echo " $(COLOR_GREEN)make all-debug$(COLOR_RESET) - Clean build/ then build (debug + dump)"
|
||||
@echo " $(COLOR_GREEN)make dump$(COLOR_RESET) - Generate disassembly dump"
|
||||
@echo " $(COLOR_GREEN)make run$(COLOR_RESET) - Build and run with QEMU"
|
||||
@echo " $(COLOR_GREEN)make run-bochs$(COLOR_RESET) - Build and run with Bochs"
|
||||
@echo " $(COLOR_GREEN)make debug-qemu$(COLOR_RESET) - Debug build and run with QEMU+GDB"
|
||||
@echo " $(COLOR_GREEN)make debug-bochs$(COLOR_RESET) - Debug build and run with Bochs"
|
||||
@echo " $(COLOR_GREEN)make clean$(COLOR_RESET) - Clean all build artifacts"
|
||||
@echo " $(COLOR_GREEN)make clean-build$(COLOR_RESET) - Clean build/ directory only"
|
||||
@echo " $(COLOR_GREEN)make show-artifacts$(COLOR_RESET) - Show build output locations"
|
||||
@echo " $(COLOR_GREEN)make check$(COLOR_RESET) - Check code"
|
||||
@echo " $(COLOR_GREEN)make fmt$(COLOR_RESET) - Format code"
|
||||
@echo " $(COLOR_GREEN)make clippy$(COLOR_RESET) - Run clippy"
|
||||
@echo " $(COLOR_GREEN)make help$(COLOR_RESET) - Show this help"
|
||||
@echo ""
|
||||
@echo "$(COLOR_YELLOW)Debug artifacts:$(COLOR_RESET)"
|
||||
@echo " - $(BUILD_DIR)/dump.txt - Kernel disassembly (debug mode only)"
|
||||
@echo " - $(BIN_DIR)/$(OS_BIN) - Kernel binary (for GDB)"
|
||||
@echo ""
|
||||
@ -1,63 +0,0 @@
|
||||
#include "multiboot.h"
|
||||
|
||||
.section .multiboot
|
||||
/* Define type as 32 bit */
|
||||
.long MB_MAGIC
|
||||
.long MB_ALIGNED_4K_MEM_MAP
|
||||
.long CHECKSUM(MB_ALIGNED_4K_MEM_MAP)
|
||||
|
||||
/* .bss: stack */
|
||||
.section .bss
|
||||
/* According to System V ABI, the stack must be aligned at 16 bytes boundary.*/
|
||||
.align 16 /* Not divisible by 16, move forward until divisible */
|
||||
stack_bottom:
|
||||
.skip 32708, 0
|
||||
stack_top:
|
||||
|
||||
/* .text: put executable code */
|
||||
.section .text
|
||||
.global start_
|
||||
start_:
|
||||
cli
|
||||
|
||||
movl $stack_top, %esp
|
||||
/*
|
||||
TODO: kernel init
|
||||
Load GDT
|
||||
Load IDT
|
||||
Enable paging
|
||||
*/
|
||||
call _kernel_init
|
||||
|
||||
/* install gdt */
|
||||
call _load_gdt
|
||||
// call _init_gdt
|
||||
// subl $0x6, %esp
|
||||
// movl $_GDT, 2(%esp)
|
||||
// movw _GDT_LIMIT, %ax
|
||||
// movw %ax, (%esp)
|
||||
// lgdt (%esp)
|
||||
// addl $0x6, %esp
|
||||
|
||||
/* processing register (CS, ES, SS, DS, FS, GS) */
|
||||
movw KERNEL_DATA_SEL, %cx /* 0x10 in binary representation is 0001 0000. If you right-shift this number by 3 bits, you will get 0000 0010, so the index is 2. */
|
||||
movw %cx, %es
|
||||
movw %cx, %ds
|
||||
movw %cx, %fs
|
||||
movw %cx, %gs
|
||||
movw %cx, %ss
|
||||
|
||||
/* Change CS:IP */
|
||||
pushw KERNEL_CODE_SEL /* 0x08 in binary representation is 0000 1000. If you right-shift this number by 3 bits, you will get 0000 0001, so the index is 1. */
|
||||
pushl $_after_gdt
|
||||
retf
|
||||
|
||||
_after_gdt:
|
||||
pushl %ebx
|
||||
|
||||
call _load_idt
|
||||
call _kernel_main
|
||||
|
||||
j_:
|
||||
hlt
|
||||
jmp j_
|
||||
@ -1,4 +0,0 @@
|
||||
// Define constants in multiboot
|
||||
#define MB_MAGIC 0x1BADB002
|
||||
#define MB_ALIGNED_4K_MEM_MAP 0x03
|
||||
#define CHECKSUM(flags) - (MB_MAGIC + flags)
|
||||
247
src/hal/cpu.rs
247
src/hal/cpu.rs
@ -1,247 +0,0 @@
|
||||
// src/hal/cpu.rs
|
||||
use x86::controlregs::{
|
||||
cr0,
|
||||
cr0_write,
|
||||
cr2,
|
||||
cr2_write,
|
||||
cr3,
|
||||
cr3_write,
|
||||
cr4,
|
||||
cr4_write,
|
||||
Cr0,
|
||||
Cr4
|
||||
};
|
||||
use x86::time::rdtsc;
|
||||
use x86::cpuid;
|
||||
use core::hint::spin_loop;
|
||||
use x86::irq::{enable, disable};
|
||||
use x86::halt;
|
||||
use core::arch::asm;
|
||||
|
||||
/// 32 位元暫存器類型
|
||||
#[allow(dead_code)]
|
||||
pub type Reg32 = u32;
|
||||
/// 16 位元暫存器類型
|
||||
#[allow(dead_code)]
|
||||
pub type Reg16 = u16;
|
||||
|
||||
/// 通用目的暫存器結構
|
||||
#[allow(dead_code)]
|
||||
#[repr(C, packed)]
|
||||
pub struct GpRegs {
|
||||
pub eax: Reg32,
|
||||
pub ebx: Reg32,
|
||||
pub ecx: Reg32,
|
||||
pub edx: Reg32,
|
||||
pub edi: Reg32,
|
||||
pub ebp: Reg32,
|
||||
pub esi: Reg32,
|
||||
pub esp: Reg32,
|
||||
}
|
||||
|
||||
/// 段暫存器結構
|
||||
#[allow(dead_code)]
|
||||
#[repr(C, packed)]
|
||||
pub struct SgReg {
|
||||
pub ss: Reg16,
|
||||
pub es: Reg16,
|
||||
pub ds: Reg16,
|
||||
pub fs: Reg16,
|
||||
pub gs: Reg16,
|
||||
pub cs: Reg16,
|
||||
}
|
||||
|
||||
/// Write cr4.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```no_run
|
||||
/// use x86::controlregs::*;
|
||||
/// unsafe {
|
||||
/// let cr4 = cr4();
|
||||
/// let cr4 = cr4 | Cr4::CR4_ENABLE_PSE;
|
||||
/// cr4_write(cr4);
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
/// 讀取 CR0 暫存器
|
||||
#[allow(dead_code)]
|
||||
#[inline]
|
||||
pub fn cpu_r_cr0() -> Cr0 {
|
||||
unsafe { cr0() }
|
||||
}
|
||||
|
||||
/// 讀取 CR2 暫存器
|
||||
#[allow(dead_code)]
|
||||
#[inline]
|
||||
pub fn cpu_r_cr2() -> usize {
|
||||
unsafe { cr2() }
|
||||
}
|
||||
|
||||
/// 讀取 CR3 暫存器
|
||||
#[allow(dead_code)]
|
||||
#[inline]
|
||||
pub fn cpu_r_cr3() -> u64 {
|
||||
unsafe { cr3() }
|
||||
}
|
||||
|
||||
/// 讀取 CR4 暫存器
|
||||
#[allow(dead_code)]
|
||||
#[inline]
|
||||
pub fn cpu_r_cr4() -> Cr4 {
|
||||
unsafe { cr4() }
|
||||
}
|
||||
|
||||
/// 寫入 CR0 暫存器
|
||||
#[allow(dead_code)]
|
||||
#[inline]
|
||||
pub fn cpu_w_cr0(val: Cr0) {
|
||||
unsafe { cr0_write(val); }
|
||||
}
|
||||
|
||||
/// 寫入 CR2 暫存器
|
||||
#[allow(dead_code)]
|
||||
#[inline]
|
||||
pub fn cpu_w_cr2(val: u64) {
|
||||
unsafe { cr2_write(val); }
|
||||
}
|
||||
|
||||
/// 寫入 CR3 暫存器
|
||||
#[allow(dead_code)]
|
||||
#[inline]
|
||||
pub fn cpu_w_cr3(val: u64) {
|
||||
unsafe { cr3_write(val); }
|
||||
}
|
||||
|
||||
/// 寫入 CR4 暫存器
|
||||
#[allow(dead_code)]
|
||||
#[inline]
|
||||
pub fn cpu_w_cr4(val: Cr4) {
|
||||
unsafe { cr4_write(val); }
|
||||
}
|
||||
|
||||
/// 獲取 CPU 型號
|
||||
///
|
||||
/// # 參數
|
||||
/// * `model_out` - 輸出緩衝區,至少需要 13 bytes
|
||||
/// # 返回
|
||||
/// 字符串切片,表示 CPU 供應商資訊
|
||||
#[allow(dead_code)]
|
||||
pub fn cpu_get_model(model_out: &mut [u8]) -> &str {
|
||||
if model_out.len() < 13 {
|
||||
return "Buffer too small";
|
||||
}
|
||||
|
||||
// 使用 cpuid 取得廠商 ID
|
||||
let vendor_id = cpuid::CpuId::new().get_vendor_info();
|
||||
|
||||
if let Some(vendor) = vendor_id {
|
||||
let vendor_string = vendor.as_str();
|
||||
let bytes = vendor_string.as_bytes();
|
||||
let copy_len = core::cmp::min(bytes.len(), model_out.len() - 1);
|
||||
|
||||
model_out[..copy_len].copy_from_slice(&bytes[..copy_len]);
|
||||
model_out[copy_len] = 0; // null
|
||||
|
||||
match core::str::from_utf8(&model_out[..copy_len]) {
|
||||
Ok(s) => s,
|
||||
Err(_) => "Invalid UTF-8"
|
||||
}
|
||||
} else {
|
||||
model_out[0] = b'?';
|
||||
model_out[1] = 0;
|
||||
"Unknown Vendor"
|
||||
}
|
||||
}
|
||||
|
||||
/// 檢查是否支持品牌字串
|
||||
#[allow(dead_code)]
|
||||
pub fn cpu_brand_string_supported() -> bool {
|
||||
let cpuid = cpuid::CpuId::new();
|
||||
cpuid.get_processor_brand_string().is_some()
|
||||
}
|
||||
|
||||
/// 獲取 CPU 品牌字串
|
||||
///
|
||||
/// # 參數
|
||||
/// * `brand_out` - 輸出緩衝區,至少需要 49 bytes
|
||||
///
|
||||
/// # 返回
|
||||
/// 字符串切片,表示 CPU 品牌
|
||||
#[allow(dead_code)]
|
||||
pub fn cpu_get_brand(brand_out: &mut [u8]) -> &str {
|
||||
if brand_out.len() < 49 {
|
||||
return "Buffer too small";
|
||||
}
|
||||
|
||||
let cpuid = cpuid::CpuId::new();
|
||||
|
||||
if let Some(brand) = cpuid.get_processor_brand_string() {
|
||||
let brand_string = brand.as_str();
|
||||
let bytes = brand_string.as_bytes();
|
||||
let copy_len = core::cmp::min(bytes.len(), brand_out.len() - 1);
|
||||
|
||||
brand_out[..copy_len].copy_from_slice(&bytes[..copy_len]);
|
||||
brand_out[copy_len] = 0; // null
|
||||
|
||||
match core::str::from_utf8(&brand_out[..copy_len]) {
|
||||
Ok(s) => s,
|
||||
Err(_) => "Invalid UTF-8"
|
||||
}
|
||||
} else {
|
||||
brand_out[0] = b'?';
|
||||
brand_out[1] = 0;
|
||||
"Unknown CPU"
|
||||
}
|
||||
}
|
||||
|
||||
/// 讀取 CPU 時間戳計數器 (TSC)
|
||||
///
|
||||
/// # 返回
|
||||
/// 時間戳計數值
|
||||
#[allow(dead_code)]
|
||||
#[inline]
|
||||
pub fn cpu_rdtsc() -> u64 {
|
||||
unsafe { rdtsc() }
|
||||
}
|
||||
|
||||
/// 執行 CPU 暫停指令
|
||||
///
|
||||
/// 在等待時減少 CPU 功耗
|
||||
#[allow(dead_code)]
|
||||
#[inline]
|
||||
pub fn cpu_pause() {
|
||||
spin_loop();
|
||||
}
|
||||
|
||||
/// 停止 CPU 執行,直到下一個中斷發生
|
||||
#[allow(dead_code)]
|
||||
#[inline]
|
||||
pub fn cpu_halt() {
|
||||
unsafe { halt(); }
|
||||
}
|
||||
|
||||
/// 停止 CPU 並進入低功耗模式
|
||||
#[allow(dead_code)]
|
||||
#[inline]
|
||||
pub fn cpu_idle() {
|
||||
unsafe { halt(); }
|
||||
}
|
||||
|
||||
/// 啟用中斷
|
||||
#[allow(dead_code)]
|
||||
#[inline]
|
||||
pub fn cpu_enable_interrupts() {
|
||||
unsafe {
|
||||
enable();
|
||||
}
|
||||
}
|
||||
|
||||
/// 禁用中斷
|
||||
#[allow(dead_code)]
|
||||
#[inline]
|
||||
pub fn cpu_disable_interrupts() {
|
||||
unsafe {
|
||||
disable();
|
||||
}
|
||||
}
|
||||
@ -1,88 +0,0 @@
|
||||
// src/hal/io.rs
|
||||
use x86::io::{inb, inl, outb, outl};
|
||||
|
||||
// :e - 32 位寄存器(如 eax, edx 等)
|
||||
// :x - 16 位寄存器(如 ax, dx 等)
|
||||
// :l - 8 位低位寄存器(如 al, dl 等)
|
||||
// :h - 8 位高位寄存器(如 ah, dh 等)
|
||||
|
||||
/// 向 I/O 端口寫入一個字節
|
||||
///
|
||||
/// # 參數
|
||||
/// * `port` - 端口號
|
||||
/// * `value` - 要寫入的值
|
||||
#[allow(dead_code)]
|
||||
#[inline]
|
||||
pub fn io_port_wb(port: u16, value: u8) {
|
||||
unsafe {
|
||||
outb(port, value);
|
||||
}
|
||||
}
|
||||
|
||||
/// 向 I/O 端口寫入一個雙字
|
||||
///
|
||||
/// # 參數
|
||||
/// * `port` - 端口號
|
||||
/// * `value` - 要寫入的值
|
||||
#[allow(dead_code)]
|
||||
#[inline]
|
||||
pub fn io_port_wl(port: u16, value: u32) {
|
||||
unsafe {
|
||||
outl(port, value);
|
||||
}
|
||||
}
|
||||
|
||||
/// 從 I/O 端口讀取一個字節
|
||||
///
|
||||
/// # 參數
|
||||
/// * `port` - 端口號
|
||||
/// # 返回
|
||||
/// 讀取到的值
|
||||
#[allow(dead_code)]
|
||||
#[inline]
|
||||
pub fn io_port_rb(port: u16) -> u8 {
|
||||
unsafe {
|
||||
inb(port)
|
||||
}
|
||||
}
|
||||
|
||||
/// 從 I/O 端口讀取一個雙字
|
||||
///
|
||||
/// # 參數
|
||||
/// * `port` - 端口號
|
||||
/// # 返回
|
||||
/// 讀取到的值
|
||||
#[allow(dead_code)]
|
||||
#[inline]
|
||||
pub fn io_port_rl(port: u16) -> u32 {
|
||||
unsafe {
|
||||
inl(port)
|
||||
}
|
||||
}
|
||||
|
||||
/// 向 I/O 端口寫入一個字
|
||||
///
|
||||
/// # 參數
|
||||
/// * `port` - 端口號
|
||||
/// * `value` - 要寫入的值
|
||||
#[allow(dead_code)]
|
||||
#[inline]
|
||||
pub fn io_port_ww(port: u16, value: u16) {
|
||||
unsafe {
|
||||
x86::io::outw(port, value);
|
||||
}
|
||||
}
|
||||
|
||||
/// 從 I/O 端口讀取一個字
|
||||
///
|
||||
/// # 參數
|
||||
/// * `port` - 端口號
|
||||
/// # 返回
|
||||
/// 讀取到的值
|
||||
#[allow(dead_code)]
|
||||
#[inline]
|
||||
pub fn io_port_rw(port: u16) -> u16 {
|
||||
unsafe {
|
||||
x86::io::inw(port)
|
||||
}
|
||||
}
|
||||
@ -1,23 +0,0 @@
|
||||
pub mod io;
|
||||
pub mod cpu;
|
||||
|
||||
pub use io::io_port_wb;
|
||||
pub use io::io_port_wl;
|
||||
pub use io::io_port_rb;
|
||||
pub use io::io_port_rl;
|
||||
|
||||
pub use cpu::cpu_r_cr0;
|
||||
pub use cpu::cpu_r_cr2;
|
||||
pub use cpu::cpu_r_cr3;
|
||||
pub use cpu::cpu_w_cr0;
|
||||
pub use cpu::cpu_w_cr2;
|
||||
pub use cpu::cpu_w_cr3;
|
||||
pub use cpu::cpu_get_model;
|
||||
pub use cpu::cpu_brand_string_supported;
|
||||
pub use cpu::cpu_get_brand;
|
||||
pub use cpu::cpu_rdtsc;
|
||||
pub use cpu::cpu_pause;
|
||||
pub use cpu::cpu_halt;
|
||||
pub use cpu::cpu_idle;
|
||||
pub use cpu::cpu_enable_interrupts;
|
||||
pub use cpu::cpu_disable_interrupts;
|
||||
@ -1 +0,0 @@
|
||||
pub mod x86;
|
||||
@ -1,112 +0,0 @@
|
||||
// src/kernel/asm/x86/gdt.rs
|
||||
use core::mem;
|
||||
use core::ptr;
|
||||
use x86::segmentation::{self, Descriptor, DataSegmentType, CodeSegmentType, SegmentSelector};
|
||||
use x86::segmentation::{SegmentDescriptorBuilder, BuildDescriptor};
|
||||
use x86::dtables::{DescriptorTablePointer, lgdt};
|
||||
use x86::Ring;
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub const SEG_DATA_RD: u64 = 0x00; // Read-Only
|
||||
#[allow(dead_code)]
|
||||
pub const SEG_DATA_RDA: u64 = 0x01; // Read-Only, accessed
|
||||
#[allow(dead_code)]
|
||||
pub const SEG_DATA_RDWR: u64 = 0x02; // Read/Write
|
||||
#[allow(dead_code)]
|
||||
pub const SEG_DATA_RDWRA: u64 = 0x03; // Read/Write, accessed
|
||||
#[allow(dead_code)]
|
||||
pub const SEG_DATA_RDEXPD: u64 = 0x04; // Read-Only, expand-down
|
||||
#[allow(dead_code)]
|
||||
pub const SEG_DATA_RDEXPDA: u64 = 0x05; // Read-Only, expand-down, accessed
|
||||
#[allow(dead_code)]
|
||||
pub const SEG_DATA_RDWREXPD: u64 = 0x06; // Read/Write, expand-down
|
||||
#[allow(dead_code)]
|
||||
pub const SEG_DATA_RDWREXPDA: u64 = 0x07; // Read/Write, expand-down, accessed
|
||||
#[allow(dead_code)]
|
||||
pub const SEG_CODE_EX: u64 = 0x08; // Execute-Only
|
||||
#[allow(dead_code)]
|
||||
pub const SEG_CODE_EXA: u64 = 0x09; // Execute-Only, accessed
|
||||
#[allow(dead_code)]
|
||||
pub const SEG_CODE_EXRD: u64 = 0x0A; // Execute/Read
|
||||
#[allow(dead_code)]
|
||||
pub const SEG_CODE_EXRDA: u64 = 0x0B; // Execute/Read, accessed
|
||||
#[allow(dead_code)]
|
||||
pub const SEG_CODE_EXC: u64 = 0x0C; // Execute-Only, conforming
|
||||
#[allow(dead_code)]
|
||||
pub const SEG_CODE_EXCA: u64 = 0x0D; // Execute-Only, conforming, accessed
|
||||
#[allow(dead_code)]
|
||||
pub const SEG_CODE_EXRDC: u64 = 0x0E; // Execute/Read, conforming
|
||||
#[allow(dead_code)]
|
||||
pub const SEG_CODE_EXRDCA: u64 = 0x0F; // Execute/Read, conforming, accessed
|
||||
|
||||
pub const GDT_ENTRY_COUNT: usize = 5;
|
||||
|
||||
#[no_mangle]
|
||||
pub static mut _GDT: [Descriptor; GDT_ENTRY_COUNT] = [Descriptor::NULL; GDT_ENTRY_COUNT];
|
||||
|
||||
#[no_mangle]
|
||||
pub static mut _GDT_LIMIT: u16 = (mem::size_of::<[Descriptor; GDT_ENTRY_COUNT]>() - 1) as u16;
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn _init_gdt() {
|
||||
unsafe {
|
||||
_GDT[0] = Descriptor::NULL;
|
||||
|
||||
_GDT[1] = segmentation::DescriptorBuilder::code_descriptor(
|
||||
0,
|
||||
0xFFFFF,
|
||||
CodeSegmentType::ExecuteRead
|
||||
)
|
||||
.present()
|
||||
.dpl(Ring::Ring0)
|
||||
.db()
|
||||
.limit_granularity_4kb()
|
||||
.finish();
|
||||
|
||||
_GDT[2] = segmentation::DescriptorBuilder::data_descriptor(
|
||||
0,
|
||||
0xFFFFF,
|
||||
DataSegmentType::ReadWrite
|
||||
)
|
||||
.present()
|
||||
.dpl(Ring::Ring0)
|
||||
.db()
|
||||
.limit_granularity_4kb()
|
||||
.finish();
|
||||
|
||||
_GDT[3] = segmentation::DescriptorBuilder::code_descriptor(
|
||||
0,
|
||||
0xFFFFF,
|
||||
CodeSegmentType::ExecuteRead
|
||||
)
|
||||
.present()
|
||||
.dpl(Ring::Ring3)
|
||||
.db()
|
||||
.limit_granularity_4kb()
|
||||
.finish();
|
||||
|
||||
_GDT[4] = segmentation::DescriptorBuilder::data_descriptor(
|
||||
0,
|
||||
0xFFFFF,
|
||||
DataSegmentType::ReadWrite
|
||||
)
|
||||
.present()
|
||||
.dpl(Ring::Ring3)
|
||||
.db()
|
||||
.limit_granularity_4kb()
|
||||
.finish();
|
||||
}
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn _load_gdt() {
|
||||
unsafe {
|
||||
_init_gdt();
|
||||
|
||||
let gdtr = DescriptorTablePointer {
|
||||
limit: _GDT_LIMIT,
|
||||
base: ptr::addr_of!(_GDT),
|
||||
};
|
||||
lgdt(&gdtr);
|
||||
}
|
||||
}
|
||||
@ -1,179 +0,0 @@
|
||||
// src/kernel/asm/x86/idt.rs
|
||||
use core::mem;
|
||||
use core::ptr;
|
||||
use x86::dtables::{DescriptorTablePointer, lidt};
|
||||
use x86::segmentation::{
|
||||
self,
|
||||
SegmentSelector,
|
||||
Descriptor,
|
||||
SystemDescriptorTypes32,
|
||||
DescriptorBuilder,
|
||||
BuildDescriptor
|
||||
};
|
||||
use x86::Ring;
|
||||
use x86::irq::{self, EXCEPTIONS};
|
||||
use x86::segmentation::GateDescriptorBuilder;
|
||||
use x86::segmentation::TaskGateDescriptorBuilder;
|
||||
use crate::kernel::asm::x86::{interrupt, segment};
|
||||
|
||||
pub const IDT_ENTRY_COUNT: usize = 256;
|
||||
|
||||
#[no_mangle]
|
||||
pub static mut _IDT: [Descriptor; IDT_ENTRY_COUNT] = [Descriptor::NULL; IDT_ENTRY_COUNT];
|
||||
|
||||
#[no_mangle]
|
||||
pub static mut _IDT_LIMIT: u16 = (mem::size_of::<[Descriptor; IDT_ENTRY_COUNT]>() - 1) as u16;
|
||||
|
||||
pub type InterruptHandler = unsafe extern "C" fn() -> ();
|
||||
pub type ExceptionHandlerWithErrorCode = fn(error_code: u32) -> ();
|
||||
|
||||
#[no_mangle]
|
||||
pub fn _set_interrupt_handler(vector: u8, selector: SegmentSelector, handler: InterruptHandler, dpl: Ring) {
|
||||
unsafe {
|
||||
let desc = DescriptorBuilder::interrupt_descriptor(selector, handler as u32)
|
||||
.present()
|
||||
.dpl(dpl)
|
||||
.finish();
|
||||
|
||||
_IDT[vector as usize] = desc;
|
||||
}
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub fn _set_interrupt_err_handler(vector: u8, selector: SegmentSelector, handler: ExceptionHandlerWithErrorCode, dpl: Ring) {
|
||||
unsafe {
|
||||
let desc = DescriptorBuilder::interrupt_descriptor(selector, handler as u32)
|
||||
.present()
|
||||
.dpl(dpl)
|
||||
.finish();
|
||||
|
||||
_IDT[vector as usize] = desc;
|
||||
}
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub fn _set_trap_handler(vector: u8, selector: SegmentSelector, handler: InterruptHandler, dpl: Ring) {
|
||||
unsafe {
|
||||
let desc = DescriptorBuilder::trap_gate_descriptor(selector, handler as u32)
|
||||
.present()
|
||||
.dpl(dpl)
|
||||
.finish();
|
||||
|
||||
_IDT[vector as usize] = desc;
|
||||
}
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub fn _set_task_gate(vector: u8, tss_selector: SegmentSelector, dpl: Ring) {
|
||||
unsafe {
|
||||
let desc = DescriptorBuilder::task_gate_descriptor(tss_selector)
|
||||
.present()
|
||||
.dpl(dpl)
|
||||
.finish();
|
||||
|
||||
_IDT[vector as usize] = desc;
|
||||
}
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub fn _init_idt() {
|
||||
unsafe {
|
||||
for i in 0..IDT_ENTRY_COUNT {
|
||||
_IDT[i] = Descriptor::NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub fn _load_idt() {
|
||||
unsafe {
|
||||
_init_idt();
|
||||
|
||||
let idtr = DescriptorTablePointer {
|
||||
limit: _IDT_LIMIT,
|
||||
base: ptr::addr_of!(_IDT) as *const _,
|
||||
};
|
||||
lidt(&idtr);
|
||||
|
||||
_setup_idt();
|
||||
}
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub fn _setup_idt() {
|
||||
extern "C" {
|
||||
fn _asm_isr0();
|
||||
fn _asm_isr1();
|
||||
fn _asm_isr2();
|
||||
fn _asm_isr3();
|
||||
fn _asm_isr4();
|
||||
fn _asm_isr5();
|
||||
fn _asm_isr6();
|
||||
fn _asm_isr7();
|
||||
fn _asm_isr8();
|
||||
fn _asm_isr9();
|
||||
fn _asm_isr10();
|
||||
fn _asm_isr11();
|
||||
fn _asm_isr12();
|
||||
fn _asm_isr13();
|
||||
fn _asm_isr14();
|
||||
fn _asm_isr15();
|
||||
fn _asm_isr16();
|
||||
fn _asm_isr17();
|
||||
fn _asm_isr18();
|
||||
fn _asm_isr19();
|
||||
fn _asm_isr20();
|
||||
fn _asm_isr21();
|
||||
fn _asm_isr22();
|
||||
fn _asm_isr23();
|
||||
fn _asm_isr24();
|
||||
fn _asm_isr25();
|
||||
fn _asm_isr26();
|
||||
fn _asm_isr27();
|
||||
fn _asm_isr28();
|
||||
fn _asm_isr29();
|
||||
fn _asm_isr30();
|
||||
fn _asm_isr31();
|
||||
}
|
||||
|
||||
_set_interrupt_handler(irq::DIVIDE_ERROR_VECTOR, segment::KERNEL_CODE_SELECTOR, _asm_isr0, Ring::Ring0);
|
||||
_set_interrupt_handler(irq::DEBUG_VECTOR, segment::KERNEL_CODE_SELECTOR, _asm_isr1, Ring::Ring0);
|
||||
_set_interrupt_handler(irq::NONMASKABLE_INTERRUPT_VECTOR, segment::KERNEL_CODE_SELECTOR, _asm_isr2, Ring::Ring0);
|
||||
_set_interrupt_handler(irq::BREAKPOINT_VECTOR, segment::KERNEL_CODE_SELECTOR, _asm_isr3, Ring::Ring0);
|
||||
_set_interrupt_handler(irq::OVERFLOW_VECTOR, segment::KERNEL_CODE_SELECTOR, _asm_isr4, Ring::Ring0);
|
||||
_set_interrupt_handler(irq::BOUND_RANGE_EXCEEDED_VECTOR, segment::KERNEL_CODE_SELECTOR, _asm_isr5, Ring::Ring0);
|
||||
_set_interrupt_handler(irq::INVALID_OPCODE_VECTOR, segment::KERNEL_CODE_SELECTOR, _asm_isr6, Ring::Ring0);
|
||||
_set_interrupt_handler(irq::DEVICE_NOT_AVAILABLE_VECTOR, segment::KERNEL_CODE_SELECTOR, _asm_isr7, Ring::Ring0);
|
||||
_set_interrupt_handler(irq::DOUBLE_FAULT_VECTOR, segment::KERNEL_CODE_SELECTOR, _asm_isr8, Ring::Ring0);
|
||||
_set_interrupt_handler(irq::COPROCESSOR_SEGMENT_OVERRUN_VECTOR, segment::KERNEL_CODE_SELECTOR, _asm_isr9, Ring::Ring0);
|
||||
_set_interrupt_handler(irq::INVALID_TSS_VECTOR, segment::KERNEL_CODE_SELECTOR, _asm_isr10, Ring::Ring0);
|
||||
_set_interrupt_handler(irq::SEGMENT_NOT_PRESENT_VECTOR, segment::KERNEL_CODE_SELECTOR, _asm_isr11, Ring::Ring0);
|
||||
_set_interrupt_handler(irq::STACK_SEGEMENT_FAULT_VECTOR, segment::KERNEL_CODE_SELECTOR, _asm_isr12, Ring::Ring0);
|
||||
_set_interrupt_handler(irq::GENERAL_PROTECTION_FAULT_VECTOR, segment::KERNEL_CODE_SELECTOR, _asm_isr13, Ring::Ring0);
|
||||
_set_interrupt_handler(irq::PAGE_FAULT_VECTOR, segment::KERNEL_CODE_SELECTOR, _asm_isr14, Ring::Ring0);
|
||||
_set_interrupt_handler(15, segment::KERNEL_CODE_SELECTOR, _asm_isr15, Ring::Ring0);
|
||||
_set_interrupt_handler(irq::X87_FPU_VECTOR, segment::KERNEL_CODE_SELECTOR, _asm_isr16, Ring::Ring0);
|
||||
_set_interrupt_handler(irq::ALIGNMENT_CHECK_VECTOR, segment::KERNEL_CODE_SELECTOR, _asm_isr17, Ring::Ring0);
|
||||
_set_interrupt_handler(irq::MACHINE_CHECK_VECTOR, segment::KERNEL_CODE_SELECTOR, _asm_isr18, Ring::Ring0);
|
||||
_set_interrupt_handler(irq::SIMD_FLOATING_POINT_VECTOR, segment::KERNEL_CODE_SELECTOR, _asm_isr19, Ring::Ring0);
|
||||
_set_interrupt_handler(irq::VIRTUALIZATION_VECTOR, segment::KERNEL_CODE_SELECTOR, _asm_isr20, Ring::Ring0);
|
||||
|
||||
_set_interrupt_handler(21, segment::KERNEL_CODE_SELECTOR, _asm_isr21, Ring::Ring0);
|
||||
_set_interrupt_handler(22, segment::KERNEL_CODE_SELECTOR, _asm_isr22, Ring::Ring0);
|
||||
_set_interrupt_handler(23, segment::KERNEL_CODE_SELECTOR, _asm_isr23, Ring::Ring0);
|
||||
_set_interrupt_handler(24, segment::KERNEL_CODE_SELECTOR, _asm_isr24, Ring::Ring0);
|
||||
_set_interrupt_handler(25, segment::KERNEL_CODE_SELECTOR, _asm_isr25, Ring::Ring0);
|
||||
_set_interrupt_handler(26, segment::KERNEL_CODE_SELECTOR, _asm_isr26, Ring::Ring0);
|
||||
_set_interrupt_handler(27, segment::KERNEL_CODE_SELECTOR, _asm_isr27, Ring::Ring0);
|
||||
_set_interrupt_handler(28, segment::KERNEL_CODE_SELECTOR, _asm_isr28, Ring::Ring0);
|
||||
_set_interrupt_handler(29, segment::KERNEL_CODE_SELECTOR, _asm_isr29, Ring::Ring0);
|
||||
_set_interrupt_handler(30, segment::KERNEL_CODE_SELECTOR, _asm_isr30, Ring::Ring0);
|
||||
_set_interrupt_handler(31, segment::KERNEL_CODE_SELECTOR, _asm_isr31, Ring::Ring0);
|
||||
|
||||
|
||||
// for i in 32..IDT_ENTRY_COUNT as u8 {
|
||||
// _set_interrupt_handler(i, segment::KERNEL_CODE_SELECTOR, interrupt::default_interrupt_handler, Ring::Ring0);
|
||||
// }
|
||||
|
||||
// crate::println!("IDT initialized with {} entries", IDT_ENTRY_COUNT);
|
||||
}
|
||||
@ -1,58 +0,0 @@
|
||||
.macro isr_template vector, no_error_code=1
|
||||
.global _asm_isr\vector
|
||||
.type _asm_isr\vector, @function
|
||||
_asm_isr\vector:
|
||||
.if \no_error_code
|
||||
pushl $0x0
|
||||
.endif
|
||||
pushl $\vector
|
||||
jmp interrupt_wrapper
|
||||
.endm
|
||||
|
||||
.section .text
|
||||
isr_template 0
|
||||
isr_template 1
|
||||
isr_template 2
|
||||
isr_template 3
|
||||
isr_template 4
|
||||
isr_template 5
|
||||
isr_template 6
|
||||
isr_template 7
|
||||
isr_template 8, 0
|
||||
isr_template 9
|
||||
isr_template 10, 0
|
||||
isr_template 11, 0
|
||||
isr_template 12, 0
|
||||
isr_template 13, 0
|
||||
isr_template 14, 0
|
||||
isr_template 15
|
||||
isr_template 16
|
||||
isr_template 17, 0
|
||||
isr_template 18
|
||||
isr_template 19
|
||||
isr_template 20
|
||||
isr_template 21
|
||||
isr_template 22
|
||||
isr_template 23
|
||||
isr_template 24
|
||||
isr_template 25
|
||||
isr_template 26
|
||||
isr_template 27
|
||||
isr_template 28
|
||||
isr_template 29
|
||||
isr_template 30
|
||||
isr_template 31
|
||||
|
||||
interrupt_wrapper:
|
||||
|
||||
movl %esp, %eax
|
||||
andl $0xfffffff0, %esp
|
||||
subl $16, %esp
|
||||
movl %eax, (%esp)
|
||||
|
||||
call interrupt_handler
|
||||
pop %eax
|
||||
movl %eax, %esp
|
||||
addl $8, %esp
|
||||
|
||||
iret
|
||||
@ -1,248 +0,0 @@
|
||||
use core::mem;
|
||||
use core::ptr;
|
||||
use x86::segmentation::{SegmentSelector, Descriptor};
|
||||
use x86::Ring;
|
||||
use x86::irq::{self, PageFaultError, EXCEPTIONS};
|
||||
use crate::{print, println};
|
||||
use crate::hal::cpu;
|
||||
|
||||
#[repr(C, packed)]
|
||||
pub struct IsrParam {
|
||||
vector: u32,
|
||||
err_code: u32,
|
||||
eip: u32,
|
||||
cs: u32,
|
||||
eflags: u32,
|
||||
esp: u32,
|
||||
ss: u32,
|
||||
}
|
||||
|
||||
impl IsrParam {
|
||||
pub fn vector(&self) -> u32 {
|
||||
return self.vector;
|
||||
}
|
||||
|
||||
pub fn err_code(&self) -> u32 {
|
||||
// unsafe {
|
||||
// let ptr = ptr::addr_of!(self.err_code);
|
||||
// ptr::read_unaligned(ptr)
|
||||
// }
|
||||
return self.err_code;
|
||||
}
|
||||
|
||||
pub fn eip(&self) -> u32 {
|
||||
return self.eip;
|
||||
}
|
||||
|
||||
pub fn cs(&self) -> u32 {
|
||||
return self.cs;
|
||||
}
|
||||
|
||||
pub fn eflags(&self) -> u32 {
|
||||
return self.eflags;
|
||||
}
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn interrupt_handler(param: *const IsrParam) {
|
||||
// param.as_ref().expect("中斷參數為 null")
|
||||
let param_ref = unsafe { param.as_ref().unwrap() };
|
||||
|
||||
match param_ref.vector {
|
||||
0 => divide_error_handler(param_ref),
|
||||
1 => debug_error_handler(param_ref),
|
||||
2 => nonmaskable_interrupt_handler(param_ref),
|
||||
3 => breakpoint_handler(param_ref),
|
||||
4 => overflow_handler(param_ref),
|
||||
|
||||
5 => bound_range_exceeded_handler(param_ref),
|
||||
6 => invalid_opcode_handler(param_ref),
|
||||
7 => device_not_available_handler(param_ref),
|
||||
8 => double_fault_handler(param_ref),
|
||||
9 => coprocessor_segment_overrun_handler(param_ref),
|
||||
|
||||
10 => invalid_tss_handler(param_ref),
|
||||
11 => segment_not_present_handler(param_ref),
|
||||
12 => stack_segment_fault_handler(param_ref),
|
||||
13 => general_protection_handler(param_ref),
|
||||
14 => page_fault_handler(param_ref),
|
||||
// 15 => reserved_handler(param_ref),
|
||||
16 => x87_fpu_floating_point_handler(param_ref),
|
||||
17 => alignment_check_handler(param_ref),
|
||||
18 => machine_check_handler(param_ref),
|
||||
19 => simd_floating_point_handler(param_ref),
|
||||
20 => virtualization_handler(param_ref),
|
||||
// 21 => reserved_handler(param_ref),
|
||||
// 22 => reserved_handler(param_ref),
|
||||
// 23 => reserved_handler(param_ref),
|
||||
// 24 => reserved_handler(param_ref),
|
||||
// 25 => reserved_handler(param_ref),
|
||||
// 26 => reserved_handler(param_ref),
|
||||
// 27 => reserved_handler(param_ref),
|
||||
// 28 => reserved_handler(param_ref),
|
||||
// 29 => reserved_handler(param_ref),
|
||||
// 30 => reserved_handler(param_ref),
|
||||
// 31 => reserved_handler(param_ref),
|
||||
|
||||
_ => reserved_handler(param_ref),
|
||||
}
|
||||
}
|
||||
|
||||
fn print_exception(param: &IsrParam) {
|
||||
let vector = param.vector();
|
||||
|
||||
if vector < 32 {
|
||||
let ex = &EXCEPTIONS[vector as usize];
|
||||
println!("CPU Exception: {}", ex);
|
||||
println!("EIP: 0x{:x}, CS: 0x{:x}, EFLAGS: 0x{:x}", param.eip(), param.cs(), param.eflags());
|
||||
|
||||
let error_code = param.err_code();
|
||||
|
||||
if error_code != 0 {
|
||||
println!("Error code: 0x{:x}", error_code);
|
||||
|
||||
if vector == irq::PAGE_FAULT_VECTOR.into() {
|
||||
let cr2 = cpu::cpu_r_cr2() ;
|
||||
let pf_error = PageFaultError::from_bits_truncate(error_code);
|
||||
|
||||
println!("Fault address: 0x{:x}", cr2);
|
||||
println!("Fault details:\n{}", pf_error);
|
||||
}
|
||||
}
|
||||
|
||||
// if let Some(addr) = fault_addr {
|
||||
// println!("Fault address: 0x{:x}", addr);
|
||||
// }
|
||||
} else {
|
||||
println!("Unhandled interrupt: Vector {}", vector);
|
||||
}
|
||||
|
||||
loop {}
|
||||
}
|
||||
|
||||
/// isr0
|
||||
#[no_mangle]
|
||||
pub fn divide_error_handler(param: &IsrParam) {
|
||||
print_exception(param)
|
||||
}
|
||||
|
||||
/// isr1
|
||||
#[no_mangle]
|
||||
pub fn debug_error_handler(param: &IsrParam) {
|
||||
print_exception(param)
|
||||
}
|
||||
|
||||
/// isr2
|
||||
#[no_mangle]
|
||||
pub fn nonmaskable_interrupt_handler(param: &IsrParam) {
|
||||
print_exception(param)
|
||||
}
|
||||
|
||||
/// isr3
|
||||
#[no_mangle]
|
||||
pub fn breakpoint_handler(param: &IsrParam) {
|
||||
print_exception(param)
|
||||
}
|
||||
|
||||
/// isr4
|
||||
#[no_mangle]
|
||||
pub fn overflow_handler(param: &IsrParam) {
|
||||
print_exception(param)
|
||||
}
|
||||
|
||||
/// isr5
|
||||
#[no_mangle]
|
||||
pub fn bound_range_exceeded_handler(param: &IsrParam) {
|
||||
print_exception(param)
|
||||
}
|
||||
|
||||
/// isr6
|
||||
#[no_mangle]
|
||||
pub fn invalid_opcode_handler(param: &IsrParam) {
|
||||
print_exception(param)
|
||||
}
|
||||
|
||||
/// isr7
|
||||
#[no_mangle]
|
||||
pub fn device_not_available_handler(param: &IsrParam) {
|
||||
print_exception(param)
|
||||
}
|
||||
|
||||
/// isr8
|
||||
#[no_mangle]
|
||||
pub fn double_fault_handler(param: &IsrParam) {
|
||||
print_exception(param)
|
||||
}
|
||||
|
||||
/// isr9
|
||||
#[no_mangle]
|
||||
pub fn coprocessor_segment_overrun_handler(param: &IsrParam) {
|
||||
print_exception(param)
|
||||
}
|
||||
|
||||
/// isr10
|
||||
#[no_mangle]
|
||||
pub fn invalid_tss_handler(param: &IsrParam) {
|
||||
print_exception(param)
|
||||
}
|
||||
|
||||
/// isr11
|
||||
#[no_mangle]
|
||||
pub fn segment_not_present_handler(param: &IsrParam) {
|
||||
print_exception(param)
|
||||
}
|
||||
|
||||
/// isr12
|
||||
#[no_mangle]
|
||||
pub fn stack_segment_fault_handler(param: &IsrParam) {
|
||||
print_exception(param)
|
||||
}
|
||||
|
||||
/// isr13
|
||||
#[no_mangle]
|
||||
pub fn general_protection_handler(param: &IsrParam) {
|
||||
print_exception(param)
|
||||
}
|
||||
|
||||
/// isr14
|
||||
#[no_mangle]
|
||||
pub fn page_fault_handler(param: &IsrParam) {
|
||||
print_exception(param)
|
||||
}
|
||||
|
||||
/// isr16
|
||||
#[no_mangle]
|
||||
pub fn x87_fpu_floating_point_handler(param: &IsrParam) {
|
||||
print_exception(param)
|
||||
}
|
||||
|
||||
/// isr17
|
||||
#[no_mangle]
|
||||
pub fn alignment_check_handler(param: &IsrParam) {
|
||||
print_exception(param)
|
||||
}
|
||||
|
||||
/// isr18
|
||||
#[no_mangle]
|
||||
pub fn machine_check_handler(param: &IsrParam) {
|
||||
print_exception(param)
|
||||
}
|
||||
|
||||
/// isr19
|
||||
#[no_mangle]
|
||||
pub fn simd_floating_point_handler(param: &IsrParam) {
|
||||
print_exception(param)
|
||||
}
|
||||
|
||||
/// isr20
|
||||
#[no_mangle]
|
||||
pub fn virtualization_handler(param: &IsrParam) {
|
||||
print_exception(param)
|
||||
}
|
||||
|
||||
|
||||
/// isr15, 21-31
|
||||
#[no_mangle]
|
||||
pub fn reserved_handler(param: &IsrParam) {
|
||||
print_exception(param)
|
||||
}
|
||||
@ -1,4 +0,0 @@
|
||||
pub mod gdt;
|
||||
pub mod idt;
|
||||
pub mod interrupt;
|
||||
pub mod segment;
|
||||
@ -1,19 +0,0 @@
|
||||
use x86::segmentation::SegmentSelector;
|
||||
use x86::Ring;
|
||||
|
||||
pub const NULL_SELECTOR: SegmentSelector = SegmentSelector::new(0, Ring::Ring0);
|
||||
pub const KERNEL_CODE_SELECTOR: SegmentSelector = SegmentSelector::new(1, Ring::Ring0);
|
||||
pub const KERNEL_DATA_SELECTOR: SegmentSelector = SegmentSelector::new(2, Ring::Ring0);
|
||||
pub const USER_CODE_SELECTOR: SegmentSelector = SegmentSelector::new(3, Ring::Ring3);
|
||||
pub const USER_DATA_SELECTOR: SegmentSelector = SegmentSelector::new(4, Ring::Ring3);
|
||||
|
||||
#[no_mangle]
|
||||
pub static NULL_SEL: u16 = NULL_SELECTOR.bits();
|
||||
#[no_mangle]
|
||||
pub static KERNEL_CODE_SEL: u16 = KERNEL_CODE_SELECTOR.bits();
|
||||
#[no_mangle]
|
||||
pub static KERNEL_DATA_SEL: u16 = KERNEL_DATA_SELECTOR.bits();
|
||||
#[no_mangle]
|
||||
pub static USER_CODE_SEL: u16 = USER_CODE_SELECTOR.bits();
|
||||
#[no_mangle]
|
||||
pub static USER_DATA_SEL: u16 = USER_DATA_SELECTOR.bits();
|
||||
@ -1,78 +0,0 @@
|
||||
// src/kernel/kernel.rs
|
||||
use core::arch::asm;
|
||||
use crate::kernel::tty::tty;
|
||||
use crate::hal::cpu;
|
||||
use crate::{print, println};
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn _kernel_init() {
|
||||
// TODO: 加載 GDT OK
|
||||
// TODO: 加載 IDT OK
|
||||
// TODO: 啟用分頁
|
||||
tty::tty_init(tty::VGA_BUFFER_PADDR);
|
||||
tty::tty_set_theme(tty::VGA_COLOR_WHITE, tty::VGA_COLOR_BLACK);
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn _kernel_post_init() {
|
||||
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn _kernel_main() {
|
||||
|
||||
println!("Loading....!");
|
||||
|
||||
// tty::tty_clear();
|
||||
|
||||
println!("Welcome to Cure OS!");
|
||||
|
||||
println!("{0} + {1} = {0}", 1, 2);
|
||||
|
||||
let name = "111";
|
||||
let age = 25;
|
||||
println!("{}, {}", name, age);
|
||||
|
||||
let value = 42;
|
||||
println!("10: {}, 16: {:x}", value, value);
|
||||
|
||||
let mut brand_buffer = [0u8; 64];
|
||||
println!("{}", cpu::cpu_get_brand(&mut brand_buffer));
|
||||
println!("{}", cpu::cpu_get_model(&mut brand_buffer));
|
||||
|
||||
unsafe {
|
||||
let eflags: u32;
|
||||
asm!("pushfd; pop {}", out(reg) eflags);
|
||||
println!("Current EFLAGS: 0x{:x}", eflags);
|
||||
}
|
||||
|
||||
// unsafe {
|
||||
// core::arch::asm!(
|
||||
// "movl $0, %eax",
|
||||
// "movl $0, %ebx",
|
||||
// "divl %ebx",
|
||||
// options(att_syntax)
|
||||
// );
|
||||
// }
|
||||
|
||||
unsafe {
|
||||
asm!(
|
||||
"mov ax, 0x27",
|
||||
"mov ds, ax",
|
||||
options(nostack)
|
||||
);
|
||||
}
|
||||
|
||||
// cpu::cpu_enable_interrupts();
|
||||
|
||||
// unsafe {
|
||||
// core::arch::asm!(
|
||||
// "int $13",
|
||||
// options(att_syntax)
|
||||
// );
|
||||
// }
|
||||
|
||||
loop {
|
||||
cpu::cpu_idle();
|
||||
}
|
||||
}
|
||||
@ -1,6 +0,0 @@
|
||||
pub mod kernel;
|
||||
pub mod tty;
|
||||
pub mod asm;
|
||||
|
||||
// 重新導出由 boot.S 調用的入口點
|
||||
// pub use kernel::{_kernel_init, _kernel_main};
|
||||
@ -1,15 +0,0 @@
|
||||
// src/kernel/tty/mod.rs
|
||||
|
||||
pub mod tty;
|
||||
|
||||
pub use tty::tty_init;
|
||||
pub use tty::tty_set_buffer;
|
||||
pub use tty::tty_set_theme;
|
||||
pub use tty::tty_put_char;
|
||||
pub use tty::tty_put_str;
|
||||
pub use tty::tty_scroll_up;
|
||||
pub use tty::tty_clear;
|
||||
pub use tty::tty_clear_line;
|
||||
pub use tty::tty_set_cpos;
|
||||
pub use tty::tty_get_cpos;
|
||||
pub use tty::tty_get_theme;
|
||||
@ -1,252 +0,0 @@
|
||||
// src/kernel/tty/tty.rs
|
||||
|
||||
use crate::hal::io;
|
||||
use core::ptr::NonNull;
|
||||
|
||||
/// VGA 屬性類型 (16位)
|
||||
#[allow(dead_code)]
|
||||
pub type VgaAttribute = u16;
|
||||
|
||||
// VGA 顏色常量
|
||||
#[allow(dead_code)]
|
||||
pub const VGA_COLOR_BLACK: u8 = 0;
|
||||
#[allow(dead_code)]
|
||||
pub const VGA_COLOR_BLUE: u8 = 1;
|
||||
#[allow(dead_code)]
|
||||
pub const VGA_COLOR_GREEN: u8 = 2;
|
||||
#[allow(dead_code)]
|
||||
pub const VGA_COLOR_CYAN: u8 = 3;
|
||||
#[allow(dead_code)]
|
||||
pub const VGA_COLOR_RED: u8 = 4;
|
||||
#[allow(dead_code)]
|
||||
pub const VGA_COLOR_MAGENTA: u8 = 5;
|
||||
#[allow(dead_code)]
|
||||
pub const VGA_COLOR_BROWN: u8 = 6;
|
||||
#[allow(dead_code)]
|
||||
pub const VGA_COLOR_LIGHT_GREY: u8 = 7;
|
||||
#[allow(dead_code)]
|
||||
pub const VGA_COLOR_DARK_GREY: u8 = 8;
|
||||
#[allow(dead_code)]
|
||||
pub const VGA_COLOR_LIGHT_BLUE: u8 = 9;
|
||||
#[allow(dead_code)]
|
||||
pub const VGA_COLOR_LIGHT_GREEN: u8 = 10;
|
||||
#[allow(dead_code)]
|
||||
pub const VGA_COLOR_LIGHT_CYAN: u8 = 11;
|
||||
#[allow(dead_code)]
|
||||
pub const VGA_COLOR_LIGHT_RED: u8 = 12;
|
||||
#[allow(dead_code)]
|
||||
pub const VGA_COLOR_LIGHT_MAGENTA: u8 = 13;
|
||||
#[allow(dead_code)]
|
||||
pub const VGA_COLOR_LIGHT_BROWN: u8 = 14;
|
||||
#[allow(dead_code)]
|
||||
pub const VGA_COLOR_WHITE: u8 = 15;
|
||||
#[allow(dead_code)]
|
||||
pub const VGA_BUFFER_PADDR: usize = 0xB8000;
|
||||
|
||||
#[allow(dead_code)]
|
||||
const TTY_WIDTH: usize = 80;
|
||||
#[allow(dead_code)]
|
||||
const TTY_HEIGHT: usize = 25;
|
||||
#[allow(dead_code)]
|
||||
const VGA_CTRL_PORT: u16 = 0x3D4;
|
||||
#[allow(dead_code)]
|
||||
const VGA_DATA_PORT: u16 = 0x3D5;
|
||||
|
||||
// 全局 TTY 狀態
|
||||
pub struct TTYState {
|
||||
vga_buffer: Option<NonNull<VgaAttribute>>,
|
||||
theme_color: VgaAttribute,
|
||||
x: usize,
|
||||
y: usize,
|
||||
}
|
||||
|
||||
impl TTYState {
|
||||
const fn new() -> Self {
|
||||
Self {
|
||||
vga_buffer: None,
|
||||
theme_color: (VGA_COLOR_BLACK as VgaAttribute) << 8,
|
||||
x: 0,
|
||||
y: 0,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static mut TTY_STATE: TTYState = TTYState::new();
|
||||
|
||||
// #[no_mangle]
|
||||
// fn update_cursor() {
|
||||
// unsafe {
|
||||
// let pos = TTY_STATE.y * TTY_WIDTH + TTY_STATE.x;
|
||||
|
||||
// io::io_port_wb(VGA_CTRL_PORT, 0x0F);
|
||||
// io::io_port_wb(VGA_DATA_PORT, (pos & 0xFF) as u8);
|
||||
// io::io_port_wb(VGA_CTRL_PORT, 0x0E);
|
||||
// io::io_port_wb(VGA_DATA_PORT, ((pos >> 8) & 0xFF) as u8);
|
||||
// }
|
||||
// }
|
||||
|
||||
/// 初始化 TTY
|
||||
// vga_buf: *mut u8
|
||||
#[no_mangle]
|
||||
pub fn tty_init(vga_buf: usize) {
|
||||
unsafe {
|
||||
TTY_STATE.vga_buffer = NonNull::new(vga_buf as *mut VgaAttribute);
|
||||
tty_clear();
|
||||
}
|
||||
}
|
||||
|
||||
/// 設置 VGA 緩衝區
|
||||
#[no_mangle]
|
||||
pub fn tty_set_buffer(vga_buf: usize) {
|
||||
unsafe {
|
||||
TTY_STATE.vga_buffer = NonNull::new(vga_buf as *mut VgaAttribute);
|
||||
}
|
||||
}
|
||||
|
||||
/// 設置主題顏色(前景色和背景色)
|
||||
#[no_mangle]
|
||||
pub fn tty_set_theme(fg: u8, bg: u8) {
|
||||
unsafe {
|
||||
TTY_STATE.theme_color = ((bg << 4 | fg) as VgaAttribute) << 8;
|
||||
}
|
||||
}
|
||||
|
||||
/// 向 TTY 輸出單個字符
|
||||
///
|
||||
/// # 注意
|
||||
/// - 僅支援 ASCII 範圍 (0-255) 的字符
|
||||
/// - 多字節 Unicode 字符會被截斷為低 8 位
|
||||
/// - '\t' 擴展為 4 個空格
|
||||
/// - '\n' 換行並將游標移至行首
|
||||
/// - '\r' 將游標移至行首
|
||||
#[no_mangle]
|
||||
pub fn tty_put_char(chr: char) {
|
||||
unsafe {
|
||||
if let Some(vga_ptr) = TTY_STATE.vga_buffer {
|
||||
match chr {
|
||||
'\t' => {
|
||||
TTY_STATE.x += 4;
|
||||
}
|
||||
'\n' => {
|
||||
TTY_STATE.y += 1;
|
||||
TTY_STATE.x = 0;
|
||||
}
|
||||
'\r' => {
|
||||
TTY_STATE.x = 0;
|
||||
}
|
||||
_ => {
|
||||
let offset = TTY_STATE.x + TTY_STATE.y * TTY_WIDTH;
|
||||
// VGA 文本模式僅支持 8 位字符
|
||||
*vga_ptr.as_ptr().add(offset) = TTY_STATE.theme_color | (chr as u8) as VgaAttribute;
|
||||
TTY_STATE.x += 1;
|
||||
}
|
||||
}
|
||||
|
||||
if TTY_STATE.x >= TTY_WIDTH {
|
||||
TTY_STATE.x = 0;
|
||||
TTY_STATE.y += 1;
|
||||
}
|
||||
|
||||
if TTY_STATE.y >= TTY_HEIGHT {
|
||||
tty_scroll_up();
|
||||
}
|
||||
|
||||
// update_cursor();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// 向 TTY 輸出字符串
|
||||
///
|
||||
/// # 注意
|
||||
/// - 字符串中的多字節 Unicode 字符會被截斷為低 8 位
|
||||
/// - 支持 Rust 字符串切片 (&str)
|
||||
#[no_mangle]
|
||||
pub fn tty_put_str(s: &str) {
|
||||
for chr in s.chars() {
|
||||
tty_put_char(chr);
|
||||
}
|
||||
}
|
||||
|
||||
/// 向上滾動一行
|
||||
#[no_mangle]
|
||||
pub fn tty_scroll_up() {
|
||||
unsafe {
|
||||
if let Some(vga_ptr) = TTY_STATE.vga_buffer {
|
||||
let last_line = TTY_WIDTH * (TTY_HEIGHT - 1);
|
||||
let buffer_ptr = vga_ptr.as_ptr();
|
||||
|
||||
// 將所有行向上移動一行
|
||||
core::ptr::copy(
|
||||
buffer_ptr.add(TTY_WIDTH),
|
||||
buffer_ptr,
|
||||
last_line
|
||||
);
|
||||
|
||||
// 清空最後一行
|
||||
for i in 0..TTY_WIDTH {
|
||||
*buffer_ptr.add(i + last_line) = TTY_STATE.theme_color;
|
||||
}
|
||||
|
||||
TTY_STATE.y = if TTY_STATE.y == 0 { 0 } else { TTY_HEIGHT - 1 };
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// 清空屏幕
|
||||
#[no_mangle]
|
||||
pub fn tty_clear() {
|
||||
unsafe {
|
||||
if let Some(vga_ptr) = TTY_STATE.vga_buffer {
|
||||
let buffer_ptr = vga_ptr.as_ptr();
|
||||
|
||||
for i in 0..(TTY_WIDTH * TTY_HEIGHT) {
|
||||
*buffer_ptr.add(i) = TTY_STATE.theme_color;
|
||||
}
|
||||
|
||||
TTY_STATE.x = 0;
|
||||
TTY_STATE.y = 0;
|
||||
// update_cursor();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// 清空指定行
|
||||
#[no_mangle]
|
||||
pub fn tty_clear_line(y: usize) {
|
||||
unsafe {
|
||||
if let Some(vga_ptr) = TTY_STATE.vga_buffer {
|
||||
let buffer_ptr = vga_ptr.as_ptr();
|
||||
|
||||
for i in 0..TTY_WIDTH {
|
||||
*buffer_ptr.add(i + y * TTY_WIDTH) = TTY_STATE.theme_color;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// 設置游標位置
|
||||
#[no_mangle]
|
||||
pub fn tty_set_cpos(x: usize, y: usize) {
|
||||
unsafe {
|
||||
TTY_STATE.x = x % TTY_WIDTH;
|
||||
TTY_STATE.y = y % TTY_HEIGHT;
|
||||
// update_cursor();
|
||||
}
|
||||
}
|
||||
|
||||
/// 獲取游標位置
|
||||
#[no_mangle]
|
||||
pub fn tty_get_cpos() -> (usize, usize) {
|
||||
unsafe {
|
||||
(TTY_STATE.x, TTY_STATE.y)
|
||||
}
|
||||
}
|
||||
|
||||
/// 獲取當前主題顏色
|
||||
#[no_mangle]
|
||||
pub fn tty_get_theme() -> VgaAttribute {
|
||||
unsafe {
|
||||
TTY_STATE.theme_color
|
||||
}
|
||||
}
|
||||
13
src/lib.rs
13
src/lib.rs
@ -1,13 +0,0 @@
|
||||
#![no_std]
|
||||
#![no_main]
|
||||
|
||||
mod kernel;
|
||||
mod hal;
|
||||
mod libs;
|
||||
|
||||
use core::panic::PanicInfo;
|
||||
|
||||
#[panic_handler]
|
||||
fn panic(_info: &PanicInfo) -> ! {
|
||||
loop {}
|
||||
}
|
||||
@ -1 +0,0 @@
|
||||
pub mod print;
|
||||
@ -1,29 +0,0 @@
|
||||
// src/libs/libc/print.rs
|
||||
|
||||
use core::fmt;
|
||||
use crate::kernel::tty::tty;
|
||||
|
||||
pub struct Writer;
|
||||
|
||||
impl fmt::Write for Writer {
|
||||
fn write_str(&mut self, s: &str) -> fmt::Result {
|
||||
tty::tty_put_str(s);
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
pub fn _print(args: fmt::Arguments) {
|
||||
use core::fmt::Write;
|
||||
Writer.write_fmt(args).unwrap();
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! print {
|
||||
($($arg:tt)*) => ($crate::libs::libc::print::_print(format_args!($($arg)*)));
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! println {
|
||||
() => ($crate::print!("\n"));
|
||||
($($arg:tt)*) => ($crate::print!("{}\n", format_args!($($arg)*)));
|
||||
}
|
||||
@ -1 +0,0 @@
|
||||
pub mod libc;
|
||||
Loading…
x
Reference in New Issue
Block a user