Support smp. TODO: delete all inner kernel locks.

This commit is contained in:
TXuian
2024-03-15 16:01:30 +08:00
parent 892613a0d5
commit d987bf0357
34 changed files with 531 additions and 150 deletions
@@ -66,18 +66,15 @@ Modification:
/// @param path path to elf file
/// @param argv arguments giving to main
/// @return
int task_exec(struct TaskMicroDescriptor* task, struct Session* session, int fd, ipc_read_fn ipc_read, char* name, char** argv)
int task_exec(struct TaskMicroDescriptor* task, char* img_start, char* name, char** argv)
{
/* load img to task */
/* 1. load elf header */
struct elfhdr elf;
memcpy((void*)&elf, img_start, sizeof(elf));
// pgdir for new task
struct TopLevelPageDirectory pgdir;
pgdir.pd_addr = NULL;
if (ipc_read(session, fd, (char*)&elf, 0, sizeof(elf)) < sizeof(elf) || elf.magic != ELF_MAGIC) {
ERROR("invalide elf file.\n");
goto error_exec;
}
// pgdir for new task
if (UNLIKELY(!xizi_pager.new_pgdir(&pgdir))) {
ERROR("create new pgdir failed.\n");
goto error_exec;
@@ -88,10 +85,8 @@ int task_exec(struct TaskMicroDescriptor* task, struct Session* session, int fd,
uintptr_t load_size = 0;
struct proghdr ph;
for (int sec_idx = 0, off = elf.phoff; sec_idx < elf.phnum; sec_idx++, off += sizeof(ph)) {
if (ipc_read(session, fd, (char*)&ph, off, sizeof(ph)) != sizeof(ph)) {
ERROR("Read elf header failed\n");
goto error_exec;
}
// load proghdr
memcpy((char*)&ph, img_start + off, sizeof(ph));
if (ph.type != ELF_PROG_LOAD)
continue;
@@ -114,10 +109,7 @@ int task_exec(struct TaskMicroDescriptor* task, struct Session* session, int fd,
panic("copy elf file to unmapped addr");
}
uintptr_t read_size = (ph.filesz - addr_offset < PAGE_SIZE ? ph.filesz - addr_offset : PAGE_SIZE);
if (read_size != ipc_read(session, fd, P2V(page_paddr), ph.off + addr_offset, read_size)) {
ERROR("read size error, off: %d, read len: %d\n", ph.off + addr_offset, read_size);
goto error_exec;
}
memcpy(P2V(page_paddr), img_start + (ph.off + addr_offset), read_size);
}
}
@@ -193,7 +185,7 @@ error_exec:
return -1;
}
int sys_exec(struct KernReadTool* read_tool, char* name, char** argv)
int sys_exec(char* img_start, char* name, char** argv)
{
/// @todo find a source of mmu_driver_tag instead of requiring from root
static struct TraceTag mmu_driver_tag;
@@ -204,12 +196,8 @@ int sys_exec(struct KernReadTool* read_tool, char* name, char** argv)
}
struct MmuCommonDone* p_mmu_driver = AchieveResource(&mmu_driver_tag);
struct TaskMicroDescriptor* current_task = cur_cpu()->task;
struct Session* session = read_tool->session;
int fd = read_tool->fd;
ipc_read_fn ipc_read = read_tool->ipc_read;
int ret = task_exec(current_task, session, fd, ipc_read, name, argv);
int ret = task_exec(current_task, img_start, name, argv);
if (ret >= 0) {
spinlock_init(&current_task->lock, current_task->name);
p_mmu_driver->LoadPgdir((uintptr_t)V2P(current_task->pgdir.pd_addr));