mirror of
https://github.com/DragonOS-Community/DragonOS.git
synced 2025-06-09 02:46:47 +00:00
🆕 exec (存在bug
This commit is contained in:
parent
844e66f6bb
commit
e2a59dbd43
11
Makefile
11
Makefile
@ -25,6 +25,17 @@ all:
|
|||||||
cd ..;\
|
cd ..;\
|
||||||
done
|
done
|
||||||
|
|
||||||
|
.PHONY: user
|
||||||
|
user:
|
||||||
|
mkdir -p bin/user/
|
||||||
|
mkdir -p bin/tmp/
|
||||||
|
@list='./user'; for subdir in $$list; do \
|
||||||
|
echo "make all in $$subdir";\
|
||||||
|
cd $$subdir;\
|
||||||
|
$(MAKE) all;\
|
||||||
|
cd ..;\
|
||||||
|
done
|
||||||
|
|
||||||
.PHONY: clean
|
.PHONY: clean
|
||||||
clean:
|
clean:
|
||||||
@list='$(SUBDIRS)'; for subdir in $$list; do \
|
@list='$(SUBDIRS)'; for subdir in $$list; do \
|
||||||
|
@ -198,7 +198,7 @@ void do_page_fault(struct pt_regs *regs, unsigned long error_code)
|
|||||||
|
|
||||||
__asm__ __volatile__("movq %%cr2, %0":"=r"(cr2)::"memory");
|
__asm__ __volatile__("movq %%cr2, %0":"=r"(cr2)::"memory");
|
||||||
|
|
||||||
kerror("do_page_fault(14),Error code :%#018lx,RSP:%#018lx,RIP:%#018lx CPU:%d\n",error_code , regs->rsp , regs->rip, proc_current_cpu_id);
|
kerror("do_page_fault(14),Error code :%#018lx,RSP:%#018lx,RIP:%#018lx CPU:%d, pid=%d\n",error_code , regs->rsp , regs->rip, proc_current_cpu_id, current_pcb->pid);
|
||||||
|
|
||||||
if(!(error_code & 0x01))
|
if(!(error_code & 0x01))
|
||||||
printk_color(RED,BLACK,"Page Not-Present,\t");
|
printk_color(RED,BLACK,"Page Not-Present,\t");
|
||||||
|
@ -31,4 +31,4 @@ ENTRY(kernel_thread_func)
|
|||||||
movq %rdx, %rdi
|
movq %rdx, %rdi
|
||||||
callq *%rbx
|
callq *%rbx
|
||||||
movq %rax, %rdi
|
movq %rax, %rdi
|
||||||
callq process_thread_do_exit
|
callq process_do_exit
|
@ -107,6 +107,14 @@ void __switch_to(struct process_control_block *prev, struct process_control_bloc
|
|||||||
// set_tss64((uint *)phys_2_virt(TSS64_Table), initial_tss[0].rsp0, initial_tss[0].rsp1, initial_tss[0].rsp2, initial_tss[0].ist1,
|
// set_tss64((uint *)phys_2_virt(TSS64_Table), initial_tss[0].rsp0, initial_tss[0].rsp1, initial_tss[0].rsp2, initial_tss[0].ist1,
|
||||||
// initial_tss[0].ist2, initial_tss[0].ist3, initial_tss[0].ist4, initial_tss[0].ist5, initial_tss[0].ist6, initial_tss[0].ist7);
|
// initial_tss[0].ist2, initial_tss[0].ist3, initial_tss[0].ist4, initial_tss[0].ist5, initial_tss[0].ist6, initial_tss[0].ist7);
|
||||||
|
|
||||||
|
if (next->pid == 2)
|
||||||
|
{
|
||||||
|
|
||||||
|
struct pt_regs *child_regs = (struct pt_regs *)next->thread->rsp;
|
||||||
|
kdebug("next->thd->rip=%#018lx", next->thread->rip);
|
||||||
|
kdebug("next proc's ret addr = %#018lx\t next child_regs->rsp = %#018lx, next new_rip=%#018lx)", child_regs->rip, child_regs->rsp, child_regs->rip);
|
||||||
|
}
|
||||||
|
|
||||||
__asm__ __volatile__("movq %%fs, %0 \n\t"
|
__asm__ __volatile__("movq %%fs, %0 \n\t"
|
||||||
: "=a"(prev->thread->fs));
|
: "=a"(prev->thread->fs));
|
||||||
__asm__ __volatile__("movq %%gs, %0 \n\t"
|
__asm__ __volatile__("movq %%gs, %0 \n\t"
|
||||||
@ -416,7 +424,8 @@ static int process_load_elf_file(struct pt_regs *regs, char *path)
|
|||||||
if ((unsigned long)filp <= 0)
|
if ((unsigned long)filp <= 0)
|
||||||
{
|
{
|
||||||
kdebug("(unsigned long)filp=%d", (long)filp);
|
kdebug("(unsigned long)filp=%d", (long)filp);
|
||||||
return (unsigned long)filp;
|
retval = -ENOEXEC;
|
||||||
|
goto load_elf_failed;
|
||||||
}
|
}
|
||||||
Elf64_Phdr *phdr = buf;
|
Elf64_Phdr *phdr = buf;
|
||||||
|
|
||||||
@ -477,19 +486,12 @@ load_elf_failed:;
|
|||||||
*
|
*
|
||||||
* @param regs 当前进程的寄存器
|
* @param regs 当前进程的寄存器
|
||||||
* @param path 可执行程序的路径
|
* @param path 可执行程序的路径
|
||||||
|
* @param argv 参数列表
|
||||||
|
* @param envp 环境变量
|
||||||
* @return ul 错误码
|
* @return ul 错误码
|
||||||
*/
|
*/
|
||||||
ul do_execve(struct pt_regs *regs, char *path)
|
ul do_execve(struct pt_regs *regs, char *path, char *argv[], char *envp[])
|
||||||
{
|
{
|
||||||
// 选择这两个寄存器是对应了sysexit指令的需要
|
|
||||||
regs->rip = 0x800000; // rip 应用层程序的入口地址 这里的地址选择没有特殊要求,只要是未使用的内存区域即可。
|
|
||||||
regs->rsp = 0xa00000; // rsp 应用层程序的栈顶地址
|
|
||||||
regs->cs = USER_CS | 3;
|
|
||||||
regs->ds = USER_DS | 3;
|
|
||||||
regs->ss = USER_DS | 0x3;
|
|
||||||
regs->rflags = 0x200246;
|
|
||||||
regs->rax = 1;
|
|
||||||
regs->es = 0;
|
|
||||||
|
|
||||||
kdebug("do_execve is running...");
|
kdebug("do_execve is running...");
|
||||||
|
|
||||||
@ -512,14 +514,10 @@ 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);
|
memcpy(phys_2_virt(new_mms->pgd) + 256, phys_2_virt(initial_proc[proc_current_cpu_id]) + 256, PAGE_4K_SIZE / 2);
|
||||||
}
|
}
|
||||||
/**
|
|
||||||
* @todo: 加载elf文件并映射对应的页
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
// 映射1个2MB的物理页
|
|
||||||
|
|
||||||
|
// 设置用户栈和用户堆的基地址
|
||||||
unsigned long stack_start_addr = 0x6fffffc00000;
|
unsigned long stack_start_addr = 0x6fffffc00000;
|
||||||
uint64_t brk_start_addr = 0x6fffffc00000;
|
const uint64_t brk_start_addr = 0x6fffffc00000;
|
||||||
|
|
||||||
process_switch_mm(current_pcb);
|
process_switch_mm(current_pcb);
|
||||||
|
|
||||||
@ -544,9 +542,49 @@ ul do_execve(struct pt_regs *regs, char *path)
|
|||||||
// 清除进程的vfork标志位
|
// 清除进程的vfork标志位
|
||||||
current_pcb->flags &= ~PF_VFORK;
|
current_pcb->flags &= ~PF_VFORK;
|
||||||
|
|
||||||
process_load_elf_file(regs, path);
|
// 加载elf格式的可执行文件
|
||||||
|
int tmp = process_load_elf_file(regs, path);
|
||||||
|
if (tmp < 0)
|
||||||
|
return tmp;
|
||||||
|
|
||||||
|
// 拷贝参数列表
|
||||||
|
if (argv != NULL)
|
||||||
|
{
|
||||||
|
int argc = 0;
|
||||||
|
|
||||||
|
// 目标程序的argv基地址指针,最大8个参数
|
||||||
|
char **dst_argv = (char **)(stack_start_addr - (sizeof(char **) << 3));
|
||||||
|
uint64_t str_addr = (uint64_t)dst_argv;
|
||||||
|
|
||||||
|
for (argc = 0; argc < 8 && argv[argc] != NULL; ++argc)
|
||||||
|
{
|
||||||
|
// 测量参数的长度(最大1023)
|
||||||
|
int argv_len = strnlen_user(argv[argc], 1023) + 1;
|
||||||
|
strncpy((char *)(str_addr - argv_len), argv[argc], argv_len - 1);
|
||||||
|
str_addr -= argv_len;
|
||||||
|
dst_argv[argc] = (char *)str_addr;
|
||||||
|
//字符串加上结尾字符
|
||||||
|
((char *)str_addr)[argv_len] = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
// 重新设定栈基址,并预留空间防止越界
|
||||||
|
stack_start_addr = str_addr - 8;
|
||||||
|
current_pcb->mm->stack_start = stack_start_addr;
|
||||||
|
regs->rsp = regs->rbp = stack_start_addr;
|
||||||
|
|
||||||
|
// 传递参数
|
||||||
|
regs->rdi = argc;
|
||||||
|
regs->rsi = (uint64_t)dst_argv;
|
||||||
|
}
|
||||||
kdebug("execve ok");
|
kdebug("execve ok");
|
||||||
|
|
||||||
|
regs->cs = USER_CS | 3;
|
||||||
|
regs->ds = USER_DS | 3;
|
||||||
|
regs->ss = USER_DS | 0x3;
|
||||||
|
regs->rflags = 0x200246;
|
||||||
|
regs->rax = 1;
|
||||||
|
regs->es = 0;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -570,7 +608,7 @@ ul initial_kernel_thread(ul arg)
|
|||||||
|
|
||||||
// 主动放弃内核线程身份
|
// 主动放弃内核线程身份
|
||||||
current_pcb->flags &= (~PF_KTHREAD);
|
current_pcb->flags &= (~PF_KTHREAD);
|
||||||
|
kdebug("in initial_kernel_thread: flags=%ld", current_pcb->flags);
|
||||||
// current_pcb->mm->pgd = kmalloc(PAGE_4K_SIZE, 0);
|
// current_pcb->mm->pgd = kmalloc(PAGE_4K_SIZE, 0);
|
||||||
// memset((void*)current_pcb->mm->pgd, 0, PAGE_4K_SIZE);
|
// memset((void*)current_pcb->mm->pgd, 0, PAGE_4K_SIZE);
|
||||||
|
|
||||||
@ -584,23 +622,47 @@ ul initial_kernel_thread(ul arg)
|
|||||||
__asm__ __volatile__("movq %1, %%rsp \n\t"
|
__asm__ __volatile__("movq %1, %%rsp \n\t"
|
||||||
"pushq %2 \n\t"
|
"pushq %2 \n\t"
|
||||||
"jmp do_execve \n\t" ::"D"(current_pcb->thread->rsp),
|
"jmp do_execve \n\t" ::"D"(current_pcb->thread->rsp),
|
||||||
"m"(current_pcb->thread->rsp), "m"(current_pcb->thread->rip), "S"("/shell.elf")
|
"m"(current_pcb->thread->rsp), "m"(current_pcb->thread->rip), "S"("/shell.elf"), "c"(NULL), "d"(NULL)
|
||||||
: "memory");
|
: "memory");
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 当子进程退出后向父进程发送通知
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void process_exit_notify()
|
||||||
|
{
|
||||||
|
|
||||||
|
wait_queue_wakeup(¤t_pcb->parent_pcb->wait_child_proc_exit, PROC_INTERRUPTIBLE);
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
* @brief 进程退出时执行的函数
|
* @brief 进程退出时执行的函数
|
||||||
*
|
*
|
||||||
* @param code 返回码
|
* @param code 返回码
|
||||||
* @return ul
|
* @return ul
|
||||||
*/
|
*/
|
||||||
ul process_thread_do_exit(ul code)
|
ul process_do_exit(ul code)
|
||||||
{
|
{
|
||||||
kinfo("thread_exiting..., code is %#018lx.", code);
|
kinfo("process exiting..., code is %#018lx.", code);
|
||||||
|
cli();
|
||||||
|
struct process_control_block *pcb = current_pcb;
|
||||||
|
|
||||||
|
// 进程退出时释放资源
|
||||||
|
process_exit_files(pcb);
|
||||||
|
process_exit_thread(pcb);
|
||||||
|
// todo: 可否在这里释放内存结构体?(在判断共享页引用问题之后)
|
||||||
|
|
||||||
|
pcb->state = PROC_ZOMBIE;
|
||||||
|
pcb->exit_code = pcb;
|
||||||
|
sti();
|
||||||
|
|
||||||
|
process_exit_notify();
|
||||||
|
sched_cfs();
|
||||||
|
|
||||||
while (1)
|
while (1)
|
||||||
;
|
hlt();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -750,6 +812,10 @@ unsigned long do_fork(struct pt_regs *regs, unsigned long clone_flags, unsigned
|
|||||||
|
|
||||||
tsk->cpu_id = proc_current_cpu_id;
|
tsk->cpu_id = proc_current_cpu_id;
|
||||||
tsk->state = PROC_UNINTERRUPTIBLE;
|
tsk->state = PROC_UNINTERRUPTIBLE;
|
||||||
|
|
||||||
|
tsk->parent_pcb = current_pcb;
|
||||||
|
wait_queue_init(&tsk->wait_child_proc_exit, NULL);
|
||||||
|
|
||||||
list_init(&tsk->list);
|
list_init(&tsk->list);
|
||||||
// list_add(&initial_proc_union.pcb.list, &tsk->list);
|
// list_add(&initial_proc_union.pcb.list, &tsk->list);
|
||||||
|
|
||||||
@ -773,6 +839,8 @@ unsigned long do_fork(struct pt_regs *regs, unsigned long clone_flags, unsigned
|
|||||||
|
|
||||||
// 拷贝成功
|
// 拷贝成功
|
||||||
retval = tsk->pid;
|
retval = tsk->pid;
|
||||||
|
|
||||||
|
kdebug("fork done: tsk->pid=%d", tsk->pid);
|
||||||
// 唤醒进程
|
// 唤醒进程
|
||||||
process_wakeup(tsk);
|
process_wakeup(tsk);
|
||||||
|
|
||||||
@ -945,13 +1013,15 @@ uint64_t process_copy_mm(uint64_t clone_flags, struct process_control_block *pcb
|
|||||||
|
|
||||||
pdpt_t *current_pdpt = (pdpt_t *)phys_2_virt(*(uint64_t *)(current_pgd + i) & (~0xfffUL));
|
pdpt_t *current_pdpt = (pdpt_t *)phys_2_virt(*(uint64_t *)(current_pgd + i) & (~0xfffUL));
|
||||||
|
|
||||||
// kdebug("current pdpt=%#018lx \t (current_pgd + i)->pml4t=%#018lx", current_pdpt, *(uint64_t *)(current_pgd+i));
|
kdebug("i=%d, current pdpt=%#018lx \t (current_pgd + i)->pml4t=%#018lx", i, current_pdpt, *(uint64_t *)(current_pgd + i));
|
||||||
// 设置二级页表
|
// 设置二级页表
|
||||||
for (int j = 0; j < 512; ++j)
|
for (int j = 0; j < 512; ++j)
|
||||||
{
|
{
|
||||||
if (*(uint64_t *)(current_pdpt + j) == 0)
|
if (*(uint64_t *)(current_pdpt + j) == 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
kdebug("j=%d *(uint64_t *)(current_pdpt + j)=%#018lx", j, *(uint64_t *)(current_pdpt + j));
|
||||||
|
|
||||||
// 分配新的三级页表
|
// 分配新的三级页表
|
||||||
pdt_t *new_pdt = (pdt_t *)kmalloc(PAGE_4K_SIZE, 0);
|
pdt_t *new_pdt = (pdt_t *)kmalloc(PAGE_4K_SIZE, 0);
|
||||||
memset(new_pdt, 0, PAGE_4K_SIZE);
|
memset(new_pdt, 0, PAGE_4K_SIZE);
|
||||||
@ -967,12 +1037,14 @@ uint64_t process_copy_mm(uint64_t clone_flags, struct process_control_block *pcb
|
|||||||
if ((current_pdt + k)->pdt == 0)
|
if ((current_pdt + k)->pdt == 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
kdebug("k=%d, (current_pdt + k)->pdt=%#018lx", k, (current_pdt + k)->pdt);
|
||||||
// 获取一个新页
|
// 获取一个新页
|
||||||
struct Page *pg = alloc_pages(ZONE_NORMAL, 1, PAGE_PGT_MAPPED);
|
struct Page *pg = alloc_pages(ZONE_NORMAL, 1, PAGE_PGT_MAPPED);
|
||||||
set_pdt((uint64_t *)(new_pdt + k), mk_pdt(pg->addr_phys, (current_pdt + k)->pdt & 0x1fffUL));
|
set_pdt((uint64_t *)(new_pdt + k), mk_pdt(pg->addr_phys, (current_pdt + k)->pdt & 0x1ffUL));
|
||||||
|
|
||||||
|
kdebug("k=%d, cpy dest=%#018lx, src=%#018lx", k, phys_2_virt(pg->addr_phys), phys_2_virt((current_pdt + k)->pdt & (~0x1ffUL)));
|
||||||
// 拷贝数据
|
// 拷贝数据
|
||||||
memcpy(phys_2_virt(pg->addr_phys), phys_2_virt((current_pdt + k)->pdt & (~0x1fffUL)), PAGE_2M_SIZE);
|
memcpy(phys_2_virt(pg->addr_phys), phys_2_virt((current_pdt + k)->pdt & (~0x1ffUL)), PAGE_2M_SIZE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1070,12 +1142,13 @@ uint64_t process_copy_thread(uint64_t clone_flags, struct process_control_block
|
|||||||
thd->fs = current_pcb->thread->fs;
|
thd->fs = current_pcb->thread->fs;
|
||||||
thd->gs = current_pcb->thread->gs;
|
thd->gs = current_pcb->thread->gs;
|
||||||
|
|
||||||
|
kdebug("pcb->flags=%ld", pcb->flags);
|
||||||
// 根据是否为内核线程,设置进程的开始执行的地址
|
// 根据是否为内核线程,设置进程的开始执行的地址
|
||||||
if (pcb->flags & PF_KTHREAD)
|
if (pcb->flags & PF_KTHREAD)
|
||||||
thd->rip = (uint64_t)kernel_thread_func;
|
thd->rip = (uint64_t)kernel_thread_func;
|
||||||
else
|
else
|
||||||
thd->rip = (uint64_t)ret_from_system_call;
|
thd->rip = (uint64_t)ret_from_system_call;
|
||||||
kdebug("new proc's ret addr = %#018lx\tchild_regs->rsp = %#018lx", child_regs->rbx, child_regs->rsp);
|
kdebug("new proc's ret addr = %#018lx\tthd->rip=%#018lx stack_start=%#018lx child_regs->rsp = %#018lx, new_rip=%#018lx)", child_regs->rbx, thd->rip,stack_start,child_regs->rsp, child_regs->rip);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -17,6 +17,7 @@
|
|||||||
#include "ptrace.h"
|
#include "ptrace.h"
|
||||||
#include <common/errno.h>
|
#include <common/errno.h>
|
||||||
#include <filesystem/VFS/VFS.h>
|
#include <filesystem/VFS/VFS.h>
|
||||||
|
#include <process/wait_queue.h>
|
||||||
|
|
||||||
// 进程最大可拥有的文件描述符数量
|
// 进程最大可拥有的文件描述符数量
|
||||||
#define PROC_MAX_FD_NUM 16
|
#define PROC_MAX_FD_NUM 16
|
||||||
@ -134,6 +135,9 @@ struct process_control_block
|
|||||||
struct process_control_block *next_pcb;
|
struct process_control_block *next_pcb;
|
||||||
// 父进程的pcb
|
// 父进程的pcb
|
||||||
struct process_control_block *parent_pcb;
|
struct process_control_block *parent_pcb;
|
||||||
|
|
||||||
|
int32_t exit_code; // 进程退出时的返回码
|
||||||
|
wait_queue_node_t wait_child_proc_exit; // 子进程退出等待队列
|
||||||
};
|
};
|
||||||
|
|
||||||
// 将进程的pcb和内核栈融合到一起,8字节对齐
|
// 将进程的pcb和内核栈融合到一起,8字节对齐
|
||||||
@ -159,7 +163,9 @@ union proc_union
|
|||||||
.cpu_id = 0, \
|
.cpu_id = 0, \
|
||||||
.fds = {0}, \
|
.fds = {0}, \
|
||||||
.next_pcb = &proc, \
|
.next_pcb = &proc, \
|
||||||
.parent_pcb = &proc \
|
.parent_pcb = &proc, \
|
||||||
|
.exit_code = 0, \
|
||||||
|
.wait_child_proc_exit = 0 \
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -280,6 +286,39 @@ struct process_control_block *process_get_pcb(long pid);
|
|||||||
*/
|
*/
|
||||||
void process_wakeup(struct process_control_block *pcb);
|
void process_wakeup(struct process_control_block *pcb);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 使当前进程去执行新的代码
|
||||||
|
*
|
||||||
|
* @param regs 当前进程的寄存器
|
||||||
|
* @param path 可执行程序的路径
|
||||||
|
* @param argv 参数列表
|
||||||
|
* @param envp 环境变量
|
||||||
|
* @return ul 错误码
|
||||||
|
*/
|
||||||
|
ul do_execve(struct pt_regs *regs, char *path, char *argv[], char *envp[]);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 释放进程的页表
|
||||||
|
*
|
||||||
|
* @param pcb 要被释放页表的进程
|
||||||
|
* @return uint64_t
|
||||||
|
*/
|
||||||
|
uint64_t process_exit_mm(struct process_control_block *pcb);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 进程退出时执行的函数
|
||||||
|
*
|
||||||
|
* @param code 返回码
|
||||||
|
* @return ul
|
||||||
|
*/
|
||||||
|
ul process_do_exit(ul code);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 当子进程退出后向父进程发送通知
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void process_exit_notify();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief 切换页表
|
* @brief 切换页表
|
||||||
* @param prev 前一个进程的pcb
|
* @param prev 前一个进程的pcb
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include <common/glib.h>
|
#include <common/glib.h>
|
||||||
#include <process/process.h>
|
// #include <process/process.h>
|
||||||
/**
|
/**
|
||||||
* @brief 信号量的等待队列
|
* @brief 信号量的等待队列
|
||||||
*
|
*
|
||||||
|
@ -9,6 +9,7 @@
|
|||||||
#include <filesystem/fat32/fat32.h>
|
#include <filesystem/fat32/fat32.h>
|
||||||
#include <filesystem/VFS/VFS.h>
|
#include <filesystem/VFS/VFS.h>
|
||||||
#include <driver/keyboard/ps2_keyboard.h>
|
#include <driver/keyboard/ps2_keyboard.h>
|
||||||
|
#include <process/process.h>
|
||||||
|
|
||||||
// 导出系统调用入口函数,定义在entry.S中
|
// 导出系统调用入口函数,定义在entry.S中
|
||||||
extern void system_call(void);
|
extern void system_call(void);
|
||||||
@ -440,8 +441,9 @@ uint64_t sys_sbrk(struct pt_regs *regs)
|
|||||||
if ((__int128_t)current_pcb->mm->brk_end + (__int128_t)regs->r8 < current_pcb->mm->brk_start)
|
if ((__int128_t)current_pcb->mm->brk_end + (__int128_t)regs->r8 < current_pcb->mm->brk_start)
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
// kdebug("do brk");
|
||||||
uint64_t new_brk = mm_do_brk(current_pcb->mm->brk_end, (int64_t)regs->r8); // 调整堆内存空间
|
uint64_t new_brk = mm_do_brk(current_pcb->mm->brk_end, (int64_t)regs->r8); // 调整堆内存空间
|
||||||
|
// kdebug("do brk done, new_brk = %#018lx", new_brk);
|
||||||
current_pcb->mm->brk_end = new_brk;
|
current_pcb->mm->brk_end = new_brk;
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
@ -549,6 +551,110 @@ uint64_t sys_getdents(struct pt_regs *regs)
|
|||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 执行新的程序
|
||||||
|
*
|
||||||
|
* @param user_path(r8寄存器) 文件路径
|
||||||
|
* @param argv(r9寄存器) 参数列表
|
||||||
|
* @return uint64_t
|
||||||
|
*/
|
||||||
|
uint64_t sys_execve(struct pt_regs *regs)
|
||||||
|
{
|
||||||
|
kdebug("sys_execve");
|
||||||
|
char *user_path = (char *)regs->r8;
|
||||||
|
char **argv = (char **)regs->r9;
|
||||||
|
|
||||||
|
int path_len = strnlen_user(user_path, PAGE_4K_SIZE);
|
||||||
|
|
||||||
|
kdebug("path_len=%d", path_len);
|
||||||
|
if (path_len >= PAGE_4K_SIZE)
|
||||||
|
return -ENAMETOOLONG;
|
||||||
|
else if (path_len <= 0)
|
||||||
|
return -EFAULT;
|
||||||
|
|
||||||
|
char *path = (char *)kmalloc(path_len + 1, 0);
|
||||||
|
if (path == NULL)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
memset(path, 0, path_len + 1);
|
||||||
|
|
||||||
|
kdebug("before copy file path from user");
|
||||||
|
// 拷贝文件路径
|
||||||
|
strncpy_from_user(path, user_path, path_len);
|
||||||
|
path[path_len] = '\0';
|
||||||
|
|
||||||
|
kdebug("before do_execve, path = %s", path);
|
||||||
|
// 执行新的程序
|
||||||
|
uint64_t retval = do_execve(regs, path, argv, NULL);
|
||||||
|
|
||||||
|
kfree(path);
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 等待进程退出
|
||||||
|
*
|
||||||
|
* @param pid 目标进程id
|
||||||
|
* @param status 返回的状态信息
|
||||||
|
* @param options 等待选项
|
||||||
|
* @param rusage
|
||||||
|
* @return uint64_t
|
||||||
|
*/
|
||||||
|
uint64_t sys_wait4(struct pt_regs *regs)
|
||||||
|
{
|
||||||
|
uint64_t pid = regs->r8;
|
||||||
|
int *status = (int *)regs->r9;
|
||||||
|
int options = regs->r10;
|
||||||
|
void *rusage = regs->r11;
|
||||||
|
|
||||||
|
struct process_control_block *proc = NULL;
|
||||||
|
struct process_control_block *child_proc = NULL;
|
||||||
|
|
||||||
|
// 查找pid为指定值的进程
|
||||||
|
// ps: 这里判断子进程的方法没有按照posix 2008来写。
|
||||||
|
// todo: 根据进程树判断是否为当前进程的子进程
|
||||||
|
for (proc = &initial_proc_union.pcb; proc->next_pcb != &initial_proc_union.pcb; proc = proc->next_pcb)
|
||||||
|
{
|
||||||
|
if (proc->next_pcb->pid == pid)
|
||||||
|
{
|
||||||
|
child_proc = proc->next_pcb;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (child_proc == NULL)
|
||||||
|
return -ECHILD;
|
||||||
|
|
||||||
|
// 暂时不支持options选项,该值目前必须为0
|
||||||
|
if (options != 0)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
// 如果子进程没有退出,则等待其退出
|
||||||
|
while (child_proc->state != PROC_ZOMBIE)
|
||||||
|
wait_queue_sleep_on_interriptible(¤t_pcb->wait_child_proc_exit);
|
||||||
|
|
||||||
|
// 拷贝子进程的返回码
|
||||||
|
copy_to_user(status, child_proc->exit_code, sizeof(int));
|
||||||
|
proc->next_pcb = child_proc->next_pcb;
|
||||||
|
|
||||||
|
// 释放子进程的页表
|
||||||
|
process_exit_mm(child_proc);
|
||||||
|
// 释放子进程的pcb
|
||||||
|
kfree(child_proc);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 进程退出
|
||||||
|
*
|
||||||
|
* @param exit_code 退出返回码
|
||||||
|
* @return uint64_t
|
||||||
|
*/
|
||||||
|
uint64_t sys_exit(struct pt_regs * regs)
|
||||||
|
{
|
||||||
|
return process_do_exit(regs->r8);
|
||||||
|
}
|
||||||
|
|
||||||
ul sys_ahci_end_req(struct pt_regs *regs)
|
ul sys_ahci_end_req(struct pt_regs *regs)
|
||||||
{
|
{
|
||||||
ahci_end_request();
|
ahci_end_request();
|
||||||
@ -579,5 +685,8 @@ system_call_t system_call_table[MAX_SYSTEM_CALL_NUM] =
|
|||||||
[11] = sys_reboot,
|
[11] = sys_reboot,
|
||||||
[12] = sys_chdir,
|
[12] = sys_chdir,
|
||||||
[13] = sys_getdents,
|
[13] = sys_getdents,
|
||||||
[14 ... 254] = system_call_not_exists,
|
[14] = sys_execve,
|
||||||
|
[15] = sys_wait4,
|
||||||
|
[16] = sys_exit,
|
||||||
|
[17 ... 254] = system_call_not_exists,
|
||||||
[255] = sys_ahci_end_req};
|
[255] = sys_ahci_end_req};
|
||||||
|
@ -20,8 +20,12 @@
|
|||||||
#define SYS_VFORK 8
|
#define SYS_VFORK 8
|
||||||
#define SYS_BRK 9
|
#define SYS_BRK 9
|
||||||
#define SYS_SBRK 10
|
#define SYS_SBRK 10
|
||||||
|
|
||||||
#define SYS_REBOOT 11 // 重启
|
#define SYS_REBOOT 11 // 重启
|
||||||
#define SYS_CHDIR 12 // 切换工作目录
|
#define SYS_CHDIR 12 // 切换工作目录
|
||||||
#define SYS_GET_DENTS 13 // 获取目录中的数据
|
#define SYS_GET_DENTS 13 // 获取目录中的数据
|
||||||
|
#define SYS_EXECVE 14 // 执行新的应用程序
|
||||||
|
#define SYS_WAIT4 15 // 等待进程退出
|
||||||
|
#define SYS_EXIT 16 // 进程退出
|
||||||
|
|
||||||
#define SYS_AHCI_END_REQ 255 // AHCI DMA请求结束end_request的系统调用
|
#define SYS_AHCI_END_REQ 255 // AHCI DMA请求结束end_request的系统调用
|
@ -13,31 +13,29 @@ CFLAGS := $(GLOBAL_CFLAGS) -I $(shell pwd)/libs
|
|||||||
current_CFLAGS := $(CFLAGS)
|
current_CFLAGS := $(CFLAGS)
|
||||||
all:
|
all:
|
||||||
|
|
||||||
|
$(shell if [ ! -e $(tmp_output_dir) ];then mkdir -p $(tmp_output_dir); fi)
|
||||||
|
$(shell if [ ! -e $(output_dir) ];then mkdir -p $(output_dir); fi)
|
||||||
|
|
||||||
@list='$(user_sub_dirs)'; for subdir in $$list; do \
|
@list='$(user_sub_dirs)'; for subdir in $$list; do \
|
||||||
|
echo "make all in $$subdir";\
|
||||||
|
cd $$subdir;\
|
||||||
|
$(MAKE) all CFLAGS="$(CFLAGS)" tmp_output_dir="$(tmp_output_dir)" output_dir="$(output_dir)" sys_libs_dir="$(shell pwd)/libs";\
|
||||||
|
cd ..;\
|
||||||
|
done
|
||||||
|
|
||||||
|
# 系统库
|
||||||
|
sys_api_lib:
|
||||||
|
@list='./libs'; for subdir in $$list; do \
|
||||||
echo "make all in $$subdir";\
|
echo "make all in $$subdir";\
|
||||||
cd $$subdir;\
|
cd $$subdir;\
|
||||||
$(MAKE) all CFLAGS="$(CFLAGS)";\
|
$(MAKE) all CFLAGS="$(CFLAGS)";\
|
||||||
cd ..;\
|
cd ..;\
|
||||||
done
|
done
|
||||||
|
|
||||||
|
# ld -b elf64-x86-64 -z muldefs -o $(tmp_output_dir)/sys_api_lib $(shell find ./libs -name "*.o")
|
||||||
$(shell if [ ! -e $(tmp_output_dir) ];then mkdir -p $(tmp_output_dir); fi)
|
|
||||||
$(shell if [ ! -e $(output_dir) ];then mkdir -p $(output_dir); fi)
|
|
||||||
|
|
||||||
# $(MAKE) sys_api_lib
|
|
||||||
$(MAKE) shell
|
|
||||||
# objcopy -I elf64-x86-64 -S -R ".eh_frame" -R ".comment" -O binary sys_api_lib $(ROOT_PATH)/bin/user/init.bin
|
|
||||||
#objcopy -I elf64-x86-64 -S -R ".eh_frame" -R ".comment" -O elf64-x86-64 sys_api_lib $(ROOT_PATH)/bin/user/init.bin
|
|
||||||
|
|
||||||
sys_api_lib:
|
|
||||||
|
|
||||||
ld -b elf64-x86-64 -z muldefs -o $(tmp_output_dir)/sys_api_lib $(shell find ./libs -name "*.o")
|
|
||||||
#ld -b elf64-x86-64 -z muldefs -o sys_api_lib init.o $(shell find . -name "*.o") -T init.lds
|
#ld -b elf64-x86-64 -z muldefs -o sys_api_lib init.o $(shell find . -name "*.o") -T init.lds
|
||||||
|
|
||||||
shell:
|
|
||||||
ld -b elf64-x86-64 -z muldefs -o $(tmp_output_dir)/shell $(shell find ./apps/shell -name "*.o") $(shell find ./libs -name "*.o") -T ./apps/shell/shell.lds
|
|
||||||
|
|
||||||
objcopy -I elf64-x86-64 -S -R ".eh_frame" -R ".comment" -O elf64-x86-64 $(tmp_output_dir)/shell $(output_dir)/shell.elf
|
|
||||||
clean:
|
clean:
|
||||||
rm -rf $(GARBAGE)
|
rm -rf $(GARBAGE)
|
||||||
|
|
7
user/apps/about/Makefile
Normal file
7
user/apps/about/Makefile
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
all: about.o
|
||||||
|
|
||||||
|
ld -b elf64-x86-64 -z muldefs -o $(tmp_output_dir)/about $(shell find . -name "*.o") $(shell find $(sys_libs_dir) -name "*.o") -T shell.lds
|
||||||
|
|
||||||
|
objcopy -I elf64-x86-64 -S -R ".eh_frame" -R ".comment" -O elf64-x86-64 $(tmp_output_dir)/about $(output_dir)/about.elf
|
||||||
|
about.o: about.c
|
||||||
|
gcc $(CFLAGS) -c about.c -o about.o
|
7
user/apps/about/about.c
Normal file
7
user/apps/about/about.c
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
#include <libc/stdio.h>
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
printf("Hello World!\n");
|
||||||
|
while(1);
|
||||||
|
}
|
@ -1,5 +1,8 @@
|
|||||||
all: shell.o cmd.o cmd_help.o
|
all: shell.o cmd.o cmd_help.o
|
||||||
|
|
||||||
|
ld -b elf64-x86-64 -z muldefs -o $(tmp_output_dir)/shell $(shell find . -name "*.o") $(shell find $(sys_libs_dir) -name "*.o") -T shell.lds
|
||||||
|
|
||||||
|
objcopy -I elf64-x86-64 -S -R ".eh_frame" -R ".comment" -O elf64-x86-64 $(tmp_output_dir)/shell $(output_dir)/shell.elf
|
||||||
shell.o: shell.c
|
shell.o: shell.c
|
||||||
gcc $(CFLAGS) -c shell.c -o shell.o
|
gcc $(CFLAGS) -c shell.c -o shell.o
|
||||||
|
|
||||||
|
@ -9,6 +9,7 @@
|
|||||||
#include <libc/stdlib.h>
|
#include <libc/stdlib.h>
|
||||||
#include <libc/fcntl.h>
|
#include <libc/fcntl.h>
|
||||||
#include <libc/dirent.h>
|
#include <libc/dirent.h>
|
||||||
|
#include <libc/sys/wait.h>
|
||||||
|
|
||||||
#include "cmd_help.h"
|
#include "cmd_help.h"
|
||||||
|
|
||||||
@ -36,6 +37,36 @@ struct built_in_cmd_t shell_cmds[] =
|
|||||||
// 总共的内建命令数量
|
// 总共的内建命令数量
|
||||||
const static int total_built_in_cmd_num = sizeof(shell_cmds) / sizeof(struct built_in_cmd_t);
|
const static int total_built_in_cmd_num = sizeof(shell_cmds) / sizeof(struct built_in_cmd_t);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 将cwd与文件名进行拼接,得到最终的文件绝对路径
|
||||||
|
*
|
||||||
|
* @param filename 文件名
|
||||||
|
* @param result_path_len 结果字符串的大小
|
||||||
|
* @return char* 结果字符串
|
||||||
|
*/
|
||||||
|
static char *get_target_filepath(const char *filename, int *result_path_len)
|
||||||
|
{
|
||||||
|
int cwd_len = strlen(shell_current_path);
|
||||||
|
|
||||||
|
// 计算文件完整路径的长度
|
||||||
|
*result_path_len = cwd_len + strlen(filename);
|
||||||
|
|
||||||
|
char *file_path = (char *)malloc(*result_path_len + 2);
|
||||||
|
|
||||||
|
memset(file_path, 0, *result_path_len + 2);
|
||||||
|
|
||||||
|
strcpy(file_path, shell_current_path);
|
||||||
|
|
||||||
|
// 在文件路径中加入斜杠
|
||||||
|
if (cwd_len > 1)
|
||||||
|
file_path[cwd_len] = '/';
|
||||||
|
|
||||||
|
// 拼接完整路径
|
||||||
|
strcat(file_path, filename);
|
||||||
|
|
||||||
|
return file_path;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief 寻找对应的主命令编号
|
* @brief 寻找对应的主命令编号
|
||||||
*
|
*
|
||||||
@ -230,7 +261,7 @@ int shell_cmd_ls(int argc, char **argv)
|
|||||||
printf("\n");
|
printf("\n");
|
||||||
closedir(dir);
|
closedir(dir);
|
||||||
|
|
||||||
if (argc > 1)
|
if (argv != NULL)
|
||||||
free(argv);
|
free(argv);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@ -247,7 +278,7 @@ int shell_cmd_pwd(int argc, char **argv)
|
|||||||
{
|
{
|
||||||
if (shell_current_path)
|
if (shell_current_path)
|
||||||
printf("%s\n", shell_current_path);
|
printf("%s\n", shell_current_path);
|
||||||
if (argc > 1)
|
if (argv != NULL)
|
||||||
free(argv);
|
free(argv);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -260,23 +291,8 @@ int shell_cmd_pwd(int argc, char **argv)
|
|||||||
*/
|
*/
|
||||||
int shell_cmd_cat(int argc, char **argv)
|
int shell_cmd_cat(int argc, char **argv)
|
||||||
{
|
{
|
||||||
int cwd_len = strlen(shell_current_path);
|
int path_len = 0;
|
||||||
|
char *file_path = get_target_filepath(argv[1], &path_len);
|
||||||
// 计算文件完整路径的长度
|
|
||||||
int file_path_len = cwd_len + strlen(argv[1]);
|
|
||||||
|
|
||||||
char *file_path = (char *)malloc(file_path_len + 2);
|
|
||||||
|
|
||||||
memset(file_path, 0, file_path_len + 2);
|
|
||||||
|
|
||||||
strcpy(file_path, shell_current_path);
|
|
||||||
|
|
||||||
// 在文件路径中加入斜杠
|
|
||||||
if (cwd_len > 1)
|
|
||||||
file_path[cwd_len] = '/';
|
|
||||||
|
|
||||||
// 拼接完整路径
|
|
||||||
strcat(file_path, argv[1]);
|
|
||||||
|
|
||||||
// 打开文件
|
// 打开文件
|
||||||
int fd = open(file_path, 0);
|
int fd = open(file_path, 0);
|
||||||
@ -298,6 +314,8 @@ int shell_cmd_cat(int argc, char **argv)
|
|||||||
|
|
||||||
close(fd);
|
close(fd);
|
||||||
free(buf);
|
free(buf);
|
||||||
|
if (argv != NULL)
|
||||||
|
free(argv);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -347,9 +365,36 @@ int shell_cmd_rmdir(int argc, char **argv) {}
|
|||||||
* @param argv
|
* @param argv
|
||||||
* @return int
|
* @return int
|
||||||
*/
|
*/
|
||||||
|
int shell_cmd_exec(int argc, char **argv)
|
||||||
|
{
|
||||||
|
pid_t pid = fork();
|
||||||
|
int retval = 0;
|
||||||
|
printf(" pid=%d \n",pid);
|
||||||
|
|
||||||
// todo:
|
while(1);
|
||||||
int shell_cmd_exec(int argc, char **argv) {}
|
if (pid == 0)
|
||||||
|
{
|
||||||
|
printf("child proc\n");
|
||||||
|
// 子进程
|
||||||
|
int path_len = 0;
|
||||||
|
char *file_path = get_target_filepath(argv[1], &path_len);
|
||||||
|
printf("before execv, path=%s\n", file_path);
|
||||||
|
execv(file_path, argv);
|
||||||
|
free(argv);
|
||||||
|
while(1);
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
printf("parent process wait for pid:[ %d ]\n", pid);
|
||||||
|
while(1);
|
||||||
|
waitpid(pid, &retval, 0);
|
||||||
|
printf("parent process wait pid [ %d ], exit code=%d\n", pid, retval);
|
||||||
|
free(argv);
|
||||||
|
}
|
||||||
|
|
||||||
|
while(1);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief 重启命令
|
* @brief 重启命令
|
||||||
|
@ -37,12 +37,21 @@ int parse_command(char *buf, int *argc, char ***argv);
|
|||||||
*
|
*
|
||||||
* @param kb_fd 键盘文件描述符
|
* @param kb_fd 键盘文件描述符
|
||||||
*/
|
*/
|
||||||
static void main_loop(int kb_fd)
|
void main_loop(int kb_fd)
|
||||||
{
|
{
|
||||||
|
|
||||||
unsigned char input_buffer[INPUT_BUFFER_SIZE] = {0};
|
unsigned char input_buffer[INPUT_BUFFER_SIZE] = {0};
|
||||||
|
|
||||||
|
sbrk(24);
|
||||||
|
pid_t pid = fork();
|
||||||
|
int retval = 0;
|
||||||
|
|
||||||
|
|
||||||
|
while (1)
|
||||||
|
printf(" @pid=%d ", pid);
|
||||||
// 初始化当前工作目录的路径
|
// 初始化当前工作目录的路径
|
||||||
shell_current_path = (char *)malloc(3);
|
shell_current_path = (char *)malloc(3);
|
||||||
|
|
||||||
memset(shell_current_path, 0, 3);
|
memset(shell_current_path, 0, 3);
|
||||||
shell_current_path[0] = '/';
|
shell_current_path[0] = '/';
|
||||||
shell_current_path[1] = '\0';
|
shell_current_path[1] = '\0';
|
||||||
@ -54,6 +63,7 @@ static void main_loop(int kb_fd)
|
|||||||
char **argv;
|
char **argv;
|
||||||
|
|
||||||
printf("[DragonOS] %s # ", shell_current_path);
|
printf("[DragonOS] %s # ", shell_current_path);
|
||||||
|
|
||||||
memset(input_buffer, 0, INPUT_BUFFER_SIZE);
|
memset(input_buffer, 0, INPUT_BUFFER_SIZE);
|
||||||
|
|
||||||
// 循环读取每一行到buffer
|
// 循环读取每一行到buffer
|
||||||
|
@ -2,7 +2,7 @@ all: libc
|
|||||||
|
|
||||||
CFLAGS += -I .
|
CFLAGS += -I .
|
||||||
|
|
||||||
libc_sub_dirs=math
|
libc_sub_dirs=math sys
|
||||||
|
|
||||||
|
|
||||||
libc: unistd.o fcntl.o malloc.o errno.o printf.o stdlib.o ctype.o string.o dirent.o
|
libc: unistd.o fcntl.o malloc.o errno.o printf.o stdlib.o ctype.o string.o dirent.o
|
||||||
|
@ -138,7 +138,7 @@ static int malloc_enlarge(int64_t size)
|
|||||||
}
|
}
|
||||||
|
|
||||||
int64_t free_space = brk_max_addr - brk_managed_addr;
|
int64_t free_space = brk_max_addr - brk_managed_addr;
|
||||||
|
// printf("size=%ld\tfree_space=%ld\n", size, free_space);
|
||||||
if (free_space < size) // 现有堆空间不足
|
if (free_space < size) // 现有堆空间不足
|
||||||
{
|
{
|
||||||
if (sbrk(size - free_space) != (void *)(-1))
|
if (sbrk(size - free_space) != (void *)(-1))
|
||||||
@ -148,6 +148,8 @@ static int malloc_enlarge(int64_t size)
|
|||||||
put_string("malloc_enlarge(): no_mem\n", COLOR_YELLOW, COLOR_BLACK);
|
put_string("malloc_enlarge(): no_mem\n", COLOR_YELLOW, COLOR_BLACK);
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// printf("brk max addr = %#018lx\n", brk_max_addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 扩展管理的堆空间
|
// 扩展管理的堆空间
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
#include <libc/unistd.h>
|
#include <libc/unistd.h>
|
||||||
#include <libc/stdlib.h>
|
#include <libc/stdlib.h>
|
||||||
#include <libc/ctype.h>
|
#include <libc/ctype.h>
|
||||||
|
#include <libsystem/syscall.h>
|
||||||
|
|
||||||
int abs(int i)
|
int abs(int i)
|
||||||
{
|
{
|
||||||
@ -44,3 +45,13 @@ int atoi(const char *str)
|
|||||||
|
|
||||||
return neg ? n : -n;
|
return neg ? n : -n;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 退出进程
|
||||||
|
*
|
||||||
|
* @param status
|
||||||
|
*/
|
||||||
|
void exit(int status)
|
||||||
|
{
|
||||||
|
syscall_invoke(SYS_EXIT, status, 0, 0, 0, 0, 0, 0, 0);
|
||||||
|
}
|
@ -33,3 +33,10 @@ long long llabs(long long i);
|
|||||||
* @return int
|
* @return int
|
||||||
*/
|
*/
|
||||||
int atoi(const char * str);
|
int atoi(const char * str);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 退出进程
|
||||||
|
*
|
||||||
|
* @param status
|
||||||
|
*/
|
||||||
|
void exit(int status);
|
8
user/libs/libc/sys/Makefile
Normal file
8
user/libs/libc/sys/Makefile
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
|
||||||
|
all: wait.o
|
||||||
|
|
||||||
|
CFLAGS += -I .
|
||||||
|
|
||||||
|
|
||||||
|
wait.o: wait.c
|
||||||
|
gcc $(CFLAGS) -c wait.c -o wait.o
|
26
user/libs/libc/sys/wait.c
Normal file
26
user/libs/libc/sys/wait.c
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
#include "wait.h"
|
||||||
|
#include <libsystem/syscall.h>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 等待所有子进程退出
|
||||||
|
*
|
||||||
|
* @param stat_loc 返回的子进程结束状态
|
||||||
|
* @return pid_t
|
||||||
|
*/
|
||||||
|
pid_t wait(int *stat_loc)
|
||||||
|
{
|
||||||
|
return waitpid((pid_t)(-1), stat_loc, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 等待指定pid的子进程退出
|
||||||
|
*
|
||||||
|
* @param pid 子进程的pid
|
||||||
|
* @param stat_loc 返回的子进程结束状态
|
||||||
|
* @param options 额外的控制选项
|
||||||
|
* @return pid_t
|
||||||
|
*/
|
||||||
|
pid_t waitpid(pid_t pid, int *stat_loc, int options)
|
||||||
|
{
|
||||||
|
return (pid_t)syscall_invoke(SYS_WAIT4, (uint64_t)pid, (uint64_t)stat_loc, options, 0, 0, 0, 0, 0);
|
||||||
|
}
|
21
user/libs/libc/sys/wait.h
Normal file
21
user/libs/libc/sys/wait.h
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "types.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 等待所有子进程退出
|
||||||
|
*
|
||||||
|
* @param stat_loc 返回的子进程结束状态
|
||||||
|
* @return pid_t
|
||||||
|
*/
|
||||||
|
pid_t wait(int *stat_loc);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 等待指定pid的子进程退出
|
||||||
|
*
|
||||||
|
* @param pid 子进程的pid
|
||||||
|
* @param stat_loc 返回的子进程结束状态
|
||||||
|
* @param options 额外的控制选项
|
||||||
|
* @return pid_t
|
||||||
|
*/
|
||||||
|
pid_t waitpid(pid_t pid, int *stat_loc, int options);
|
@ -123,16 +123,26 @@ int64_t chdir(char *dest_path)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
int retval = syscall_invoke(SYS_CHDIR, (uint64_t)dest_path, 0,0,0,0,0,0,0);
|
return syscall_invoke(SYS_CHDIR, (uint64_t)dest_path, 0, 0, 0, 0, 0, 0, 0);
|
||||||
if(retval == 0)
|
|
||||||
{
|
|
||||||
errno = 0;
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
else
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 执行新的程序
|
||||||
|
*
|
||||||
|
* @param path 文件路径
|
||||||
|
* @param argv 参数列表
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
int execv(const char *path, char *const argv[])
|
||||||
{
|
{
|
||||||
errno = retval;
|
if (path == NULL)
|
||||||
|
{
|
||||||
|
errno = -ENOENT;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
int retval = syscall_invoke(SYS_EXECVE, (uint64_t)path, (uint64_t)argv, 0, 0, 0, 0, 0, 0);
|
||||||
|
if(retval != 0)
|
||||||
|
return -1;
|
||||||
|
else return 0;
|
||||||
}
|
}
|
@ -80,3 +80,12 @@ void *sbrk(int64_t increment);
|
|||||||
* @return int64_t 成功:0,失败:负值(错误码)
|
* @return int64_t 成功:0,失败:负值(错误码)
|
||||||
*/
|
*/
|
||||||
int64_t chdir(char *dest_path);
|
int64_t chdir(char *dest_path);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 执行新的程序
|
||||||
|
*
|
||||||
|
* @param path 文件路径
|
||||||
|
* @param argv 参数列表
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
int execv(const char* path, char * const argv[]);
|
||||||
|
@ -14,9 +14,13 @@
|
|||||||
#define SYS_VFORK 8
|
#define SYS_VFORK 8
|
||||||
#define SYS_BRK 9
|
#define SYS_BRK 9
|
||||||
#define SYS_SBRK 10
|
#define SYS_SBRK 10
|
||||||
#define SYS_REBOOT 11
|
|
||||||
|
#define SYS_REBOOT 11 // 重启
|
||||||
#define SYS_CHDIR 12 // 切换工作目录
|
#define SYS_CHDIR 12 // 切换工作目录
|
||||||
#define SYS_GET_DENTS 13 // 获取目录中的数据
|
#define SYS_GET_DENTS 13 // 获取目录中的数据
|
||||||
|
#define SYS_EXECVE 14 // 执行新的应用程序
|
||||||
|
#define SYS_WAIT4 15 // 等待进程退出
|
||||||
|
#define SYS_EXIT 16 // 进程退出
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief 用户态系统调用函数
|
* @brief 用户态系统调用函数
|
||||||
|
Loading…
x
Reference in New Issue
Block a user