🆕 运行文件系统中的二进制程序

This commit is contained in:
fslongjin
2022-05-06 00:25:32 +08:00
parent 099b24539a
commit 0aec6827ee
24 changed files with 673 additions and 68 deletions

View File

@ -322,6 +322,37 @@ void user_level_function()
while (1)
pause();
}
/**
* @brief 打开要执行的程序文件
*
* @param path
* @return struct vfs_file_t*
*/
struct vfs_file_t *process_open_exec_file(char *path)
{
struct vfs_dir_entry_t *dentry = NULL;
struct vfs_file_t *filp = NULL;
dentry = vfs_path_walk(path, 0);
if (dentry == NULL)
return (void *)-ENOENT;
if (dentry->dir_inode->attribute == VFS_ATTR_DIR)
return (void *)-ENOTDIR;
filp = (struct vfs_file_t *)kmalloc(sizeof(struct vfs_file_t), 0);
if (filp == NULL)
return (void *)-ENOMEM;
filp->position = 0;
filp->mode = 0;
filp->dEntry = dentry;
filp->mode = ATTR_READ_ONLY;
filp->file_ops = dentry->dir_inode->file_ops;
return filp;
}
/**
* @brief 使当前进程去执行新的代码
*
@ -340,7 +371,7 @@ ul do_execve(struct pt_regs *regs, char *path)
regs->rflags = 0x200246;
regs->rax = 1;
regs->es = 0;
kdebug("do_execve is running...");
// 当前进程正在与父进程共享地址空间,需要创建
@ -362,7 +393,6 @@ ul do_execve(struct pt_regs *regs, char *path)
// 拷贝内核空间的页表指针
memcpy(phys_2_virt(new_mms->pgd) + 256, phys_2_virt(initial_proc[proc_current_cpu_id]) + 256, PAGE_4K_SIZE / 2);
}
/**
* @todo: 加载elf文件并映射对应的页
*
@ -371,7 +401,6 @@ ul do_execve(struct pt_regs *regs, char *path)
unsigned long code_start_addr = 0x800000;
unsigned long stack_start_addr = 0xa00000;
// mm_map_phys_addr_user(code_start_addr, alloc_pages(ZONE_NORMAL, 1, PAGE_PGT_MAPPED)->addr_phys, PAGE_2M_SIZE, PAGE_USER_PAGE);
mm_map_proc_page_table((uint64_t)current_pcb->mm->pgd, true, code_start_addr, alloc_pages(ZONE_NORMAL, 1, PAGE_PGT_MAPPED)->addr_phys, PAGE_2M_SIZE, PAGE_USER_PAGE, true);
process_switch_mm(current_pcb);
@ -394,24 +423,21 @@ ul do_execve(struct pt_regs *regs, char *path)
// 关闭之前的文件描述符
process_exit_files(current_pcb);
// 清除进程的vfork标志位
current_pcb->flags &= ~PF_VFORK;
int fd_num = enter_syscall_int(SYS_OPEN, path, ATTR_READ_ONLY, 0, 0, 0, 0, 0, 0);
if (fd_num < 0)
return fd_num;
struct vfs_file_t* filp = process_open_exec_file(path);
if((unsigned long)filp <= 0 )
return (unsigned long)filp;
memset((void *)code_start_addr, 0, PAGE_2M_SIZE);
uint64_t pos = 0;
int retval = filp->file_ops->read(filp, code_start_addr, PAGE_2M_SIZE, &pos);
kdebug("execve ok");
// 将程序代码拷贝到对应的内存中
int retval = enter_syscall_int(SYS_READ, fd_num, code_start_addr, PAGE_2M_SIZE, 0, 0, 0, 0, 0);
if (retval)
{
enter_syscall_int(SYS_CLOSE, fd_num, 0, 0, 0, 0, 0, 0, 0);
return retval;
}
retval = enter_syscall_int(SYS_CLOSE, fd_num, 0, 0, 0, 0, 0, 0, 0);
// kdebug("program copied!");
return 0;
}
@ -430,13 +456,12 @@ ul initial_kernel_thread(ul arg)
current_pcb->thread->rip = (ul)ret_from_system_call;
current_pcb->thread->rsp = (ul)current_pcb + STACK_SIZE - sizeof(struct pt_regs);
current_pcb->thread->fs = USER_DS|0x3;
current_pcb->thread->gs = USER_DS|0x3;
current_pcb->thread->fs = USER_DS | 0x3;
current_pcb->thread->gs = USER_DS | 0x3;
// 主动放弃内核线程身份
current_pcb->flags &= (~PF_KTHREAD);
// current_pcb->mm->pgd = kmalloc(PAGE_4K_SIZE, 0);
// memset((void*)current_pcb->mm->pgd, 0, PAGE_4K_SIZE);
@ -445,11 +470,12 @@ ul initial_kernel_thread(ul arg)
current_pcb->flags = 0;
// 将返回用户层的代码压入堆栈向rdx传入regs的地址然后jmp到do_execve这个系统调用api的处理函数 这里的设计思路和switch_proc类似
// 加载用户态程序init.bin
char init_path[] = "/init.bin";
uint64_t addr = (uint64_t)&init_path;
__asm__ __volatile__("movq %1, %%rsp \n\t"
"pushq %2 \n\t"
"jmp do_execve \n\t" ::"D"(current_pcb->thread->rsp),
"S"("/init.bin"),
"m"(current_pcb->thread->rsp), "m"(current_pcb->thread->rip)
"m"(current_pcb->thread->rsp), "m"(current_pcb->thread->rip), "S"("/init.bin")
: "memory");
return 1;
@ -662,35 +688,6 @@ copy_flags_failed:;
kfree(tsk);
return retval;
/*
// 将线程结构体放置在pcb的后面
struct thread_struct *thd = (struct thread_struct *)(tsk + 1);
memset(thd, 0, sizeof(struct thread_struct));
tsk->thread = thd;
// kdebug("333\tregs.rip = %#018lx", regs->rip);
// 将寄存器信息存储到进程的内核栈空间的顶部
memcpy((void *)((ul)tsk + STACK_SIZE - sizeof(struct pt_regs)), regs, sizeof(struct pt_regs));
// kdebug("regs.rip = %#018lx", regs->rip);
// 设置进程的内核栈
thd->rbp = (ul)tsk + STACK_SIZE;
thd->rip = regs->rip;
thd->rsp = (ul)tsk + STACK_SIZE - sizeof(struct pt_regs);
thd->fs = KERNEL_DS;
thd->gs = KERNEL_DS;
// kdebug("do_fork() thd->rsp=%#018lx", thd->rsp);
// 若进程不是内核层的进程则跳转到ret from system call
if (!(tsk->flags & PF_KTHREAD))
thd->rip = regs->rip = (ul)ret_from_system_call;
else
kdebug("is kernel proc.");
tsk->state = PROC_RUNNING;
sched_cfs_enqueue(tsk);
*/
return 0;
}
@ -953,6 +950,7 @@ uint64_t process_copy_thread(uint64_t clone_flags, struct process_control_block
struct pt_regs *child_regs = (struct pt_regs *)((uint64_t)pcb + STACK_SIZE - sizeof(struct pt_regs));
memcpy(child_regs, current_regs, sizeof(struct pt_regs));
// 设置子进程的返回值为0
child_regs->rax = 0;
child_regs->rsp = stack_start;