This commit is contained in:
pjht 2024-06-06 22:02:00 -05:00
parent 8fd2b83b40
commit 8bbc165e58
Signed by: pjht
GPG Key ID: 7B5F6AFBEC7EE78E
17 changed files with 308 additions and 318 deletions

View File

@ -4,7 +4,7 @@ build-std = ["core", "compiler_builtins", "alloc"]
[build]
target = "x86_64-unknown-none"
rustflags = ["-C", "link-args=--image-base 0xffff800000000000", "-C", "force-unwind-tables", "-C", "link-args=/home/pjht/projects/os-rust/kernel/eh_frame.ld"]
rustflags = ["-C", "link-args=--image-base 0xffff800000000000", "-C", "force-unwind-tables", "-C", "link-args=/home/pterpstra/projects/os-rust/kernel/eh_frame.ld"]
[target.'cfg(target_os = "none")']
runner = "./run.sh"

254
Cargo.lock generated
View File

@ -4,32 +4,33 @@ version = 3
[[package]]
name = "ahash"
version = "0.7.6"
version = "0.8.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fcb51a0695d8f838b1ee009b3fbf66bda078cd64590202a864a8f3e8c4315c47"
checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011"
dependencies = [
"getrandom",
"cfg-if",
"once_cell",
"version_check",
"zerocopy",
]
[[package]]
name = "arrayvec"
version = "0.7.2"
name = "allocator-api2"
version = "0.2.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8da52d66c7071e2e3fa2a1e5c6d088fec47b593032b254f5e980de8ea54454d6"
checksum = "5c6cb57a04249c6480766f7f7cef5467412af1490f8d1e243141daddada3264f"
[[package]]
name = "autocfg"
version = "1.1.0"
version = "1.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0"
[[package]]
name = "bit_field"
version = "0.10.1"
version = "0.10.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dcb6dd1c2376d2e096796e234a70e17e94cc2d5d54ff8ce42b28cef1d0d359a4"
checksum = "dc827186963e592360843fb5ba4b973e145841266c1357f7180c43526f2e5b61"
[[package]]
name = "bitflags"
@ -38,10 +39,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
[[package]]
name = "bootloader_api"
version = "0.11.0"
name = "bitflags"
version = "2.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "babfb07dea4565842980315ad530a023aa348db43d03dfa104a70fdaca97d48e"
checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1"
[[package]]
name = "bootloader_api"
version = "0.11.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a35ba5100c2431e20b924c8103c2cf8adb919ed9880f625e8770c3cb9d1b06aa"
[[package]]
name = "cfg-if"
@ -51,65 +58,46 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "crossbeam-queue"
version = "0.3.6"
version = "0.3.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1cd42583b04998a5363558e5f9291ee5a5ff6b49944332103f251e7479a82aa7"
checksum = "df0346b5d5e76ac2fe4e327c5fd1118d6be7c51dfb18f9b7922923f287471e35"
dependencies = [
"cfg-if",
"crossbeam-utils",
]
[[package]]
name = "crossbeam-utils"
version = "0.8.12"
version = "0.8.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "edbafec5fa1f196ca66527c1b12c2ec4745ca14b50f1ad8f9f6f720b55d11fac"
dependencies = [
"cfg-if",
]
checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80"
[[package]]
name = "elfloader"
version = "0.14.0"
name = "elf"
version = "0.7.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a249d6a9d50f3bf5a3cb7bfd75e84989cad89c6c77b5996c8b084e844146ff04"
dependencies = [
"bitflags",
"log",
"xmas-elf",
]
[[package]]
name = "getrandom"
version = "0.2.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c05aeb6a22b8f62540c194aac980f2115af067bfe15a0734d7277a768d396b31"
dependencies = [
"cfg-if",
"libc",
"wasi",
]
checksum = "4445909572dbd556c457c849c4ca58623d84b27c8fff1e74b0b4227d8b90d17b"
[[package]]
name = "gimli"
version = "0.26.2"
version = "0.28.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "22030e2c5a68ec659fde1e949a745124b48e6fa8b045b7ed5bd1fe4ccc5c4e5d"
checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253"
[[package]]
name = "hashbrown"
version = "0.12.3"
version = "0.14.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888"
checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1"
dependencies = [
"ahash",
"allocator-api2",
]
[[package]]
name = "intrusive-collections"
version = "0.9.4"
version = "0.9.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bfe531a7789d7120f3e17d4f3f2cd95f54418ba7354f60b7b622b6644a07888a"
checksum = "b694dc9f70c3bda874626d2aed13b780f137aab435f4e9814121955cf706122e"
dependencies = [
"memoffset",
]
@ -120,7 +108,7 @@ version = "0.1.0"
dependencies = [
"bootloader_api",
"crossbeam-queue",
"elfloader",
"elf",
"hashbrown",
"intrusive-collections",
"linked_list_allocator",
@ -136,26 +124,20 @@ dependencies = [
"x86_64",
]
[[package]]
name = "libc"
version = "0.2.137"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fc7fcc620a3bff7cdd7a365be3376c97191aeaccc2a603e600951e452615bf89"
[[package]]
name = "linked_list_allocator"
version = "0.9.1"
version = "0.10.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "549ce1740e46b291953c4340adcd74c59bcf4308f4cac050fd33ba91b7168f4a"
checksum = "9afa463f5405ee81cdb9cc2baf37e08ec7e4c8209442b5d72c04cfb2cd6e6286"
dependencies = [
"spinning_top",
]
[[package]]
name = "lock_api"
version = "0.4.9"
version = "0.4.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "435011366fe56583b16cf956f9df0095b405b82d76425bc8981c0e22e60ec4df"
checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17"
dependencies = [
"autocfg",
"scopeguard",
@ -163,37 +145,76 @@ dependencies = [
[[package]]
name = "log"
version = "0.4.17"
version = "0.4.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e"
dependencies = [
"cfg-if",
]
checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c"
[[package]]
name = "memchr"
version = "2.7.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6c8640c5d730cb13ebd907d8d04b52f55ac9a2eec55b440c8892f40d56c76c1d"
[[package]]
name = "memoffset"
version = "0.5.6"
version = "0.9.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "043175f069eda7b85febe4a74abbaeff828d9f8b448515d3151a14a3542811aa"
checksum = "488016bfae457b036d996092f6cb448677611ce4449e970ceaf42695203f218a"
dependencies = [
"autocfg",
]
[[package]]
name = "num-traits"
version = "0.2.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841"
dependencies = [
"autocfg",
]
[[package]]
name = "once_cell"
version = "1.15.0"
version = "1.19.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e82dad04139b71a90c080c8463fe0dc7902db5192d939bd0950f074d014339e1"
checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92"
[[package]]
name = "pic8259"
version = "0.10.2"
version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "24ec21f514e2e16e94649f1d041ca4a7069b512c037ac156360652a775e6229d"
checksum = "62d9a86c292b165f757e47e7fd66855def189b2564609bc4203727b27c33db22"
dependencies = [
"x86_64",
]
[[package]]
name = "proc-macro2"
version = "1.0.85"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "22244ce15aa966053a896d1accb3a6e68469b97c7f33f284b99f0d576879fc23"
dependencies = [
"unicode-ident",
]
[[package]]
name = "quote"
version = "1.0.36"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7"
dependencies = [
"proc-macro2",
]
[[package]]
name = "raw-cpuid"
version = "10.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6c297679cb867470fa8c9f67dbba74a78d78e3e98d7cf2b08d6d71540f797332"
dependencies = [
"bitflags 1.3.2",
]
[[package]]
name = "replace_with"
version = "0.1.7"
@ -202,39 +223,39 @@ checksum = "e3a8614ee435691de62bcffcf4a66d91b3594bf1428a5722e79103249a095690"
[[package]]
name = "rustversion"
version = "1.0.9"
version = "1.0.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "97477e48b4cf8603ad5f7aaf897467cf42ab4218a38ef76fb14c2d6773a6d6a8"
checksum = "955d28af4278de8121b7ebeb796b6a45735dc01436d898801014aced2773a3d6"
[[package]]
name = "scopeguard"
version = "1.1.0"
version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
[[package]]
name = "slab"
version = "0.4.7"
version = "0.4.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4614a76b2a8be0058caa9dbbaf66d988527d86d003c11a94fbd335d7661edcef"
checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67"
dependencies = [
"autocfg",
]
[[package]]
name = "spin"
version = "0.9.4"
version = "0.9.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7f6002a767bff9e83f8eeecf883ecb8011875a21ae8da43bffb817a57e78cc09"
checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67"
dependencies = [
"lock_api",
]
[[package]]
name = "spinning_top"
version = "0.2.4"
version = "0.2.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "75adad84ee84b521fb2cca2d4fd0f1dab1d8d026bda3c5bea4ca63b5f9f9293c"
checksum = "5b9eb1a2f4c41445a3a0ff9abc5221c5fcd28e1f13cd7c0397706f9ac938ddb0"
dependencies = [
"lock_api",
]
@ -245,6 +266,17 @@ version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f"
[[package]]
name = "syn"
version = "2.0.66"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c42f3f41a2de00b01c0aaad383c5a45241efc8b2d1eda5661812fda5f3cdcff5"
dependencies = [
"proc-macro2",
"quote",
"unicode-ident",
]
[[package]]
name = "tap"
version = "1.0.1"
@ -253,27 +285,36 @@ checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369"
[[package]]
name = "tar-no-std"
version = "0.1.7"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4d897790ee033615752cc7bf882343881ad748438c01bc7e1b9d6242bf14a2c6"
dependencies = [
"arrayvec",
"bitflags",
"bitflags 2.5.0",
"log",
"memchr",
"num-traits",
]
[[package]]
name = "uart_16550"
version = "0.2.18"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b074eb9300ad949edd74c529c0e8d451625af71bb948e6b65fe69f72dc1363d9"
checksum = "6dc00444796f6c71f47c85397a35e9c4dbf9901902ac02386940d178e2b78687"
dependencies = [
"bitflags",
"bitflags 1.3.2",
"rustversion",
"x86_64",
"x86",
]
[[package]]
name = "unicode-ident"
version = "1.0.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b"
[[package]]
name = "unwinding"
version = "0.1.5"
version = "0.2.1"
dependencies = [
"gimli",
]
@ -286,38 +327,49 @@ checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
[[package]]
name = "volatile"
version = "0.4.5"
version = "0.4.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e3ca98349dda8a60ae74e04fd90c7fb4d6a4fbe01e6d3be095478aa0b76f6c0c"
checksum = "442887c63f2c839b346c192d047a7c87e73d0689c9157b00b53dcc27dd5ea793"
[[package]]
name = "wasi"
version = "0.11.0+wasi-snapshot-preview1"
name = "x86"
version = "0.52.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
checksum = "2781db97787217ad2a2845c396a5efe286f87467a5810836db6d74926e94a385"
dependencies = [
"bit_field",
"bitflags 1.3.2",
"raw-cpuid",
]
[[package]]
name = "x86_64"
version = "0.14.10"
source = "git+https://github.com/pjht/x86_64#5d941e68fa70779e07576d42a9f49bc89afdb9ed"
version = "0.15.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4bc79523af8abf92fb1a970c3e086c5a343f6bcc1a0eb890f575cbb3b45743df"
dependencies = [
"bit_field",
"bitflags",
"bitflags 2.5.0",
"rustversion",
"volatile",
]
[[package]]
name = "xmas-elf"
version = "0.8.0"
name = "zerocopy"
version = "0.7.34"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8d29b4d8e7beaceb4e77447ba941a7600d23d0319ab52da0461abea214832d5a"
checksum = "ae87e3fcd617500e5d106f0380cf7b77f3c6092aae37191433159dda23cfb087"
dependencies = [
"zero",
"zerocopy-derive",
]
[[package]]
name = "zero"
version = "0.1.2"
name = "zerocopy-derive"
version = "0.7.34"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5f1bc8a6b2005884962297587045002d8cfb8dcec9db332f4ca216ddc5de82c5"
checksum = "15e934569e47891f7d9411f1a451d947a60e000ab3bd24fbb970f000387d1b3b"
dependencies = [
"proc-macro2",
"quote",
"syn",
]

View File

@ -4,21 +4,21 @@ version = "0.1.0"
edition = "2021"
[dependencies]
x86_64 = { git = "https://github.com/pjht/x86_64", features = ["experimental"] }
tar-no-std = { path = "../tar-no-std" }
# x86_64 = { git = "https://gitea.pterpstra.com/mikros/x86_64" }
tar-no-std = { version = "0.3.0" }
unwinding = { path = "../unwinding", default-features = false, features = ["personality", "panic", "unwinder", "fde-static", "hide-trace"] }
uart_16550 = "0.2.18"
spin = "0.9.4"
linked_list_allocator = "0.10.4"
elfloader = "0.16.0"
uart_16550 = "0.3.0"
spin = "0.9.8"
linked_list_allocator = "0.10.5"
tap = "1.0.1"
replace_with = { version = "0.1.7", default-features = false, features = ["nightly"] }
hashbrown = "0.13.1"
pic8259 = "0.10.2"
bootloader_api = "0.11.0"
hashbrown = "0.14.5"
pic8259 = "0.11.0"
bootloader_api = "0.11.7"
static_assertions = "1.1.0"
crossbeam-queue = { version = "0.3.8", default-features = false, features = ["alloc"] }
slab = { version = "0.4.7", default-features = false }
intrusive-collections = "0.9.4"
xmas-elf = "0.8.0"
crossbeam-queue = { version = "0.3.11", default-features = false, features = ["alloc"] }
slab = { version = "0.4.9", default-features = false }
intrusive-collections = "0.9.6"
elf = { version = "0.7.4", default-features = false }
x86_64 = "0.15.1"

View File

@ -1,18 +0,0 @@
use std::process::Command;
fn main() {
println!("cargo:rerun-if-changed=sysroot");
println!("cargo:rerun-if-changed=build.rs");
println!(
"{}",
String::from_utf8(
Command::new("sh")
.arg("-c")
.arg("cd sysroot; tar cvf ../initrd.tar *")
.output()
.expect("failed to execute process")
.stdout
)
.expect("command output not valid utf8")
);
}

Binary file not shown.

View File

@ -1,3 +1,5 @@
use core::ptr::addr_of;
use x86_64::{
instructions::tables::load_tss,
registers::segmentation::{Segment, SegmentSelector, CS, SS},
@ -26,15 +28,12 @@ static mut TSS: TaskStateSegment = TaskStateSegment::new();
static GDT: Lazy<GDTAndSelectors> = Lazy::new(|| {
let mut gdt = GlobalDescriptorTable::new();
let selectors = Selectors {
code_sel: gdt.add_entry(Descriptor::kernel_code_segment()),
data_sel: gdt.add_entry(Descriptor::kernel_data_segment()),
// SAFETY: This might actually be unsafe, as we are passing in a
// shared reference to the TSS but we can mutate it via `set_tss_stack`,
// but since it immediately turns the ref into a pointer, and the CPU never
// reads the TSS outside of ring switches, it should be safe.
tss_sel: gdt.add_entry(Descriptor::tss_segment(unsafe { &TSS })),
user_data_sel: gdt.add_entry(Descriptor::user_data_segment()),
user_code_sel: gdt.add_entry(Descriptor::user_code_segment()),
code_sel: gdt.append(Descriptor::kernel_code_segment()),
data_sel: gdt.append(Descriptor::kernel_data_segment()),
// SAFETY: The TSS is a static and thus a pointer to it will always be valid
tss_sel: gdt.append(unsafe { Descriptor::tss_segment_unchecked(addr_of!(TSS))}),
user_data_sel: gdt.append(Descriptor::user_data_segment()),
user_code_sel: gdt.append(Descriptor::user_code_segment()),
};
GDTAndSelectors { gdt, selectors }
});

View File

@ -1,10 +1,8 @@
use crate::{
dbg, print, println,
virtual_memory::{ASpaceMutex, AddressSpace, ACTIVE_SPACE, KERNEL_SPACE},
INITRD, TASKING,
bootinfo::BOOTINFO, dbg, print, println, virtual_memory::{ASpaceMutex, AddressSpace, ACTIVE_SPACE, KERNEL_SPACE}, TASKING
};
use alloc::{boxed::Box, vec::Vec};
use core::{arch::asm, ptr::addr_of, str};
use core::{arch::asm, ptr::{addr_of, slice_from_raw_parts_mut}, slice, str};
use hashbrown::HashMap;
use pic8259::ChainedPics;
use spin::{Lazy, Mutex, RwLock};
@ -75,6 +73,7 @@ pub struct InvalidIrq;
pub fn init() {
IDT.load();
unsafe { PICS.lock().initialize() };
unsafe { PICS.lock().write_masks(0, 0) };
x86_64::instructions::interrupts::enable();
}
@ -85,8 +84,8 @@ extern "x86-interrupt" fn page_fault_handler(
if error_code.contains(PageFaultErrorCode::PROTECTION_VIOLATION) {
panic!(
"Got Page Fault {error_code:#?} at {:#x}\nEntry flags: {:#?}\n{stack_frame:#?}",
Cr2::read(),
match ACTIVE_SPACE.lock().translate(Cr2::read()) {
Cr2::read().unwrap(),
match ACTIVE_SPACE.lock().translate(Cr2::read().unwrap()) {
TranslateResult::Mapped { flags, .. } => flags,
_ => {
panic!();
@ -94,7 +93,7 @@ extern "x86-interrupt" fn page_fault_handler(
},
);
} else {
panic!("Got Page Fault {error_code:#?} at {:#x}\n{stack_frame:#?}", Cr2::read(),);
panic!("Got Page Fault {error_code:#?} at {:#x}\n{stack_frame:#?}", Cr2::read().unwrap(),);
}
}
@ -132,7 +131,7 @@ fn irq_handler(_stack_frame: InterruptStackFrame, index: u8, _error_code: Option
}
#[repr(C)]
#[derive(Debug)]
#[derive(Debug, Clone, Copy)]
struct SyscallRegs {
rax: u64,
rbx: u64,
@ -211,13 +210,10 @@ static REGISTERD_PIDS: Lazy<RwLock<HashMap<u64, u64>>> = Lazy::new(|| RwLock::ne
#[no_mangle]
#[allow(clippy::unit_arg)]
extern "C" fn syscall_handler() {
let regs = unsafe { &SYSCALL_REGS };
let regs = unsafe { SYSCALL_REGS };
let mut retval = 0;
let mut retval2 = regs.rcx;
let mut retval3 = regs.rdx;
// if regs.rax == 16 {
// println!("Syscall {}", regs.rax);
// }
match regs.rax {
0 => {
retval = if let Some(chr) = char::from_u32(regs.rcx as u32) {
@ -245,9 +241,14 @@ extern "C" fn syscall_handler() {
}
}
3 => {
let initrd = unsafe {
let ramdisk_start = BOOTINFO.ramdisk_addr.into_option().expect("ramdisk to be present");
let ramdisk_len = BOOTINFO.ramdisk_len;
slice::from_raw_parts(ramdisk_start as *const u8, ramdisk_len as usize)
};
let initrd = Box::leak(
Vec::with_capacity_in(INITRD.len(), &*ACTIVE_SPACE)
.tap_mut(|v| v.extend_from_slice(INITRD))
Vec::with_capacity_in(initrd.len(), &*ACTIVE_SPACE)
.tap_mut(|v| v.extend_from_slice(initrd))
.into_boxed_slice(),
);
retval = addr_of!(initrd[0]) as u64;
@ -280,17 +281,8 @@ extern "C" fn syscall_handler() {
if let Some(buffer) = get_buffer(regs.rdx) {
let len = regs.rdi;
assert!(len <= buffer.len() as u64);
// let aligned_address = regs.rsi & !0xFFF;
// let aligned_len = len as u64 + (regs.rsi - aligned_address);
let mut tasking = TASKING.lock();
let space = tasking.address_spaces_mut().get_mut((regs.rcx - 1) as usize).unwrap();
// space
// .map_assert_unused(
// Page::from_start_address(VirtAddr::new(aligned_address)).unwrap(),
// aligned_len as usize / 4096 + if aligned_len % 4096 > 0 { 1 } else { 0 },
// PageTableFlags::USER_ACCESSIBLE | PageTableFlags::WRITABLE,
// )
// .unwrap();
space.run(|| unsafe { (regs.rsi as *mut u8).copy_from(&buffer[0], len as usize) });
retval = 0;
} else {
@ -352,7 +344,20 @@ extern "C" fn syscall_handler() {
retval = TASKING.lock().current_pid().unwrap() as u64;
}
14 => {
// AVAILABLE
let page = Page::from_start_address(VirtAddr::new(regs.rdx)).unwrap();
let num_pages = regs.rsi as usize;
let flags = PageTableFlags::from_bits_truncate(regs.rdi);
retval = if regs.rcx == 0 {
ACTIVE_SPACE.lock().map_only_unused(page, num_pages, flags)
} else {
TASKING
.lock()
.address_spaces_mut()
.get_mut((regs.rcx - 1) as usize)
.unwrap()
.map_only_unused(page, num_pages, flags)
}
.is_err() as u64;
}
15 => {
get_buffer(regs.rcx);
@ -361,13 +366,7 @@ extern "C" fn syscall_handler() {
let size = regs.rcx as usize;
let rounded_size = size + (4096 - (size % 4096));
KERNEL_SPACE.lock().alloc_force_user = true;
// let buffer = Box::into_raw(
// Vec::with_capacity_in(rounded_size, &*KERNEL_SPACE)
// .tap_mut(|v| v.resize(rounded_size, 0))
// .into_boxed_slice(),
// );
let mut buffer = Vec::with_capacity_in(rounded_size, &*KERNEL_SPACE);
// dbg!(KERNEL_SPACE.lock().translate(VirtAddr::new(0xffff_8000_003f_f000)));
buffer.resize(rounded_size, 0);
let buffer = buffer.into_boxed_slice();
let buffer = Box::into_raw(buffer);
@ -376,11 +375,14 @@ extern "C" fn syscall_handler() {
retval2 = buffer as *mut u8 as u64;
retval3 = rounded_size as u64;
}
17 => {
let mut tasking = TASKING.lock();
let space = tasking.address_spaces_mut().get_mut((regs.rcx - 1) as usize).unwrap();
space.run(|| unsafe { slice::from_raw_parts_mut(regs.rdx as *mut u8, regs.rsi as usize).fill(0) });
retval = 0;
}
_ => (),
};
// if regs.rax == 16 {
// println!("Syscall {} done", regs.rax);
// }
unsafe {
asm!(
"mov rbx, [rip+SYSCALL_REGS+8]",

View File

@ -19,51 +19,110 @@ mod physical_memory;
mod pit;
mod qemu_exit;
mod serial;
mod simple_loader;
mod start;
mod tasking;
mod virtual_memory;
use elfloader::ElfBinary;
use simple_loader::SimpleLoader;
use core::{slice, usize};
use bootinfo::BOOTINFO;
use elf::{abi::{PT_DYNAMIC, PT_GNU_EH_FRAME, PT_GNU_RELRO, PT_GNU_STACK, PT_LOAD, PT_NULL, PT_PHDR, R_X86_64_RELATIVE, SHT_REL, SHT_RELA}, endian::AnyEndian, ElfBytes};
use tar_no_std::TarArchiveRef;
use tasking::TASKING;
use x86_64::registers::rflags::{self, RFlags};
use x86_64::{registers::rflags::{self, RFlags}, structures::paging::{Page, PageTableFlags}, VirtAddr};
pub static INITRD: &[u8] = include_bytes!("../initrd.tar");
use crate::virtual_memory::AddressSpace;
// pub static INITRD: &[u8] = include_bytes!("../initrd.tar");
pub fn main() {
dbg!();
let mut rflags_data = rflags::read();
dbg!();
rflags_data |= RFlags::IOPL_HIGH | RFlags::IOPL_LOW;
dbg!();
unsafe {
rflags::write(rflags_data);
}
dbg!();
gdt::init();
dbg!();
interrupts::init();
dbg!();
pit::init(100);
dbg!();
let initrd = TarArchiveRef::new(INITRD);
dbg!();
let init = initrd
let initrd = unsafe {
let ramdisk_start = BOOTINFO.ramdisk_addr.into_option().expect("ramdisk to be present");
let ramdisk_len = BOOTINFO.ramdisk_len;
slice::from_raw_parts(ramdisk_start as *const u8, ramdisk_len as usize)
};
let initrd = TarArchiveRef::new(initrd).unwrap();
let init_data = initrd
.entries()
.find(|x| x.filename() == *"bin/init")
.find(|x| x.filename().as_str().unwrap() == "bin/init")
.expect("Could not find init in initrd")
.data();
dbg!();
let init = ElfBinary::new(init).expect("Init not an ELF binary");
dbg!();
let init = ElfBytes::<AnyEndian>::minimal_parse(&init_data).unwrap();
let mut init_addr_space = AddressSpace::new().unwrap();
for mut pheader in init.segments().unwrap().iter() {
match pheader.p_type {
PT_NULL => (),
PT_LOAD => {
if pheader.p_vaddr < 0x1000 {
if pheader.p_memsz < 0x1000 {
continue;
}
pheader.p_offset += 0x1000-pheader.p_vaddr;
pheader.p_memsz -= 0x1000-pheader.p_vaddr;
pheader.p_filesz -= 0x1000-pheader.p_vaddr;
pheader.p_vaddr = 0x1000;
}
let start_page = Page::containing_address(VirtAddr::new(pheader.p_vaddr));
let num_pages = (pheader.p_memsz.div_ceil(4096)
+ (pheader.p_vaddr & 0xFFF).div_ceil(4096))
as usize;
assert!(
(start_page.start_address().as_u64() + num_pages as u64 * 4096)
>= (pheader.p_vaddr + pheader.p_memsz)
);
#[allow(clippy::cast_possible_truncation)]
init_addr_space
.map_only_unused(start_page, num_pages, PageTableFlags::USER_ACCESSIBLE)
.expect("Unable to map region");
init_addr_space.run(|| unsafe {
let dst = slice::from_raw_parts_mut(pheader.p_vaddr as *mut u8, pheader.p_memsz as usize);
dst[0..pheader.p_filesz as usize].copy_from_slice(&init_data[(pheader.p_offset as usize)..((pheader.p_offset+pheader.p_filesz) as usize)]);
dst[(pheader.p_filesz as usize)..(pheader.p_memsz as usize)].fill(0)
});
}
PT_GNU_RELRO => (),
PT_GNU_EH_FRAME => (),
PT_GNU_STACK => (),
PT_DYNAMIC => (),
PT_PHDR => (),
_ => println!("Warning: Unimplemented ELF program header type {:#x}", pheader.p_type),
}
}
for section in init.section_headers().unwrap().iter() {
if section.sh_type == SHT_REL {
for rel in init.section_data_as_rels(&section).unwrap() {
match rel.r_type {
_ => unimplemented!("ELF relocation type {}", rel.r_type),
}
}
}
if section.sh_type == SHT_RELA {
for rela in init.section_data_as_relas(&section).unwrap() {
match rela.r_type {
R_X86_64_RELATIVE => {
init_addr_space.run(|| unsafe {
let ptr = rela.r_offset as *mut u64;
ptr.write(rela.r_addend as u64);
});
}
_ => unimplemented!("ELF relocation type {}", rela.r_type),
}
}
}
}
TASKING
.lock()
.new_process(
init.entry_point() as _,
SimpleLoader::load(&init).expect("Failed to load init"),
init.ehdr.e_entry as _,
init_addr_space,
)
.expect("Failed to create init process");
dbg!();
}

View File

@ -3,7 +3,7 @@ fn print_backtrace() {
use core::ffi::c_void;
use unwinding::abi::{UnwindContext, UnwindReasonCode, _Unwind_Backtrace, _Unwind_GetIP};
extern "C" fn callback(
unwind_ctx: &mut UnwindContext<'_>,
unwind_ctx: &UnwindContext<'_>,
_arg: *mut c_void,
) -> UnwindReasonCode {
println!("{:#x}", _Unwind_GetIP(unwind_ctx));

View File

@ -1,106 +0,0 @@
use crate::virtual_memory::{AddressSpace, PagingError};
use core::slice;
use elfloader::{
arch::x86_64::RelocationTypes, ElfBinary, ElfLoader, ElfLoaderErr, Flags, LoadableHeaders,
RelocationEntry, RelocationType, VAddr,
};
use x86_64::{
structures::paging::{Page, PageTableFlags},
VirtAddr,
};
#[derive(Debug)]
pub enum LoadError {
Paging(PagingError),
ElfLoader(ElfLoaderErr),
}
impl From<PagingError> for LoadError {
fn from(err: PagingError) -> Self {
Self::Paging(err)
}
}
impl From<ElfLoaderErr> for LoadError {
fn from(err: ElfLoaderErr) -> Self {
Self::ElfLoader(err)
}
}
pub struct SimpleLoader(AddressSpace);
impl SimpleLoader {
pub fn load(binary: &ElfBinary) -> Result<AddressSpace, LoadError> {
let mut loader = Self(AddressSpace::new()?);
binary.load(&mut loader)?;
Ok(loader.0)
}
}
impl ElfLoader for SimpleLoader {
fn allocate(&mut self, load_headers: LoadableHeaders) -> Result<(), ElfLoaderErr> {
for header in load_headers {
let start_page = Page::containing_address(VirtAddr::new(header.virtual_addr()));
let num_pages = (header.mem_size().div_ceil(4096)
+ (header.virtual_addr() & 0xFFF).div_ceil(4096))
as usize;
assert!(
(start_page.start_address().as_u64() + num_pages as u64 * 4096)
>= (header.virtual_addr() + header.mem_size())
);
#[allow(clippy::cast_possible_truncation)]
self.0
.map_only_unused(start_page, num_pages, PageTableFlags::USER_ACCESSIBLE)
.expect("Unable to map region");
}
Ok(())
}
fn relocate(&mut self, entry: RelocationEntry) -> Result<(), ElfLoaderErr> {
let rel = match entry.rtype {
RelocationType::x86_64(rel) => rel,
_ => panic!("Non x86_64 relocation"),
};
match rel {
RelocationTypes::R_AMD64_NONE => (),
RelocationTypes::R_AMD64_64 => todo!(),
RelocationTypes::R_AMD64_PC32 => todo!(),
RelocationTypes::R_AMD64_GOT32 => todo!(),
RelocationTypes::R_AMD64_PLT32 => todo!(),
RelocationTypes::R_AMD64_COPY => todo!(),
RelocationTypes::R_AMD64_GLOB_DAT => todo!(),
RelocationTypes::R_AMD64_JMP_SLOT => todo!(),
RelocationTypes::R_AMD64_RELATIVE => {
self.0.run(|| unsafe {
let ptr = entry.offset as *mut u64;
ptr.write(entry.addend.unwrap());
});
}
RelocationTypes::R_AMD64_GOTPCREL => todo!(),
RelocationTypes::R_AMD64_32 => todo!(),
RelocationTypes::R_AMD64_32S => todo!(),
RelocationTypes::R_AMD64_16 => todo!(),
RelocationTypes::R_AMD64_PC16 => todo!(),
RelocationTypes::R_AMD64_8 => todo!(),
RelocationTypes::R_AMD64_PC8 => todo!(),
RelocationTypes::R_AMD64_DTPMOD64 => todo!(),
RelocationTypes::R_AMD64_DTPOFF64 => todo!(),
RelocationTypes::R_AMD64_TPOFF64 => todo!(),
RelocationTypes::R_AMD64_TLSGD => todo!(),
RelocationTypes::R_AMD64_TLSLD => todo!(),
RelocationTypes::R_AMD64_DTPOFF32 => todo!(),
RelocationTypes::R_AMD64_GOTTPOFF => todo!(),
RelocationTypes::R_AMD64_TPOFF32 => todo!(),
RelocationTypes::Unknown(_) => todo!(),
}
// Err(ElfLoaderErr::UnsupportedRelocationEntry)
Ok(())
}
fn load(&mut self, _flags: Flags, base: VAddr, region: &[u8]) -> Result<(), ElfLoaderErr> {
self.0.run(|| unsafe {
slice::from_raw_parts_mut(base as *mut u8, region.len()).copy_from_slice(region);
});
Ok(())
}
}

View File

@ -7,7 +7,7 @@ use core::{arch::asm, ptr::addr_of};
use crossbeam_queue::SegQueue;
use slab::Slab;
use spin::{Lazy, Mutex};
use x86_64::{instructions::interrupts, structures::paging::PageTableFlags, VirtAddr};
use x86_64::{instructions::interrupts, structures::paging::{Page, PageTableFlags}, VirtAddr};
#[naked]
extern "C" fn switch_to_asm(current_stack: *mut *mut usize, next_stack: *mut usize) {
@ -117,8 +117,8 @@ impl Tasking {
kernel_stack.resize(0x1_0000, 0);
let mut kernel_stack = kernel_stack.into_boxed_slice();
kernel_stack[0xFFFF] = entry_point as usize;
kernel_stack[0xFFFE] =
address_space.map_free(16, PageTableFlags::USER_ACCESSIBLE)? as usize + 0x10000;
address_space.map_assert_unused(Page::from_start_address(VirtAddr::new(0xFFF_FF80_0000)).unwrap(), 16, PageTableFlags::USER_ACCESSIBLE)?;
kernel_stack[0xFFFE] = 0xFFF_FF80_0000 + (16*4096);
kernel_stack[0xFFFD] = task_init as usize;
kernel_stack[0xFFFC] = task_force_unlock as usize;
let pid = self.processes.insert(Process {

View File

@ -30,7 +30,7 @@ impl fmt::Debug for AddressSpace {
f.debug_struct("AddressSpace")
.field("is_kernel", &self.is_kernel)
.field("alloc_force_user", &self.alloc_force_user)
.field("level_4_table", &(self.mapper.level_4_table_immut() as *const PageTable))
.field("level_4_table", &(self.mapper.level_4_table() as *const PageTable))
.finish()
}
}
@ -153,13 +153,17 @@ pub static KERNEL_SPACE: Lazy<ASpaceMutex> = Lazy::new(|| {
}
let mut kernel_space = AddressSpace::new_with_addr(table);
kernel_space.is_kernel = true;
kernel_space.mapper.activate();
let l4_virt = VirtAddr::from_ptr(kernel_space.mapper.level_4_table() as *const PageTable);
let l4_phys = kernel_space.mapper.translate_addr(l4_virt).unwrap();
unsafe { Cr3::write(PhysFrame::containing_address(l4_phys), Cr3::read().1) };
ASpaceMutex::new(kernel_space)
});
pub static ACTIVE_SPACE: Lazy<ASpaceMutex> = Lazy::new(|| {
let new_space = AddressSpace::new().expect("Could not allocate new user table");
new_space.mapper.activate();
let l4_virt = VirtAddr::from_ptr(new_space.mapper.level_4_table() as *const PageTable);
let l4_phys = new_space.mapper.translate_addr(l4_virt).unwrap();
unsafe { Cr3::write(PhysFrame::containing_address(l4_phys), Cr3::read().1) };
ASpaceMutex::new(new_space)
});
@ -174,7 +178,7 @@ impl AddressSpace {
// the reference cannot point to uninitialized data.
let new_table = unsafe {
let new_table = alloc_pt()?.0;
new_table.copy_from(KERNEL_SPACE.lock().mapper.level_4_table_immut(), 1);
new_table.copy_from(KERNEL_SPACE.lock().mapper.level_4_table(), 1);
&mut *new_table
};
Ok(Self::new_with_addr(new_table))
@ -199,7 +203,9 @@ impl AddressSpace {
// ownership of a value in a mutex unless you own the mutex, and no function owns a static.
assert!(!self.is_kernel);
Lazy::force(&ACTIVE_SPACE);
self.mapper.activate();
let l4_virt = VirtAddr::from_ptr(self.mapper.level_4_table() as *const PageTable);
let l4_phys = self.mapper.translate_addr(l4_virt).unwrap();
unsafe { Cr3::write(PhysFrame::containing_address(l4_phys), Cr3::read().1) };
core::mem::replace(&mut *ACTIVE_SPACE.lock(), self)
}
@ -463,7 +469,7 @@ impl AddressSpace {
impl Drop for AddressSpace {
fn drop(&mut self) {
drop_table(self.mapper.level_4_table_immut(), 4);
drop_table(self.mapper.level_4_table(), 4);
}
}

View File

@ -105,7 +105,7 @@ unsafe impl PointerOps for HolePtrOps {
unsafe fn from_raw(&self, value: *const Self::Value) -> Self::Pointer {
let page = (value as usize & !0xFFFusize) as *const HolePage;
let holes = addr_of!((*page).holes).cast::<Hole>();
let holes = unsafe { addr_of!((*page).holes).cast::<Hole>() };
let idx = unsafe { value.offset_from(holes) };
HolePtr { page: unsafe { &*page }, idx: idx as u8 }
}

View File

@ -1,3 +0,0 @@
[v1]
"init 0.1.0 (path+file:///home/pjht/projects/os-rust/init)" = ["init"]
"test_proc 0.1.0 (path+file:///home/pjht/projects/os-rust/test_proc)" = ["test_proc"]

View File

@ -1 +0,0 @@
{"installs":{"init 0.1.0 (path+file:///home/pjht/projects/os-rust/init)":{"version_req":null,"bins":["init"],"features":[],"all_features":false,"no_default_features":false,"profile":"release","target":"x86_64-unknown-none","rustc":"rustc 1.68.0-nightly (3020239de 2023-01-09)\nbinary: rustc\ncommit-hash: 3020239de947ec52677e9b4e853a6a9fc073d1f9\ncommit-date: 2023-01-09\nhost: x86_64-unknown-linux-gnu\nrelease: 1.68.0-nightly\nLLVM version: 15.0.6\n"},"test_proc 0.1.0 (path+file:///home/pjht/projects/os-rust/test_proc)":{"version_req":null,"bins":["test_proc"],"features":[],"all_features":false,"no_default_features":false,"profile":"release","target":"x86_64-unknown-none","rustc":"rustc 1.65.0-nightly (0b79f758c 2022-08-18)\nbinary: rustc\ncommit-hash: 0b79f758c9aa6646606662a6d623a0752286cd17\ncommit-date: 2022-08-18\nhost: x86_64-unknown-linux-gnu\nrelease: 1.65.0-nightly\nLLVM version: 15.0.0\n"}}}

Binary file not shown.

Binary file not shown.