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

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

@ -7,17 +7,10 @@ DIR_LIB=lib
lib_patterns := *.a
LIB_FILES := $(foreach DIR,$(DIR_LIB),$(addprefix $(DIR)/,$(lib_patterns)))
DEBUG=DEBUG
CFLAGS := -mcmodel=large -fno-builtin -m64 -O0 -I . -fno-stack-protector
ifeq ($(DEBUG), DEBUG)
CFLAGS += -g
endif
ARCH=x86_64
# 控制操作系统使用的中断控制器 _INTR_8259A_ _INTR_APIC_
PIC := _INTR_APIC_
CFLAGS += -D $(PIC) -D $(ARCH)
CFLAGS = $(GLOBAL_CFLAGS) -D $(PIC) -I .
ASFLAGS := --64

View File

@ -624,7 +624,7 @@ void mm_map_phys_addr_user(ul virt_addr_start, ul phys_addr_start, ul length, ul
*/
void mm_map_proc_page_table(ul proc_page_table_addr, bool is_phys, ul virt_addr_start, ul phys_addr_start, ul length, ul flags, bool user)
{
// kdebug("proc_page_table_addr=%#018lx",proc_page_table_addr);
kdebug("proc_page_table_addr=%#018lx",proc_page_table_addr);
// 计算线性地址对应的pml4页表项的地址
ul *tmp;
if (is_phys)

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;

View File

@ -97,10 +97,7 @@ long enter_syscall_int(ul syscall_id, ul arg0, ul arg1, ul arg2, ul arg3, ul arg
ul sys_put_string(struct pt_regs *regs)
{
if (regs->r9 == 0 && regs->r10 == 0)
printk((char *)regs->r8);
else
printk_color(regs->r9, regs->r10, (char *)regs->r8);
printk_color(regs->r9, regs->r10, (char *)regs->r8);
// printk_color(BLACK, WHITE, (char *)regs->r8);
return 0;
@ -310,7 +307,7 @@ uint64_t sys_write(struct pt_regs *regs)
* @param fd_num 文件描述符号
* @param offset 偏移量
* @param whence 调整模式
* @return uint64_t
* @return uint64_t 调整结束后的文件访问位置
*/
uint64_t sys_lseek(struct pt_regs *regs)
{
@ -370,5 +367,7 @@ system_call_t system_call_table[MAX_SYSTEM_CALL_NUM] =
[4] = sys_read,
[5] = sys_write,
[6] = sys_lseek,
[7 ... 254] = system_call_not_exists,
[7] = sys_fork,
[8] = sys_vfork,
[9 ... 254] = system_call_not_exists,
[255] = sys_ahci_end_req};

View File

@ -16,5 +16,7 @@
#define SYS_READ 4
#define SYS_WRITE 5
#define SYS_LSEEK 6
#define SYS_FORK 7
#define SYS_VFORK 8
#define SYS_AHCI_END_REQ 255 // AHCI DMA请求结束end_request的系统调用