diff --git a/.cargo/config.toml b/.cargo/config.toml index 1e49d08..1563d91 100644 --- a/.cargo/config.toml +++ b/.cargo/config.toml @@ -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" diff --git a/Cargo.lock b/Cargo.lock index bb0ccf4..722837c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -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", +] diff --git a/Cargo.toml b/Cargo.toml index ea6bf8d..1382cdb 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -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" diff --git a/build.rs b/build.rs deleted file mode 100644 index ee84cfd..0000000 --- a/build.rs +++ /dev/null @@ -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") - ); -} diff --git a/initrd.tar b/initrd.tar deleted file mode 100644 index 3206566..0000000 Binary files a/initrd.tar and /dev/null differ diff --git a/src/gdt.rs b/src/gdt.rs index 32903f1..2851a41 100644 --- a/src/gdt.rs +++ b/src/gdt.rs @@ -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 = 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 } }); diff --git a/src/interrupts.rs b/src/interrupts.rs index 27fd67d..9ee5cb7 100644 --- a/src/interrupts.rs +++ b/src/interrupts.rs @@ -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>> = 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]", diff --git a/src/main.rs b/src/main.rs index c7b1279..cb4694a 100644 --- a/src/main.rs +++ b/src/main.rs @@ -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::::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(§ion).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(§ion).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!(); } diff --git a/src/panic_handler.rs b/src/panic_handler.rs index edf5cb2..2338d99 100644 --- a/src/panic_handler.rs +++ b/src/panic_handler.rs @@ -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)); diff --git a/src/simple_loader.rs b/src/simple_loader.rs deleted file mode 100644 index 5e98e18..0000000 --- a/src/simple_loader.rs +++ /dev/null @@ -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 for LoadError { - fn from(err: PagingError) -> Self { - Self::Paging(err) - } -} - -impl From for LoadError { - fn from(err: ElfLoaderErr) -> Self { - Self::ElfLoader(err) - } -} - -pub struct SimpleLoader(AddressSpace); - -impl SimpleLoader { - pub fn load(binary: &ElfBinary) -> Result { - 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(()) - } -} diff --git a/src/tasking.rs b/src/tasking.rs index c1baafb..4746943 100644 --- a/src/tasking.rs +++ b/src/tasking.rs @@ -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 { diff --git a/src/virtual_memory.rs b/src/virtual_memory.rs index 4c55e89..33c7a97 100644 --- a/src/virtual_memory.rs +++ b/src/virtual_memory.rs @@ -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 = 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 = 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); } } diff --git a/src/virtual_memory/holes.rs b/src/virtual_memory/holes.rs index 59ab89a..a9dddd5 100644 --- a/src/virtual_memory/holes.rs +++ b/src/virtual_memory/holes.rs @@ -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::(); + let holes = unsafe { addr_of!((*page).holes).cast::() }; let idx = unsafe { value.offset_from(holes) }; HolePtr { page: unsafe { &*page }, idx: idx as u8 } } diff --git a/sysroot/.crates.toml b/sysroot/.crates.toml deleted file mode 100644 index d4527bc..0000000 --- a/sysroot/.crates.toml +++ /dev/null @@ -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"] diff --git a/sysroot/.crates2.json b/sysroot/.crates2.json deleted file mode 100644 index bb78f31..0000000 --- a/sysroot/.crates2.json +++ /dev/null @@ -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"}}} \ No newline at end of file diff --git a/sysroot/bin/init b/sysroot/bin/init deleted file mode 100755 index 261bbc1..0000000 Binary files a/sysroot/bin/init and /dev/null differ diff --git a/sysroot/bin/test_proc b/sysroot/bin/test_proc deleted file mode 100755 index 94f837b..0000000 Binary files a/sysroot/bin/test_proc and /dev/null differ