mirror of
https://github.com/DragonOS-Community/DragonOS.git
synced 2025-06-18 12:16:31 +00:00
🆕 运行文件系统中的二进制程序
This commit is contained in:
@ -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
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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};
|
||||
|
@ -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的系统调用
|
Reference in New Issue
Block a user