kernel_thread/task/init.rs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128
use alloc::{collections::btree_map::BTreeMap, vec::Vec};
use common::config::{DEFAULT_PARENT_EP, LINUX_APP_CNODE_RADIX_BITS, PAGE_SIZE, STACK_ALIGN_SIZE};
use libc_core::elf::AuxType;
use memory_addr::MemoryAddr;
use sel4::{CNodeCapData, init_thread::slot};
use sel4_kit::slot_manager::LeafSlot;
use crate::consts::task::{DEF_STACK_TOP, VDSO_APP_ADDR};
use super::Sel4Task;
impl Sel4Task {
/// 初始化用户栈,传递参数(args),环境变量(env)和辅助向量(auxv)
///
/// 需要传递的栈,环境变量和辅助向量需要提前填充到 [Sel4Task::info] 下
pub fn init_stack(&self) -> usize {
// Other Strings 以 STACK_ALIGN_SIZE 对齐
//
// +------------------+ <- 用户栈顶
// │ EnvArg Strings│
// +------------------+
// │ 0 │
// +------------------+
// │ AuxNull(0) │
// +------------------+
// │ AuxValue │
// +------------------+
// │ AuxKey │
// +------------------+
// │ ... |
// +------------------+
// │ 0 │
// +------------------+
// │ EnvPtr... │
// +------------------+
// │ 0 │
// +------------------+
// │ ArgPtr... │
// +------------------+
// │ ArgLen │
// +------------------+
let mut stack_ptr = DEF_STACK_TOP;
let mem = self.mem.lock();
let mut page_writer = mem
.mapped_page
.get(&(DEF_STACK_TOP - PAGE_SIZE))
.unwrap()
.lock();
let args_ptr: Vec<_> = self
.info
.lock()
.args
.iter()
.map(|arg| {
// TODO: set end bit was zeroed manually.
stack_ptr = (stack_ptr - arg.len() - 1).align_down(STACK_ALIGN_SIZE);
page_writer.write_bytes(stack_ptr, arg.as_bytes());
page_writer.write_u8(stack_ptr + arg.len(), 0);
stack_ptr
})
.collect();
let envs = [
"LD_LIBRARY_PATH=/",
"PS1=\x1b[1m\x1b[32mrelk\x1b[0m:\x1b[1m\x1b[34m\\w\x1b[0m\\$ \0",
"PATH=/:/bin:/usr/bin",
"UB_BINDIR=./",
];
let envps: Vec<_> = envs
.iter()
.map(|env| {
stack_ptr = (stack_ptr - env.len() - 1).align_down(STACK_ALIGN_SIZE);
page_writer.write_bytes(stack_ptr, env.as_bytes());
page_writer.write_u8(stack_ptr + env.len(), 0);
stack_ptr
})
.collect();
let mut push_num = |num: usize| {
stack_ptr -= core::mem::size_of::<usize>();
page_writer.write_usize(stack_ptr, num);
};
let mut auxv = BTreeMap::new();
auxv.insert(AuxType::ExecFn, args_ptr[0]);
auxv.insert(AuxType::PageSize, PAGE_SIZE);
auxv.insert(AuxType::Entry, self.info.lock().entry);
auxv.insert(AuxType::GID, 0);
auxv.insert(AuxType::EGID, 0);
auxv.insert(AuxType::UID, 0);
auxv.insert(AuxType::EUID, 0);
auxv.insert(AuxType::SysInfoEhdr, VDSO_APP_ADDR);
auxv.insert(AuxType::Null, 0);
// push auxiliary vector
for (key, v) in auxv.into_iter() {
push_num(v);
push_num(key as usize);
}
// push environment
push_num(0);
envps.iter().rev().for_each(|x| push_num(*x));
// push args pointer
push_num(0);
args_ptr.iter().rev().for_each(|x| push_num(*x));
// push argv
push_num(args_ptr.len());
stack_ptr
}
/// 初始化 [sel4::cap::Tcb] 信息
///
/// 初始化 tcb 信息,设置调度优先级,目前设定为固定值
/// TODO: 更改调度优先级的设置,更加灵活自由
pub fn init_tcb(&self) -> Result<(), sel4::Error> {
self.tcb.tcb_configure(
DEFAULT_PARENT_EP.cptr(),
self.cnode,
CNodeCapData::new(0, sel4::WORD_SIZE - LINUX_APP_CNODE_RADIX_BITS),
self.vspace,
0,
LeafSlot::new(0).cap(),
)?;
self.tcb.tcb_set_sched_params(slot::TCB.cap(), 0, 255)
}
}