Nothing to see here, move along
at main 109 lines 4.1 kB view raw
1use lancer_core::header::KernelObjectHeader; 2use lancer_core::object_layout::{CNodeObject, KernelObject, ProcessObject, SchedContextObject}; 3use lancer_core::object_tag::ObjectTag; 4 5use crate::cap::cnode; 6use crate::cap::kernel_objects; 7use crate::cap::pool::POOL; 8use crate::cap::table::{CapRef, Rights}; 9use crate::error::KernelError; 10use crate::types::{Pid, Priority}; 11 12const SLOT_SELF: u64 = 0; 13const SLOT_INIT_SCHED: u64 = 63; 14 15pub fn bootstrap_root_cnode(pid: Pid, size_bits: u8) -> Result<(), KernelError> { 16 let allocator = &crate::mem::phys::BitmapFrameAllocator; 17 let cnode_data = cnode::create_cnode(size_bits, allocator)?; 18 let frame_count = cnode_data.frame_count; 19 20 let obj_phys = kernel_objects::alloc_slot().ok_or(KernelError::PoolExhausted)?; 21 let header = KernelObjectHeader::new(ObjectTag::CNode, 0, 64); 22 let mut obj = CNodeObject::init_default(header); 23 obj.slots_phys = cnode_data.slots_phys.as_u64(); 24 obj.size_bits = cnode_data.size_bits; 25 obj.frame_count = cnode_data.frame_count; 26 kernel_objects::write_at(obj_phys, obj); 27 28 let (cnode_id, cnode_gen) = match POOL.lock().register_object(obj_phys, ObjectTag::CNode) { 29 Ok(pair) => pair, 30 Err(e) => { 31 kernel_objects::free_slot(obj_phys); 32 return Err(e); 33 } 34 }; 35 36 let mut ptable = crate::proc::PROCESSES.lock(); 37 let _sched = ptable.get(pid).ok_or(KernelError::InvalidObject)?; 38 let exec = ptable.exec_mut(pid).ok_or(KernelError::InvalidObject)?; 39 exec.root_cnode = Some((cnode_id, cnode_gen)); 40 exec.cnode_depth = 64; 41 exec.root_guard_bits = 64 - size_bits; 42 exec.root_guard_value = 0; 43 exec.charge_frames(frame_count as u16)?; 44 Ok(()) 45} 46 47fn install_cap_phys(pid: Pid, slot: u64, tag: ObjectTag, obj_phys: u64) -> Result<(), KernelError> { 48 let (object_id, generation) = POOL.lock().register_object(obj_phys, tag)?; 49 let cap = CapRef::new(tag, object_id, Rights::ALL, generation); 50 let ptable = crate::proc::PROCESSES.lock(); 51 let pool = POOL.lock_after(&ptable); 52 match cnode::resolve_caller_insert(pid, slot, cap, &ptable, &pool) { 53 Ok(()) => Ok(()), 54 Err(e) => { 55 drop(pool); 56 let r = POOL.lock_after(&ptable).free_phys(object_id, generation); 57 debug_assert!(r.is_ok()); 58 Err(e) 59 } 60 } 61} 62 63pub fn bootstrap_self_cap(pid: Pid, cnode_size_bits: u8) -> Result<(), KernelError> { 64 bootstrap_root_cnode(pid, cnode_size_bits)?; 65 66 let obj_phys = kernel_objects::alloc_slot().ok_or(KernelError::PoolExhausted)?; 67 let header = KernelObjectHeader::new(ObjectTag::Process, 0, 64); 68 let mut obj = ProcessObject::init_default(header); 69 obj.pid = pid.raw(); 70 kernel_objects::write_at(obj_phys, obj); 71 install_cap_phys(pid, SLOT_SELF, ObjectTag::Process, obj_phys)?; 72 73 bootstrap_init_sched(pid) 74} 75 76fn bootstrap_init_sched(pid: Pid) -> Result<(), KernelError> { 77 let priority = Priority::new(200); 78 79 let obj_phys = kernel_objects::alloc_slot().ok_or(KernelError::PoolExhausted)?; 80 let header = KernelObjectHeader::new(ObjectTag::SchedContext, 0, 64); 81 let mut obj = SchedContextObject::init_default(header); 82 obj.budget_us = 10_000_000; 83 obj.period_us = 10_000_000; 84 obj.remaining_us = 10_000_000; 85 obj.priority = priority.raw(); 86 kernel_objects::write_at(obj_phys, obj); 87 88 let (sc_id, sc_gen) = match POOL 89 .lock() 90 .register_object(obj_phys, ObjectTag::SchedContext) 91 { 92 Ok(pair) => pair, 93 Err(e) => { 94 kernel_objects::free_slot(obj_phys); 95 return Err(e); 96 } 97 }; 98 99 { 100 let mut ptable = crate::proc::PROCESSES.lock(); 101 let proc = ptable.get_mut(pid).ok_or(KernelError::InvalidObject)?; 102 proc.attach_sched_context(sc_id, sc_gen, priority); 103 } 104 105 let cap = CapRef::new(ObjectTag::SchedContext, sc_id, Rights::ALL, sc_gen); 106 let ptable = crate::proc::PROCESSES.lock(); 107 let pool = POOL.lock_after(&ptable); 108 cnode::resolve_caller_insert(pid, SLOT_INIT_SCHED, cap, &ptable, &pool) 109}