diff --git a/kernel/arch/i686/src/context.rs b/kernel/arch/i686/src/context.rs index 97572962..3240b55f 100644 --- a/kernel/arch/i686/src/context.rs +++ b/kernel/arch/i686/src/context.rs @@ -74,6 +74,8 @@ pub struct InterruptFrame { struct Inner { // 0x00 sp: usize, + + gs_base: usize, } #[allow(dead_code)] @@ -88,11 +90,29 @@ pub struct TaskContextImpl< cr3: u32, tss_esp0: u32, - gs_base: usize, _pd: PhantomData<(K, PA)>, } +impl> + TaskContextImpl +{ + unsafe fn store_state(&self) { + if let Some(fpu) = self.fpu_context.as_ref() { + FpuContext::store(fpu.get()); + } + } + + unsafe fn load_state(&self) { + if let Some(fpu) = self.fpu_context.as_ref() { + FpuContext::restore(fpu.get()); + } + gdt::set_gs_base((*self.inner.get()).gs_base); + TSS.esp0 = self.tss_esp0; + CR3.set(self.cr3 as _); + } +} + impl> TaskContext for TaskContextImpl { @@ -123,14 +143,16 @@ impl ! { - if let Some(dst_fpu) = self.fpu_context.as_ref() { - FpuContext::restore(dst_fpu.get()); - } - gdt::set_gs_base(self.gs_base); - TSS.esp0 = self.tss_esp0; - CR3.set(self.cr3 as _); - + self.load_state(); __i686_enter_task(self.inner.get()) } unsafe fn switch_and_drop(&self, thread: *const ()) { - if let Some(dst_fpu) = self.fpu_context.as_ref() { - FpuContext::restore(dst_fpu.get()); - } - gdt::set_gs_base(self.gs_base); - TSS.esp0 = self.tss_esp0; - CR3.set(self.cr3 as _); + self.load_state(); + __i686_switch_and_drop(self.inner.get(), thread); + } - __i686_switch_and_drop(self.inner.get(), thread) + fn set_thread_pointer(&self, tp: usize) { + unsafe { (*self.inner.get()).gs_base = tp }; + gdt::set_gs_base(tp); } } diff --git a/lib/runtime/src/process/thread_local/i686.rs b/lib/runtime/src/process/thread_local/i686.rs index 35b2a8c1..ac20cdf3 100644 --- a/lib/runtime/src/process/thread_local/i686.rs +++ b/lib/runtime/src/process/thread_local/i686.rs @@ -1,6 +1,6 @@ #![allow(missing_docs)] -use abi::error::Error; +use abi::{error::Error, process::ThreadOption}; pub fn get_thread_pointer() -> usize { let tp: usize; @@ -11,5 +11,5 @@ pub fn get_thread_pointer() -> usize { } pub unsafe fn set_thread_pointer(value: usize) -> Result<(), Error> { - todo!() + crate::sys::set_thread_option(&ThreadOption::ThreadPointer(value)) } diff --git a/lib/runtime/src/process/thread_local/variant2.rs b/lib/runtime/src/process/thread_local/variant2.rs index 1a56c20e..2e7b74d3 100644 --- a/lib/runtime/src/process/thread_local/variant2.rs +++ b/lib/runtime/src/process/thread_local/variant2.rs @@ -76,6 +76,8 @@ pub fn clone_tls(image: &TlsImage, tcb_size: usize) -> Result<(usize, usize), Er // Zero the TCB after the self-pointer tcb[size_of::()..].fill(0); + crate::debug_trace!("TLS: base={:#x}, tp={:#x}", base, tp); + Ok((base, tp)) } diff --git a/userspace/dyn-loader/src/relocation/i686.rs b/userspace/dyn-loader/src/relocation/i686.rs new file mode 100644 index 00000000..a0547943 --- /dev/null +++ b/userspace/dyn-loader/src/relocation/i686.rs @@ -0,0 +1,33 @@ +use elf::relocation::{Rel, Rela}; + +use crate::{error::Error, object::ResolvedSymbol, state::State}; + +use super::{RelValue, RelaValue, Relocation}; + +impl Relocation for Rela { + type Value = RelaValue; + + fn resolve( + &self, + _state: &State, + _name: &str, + _symbol: &ResolvedSymbol, + _load_base: usize, + ) -> Result, Error> { + unimplemented!("rela-type relocations are not implemented for i686") + } +} + +impl Relocation for Rel { + type Value = RelValue; + + fn resolve( + &self, + state: &State, + name: &str, + symbol: &ResolvedSymbol, + load_base: usize, + ) -> Result, Error> { + todo!() + } +} diff --git a/userspace/dyn-loader/src/relocation/mod.rs b/userspace/dyn-loader/src/relocation/mod.rs index 96f912c4..ab456cef 100644 --- a/userspace/dyn-loader/src/relocation/mod.rs +++ b/userspace/dyn-loader/src/relocation/mod.rs @@ -2,11 +2,17 @@ use crate::{error::Error, mapping::Mapping, object::ResolvedSymbol, state::State #[cfg(any(target_arch = "x86_64", rust_analyzer))] mod x86_64; +#[cfg(any(target_arch = "x86", rust_analyzer))] +mod i686; pub enum RelaValue { QWord(i64), } +pub enum RelValue { + +} + pub trait RelocationValue { fn write(&self, mapping: &mut Mapping, offset: u64); } @@ -30,3 +36,9 @@ impl RelocationValue for RelaValue { } } } + +impl RelocationValue for RelValue { + fn write(&self, mapping: &mut Mapping, offset: u64) { + match *self {} + } +} diff --git a/xtask/src/build/userspace.rs b/xtask/src/build/userspace.rs index bdac79bc..322fbd6a 100644 --- a/xtask/src/build/userspace.rs +++ b/xtask/src/build/userspace.rs @@ -9,7 +9,7 @@ use walkdir::WalkDir; use crate::{ build::{c, cargo::CargoBuilder}, check::AllOk, - env::BuildEnv, + env::{Arch, BuildEnv}, error::Error, util, }; @@ -62,8 +62,6 @@ const PROGRAMS: &[(&str, &str)] = &[ ("crypt", "bin/crypt"), ("dyn-loader", "libexec/dyn-loader"), // TODO: proper process for C program builds - ("c-test", "c-test"), - ("c-test-static", "c-test-static"), ]; fn build_userspace( @@ -73,8 +71,11 @@ fn build_userspace( ) -> Result<(), Error> { log::info!("Building userspace"); CargoBuilder::Userspace(env).build(env.workspace_root.join("userspace"))?; - CargoBuilder::Userspace(env).build(env.workspace_root.join("userspace/dynload-program"))?; - c::build_c(env, extra)?; + // TODO other architectures + if env.arch == Arch::x86_64 { + CargoBuilder::Userspace(env).build(env.workspace_root.join("userspace/dynload-program"))?; + c::build_c(env, extra)?; + } Ok(()) } @@ -116,20 +117,22 @@ fn build_rootfs, D: AsRef>( // TODO this is a temporary hack fs::create_dir_all(rootfs_dir.join("lib"))?; - util::copy_file( - env.workspace_root.join(format!( - "userspace/dynload-program/target/{}-unknown-yggdrasil/{}/dynload-program", - env.arch.name(), - env.profile.name() - )), - rootfs_dir.join("dynload-program"), - )?; - util::copy_file(format!( - "/home/alnyan/build/ygg/toolchain/build/host/stage1-std/{}-unknown-yggdrasil/release/libstd.so", - env.arch.name() - ), rootfs_dir.join("lib/libstd.so"))?; + // TODO other architectures + if env.arch == Arch::x86_64 { + util::copy_file( + env.workspace_root.join(format!( + "userspace/dynload-program/target/{}-unknown-yggdrasil/{}/dynload-program", + env.arch.name(), + env.profile.name() + )), + rootfs_dir.join("dynload-program"), + )?; - log::info!("Installing ygglibc"); + util::copy_file(format!( + "/home/alnyan/build/ygg/toolchain/build/host/stage1-std/{}-unknown-yggdrasil/release/libstd.so", + env.arch.name() + ), rootfs_dir.join("lib/libstd.so"))?; + } log::info!("Installing extras"); for (src, dst) in install_extra {