15#include "kstd_cstring"
21auto LoadElf(
const uint8_t* elf_data, uint64_t* page_table) -> uint64_t {
23 auto* ehdr =
reinterpret_cast<const Elf64_Ehdr*
>(elf_data);
24 if (ehdr->e_ident[EI_MAG0] != ELFMAG0 || ehdr->e_ident[EI_MAG1] != ELFMAG1 ||
25 ehdr->e_ident[EI_MAG2] != ELFMAG2 || ehdr->e_ident[EI_MAG3] != ELFMAG3) {
30 auto* phdr =
reinterpret_cast<const Elf64_Phdr*
>(elf_data + ehdr->e_phoff);
31 auto& vm = VirtualMemorySingleton::instance();
33 for (
int i = 0; i < ehdr->e_phnum; ++i) {
34 if (phdr[i].p_type != PT_LOAD)
continue;
36 uintptr_t vaddr = phdr[i].p_vaddr;
37 uintptr_t memsz = phdr[i].p_memsz;
38 uintptr_t filesz = phdr[i].p_filesz;
39 uintptr_t offset = phdr[i].p_offset;
42 (phdr[i].p_flags & PF_R) != 0, (phdr[i].p_flags & PF_W) != 0,
43 (phdr[i].p_flags & PF_X) != 0);
48 for (uintptr_t page = start_page; page < end_page;
53 klog::Err(
"Failed to allocate page for ELF");
59 uintptr_t v_start = page;
63 uintptr_t file_start = vaddr;
64 uintptr_t file_end = vaddr + filesz;
66 uintptr_t copy_start = std::max(v_start, file_start);
67 uintptr_t copy_end = std::min(v_end, file_end);
69 if (copy_end > copy_start) {
70 uintptr_t dst_off = copy_start - v_start;
71 uintptr_t src_off = (copy_start - vaddr) + offset;
72 kstd::memcpy(
static_cast<uint8_t*
>(p_page) + dst_off,
73 elf_data + src_off, copy_end - copy_start);
76 if (!vm.MapPage(page_table,
reinterpret_cast<void*
>(page), p_page,
93 if (!leader || leader ==
this) {
98 aux->tgid = leader->aux->tgid;
101 etl::link_splice<ThreadGroupLink>(*leader, *
this);
118 curr = curr->etl_previous;
125 curr = curr->etl_next;
137 klog::Err(
"Failed to allocate TaskAuxData for task {}",
name);
149 klog::Err(
"Failed to allocate kernel stack for task {}",
name);
168 uint8_t* elf,
int argc,
char** argv)
173 klog::Err(
"Failed to allocate TaskAuxData for task {}",
name);
187 LoadElf(
nullptr,
nullptr);
206 VirtualMemorySingleton::instance().DestroyPageDirectory(
page_table,
auto InitTaskContext(cpu_io::CalleeSavedContext *task_context, void(*entry)(void *), void *arg, uint64_t stack_top) -> void
初始化内核线程的任务上下文(重载1)
auto Start() -> void
启动 FSM(在 TCB 完全构造后调用)
auto GetStateId() const -> etl::fsm_state_id_t
获取当前状态 ID
constexpr uint64_t kVm
共享地址空间
static constexpr size_t kPageSize
auto PageAlign(uint64_t addr) -> uint64_t
auto GetUserPagePermissions(bool readable=true, bool writable=false, bool executable=false, bool global=false) -> uint64_t
auto PageAlignUp(uint64_t addr) -> uint64_t
auto Err(etl::format_string< Args... > fmt, Args &&... args) -> void
以 ERROR 级别记录日志
void aligned_free(void *ptr)
void * aligned_alloc(size_t alignment, size_t size)
Pid tgid
线程组 ID (主线程的 PID)
CloneFlags clone_flags
克隆标志位
int priority
优先级 (数字越小优先级越高)
int base_priority
基础优先级 (静态,用于优先级继承)
auto JoinThreadGroup(TaskControlBlock *leader) -> void
将线程添加到线程组
struct TaskControlBlock::SchedInfo sched_info
auto LeaveThreadGroup() -> void
从线程组中移除自己
auto GetStatus() const -> etl::fsm_state_id_t
获取当前任务状态
TaskControlBlock()=default
TaskAuxData * aux
非调度热路径的辅助数据
uint8_t * kernel_stack
内核栈
auto GetThreadGroupSize() const -> size_t
获取线程组中的线程数量
cpu_io::CalleeSavedContext task_context
任务上下文
static constexpr size_t kDefaultKernelStackSize
默认内核栈大小 (16 KB)
cpu_io::TrapContext * trap_context_ptr
Trap 上下文
etl::bidirectional_link< 0 > ThreadGroupLink
线程组侵入式链表节点类型
void(*)(void *) ThreadEntry
线程入口函数类型