mirror of
https://github.com/DragonOS-Community/DragonOS.git
synced 2025-06-09 11:16:47 +00:00
🆕 运行文件系统中的二进制程序
This commit is contained in:
parent
099b24539a
commit
0aec6827ee
6
.vscode/settings.json
vendored
6
.vscode/settings.json
vendored
@ -88,7 +88,11 @@
|
|||||||
"typeinfo": "c",
|
"typeinfo": "c",
|
||||||
"x86_64_ipi.h": "c",
|
"x86_64_ipi.h": "c",
|
||||||
"unistd.h": "c",
|
"unistd.h": "c",
|
||||||
"syscall_num.h": "c"
|
"syscall_num.h": "c",
|
||||||
|
"stdint.h": "c",
|
||||||
|
"syscall.h": "c",
|
||||||
|
"fcntl.h": "c",
|
||||||
|
"types.h": "c"
|
||||||
},
|
},
|
||||||
"C_Cpp.errorSquiggles": "Enabled",
|
"C_Cpp.errorSquiggles": "Enabled",
|
||||||
"esbonio.sphinx.confDir": ""
|
"esbonio.sphinx.confDir": ""
|
||||||
|
16
Makefile
16
Makefile
@ -1,8 +1,22 @@
|
|||||||
SUBDIRS = kernel
|
SUBDIRS = kernel user
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
export ARCH=x86_64
|
||||||
|
export ROOT_PATH=$(shell pwd)
|
||||||
|
|
||||||
|
export DEBUG=DEBUG
|
||||||
|
export GLOBAL_CFLAGS := -mcmodel=large -fno-builtin -m64 -O0 -fno-stack-protector -D $(ARCH)
|
||||||
|
|
||||||
|
ifeq ($(DEBUG), DEBUG)
|
||||||
|
GLOBAL_CFLAGS += -g
|
||||||
|
endif
|
||||||
|
|
||||||
.PHONY: all
|
.PHONY: all
|
||||||
all:
|
all:
|
||||||
mkdir -p bin/kernel/
|
mkdir -p bin/kernel/
|
||||||
|
mkdir -p bin/user/
|
||||||
@list='$(SUBDIRS)'; for subdir in $$list; do \
|
@list='$(SUBDIRS)'; for subdir in $$list; do \
|
||||||
echo "make all in $$subdir";\
|
echo "make all in $$subdir";\
|
||||||
cd $$subdir;\
|
cd $$subdir;\
|
||||||
|
@ -7,17 +7,10 @@ DIR_LIB=lib
|
|||||||
lib_patterns := *.a
|
lib_patterns := *.a
|
||||||
LIB_FILES := $(foreach DIR,$(DIR_LIB),$(addprefix $(DIR)/,$(lib_patterns)))
|
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_
|
# 控制操作系统使用的中断控制器 _INTR_8259A_ _INTR_APIC_
|
||||||
PIC := _INTR_APIC_
|
PIC := _INTR_APIC_
|
||||||
CFLAGS += -D $(PIC) -D $(ARCH)
|
CFLAGS = $(GLOBAL_CFLAGS) -D $(PIC) -I .
|
||||||
|
|
||||||
ASFLAGS := --64
|
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)
|
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页表项的地址
|
// 计算线性地址对应的pml4页表项的地址
|
||||||
ul *tmp;
|
ul *tmp;
|
||||||
if (is_phys)
|
if (is_phys)
|
||||||
|
@ -322,6 +322,37 @@ void user_level_function()
|
|||||||
while (1)
|
while (1)
|
||||||
pause();
|
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 使当前进程去执行新的代码
|
* @brief 使当前进程去执行新的代码
|
||||||
*
|
*
|
||||||
@ -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);
|
memcpy(phys_2_virt(new_mms->pgd) + 256, phys_2_virt(initial_proc[proc_current_cpu_id]) + 256, PAGE_4K_SIZE / 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @todo: 加载elf文件并映射对应的页
|
* @todo: 加载elf文件并映射对应的页
|
||||||
*
|
*
|
||||||
@ -371,7 +401,6 @@ ul do_execve(struct pt_regs *regs, char *path)
|
|||||||
unsigned long code_start_addr = 0x800000;
|
unsigned long code_start_addr = 0x800000;
|
||||||
unsigned long stack_start_addr = 0xa00000;
|
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);
|
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);
|
process_switch_mm(current_pcb);
|
||||||
@ -394,24 +423,21 @@ ul do_execve(struct pt_regs *regs, char *path)
|
|||||||
|
|
||||||
// 关闭之前的文件描述符
|
// 关闭之前的文件描述符
|
||||||
process_exit_files(current_pcb);
|
process_exit_files(current_pcb);
|
||||||
|
|
||||||
// 清除进程的vfork标志位
|
// 清除进程的vfork标志位
|
||||||
current_pcb->flags &= ~PF_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);
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -436,7 +462,6 @@ ul initial_kernel_thread(ul arg)
|
|||||||
// 主动放弃内核线程身份
|
// 主动放弃内核线程身份
|
||||||
current_pcb->flags &= (~PF_KTHREAD);
|
current_pcb->flags &= (~PF_KTHREAD);
|
||||||
|
|
||||||
|
|
||||||
// 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);
|
||||||
|
|
||||||
@ -445,11 +470,12 @@ ul initial_kernel_thread(ul arg)
|
|||||||
current_pcb->flags = 0;
|
current_pcb->flags = 0;
|
||||||
// 将返回用户层的代码压入堆栈,向rdx传入regs的地址,然后jmp到do_execve这个系统调用api的处理函数 这里的设计思路和switch_proc类似
|
// 将返回用户层的代码压入堆栈,向rdx传入regs的地址,然后jmp到do_execve这个系统调用api的处理函数 这里的设计思路和switch_proc类似
|
||||||
// 加载用户态程序:init.bin
|
// 加载用户态程序:init.bin
|
||||||
|
char init_path[] = "/init.bin";
|
||||||
|
uint64_t addr = (uint64_t)&init_path;
|
||||||
__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),
|
||||||
"S"("/init.bin"),
|
"m"(current_pcb->thread->rsp), "m"(current_pcb->thread->rip), "S"("/init.bin")
|
||||||
"m"(current_pcb->thread->rsp), "m"(current_pcb->thread->rip)
|
|
||||||
: "memory");
|
: "memory");
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
@ -662,35 +688,6 @@ copy_flags_failed:;
|
|||||||
kfree(tsk);
|
kfree(tsk);
|
||||||
return retval;
|
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;
|
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));
|
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));
|
memcpy(child_regs, current_regs, sizeof(struct pt_regs));
|
||||||
|
|
||||||
|
// 设置子进程的返回值为0
|
||||||
child_regs->rax = 0;
|
child_regs->rax = 0;
|
||||||
child_regs->rsp = stack_start;
|
child_regs->rsp = stack_start;
|
||||||
|
|
||||||
|
@ -97,9 +97,6 @@ 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)
|
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);
|
// printk_color(BLACK, WHITE, (char *)regs->r8);
|
||||||
|
|
||||||
@ -310,7 +307,7 @@ uint64_t sys_write(struct pt_regs *regs)
|
|||||||
* @param fd_num 文件描述符号
|
* @param fd_num 文件描述符号
|
||||||
* @param offset 偏移量
|
* @param offset 偏移量
|
||||||
* @param whence 调整模式
|
* @param whence 调整模式
|
||||||
* @return uint64_t
|
* @return uint64_t 调整结束后的文件访问位置
|
||||||
*/
|
*/
|
||||||
uint64_t sys_lseek(struct pt_regs *regs)
|
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,
|
[4] = sys_read,
|
||||||
[5] = sys_write,
|
[5] = sys_write,
|
||||||
[6] = sys_lseek,
|
[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};
|
[255] = sys_ahci_end_req};
|
||||||
|
@ -16,5 +16,7 @@
|
|||||||
#define SYS_READ 4
|
#define SYS_READ 4
|
||||||
#define SYS_WRITE 5
|
#define SYS_WRITE 5
|
||||||
#define SYS_LSEEK 6
|
#define SYS_LSEEK 6
|
||||||
|
#define SYS_FORK 7
|
||||||
|
#define SYS_VFORK 8
|
||||||
|
|
||||||
#define SYS_AHCI_END_REQ 255 // AHCI DMA请求结束end_request的系统调用
|
#define SYS_AHCI_END_REQ 255 // AHCI DMA请求结束end_request的系统调用
|
10
run.sh
10
run.sh
@ -22,7 +22,7 @@ iso_boot_grub='./iso/boot/grub'
|
|||||||
iso_boot='./iso/boot/'
|
iso_boot='./iso/boot/'
|
||||||
iso='./DragonOS.iso'
|
iso='./DragonOS.iso'
|
||||||
iso_folder='./iso/'
|
iso_folder='./iso/'
|
||||||
|
root_folder="$(pwd)"
|
||||||
|
|
||||||
# toolchain
|
# toolchain
|
||||||
OS=`uname -s`
|
OS=`uname -s`
|
||||||
@ -88,6 +88,14 @@ else
|
|||||||
flag_can_run=1
|
flag_can_run=1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# 拷贝init文件到硬盘
|
||||||
|
cd tools
|
||||||
|
bash m*
|
||||||
|
sudo cp ${root_folder}/bin/user/init.bin ${root_folder}/bin/disk_mount
|
||||||
|
sync
|
||||||
|
bash u*
|
||||||
|
cd ..
|
||||||
|
|
||||||
if [ $flag_can_run -eq 1 ]; then
|
if [ $flag_can_run -eq 1 ]; then
|
||||||
if [ ${IA32_USE_QEMU} == 0 ]; then
|
if [ ${IA32_USE_QEMU} == 0 ]; then
|
||||||
bochs -q -f ${bochsrc} -rc ./tools/bochsinit
|
bochs -q -f ${bochsrc} -rc ./tools/bochsinit
|
||||||
|
33
user/Makefile
Normal file
33
user/Makefile
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
user_sub_dirs = libs
|
||||||
|
|
||||||
|
SUBDIR_ROOTS := .
|
||||||
|
DIRS := . $(shell find $(SUBDIR_ROOTS) -type d)
|
||||||
|
GARBAGE_PATTERNS := *.o *.s~ *.s *.S~ *.c~ *.h~ kernel
|
||||||
|
GARBAGE := $(foreach DIR,$(DIRS),$(addprefix $(DIR)/,$(GARBAGE_PATTERNS)))
|
||||||
|
|
||||||
|
|
||||||
|
objs :=
|
||||||
|
CFLAGS := $(GLOBAL_CFLAGS)
|
||||||
|
current_CFLAGS := $(CFLAGS) -I $(shell pwd)/libs
|
||||||
|
all:
|
||||||
|
|
||||||
|
@list='$(user_sub_dirs)'; for subdir in $$list; do \
|
||||||
|
echo "make all in $$subdir";\
|
||||||
|
cd $$subdir;\
|
||||||
|
$(MAKE) all CFLAGS="$(CFLAGS)";\
|
||||||
|
cd ..;\
|
||||||
|
done
|
||||||
|
$(MAKE) init.o
|
||||||
|
$(MAKE) sys_api_lib
|
||||||
|
|
||||||
|
objcopy -I elf64-x86-64 -S -R ".eh_frame" -R ".comment" -O binary sys_api_lib $(ROOT_PATH)/bin/user/init.bin
|
||||||
|
|
||||||
|
sys_api_lib: init.o
|
||||||
|
|
||||||
|
|
||||||
|
ld -b elf64-x86-64 -z muldefs -o sys_api_lib init.o $(shell find . -name "*.o") -T init.lds
|
||||||
|
|
||||||
|
init.o: init.c
|
||||||
|
gcc $(current_CFLAGS) -c init.c -o init.o
|
||||||
|
clean:
|
||||||
|
rm -rf $(GARBAGE)
|
31
user/init.c
Normal file
31
user/init.c
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
#include <libc/unistd.h>
|
||||||
|
#include <libc/stdio.h>
|
||||||
|
#include <libc/fcntl.h>
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
|
||||||
|
char string[] = "333.txt";
|
||||||
|
uint8_t buf[128] = {0};
|
||||||
|
char tips_str[] = "The first application 'init.bin' started successfully!\n";
|
||||||
|
put_string(tips_str, COLOR_GREEN, COLOR_BLACK);
|
||||||
|
int fd = open(string, 0);
|
||||||
|
read(fd, buf, 128);
|
||||||
|
|
||||||
|
put_string(buf, COLOR_ORANGE, COLOR_BLACK);
|
||||||
|
|
||||||
|
lseek(fd, 0, SEEK_SET);
|
||||||
|
write(fd, tips_str, sizeof(tips_str)-1);
|
||||||
|
lseek(fd, 0, SEEK_SET);
|
||||||
|
|
||||||
|
// 由于暂时没有实现用户态的memset,因此先手动清零
|
||||||
|
for(int i=0;i<128;++i)
|
||||||
|
buf[i] = 0;
|
||||||
|
|
||||||
|
read(fd, buf, 128);
|
||||||
|
put_string(buf, COLOR_YELLOW, COLOR_BLACK);
|
||||||
|
close(fd);
|
||||||
|
|
||||||
|
while (1)
|
||||||
|
;
|
||||||
|
}
|
50
user/init.lds
Normal file
50
user/init.lds
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
|
||||||
|
OUTPUT_FORMAT("elf64-x86-64","elf64-x86-64","elf64-x86-64")
|
||||||
|
OUTPUT_ARCH(i386:x86-64)
|
||||||
|
ENTRY(main)
|
||||||
|
|
||||||
|
SECTIONS
|
||||||
|
{
|
||||||
|
|
||||||
|
. = 0x800000;
|
||||||
|
|
||||||
|
|
||||||
|
.text :
|
||||||
|
{
|
||||||
|
_text = .;
|
||||||
|
|
||||||
|
init.o(.text)
|
||||||
|
|
||||||
|
_etext = .;
|
||||||
|
}
|
||||||
|
. = ALIGN(8);
|
||||||
|
|
||||||
|
.data :
|
||||||
|
{
|
||||||
|
_data = .;
|
||||||
|
*(.data)
|
||||||
|
|
||||||
|
_edata = .;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
rodata_start_pa = .;
|
||||||
|
.rodata :
|
||||||
|
{
|
||||||
|
_rodata = .;
|
||||||
|
*(.rodata)
|
||||||
|
_erodata = .;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.bss :
|
||||||
|
{
|
||||||
|
_bss = .;
|
||||||
|
*(.bss)
|
||||||
|
_ebss = .;
|
||||||
|
}
|
||||||
|
|
||||||
|
_end = .;
|
||||||
|
|
||||||
|
|
||||||
|
}
|
11
user/libs/Makefile
Normal file
11
user/libs/Makefile
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
|
||||||
|
user_libs_sub_dirs=libc libsystem
|
||||||
|
|
||||||
|
|
||||||
|
all:
|
||||||
|
@list='$(user_libs_sub_dirs)'; for subdir in $$list; do \
|
||||||
|
echo "make all in $$subdir";\
|
||||||
|
cd $$subdir;\
|
||||||
|
$(MAKE) all CFLAGS="$(CFLAGS) -I $(shell pwd)";\
|
||||||
|
cd ..;\
|
||||||
|
done
|
12
user/libs/libc/Makefile
Normal file
12
user/libs/libc/Makefile
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
all: libc
|
||||||
|
|
||||||
|
CFLAGS += -I .
|
||||||
|
|
||||||
|
|
||||||
|
libc: unistd.o fcntl.o
|
||||||
|
|
||||||
|
unistd.o: unistd.c
|
||||||
|
gcc $(CFLAGS) -c unistd.c -o unistd.o
|
||||||
|
|
||||||
|
fcntl.o: fcntl.c
|
||||||
|
gcc $(CFLAGS) -c fcntl.c -o fcntl.o
|
101
user/libs/libc/errno.h
Normal file
101
user/libs/libc/errno.h
Normal file
@ -0,0 +1,101 @@
|
|||||||
|
/**
|
||||||
|
* @file errno.h
|
||||||
|
* @author fslongjin (longjin@RinGoTek.cn)
|
||||||
|
* @brief
|
||||||
|
* @version 0.1
|
||||||
|
* @date 2022-04-22
|
||||||
|
*
|
||||||
|
* @copyright Copyright (c) 2022
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#define E2BIG 1 /* 参数列表过长,或者在输出buffer中缺少空间 或者参数比系统内建的最大值要大 Argument list too long. */
|
||||||
|
#define EACCES 2 /* 访问被拒绝 Permission denied */
|
||||||
|
#define EADDRINUSE 3 /* 地址正在被使用 Address in use.*/
|
||||||
|
#define EADDRNOTAVAIL 4 /* 地址不可用 Address not available.*/
|
||||||
|
#define EAFNOSUPPORT 5 /* 地址family不支持 Address family not supported. */
|
||||||
|
#define EAGAIN 6 /* 资源不可用,请重试。 Resource unavailable, try again (may be the same value as [EWOULDBLOCK]).*/
|
||||||
|
#define EALREADY 7 /* 连接已经在处理 Connection already in progress. */
|
||||||
|
#define EBADF 8 /* 错误的文件描述符 Bad file descriptor. */
|
||||||
|
#define EBADMSG 9 /* 错误的消息 Bad message. */
|
||||||
|
|
||||||
|
#define EBUSY 10 /* 设备或资源忙 Device or resource busy. */
|
||||||
|
#define ECANCELED 11 /* 操作被取消 Operation canceled. */
|
||||||
|
#define ECHILD 12 /* 没有子进程 No child processes. */
|
||||||
|
#define ECONNABORTED 13 /* 连接已断开 Connection aborted. */
|
||||||
|
#define ECONNREFUSED 14 /* 连接被拒绝 Connection refused. */
|
||||||
|
#define ECONNRESET 15 /* 连接被重置 Connection reset. */
|
||||||
|
#define EDEADLK 16 /* 资源死锁将要发生 Resource deadlock would occur. */
|
||||||
|
#define EDESTADDRREQ 17 /* 需要目标地址 Destination address required.*/
|
||||||
|
#define EDOM 18 /* 数学参数超出作用域 Mathematics argument out of domain of function. */
|
||||||
|
#define EDQUOT 19 /* 保留使用 Reserved */
|
||||||
|
|
||||||
|
#define EEXIST 20 /* 文件已存在 File exists. */
|
||||||
|
#define EFAULT 21 /* 错误的地址 Bad address */
|
||||||
|
#define EFBIG 22 /* 文件太大 File too large. */
|
||||||
|
#define EHOSTUNREACH 23 /* 主机不可达 Host is unreachable.*/
|
||||||
|
#define EIDRM 24 /* 标志符被移除 Identifier removed. */
|
||||||
|
#define EILSEQ 25 /* 不合法的字符序列 Illegal byte sequence. */
|
||||||
|
#define EINPROGRESS 26 /* 操作正在处理 Operation in progress. */
|
||||||
|
#define EINTR 27 /* 被中断的函数 Interrupted function. */
|
||||||
|
#define EINVAL 28 /* 不可用的参数 Invalid argument. */
|
||||||
|
#define EIO 29 /* I/O错误 I/O error. */
|
||||||
|
|
||||||
|
#define EISCONN 30 /* 套接字已连接 Socket is connected. */
|
||||||
|
#define EISDIR 31 /* 是一个目录 Is a directory */
|
||||||
|
#define ELOOP 32 /* 符号链接级别过多 Too many levels of symbolic links. */
|
||||||
|
#define EMFILE 33 /* 文件描述符的值过大 File descriptor value too large. */
|
||||||
|
#define EMLINK 34 /* 链接数过多 Too many links. */
|
||||||
|
#define EMSGSIZE 35 /* 消息过大 Message too large. */
|
||||||
|
#define EMULTIHOP 36 /* 保留使用 Reserved. */
|
||||||
|
#define ENAMETOOLONG 37 /* 文件名过长 Filename too long. */
|
||||||
|
#define ENETDOWN 38 /* 网络已关闭 Network is down. */
|
||||||
|
#define ENETRESET 39 /* 网络连接已断开 Connection aborted by network. */
|
||||||
|
|
||||||
|
#define ENETUNREACH 40 /* 网络不可达 Network unreachable. */
|
||||||
|
#define ENFILE 41 /* 系统中打开的文件过多 Too many files open in system.*/
|
||||||
|
#define ENOBUFS 42 /* 缓冲区空间不足 No buffer space available. */
|
||||||
|
#define ENODATA 43 /* 队列头没有可读取的消息 No message is available on the STREAM head read queue. */
|
||||||
|
#define ENODEV 44 /* 没有指定的设备 No such device. */
|
||||||
|
#define ENOENT 45 /* 没有指定的文件或目录 No such file or directory. */
|
||||||
|
#define ENOEXEC 46 /* 可执行文件格式错误 Executable file format error. */
|
||||||
|
#define ENOLCK 47 /* 没有可用的锁 No locks available. */
|
||||||
|
#define ENOLINK 48 /* 保留 Reserved. */
|
||||||
|
#define ENOMEM 49 /* 没有足够的空间 Not enough space. */
|
||||||
|
|
||||||
|
#define ENOMSG 50 /* 没有期待类型的消息 No message of the desired type. */
|
||||||
|
#define ENOPROTOOPT 51 /* 协议不可用 Protocol not available. */
|
||||||
|
#define ENOSPC 52 /* 设备上没有空间 No space left on device. */
|
||||||
|
#define ENOSR 53 /* 没有STREAM资源 No STREAM resources.*/
|
||||||
|
#define ENOSTR 54 /* 不是STREAM Not a STREAM */
|
||||||
|
#define ENOSYS 55 /* 功能不支持 Function not supported. */
|
||||||
|
#define ENOTCONN 56 /* 套接字未连接 The socket is not connected. */
|
||||||
|
#define ENOTDIR 57 /* 不是目录 Not a directory. */
|
||||||
|
#define ENOTEMPTY 58 /* 目录非空 Directory not empty. */
|
||||||
|
#define ENOTRECOVERABLE 59 /* 状态不可覆盖 State not recoverable. */
|
||||||
|
|
||||||
|
#define ENOTSOCK 60 /* 不是一个套接字 Not a socket.*/
|
||||||
|
#define ENOTSUP 61 /* 不被支持 Not supported (may be the same value as [EOPNOTSUPP]). */
|
||||||
|
#define ENOTTY 62 /* 不正确的I/O控制操作 Inappropriate I/O control operation. */
|
||||||
|
#define ENXIO 63 /* 没有这样的设备或地址 No such device or address. */
|
||||||
|
#define EOPNOTSUPP 64 /* 套接字不支持该操作 Operation not supported on socket (may be the same value as [ENOTSUP]). */
|
||||||
|
#define EOVERFLOW 65 /* 数值过大,产生溢出 Value too large to be stored in data type. */
|
||||||
|
#define EOWNERDEAD 66 /* 之前的拥有者挂了 Previous owner died. */
|
||||||
|
#define EPERM 67 /* 操作不被允许 Operation not permitted. */
|
||||||
|
#define EPIPE 68 /* 断开的管道 Broken pipe. */
|
||||||
|
#define EPROTO 69 /* 协议错误 Protocol error. */
|
||||||
|
|
||||||
|
#define EPROTONOSUPPORT 70 /* 协议不被支持 Protocol not supported. */
|
||||||
|
#define EPROTOTYPE 71 /* 对于套接字而言,错误的协议 Protocol wrong type for socket. */
|
||||||
|
#define ERANGE 72 /* 结果过大 Result too large. */
|
||||||
|
#define EROFS 73 /* 只读的文件系统 Read-only file system. */
|
||||||
|
#define ESPIPE 74 /* 错误的寻道 Invalid seek. */
|
||||||
|
#define ESRCH 75 /* 没有这样的进程 No such process. */
|
||||||
|
#define ESTALE 76 /* 保留 Reserved. */
|
||||||
|
#define ETIME 77 /* 流式ioctl()超时 Stream ioctl() timeout */
|
||||||
|
#define ETIMEDOUT 78 /* 连接超时 Connection timed out.*/
|
||||||
|
#define ETXTBSY 79 /* 文本文件忙 Text file busy. */
|
||||||
|
|
||||||
|
#define EWOULDBLOCK 80 /* 操作将被禁止 Operation would block (may be the same value as [EAGAIN]). */
|
||||||
|
#define EXDEV 81 /* 跨设备连接 Cross-device link. */
|
15
user/libs/libc/fcntl.c
Normal file
15
user/libs/libc/fcntl.c
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
#include <libc/fcntl.h>
|
||||||
|
#include <libsystem/syscall.h>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 打开文件的接口
|
||||||
|
*
|
||||||
|
* @param path 文件路径
|
||||||
|
* @param options 打开选项
|
||||||
|
* @param ...
|
||||||
|
* @return int 文件描述符
|
||||||
|
*/
|
||||||
|
int open(const char *path, int options, ...)
|
||||||
|
{
|
||||||
|
return syscall_invoke(SYS_OPEN, (uint64_t)path, 0, 0, 0, 0, 0, 0, 0);
|
||||||
|
}
|
42
user/libs/libc/fcntl.h
Normal file
42
user/libs/libc/fcntl.h
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
/**
|
||||||
|
* @file fcntl.h
|
||||||
|
* @author fslongjin (longjin@RinGoTek.cn)
|
||||||
|
* @brief
|
||||||
|
* @version 0.1
|
||||||
|
* @date 2022-04-26
|
||||||
|
*
|
||||||
|
* @copyright Copyright (c) 2022
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#define O_RDONLY 00000000 // Open Read-only
|
||||||
|
#define O_WRONLY 00000001 // Open Write-only
|
||||||
|
#define O_RDWR 00000002 // Open read/write
|
||||||
|
#define O_ACCMODE 00000003 // Mask for file access modes
|
||||||
|
|
||||||
|
#define O_CREAT 00000100 // Create file if it does not exist
|
||||||
|
#define O_EXCL 00000200 // Fail if file already exists
|
||||||
|
#define O_NOCTTY 00000400 // Do not assign controlling terminal
|
||||||
|
|
||||||
|
#define O_TRUNC 00001000 // 文件存在且是普通文件,并以O_RDWR或O_WRONLY打开,则它会被清空
|
||||||
|
|
||||||
|
#define O_APPEND 00002000 // 文件指针会被移动到文件末尾
|
||||||
|
|
||||||
|
#define O_NONBLOCK 00004000 // 非阻塞式IO模式
|
||||||
|
|
||||||
|
#define O_EXEC 00010000 // 以仅执行的方式打开(非目录文件)
|
||||||
|
#define O_SEARCH 00020000 // Open the directory for search only
|
||||||
|
#define O_DIRECTORY 00040000 // 打开的必须是一个目录
|
||||||
|
#define O_NOFOLLOW 00100000 // Do not follow symbolic links
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 打开文件的接口
|
||||||
|
*
|
||||||
|
* @param path 文件路径
|
||||||
|
* @param options 打开选项
|
||||||
|
* @param ...
|
||||||
|
* @return int 文件描述符
|
||||||
|
*/
|
||||||
|
int open(const char * path, int options, ...);
|
7
user/libs/libc/stdio.h
Normal file
7
user/libs/libc/stdio.h
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#define SEEK_SET 0 /* Seek relative to start-of-file */
|
||||||
|
#define SEEK_CUR 1 /* Seek relative to current position */
|
||||||
|
#define SEEK_END 2 /* Seek relative to end-of-file */
|
||||||
|
|
||||||
|
#define SEEK_MAX 3
|
83
user/libs/libc/sys/types.h
Normal file
83
user/libs/libc/sys/types.h
Normal file
@ -0,0 +1,83 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
typedef unsigned char u_char;
|
||||||
|
typedef unsigned short u_short;
|
||||||
|
typedef unsigned int u_int;
|
||||||
|
typedef unsigned long u_long;
|
||||||
|
|
||||||
|
typedef uint32_t uid_t;
|
||||||
|
typedef uint32_t gid_t;
|
||||||
|
typedef long long ssize_t;
|
||||||
|
|
||||||
|
typedef int __pid_t;
|
||||||
|
#define pid_t __pid_t
|
||||||
|
typedef __SIZE_TYPE__ size_t;
|
||||||
|
|
||||||
|
typedef char *caddr_t;
|
||||||
|
|
||||||
|
typedef int id_t;
|
||||||
|
|
||||||
|
typedef uint64_t ino_t;
|
||||||
|
typedef int64_t off_t;
|
||||||
|
|
||||||
|
typedef uint32_t blkcnt_t;
|
||||||
|
typedef uint32_t blksize_t;
|
||||||
|
typedef uint32_t dev_t;
|
||||||
|
typedef uint16_t mode_t;
|
||||||
|
typedef uint32_t nlink_t;
|
||||||
|
|
||||||
|
typedef int64_t time_t;
|
||||||
|
typedef uint32_t useconds_t;
|
||||||
|
typedef int32_t suseconds_t;
|
||||||
|
typedef uint32_t clock_t;
|
||||||
|
|
||||||
|
typedef uint64_t fsblkcnt_t;
|
||||||
|
typedef uint64_t fsfilcnt_t;
|
||||||
|
|
||||||
|
#define __socklen_t_defined
|
||||||
|
#define __socklen_t uint32_t
|
||||||
|
typedef __socklen_t socklen_t;
|
||||||
|
|
||||||
|
struct utimbuf
|
||||||
|
{
|
||||||
|
time_t actime;
|
||||||
|
time_t modtime;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef int pthread_t;
|
||||||
|
typedef int pthread_key_t;
|
||||||
|
typedef uint32_t pthread_once_t;
|
||||||
|
|
||||||
|
typedef struct __pthread_mutex_t
|
||||||
|
{
|
||||||
|
uint32_t lock;
|
||||||
|
pthread_t owner;
|
||||||
|
int level;
|
||||||
|
int type;
|
||||||
|
} pthread_mutex_t;
|
||||||
|
|
||||||
|
typedef void *pthread_attr_t;
|
||||||
|
typedef struct __pthread_mutexattr_t
|
||||||
|
{
|
||||||
|
int type;
|
||||||
|
} pthread_mutexattr_t;
|
||||||
|
|
||||||
|
typedef struct __pthread_cond_t
|
||||||
|
{
|
||||||
|
pthread_mutex_t *mutex;
|
||||||
|
uint32_t value;
|
||||||
|
int clockid; // clockid_t
|
||||||
|
} pthread_cond_t;
|
||||||
|
|
||||||
|
typedef uint64_t pthread_rwlock_t;
|
||||||
|
typedef void *pthread_rwlockattr_t;
|
||||||
|
typedef struct __pthread_spinlock_t
|
||||||
|
{
|
||||||
|
int m_lock;
|
||||||
|
} pthread_spinlock_t;
|
||||||
|
typedef struct __pthread_condattr_t
|
||||||
|
{
|
||||||
|
int clockid; // clockid_t
|
||||||
|
} pthread_condattr_t;
|
65
user/libs/libc/unistd.c
Normal file
65
user/libs/libc/unistd.c
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
#include <libc/unistd.h>
|
||||||
|
#include <libsystem/syscall.h>
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 往屏幕上输出字符串
|
||||||
|
*
|
||||||
|
* @param str 字符串指针
|
||||||
|
* @param front_color 前景色
|
||||||
|
* @param bg_color 背景色
|
||||||
|
* @return int64_t
|
||||||
|
*/
|
||||||
|
int64_t put_string(char* str, uint64_t front_color, uint64_t bg_color)
|
||||||
|
{
|
||||||
|
return syscall_invoke(SYS_PUT_STRING, str, front_color, bg_color,0,0,0,0,0);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* @brief 关闭文件接口
|
||||||
|
*
|
||||||
|
* @param fd 文件描述符
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
int close(int fd)
|
||||||
|
{
|
||||||
|
return syscall_invoke(SYS_CLOSE, fd, 0, 0, 0, 0, 0, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 从文件读取数据的接口
|
||||||
|
*
|
||||||
|
* @param fd 文件描述符
|
||||||
|
* @param buf 缓冲区
|
||||||
|
* @param count 待读取数据的字节数
|
||||||
|
* @return ssize_t 成功读取的字节数
|
||||||
|
*/
|
||||||
|
ssize_t read(int fd, void *buf, size_t count)
|
||||||
|
{
|
||||||
|
return (ssize_t)syscall_invoke(SYS_READ, fd, buf, count,0,0,0,0,0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 向文件写入数据的接口
|
||||||
|
*
|
||||||
|
* @param fd 文件描述符
|
||||||
|
* @param buf 缓冲区
|
||||||
|
* @param count 待写入数据的字节数
|
||||||
|
* @return ssize_t 成功写入的字节数
|
||||||
|
*/
|
||||||
|
ssize_t write(int fd, void const *buf, size_t count)
|
||||||
|
{
|
||||||
|
return (ssize_t)syscall_invoke(SYS_WRITE, fd, buf, count,0,0,0,0,0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 调整文件的访问位置
|
||||||
|
*
|
||||||
|
* @param fd 文件描述符号
|
||||||
|
* @param offset 偏移量
|
||||||
|
* @param whence 调整模式
|
||||||
|
* @return uint64_t 调整结束后的文件访问位置
|
||||||
|
*/
|
||||||
|
off_t lseek(int fd, off_t offset, int whence)
|
||||||
|
{
|
||||||
|
return (off_t)syscall_invoke(SYS_LSEEK, fd, offset, whence, 0,0,0,0,0);
|
||||||
|
}
|
79
user/libs/libc/unistd.h
Normal file
79
user/libs/libc/unistd.h
Normal file
@ -0,0 +1,79 @@
|
|||||||
|
#pragma once
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <libc/sys/types.h>
|
||||||
|
|
||||||
|
// 字体颜色的宏定义
|
||||||
|
#define COLOR_WHITE 0x00ffffff //白
|
||||||
|
#define COLOR_BLACK 0x00000000 //黑
|
||||||
|
#define COLOR_RED 0x00ff0000 //红
|
||||||
|
#define COLOR_ORANGE 0x00ff8000 //橙
|
||||||
|
#define COLOR_YELLOW 0x00ffff00 //黄
|
||||||
|
#define COLOR_GREEN 0x0000ff00 //绿
|
||||||
|
#define COLOR_BLUE 0x000000ff //蓝
|
||||||
|
#define COLOR_INDIGO 0x0000ffff //靛
|
||||||
|
#define COLOR_PURPLE 0x008000ff //紫
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 往屏幕上输出字符串
|
||||||
|
*
|
||||||
|
* @param str 字符串指针
|
||||||
|
* @param front_color 前景色
|
||||||
|
* @param bg_color 背景色
|
||||||
|
* @return int64_t
|
||||||
|
*/
|
||||||
|
int64_t put_string(char* str, uint64_t front_color, uint64_t bg_color);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 关闭文件接口
|
||||||
|
*
|
||||||
|
* @param fd 文件描述符
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
int close(int fd);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 从文件读取数据的接口
|
||||||
|
*
|
||||||
|
* @param fd 文件描述符
|
||||||
|
* @param buf 缓冲区
|
||||||
|
* @param count 待读取数据的字节数
|
||||||
|
* @return ssize_t 成功读取的字节数
|
||||||
|
*/
|
||||||
|
ssize_t read(int fd, void *buf, size_t count);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 向文件写入数据的接口
|
||||||
|
*
|
||||||
|
* @param fd 文件描述符
|
||||||
|
* @param buf 缓冲区
|
||||||
|
* @param count 待写入数据的字节数
|
||||||
|
* @return ssize_t 成功写入的字节数
|
||||||
|
*/
|
||||||
|
ssize_t write(int fd, void const *buf, size_t count);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 调整文件的访问位置
|
||||||
|
*
|
||||||
|
* @param fd 文件描述符号
|
||||||
|
* @param offset 偏移量
|
||||||
|
* @param whence 调整模式
|
||||||
|
* @return uint64_t 调整结束后的文件访问位置
|
||||||
|
*/
|
||||||
|
off_t lseek(int fd, off_t offset, int whence);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief fork当前进程
|
||||||
|
*
|
||||||
|
* @return pid_t
|
||||||
|
*/
|
||||||
|
pid_t fork(void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief fork当前进程,但是与父进程共享VM、flags、fd
|
||||||
|
*
|
||||||
|
* @return pid_t
|
||||||
|
*/
|
||||||
|
pid_t vfork(void);
|
||||||
|
|
8
user/libs/libsystem/Makefile
Normal file
8
user/libs/libsystem/Makefile
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
all: libsystem
|
||||||
|
# echo $(shell pwd)
|
||||||
|
|
||||||
|
|
||||||
|
libsystem: syscall.o
|
||||||
|
|
||||||
|
syscall.o: syscall.c
|
||||||
|
gcc $(CFLAGS) -c syscall.c -o syscall.o
|
20
user/libs/libsystem/syscall.c
Normal file
20
user/libs/libsystem/syscall.c
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
#include "syscall.h"
|
||||||
|
|
||||||
|
long syscall_invoke(uint64_t syscall_id, uint64_t arg0, uint64_t arg1, uint64_t arg2, uint64_t arg3, uint64_t arg4, uint64_t arg5, uint64_t arg6, uint64_t arg7)
|
||||||
|
{
|
||||||
|
long err_code;
|
||||||
|
__asm__ __volatile__(
|
||||||
|
"movq %2, %%r8 \n\t"
|
||||||
|
"movq %3, %%r9 \n\t"
|
||||||
|
"movq %4, %%r10 \n\t"
|
||||||
|
"movq %5, %%r11 \n\t"
|
||||||
|
"movq %6, %%r12 \n\t"
|
||||||
|
"movq %7, %%r13 \n\t"
|
||||||
|
"movq %8, %%r14 \n\t"
|
||||||
|
"movq %9, %%r15 \n\t"
|
||||||
|
"int $0x80 \n\t"
|
||||||
|
: "=a"(err_code)
|
||||||
|
: "a"(syscall_id), "m"(arg0), "m"(arg1), "m"(arg2), "m"(arg3), "m"(arg4), "m"(arg5), "m"(arg6), "m"(arg7)
|
||||||
|
: "memory", "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15", "rcx", "rdx");
|
||||||
|
return err_code;
|
||||||
|
}
|
30
user/libs/libsystem/syscall.h
Normal file
30
user/libs/libsystem/syscall.h
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
// 系统调用号
|
||||||
|
#define SYS_NOT_EXISTS 0
|
||||||
|
#define SYS_PUT_STRING 1
|
||||||
|
#define SYS_OPEN 2
|
||||||
|
#define SYS_CLOSE 3
|
||||||
|
#define SYS_READ 4
|
||||||
|
#define SYS_WRITE 5
|
||||||
|
#define SYS_LSEEK 6
|
||||||
|
#define SYS_FORK 7
|
||||||
|
#define SYS_VFORK 8
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 用户态系统调用函数
|
||||||
|
*
|
||||||
|
* @param syscall_id
|
||||||
|
* @param arg0
|
||||||
|
* @param arg1
|
||||||
|
* @param arg2
|
||||||
|
* @param arg3
|
||||||
|
* @param arg4
|
||||||
|
* @param arg5
|
||||||
|
* @param arg6
|
||||||
|
* @param arg7
|
||||||
|
* @return long
|
||||||
|
*/
|
||||||
|
long syscall_invoke(uint64_t syscall_id, uint64_t arg0, uint64_t arg1, uint64_t arg2, uint64_t arg3, uint64_t arg4, uint64_t arg5, uint64_t arg6, uint64_t arg7);
|
BIN
user/sys_api_lib
Normal file
BIN
user/sys_api_lib
Normal file
Binary file not shown.
Loading…
x
Reference in New Issue
Block a user