mirror of
https://github.com/DragonOS-Community/DragonOS.git
synced 2025-06-08 18:26:48 +00:00
🆕 sys_open系统调用
This commit is contained in:
parent
d94d92f5ee
commit
966d67fcde
4
.vscode/settings.json
vendored
4
.vscode/settings.json
vendored
@ -86,7 +86,9 @@
|
||||
"cinttypes": "c",
|
||||
"cstdbool": "c",
|
||||
"typeinfo": "c",
|
||||
"x86_64_ipi.h": "c"
|
||||
"x86_64_ipi.h": "c",
|
||||
"unistd.h": "c",
|
||||
"syscall_num.h": "c"
|
||||
},
|
||||
"C_Cpp.errorSquiggles": "Enabled",
|
||||
"esbonio.sphinx.confDir": ""
|
||||
|
31
kernel/common/fcntl.h
Normal file
31
kernel/common/fcntl.h
Normal file
@ -0,0 +1,31 @@
|
||||
/**
|
||||
* @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
|
@ -456,11 +456,11 @@ bool verify_area(uint64_t addr_start, uint64_t length)
|
||||
|
||||
/**
|
||||
* @brief 从用户空间搬运数据到内核空间
|
||||
*
|
||||
*
|
||||
* @param dst 目的地址
|
||||
* @param src 源地址
|
||||
* @param size 搬运的大小
|
||||
* @return uint64_t
|
||||
* @return uint64_t
|
||||
*/
|
||||
static inline uint64_t copy_from_user(void *dst, void *src, uint64_t size)
|
||||
{
|
||||
@ -470,7 +470,7 @@ static inline uint64_t copy_from_user(void *dst, void *src, uint64_t size)
|
||||
|
||||
/**
|
||||
* @brief 先每次搬运8 bytes,剩余就直接一个个byte搬运
|
||||
*
|
||||
*
|
||||
*/
|
||||
asm volatile("rep \n\t"
|
||||
"movsq \n\t"
|
||||
@ -484,11 +484,11 @@ static inline uint64_t copy_from_user(void *dst, void *src, uint64_t size)
|
||||
|
||||
/**
|
||||
* @brief 从内核空间搬运数据到用户空间
|
||||
*
|
||||
*
|
||||
* @param dst 目的地址
|
||||
* @param src 源地址
|
||||
* @param size 搬运的大小
|
||||
* @return uint64_t
|
||||
* @return uint64_t
|
||||
*/
|
||||
static inline uint64_t copy_to_user(void *dst, void *src, uint64_t size)
|
||||
{
|
||||
@ -498,7 +498,7 @@ static inline uint64_t copy_to_user(void *dst, void *src, uint64_t size)
|
||||
|
||||
/**
|
||||
* @brief 先每次搬运8 bytes,剩余就直接一个个byte搬运
|
||||
*
|
||||
*
|
||||
*/
|
||||
asm volatile("rep \n\t"
|
||||
"movsq \n\t"
|
||||
@ -508,4 +508,50 @@ static inline uint64_t copy_to_user(void *dst, void *src, uint64_t size)
|
||||
: "=&c"(size), "=&D"(tmp0), "=&S"(tmp1)
|
||||
: "r"(size & 7), "0"(size >> 3), "1"(dst), "2"(src));
|
||||
return size;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 测量来自用户空间的字符串的长度,会检验地址空间是否属于用户空间
|
||||
* @param src
|
||||
* @param maxlen
|
||||
* @return long
|
||||
*/
|
||||
long strnlen_user(void *src, unsigned long maxlen)
|
||||
{
|
||||
|
||||
unsigned long size = strlen(src);
|
||||
|
||||
// 地址不合法
|
||||
if (!verify_area((uint64_t)src, size))
|
||||
return 0;
|
||||
|
||||
return size <= maxlen ? size : maxlen;
|
||||
}
|
||||
|
||||
char *strncpy(char *Dest, char *Src, long Count)
|
||||
{
|
||||
__asm__ __volatile__("cld \n\t"
|
||||
"1: \n\t"
|
||||
"decq %2 \n\t"
|
||||
"js 2f \n\t"
|
||||
"lodsb \n\t"
|
||||
"stosb \n\t"
|
||||
"testb %%al, %%al \n\t"
|
||||
"jne 1b \n\t"
|
||||
"rep \n\t"
|
||||
"stosb \n\t"
|
||||
"2: \n\t"
|
||||
:
|
||||
: "S"(Src), "D"(Dest), "c"(Count)
|
||||
: "ax", "memory");
|
||||
return Dest;
|
||||
}
|
||||
|
||||
long strncpy_from_user(void *dst, void *src, unsigned long size)
|
||||
{
|
||||
if (!verify_area((uint64_t)src, size))
|
||||
return 0;
|
||||
|
||||
strncpy(dst, src, size);
|
||||
return size;
|
||||
}
|
@ -1,10 +1,10 @@
|
||||
#include "VFS.h"
|
||||
#include <common/kprint.h>
|
||||
#include <mm/slab.h>
|
||||
|
||||
// 为filesystem_type_t结构体实例化一个链表头
|
||||
static struct vfs_filesystem_type_t vfs_fs = {"filesystem", 0};
|
||||
|
||||
|
||||
/**
|
||||
* @brief 挂载文件系统
|
||||
*
|
||||
@ -31,16 +31,16 @@ struct vfs_superblock_t *vfs_mount_fs(char *name, void *DPTE, uint8_t DPT_type,
|
||||
|
||||
/**
|
||||
* @brief 在VFS中注册文件系统
|
||||
*
|
||||
*
|
||||
* @param fs 文件系统类型结构体
|
||||
* @return uint64_t
|
||||
* @return uint64_t
|
||||
*/
|
||||
uint64_t vfs_register_filesystem(struct vfs_filesystem_type_t *fs)
|
||||
{
|
||||
struct vfs_filesystem_type_t *p = NULL;
|
||||
for(p = &vfs_fs; p;p = p->next)
|
||||
for (p = &vfs_fs; p; p = p->next)
|
||||
{
|
||||
if(!strcmp(p->name,fs->name)) // 已经注册相同名称的文件系统
|
||||
if (!strcmp(p->name, fs->name)) // 已经注册相同名称的文件系统
|
||||
return VFS_E_FS_EXISTED;
|
||||
}
|
||||
|
||||
@ -52,15 +52,86 @@ uint64_t vfs_register_filesystem(struct vfs_filesystem_type_t *fs)
|
||||
uint64_t vfs_unregister_filesystem(struct vfs_filesystem_type_t *fs)
|
||||
{
|
||||
struct vfs_filesystem_type_t *p = &vfs_fs;
|
||||
while(p->next)
|
||||
while (p->next)
|
||||
{
|
||||
if(p->next == fs)
|
||||
if (p->next == fs)
|
||||
{
|
||||
p->next = p->next->next;
|
||||
fs->next = NULL;
|
||||
return VFS_SUCCESS;
|
||||
}
|
||||
else p = p->next;
|
||||
else
|
||||
p = p->next;
|
||||
}
|
||||
return VFS_E_FS_NOT_EXIST;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 按照路径查找文件
|
||||
*
|
||||
* @param path 路径
|
||||
* @param flags 1:返回父目录项, 0:返回结果目录项
|
||||
* @return struct vfs_dir_entry_t* 目录项
|
||||
*/
|
||||
struct vfs_dir_entry_t *vfs_path_walk(char *path, uint64_t flags)
|
||||
{
|
||||
|
||||
struct vfs_dir_entry_t *parent = vfs_root_sb->root;
|
||||
// 去除路径前的斜杠
|
||||
while (*path == '/')
|
||||
++path;
|
||||
|
||||
if ((!*path) || (*path == '\0'))
|
||||
return parent;
|
||||
|
||||
struct vfs_dir_entry_t *dentry;
|
||||
|
||||
while (true)
|
||||
{
|
||||
// 提取出下一级待搜索的目录名或文件名,并保存在dEntry_name中
|
||||
char *tmp_path = path;
|
||||
while ((*path && *path != '\0') && (*path != '/'))
|
||||
++path;
|
||||
int tmp_path_len = path - tmp_path;
|
||||
|
||||
dentry = (struct vfs_dir_entry_t *)kmalloc(sizeof(struct vfs_dir_entry_t), 0);
|
||||
memset(dentry, 0, sizeof(struct vfs_dir_entry_t));
|
||||
// 为目录项的名称分配内存
|
||||
dentry->name = (char *)kmalloc(tmp_path_len + 1, 0);
|
||||
// 貌似这里不需要memset,因为空间会被覆盖
|
||||
// memset(dentry->name, 0, tmp_path_len+1);
|
||||
|
||||
memcpy(dentry->name, tmp_path, tmp_path_len);
|
||||
dentry->name[tmp_path_len] = '\0';
|
||||
dentry->name_length = tmp_path_len;
|
||||
|
||||
if (parent->dir_inode->inode_ops->lookup(parent->dir_inode, dentry) == NULL)
|
||||
{
|
||||
// 搜索失败
|
||||
kerror("cannot find the file/dir : %s", dentry->name);
|
||||
kfree(dentry->name);
|
||||
kfree(dentry);
|
||||
return NULL;
|
||||
}
|
||||
// 找到子目录项
|
||||
// 初始化子目录项的entry
|
||||
list_init(&dentry->child_node_list);
|
||||
list_init(&dentry->subdirs_list);
|
||||
dentry->parent = parent;
|
||||
|
||||
while (*path == '/')
|
||||
++path;
|
||||
|
||||
if ((!*path) || (*path == '\0')) // 已经到达末尾
|
||||
{
|
||||
if (flags & 1) // 返回父目录
|
||||
{
|
||||
return parent;
|
||||
}
|
||||
|
||||
return dentry;
|
||||
}
|
||||
|
||||
parent = dentry;
|
||||
}
|
||||
}
|
@ -71,13 +71,17 @@ struct vfs_index_node_t
|
||||
void *private_inode_info;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief 文件描述符
|
||||
*
|
||||
*/
|
||||
struct vfs_file_t
|
||||
{
|
||||
long position;
|
||||
uint64_t mode;
|
||||
|
||||
struct vfs_dir_entry_t *dEntry;
|
||||
struct vfs_file_opeartions_t *file_ops;
|
||||
struct vfs_file_operations_t *file_ops;
|
||||
void *private_data;
|
||||
};
|
||||
|
||||
@ -147,4 +151,14 @@ uint64_t vfs_unregister_filesystem(struct vfs_filesystem_type_t *fs);
|
||||
* @param buf 文件系统的引导扇区
|
||||
* @return struct vfs_superblock_t*
|
||||
*/
|
||||
struct vfs_superblock_t *vfs_mount_fs(char *name, void *DPTE, uint8_t DPT_type, void *buf, int8_t ahci_ctrl_num, int8_t ahci_port_num, int8_t part_num);
|
||||
struct vfs_superblock_t *vfs_mount_fs(char *name, void *DPTE, uint8_t DPT_type, void *buf, int8_t ahci_ctrl_num, int8_t ahci_port_num, int8_t part_num);
|
||||
|
||||
|
||||
/**
|
||||
* @brief 按照路径查找文件
|
||||
*
|
||||
* @param path 路径
|
||||
* @param flags 1:返回父目录项, 0:返回结果目录项
|
||||
* @return struct vfs_dir_entry_t* 目录项
|
||||
*/
|
||||
struct vfs_dir_entry_t *vfs_path_walk(char *path, uint64_t flags);
|
@ -344,76 +344,6 @@ find_lookup_success:; // 找到目标dentry
|
||||
return dest_dentry;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 按照路径查找文件
|
||||
*
|
||||
* @param part_id fat32分区id
|
||||
* @param path
|
||||
* @param flags 1:返回父目录项, 0:返回结果目录项
|
||||
* @return struct vfs_dir_entry_t* 目录项
|
||||
*/
|
||||
struct vfs_dir_entry_t *fat32_path_walk(char *path, uint64_t flags)
|
||||
{
|
||||
|
||||
struct vfs_dir_entry_t *parent = vfs_root_sb->root;
|
||||
// 去除路径前的斜杠
|
||||
while (*path == '/')
|
||||
++path;
|
||||
|
||||
if ((!*path) || (*path == '\0'))
|
||||
return parent;
|
||||
|
||||
struct vfs_dir_entry_t *dentry;
|
||||
|
||||
while (true)
|
||||
{
|
||||
// 提取出下一级待搜索的目录名或文件名,并保存在dEntry_name中
|
||||
char *tmp_path = path;
|
||||
while ((*path && *path != '\0') && (*path != '/'))
|
||||
++path;
|
||||
int tmp_path_len = path - tmp_path;
|
||||
|
||||
dentry = (struct vfs_dir_entry_t *)kmalloc(sizeof(struct vfs_dir_entry_t), 0);
|
||||
memset(dentry, 0, sizeof(struct vfs_dir_entry_t));
|
||||
// 为目录项的名称分配内存
|
||||
dentry->name = (char *)kmalloc(tmp_path_len + 1, 0);
|
||||
// 貌似这里不需要memset,因为空间会被覆盖
|
||||
// memset(dentry->name, 0, tmp_path_len+1);
|
||||
|
||||
memcpy(dentry->name, tmp_path, tmp_path_len);
|
||||
dentry->name[tmp_path_len] = '\0';
|
||||
dentry->name_length = tmp_path_len;
|
||||
|
||||
if (parent->dir_inode->inode_ops->lookup(parent->dir_inode, dentry) == NULL)
|
||||
{
|
||||
// 搜索失败
|
||||
kerror("cannot find the file/dir : %s", dentry->name);
|
||||
kfree(dentry->name);
|
||||
kfree(dentry);
|
||||
return NULL;
|
||||
}
|
||||
// 找到子目录项
|
||||
// 初始化子目录项的entry
|
||||
list_init(&dentry->child_node_list);
|
||||
list_init(&dentry->subdirs_list);
|
||||
dentry->parent = parent;
|
||||
|
||||
while (*path == '/')
|
||||
++path;
|
||||
|
||||
if ((!*path) || (*path == '\0')) // 已经到达末尾
|
||||
{
|
||||
if (flags & 1) // 返回父目录
|
||||
{
|
||||
return parent;
|
||||
}
|
||||
|
||||
return dentry;
|
||||
}
|
||||
|
||||
parent = dentry;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 创建fat32文件系统的超级块
|
||||
@ -610,6 +540,7 @@ struct vfs_dir_entry_operations_t fat32_dEntry_ops =
|
||||
// todo: open
|
||||
long fat32_open(struct vfs_index_node_t *inode, struct vfs_file_t *file_ptr)
|
||||
{
|
||||
return VFS_SUCCESS;
|
||||
}
|
||||
|
||||
// todo: close
|
||||
|
@ -176,15 +176,6 @@ typedef struct fat32_inode_info_t fat32_inode_info_t;
|
||||
*/
|
||||
struct vfs_superblock_t *fat32_register_partition(uint8_t ahci_ctrl_num, uint8_t ahci_port_num, uint8_t part_num);
|
||||
|
||||
/**
|
||||
* @brief 按照路径查找文件
|
||||
*
|
||||
* @param part_id fat32分区id
|
||||
* @param path
|
||||
* @param flags 1:返回父目录项, 0:返回结果目录项
|
||||
* @return struct vfs_dir_entry_t* 目录项
|
||||
*/
|
||||
struct vfs_dir_entry_t *fat32_path_walk(char *path, uint64_t flags);
|
||||
|
||||
/**
|
||||
* @brief 创建fat32文件系统的超级块
|
||||
|
@ -156,8 +156,8 @@ void system_initialize()
|
||||
|
||||
process_init();
|
||||
HPET_init();
|
||||
fat32_init();
|
||||
|
||||
// fat32_init();
|
||||
// 系统初始化到此结束,剩下的初始化功能应当放在初始内核线程中执行
|
||||
|
||||
}
|
||||
|
||||
@ -185,19 +185,20 @@ void Start_Kernel(void)
|
||||
|
||||
system_initialize();
|
||||
|
||||
/*
|
||||
// int part_id = fat32_register_partition(0, 0, 0);
|
||||
struct vfs_dir_entry_t *dentry = fat32_path_walk("a.txt", 0);
|
||||
struct vfs_dir_entry_t *dentry = vfs_path_walk("a.txt", 0);
|
||||
if (dentry != NULL)
|
||||
printk_color(ORANGE, BLACK, "Found a.txt\nDIR_FstClus:%#018lx\tDIR_FileSize:%#018lx\n", ((struct fat32_inode_info_t *)(dentry->dir_inode->private_inode_info))->first_clus, dentry->dir_inode->file_size);
|
||||
else
|
||||
printk_color(ORANGE, BLACK, "Can`t find file\n");
|
||||
|
||||
dentry = fat32_path_walk("xx/12.png", 0);
|
||||
dentry = vfs_path_walk("xx/12.png", 0);
|
||||
if (dentry != NULL)
|
||||
printk_color(ORANGE, BLACK, "Found xx/12.png\nDIR_FstClus:%#018lx\tDIR_FileSize:%#018lx\n", ((struct fat32_inode_info_t *)(dentry->dir_inode->private_inode_info))->first_clus, dentry->dir_inode->file_size);
|
||||
else
|
||||
printk_color(ORANGE, BLACK, "Can`t find file\n");
|
||||
|
||||
*/
|
||||
// show_welcome();
|
||||
// test_mm();
|
||||
|
||||
|
@ -7,8 +7,9 @@
|
||||
#define PTRS_PER_PGT 512
|
||||
|
||||
// 内核层的起始地址
|
||||
#define PAGE_OFFSET ((unsigned long)0xffff800000000000)
|
||||
#define KERNEL_BASE_LINEAR_ADDR ((unsigned long)0xffff800000000000)
|
||||
#define PAGE_OFFSET (0xffff800000000000UL)
|
||||
#define KERNEL_BASE_LINEAR_ADDR (0xffff800000000000UL)
|
||||
#define USER_MAX_LINEAR_ADDR 0x00007fffffffffffUL;
|
||||
|
||||
#define PAGE_4K_SHIFT 12
|
||||
#define PAGE_2M_SHIFT 21
|
||||
|
@ -7,6 +7,7 @@
|
||||
#include "../syscall/syscall_num.h"
|
||||
#include <mm/slab.h>
|
||||
#include <sched/sched.h>
|
||||
#include <filesystem/fat32/fat32.h>
|
||||
|
||||
extern void system_call(void);
|
||||
extern void kernel_thread_func(void);
|
||||
@ -72,16 +73,9 @@ void user_level_function()
|
||||
long ret = 0;
|
||||
// printk_color(RED,BLACK,"user_level_function task is running\n");
|
||||
|
||||
char string[] = "User level process.\n";
|
||||
/*
|
||||
__asm__ __volatile__("leaq sysexit_return_address(%%rip), %%rdx \n\t"
|
||||
"movq %%rsp, %%rcx \n\t"
|
||||
"sysenter \n\t"
|
||||
"sysexit_return_address: \n\t"
|
||||
: "=a"(ret)
|
||||
: "0"(1), "D"(string)
|
||||
: "memory");
|
||||
*/
|
||||
// 测试sys put string
|
||||
char string[] = "User level process.\n";
|
||||
long err_code = 1;
|
||||
ul addr = (ul)string;
|
||||
__asm__ __volatile__(
|
||||
@ -90,19 +84,26 @@ void user_level_function()
|
||||
: "=a"(err_code)
|
||||
: "a"(SYS_PUT_STRING), "m"(addr)
|
||||
: "memory", "r8");
|
||||
if (err_code == 0)
|
||||
{
|
||||
char str[] = "errno is 0\n";
|
||||
addr = (ul)str;
|
||||
__asm__ __volatile__(
|
||||
"movq %2, %%r8 \n\t"
|
||||
"int $0x80 \n\t"
|
||||
: "=a"(err_code)
|
||||
: "a"(SYS_PUT_STRING), "m"(addr)
|
||||
: "memory", "r8");
|
||||
}
|
||||
// enter_syscall_int(SYS_PRINTF, (ul) "test_sys_printf\n", 0, 0, 0, 0, 0, 0, 0);
|
||||
// kinfo("Return from syscall id 15...");
|
||||
*/
|
||||
|
||||
// 测试sys_open
|
||||
char string[] = "/xx/12.png";
|
||||
long err_code = 1;
|
||||
int zero = 0;
|
||||
uint64_t addr = (ul)string;
|
||||
__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"(SYS_OPEN), "m"(addr), "m"(zero), "m"(zero), "m"(zero), "m"(zero), "m"(zero), "m"(zero), "m"(zero)
|
||||
: "memory", "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15", "rcx", "rdx");
|
||||
|
||||
while (1)
|
||||
pause();
|
||||
@ -151,7 +152,7 @@ ul do_execve(struct pt_regs *regs)
|
||||
mm_map_phys_addr_user(addr, alloc_pages(ZONE_NORMAL, 1, PAGE_PGT_MAPPED)->addr_phys, PAGE_2M_SIZE, PAGE_USER_PAGE);
|
||||
|
||||
if (!(current_pcb->flags & PF_KTHREAD))
|
||||
current_pcb->addr_limit = KERNEL_BASE_LINEAR_ADDR;
|
||||
current_pcb->addr_limit = USER_MAX_LINEAR_ADDR;
|
||||
// 将程序代码拷贝到对应的内存中
|
||||
memcpy((void *)0x800000, user_level_function, 1024);
|
||||
|
||||
@ -168,6 +169,7 @@ ul do_execve(struct pt_regs *regs)
|
||||
ul initial_kernel_thread(ul arg)
|
||||
{
|
||||
// kinfo("initial proc running...\targ:%#018lx", arg);
|
||||
fat32_init();
|
||||
|
||||
struct pt_regs *regs;
|
||||
|
||||
@ -377,7 +379,7 @@ unsigned long do_fork(struct pt_regs *regs, unsigned long clone_flags, unsigned
|
||||
// 将寄存器信息存储到进程的内核栈空间的顶部
|
||||
memcpy((void *)((ul)tsk + STACK_SIZE - sizeof(struct pt_regs)), regs, sizeof(struct pt_regs));
|
||||
|
||||
kdebug("regs.rip = %#018lx", regs->rip);
|
||||
// kdebug("regs.rip = %#018lx", regs->rip);
|
||||
// 设置进程的内核栈
|
||||
thd->rbp = (ul)tsk + STACK_SIZE;
|
||||
thd->rip = regs->rip;
|
||||
|
@ -16,6 +16,11 @@
|
||||
#include "../syscall/syscall.h"
|
||||
#include "ptrace.h"
|
||||
|
||||
#include <filesystem/VFS/VFS.h>
|
||||
|
||||
// 进程最大可拥有的文件描述符数量
|
||||
#define PROC_MAX_FD_NUM 16
|
||||
|
||||
// 进程的内核栈大小 32K
|
||||
#define STACK_SIZE 32768
|
||||
|
||||
@ -116,6 +121,10 @@ struct process_control_block
|
||||
long pid;
|
||||
long priority; // 优先级
|
||||
long virtual_runtime; // 虚拟运行时间
|
||||
|
||||
// 进程拥有的文件描述符的指针数组
|
||||
// todo: 改用动态指针数组
|
||||
struct vfs_file_t *fds[PROC_MAX_FD_NUM];
|
||||
};
|
||||
|
||||
// 将进程的pcb和内核栈融合到一起,8字节对齐
|
||||
@ -138,7 +147,8 @@ union proc_union
|
||||
.signal = 0, \
|
||||
.priority = 2, \
|
||||
.preempt_count = 0, \
|
||||
.cpu_id = 0 \
|
||||
.cpu_id = 0, \
|
||||
.fds = { 0 } \
|
||||
}
|
||||
|
||||
/**
|
||||
@ -211,19 +221,17 @@ struct process_control_block *get_current_pcb()
|
||||
#define switch_proc(prev, next) \
|
||||
do \
|
||||
{ \
|
||||
__asm__ __volatile__("cli \n\t" \
|
||||
"pushq %%rbp \n\t" \
|
||||
__asm__ __volatile__("pushq %%rbp \n\t" \
|
||||
"pushq %%rax \n\t" \
|
||||
"movq %%rsp, %0 \n\t" \
|
||||
"movq %2, %%rsp \n\t" \
|
||||
"leaq switch_proc_ret_addr(%%rip), %%rax \n\t" \
|
||||
"leaq switch_proc_ret_addr(%%rip), %%rax \n\t" \
|
||||
"movq %%rax, %1 \n\t" \
|
||||
"pushq %3 \n\t" \
|
||||
"jmp __switch_to \n\t" \
|
||||
"switch_proc_ret_addr: \n\t" \
|
||||
"switch_proc_ret_addr: \n\t" \
|
||||
"popq %%rax \n\t" \
|
||||
"popq %%rbp \n\t" \
|
||||
"sti \n\t" \
|
||||
: "=m"(prev->thread->rsp), "=m"(prev->thread->rip) \
|
||||
: "m"(next->thread->rsp), "m"(next->thread->rip), "D"(prev), "S"(next) \
|
||||
: "memory"); \
|
||||
|
@ -50,7 +50,7 @@ void sched_cfs_enqueue(struct process_control_block *pcb)
|
||||
*/
|
||||
void sched_cfs()
|
||||
{
|
||||
|
||||
cli();
|
||||
current_pcb->flags &= ~PROC_NEED_SCHED;
|
||||
struct process_control_block *proc = sched_cfs_dequeue();
|
||||
|
||||
@ -100,6 +100,8 @@ void sched_cfs()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sti();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -3,6 +3,10 @@
|
||||
#include <exception/gate.h>
|
||||
#include <exception/irq.h>
|
||||
#include <driver/disk/ahci/ahci.h>
|
||||
#include <mm/slab.h>
|
||||
#include <common/errno.h>
|
||||
#include <common/fcntl.h>
|
||||
#include <filesystem/fat32/fat32.h>
|
||||
|
||||
// 导出系统调用入口函数,定义在entry.S中
|
||||
extern void system_call(void);
|
||||
@ -10,11 +14,11 @@ extern void syscall_int(void);
|
||||
|
||||
/**
|
||||
* @brief 导出系统调用处理函数的符号
|
||||
*
|
||||
*
|
||||
*/
|
||||
#define SYSCALL_COMMON(syscall_num, symbol) extern unsigned long symbol(struct pt_regs *regs);
|
||||
SYSCALL_COMMON(0, system_call_not_exists); // 导出system_call_not_exists函数
|
||||
#undef SYSCALL_COMMON // 取消前述宏定义
|
||||
SYSCALL_COMMON(0, system_call_not_exists); // 导出system_call_not_exists函数
|
||||
#undef SYSCALL_COMMON // 取消前述宏定义
|
||||
|
||||
/**
|
||||
* @brief 重新定义为:把系统调用函数加入系统调用表
|
||||
@ -23,8 +27,6 @@ SYSCALL_COMMON(0, system_call_not_exists); // 导出system_call_not_exists函
|
||||
*/
|
||||
#define SYSCALL_COMMON(syscall_num, symbol) [syscall_num] = symbol,
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @brief sysenter的系统调用函数,从entry.S中跳转到这里
|
||||
*
|
||||
@ -44,7 +46,7 @@ void syscall_init()
|
||||
{
|
||||
kinfo("Initializing syscall...");
|
||||
|
||||
set_system_trap_gate(0x80, 0, syscall_int); // 系统调用门
|
||||
set_system_intr_gate(0x80, 0, syscall_int); // 系统调用门
|
||||
}
|
||||
|
||||
/**
|
||||
@ -92,7 +94,7 @@ long enter_syscall_int(ul syscall_id, ul arg0, ul arg1, ul arg2, ul arg3, ul arg
|
||||
* @param arg2 背景色
|
||||
* @return ul 返回值
|
||||
*/
|
||||
ul sys_printf(struct pt_regs *regs)
|
||||
ul sys_put_string(struct pt_regs *regs)
|
||||
{
|
||||
|
||||
if (regs->r9 == 0 && regs->r10 == 0)
|
||||
@ -104,6 +106,102 @@ ul sys_printf(struct pt_regs *regs)
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint64_t sys_open(struct pt_regs *regs)
|
||||
{
|
||||
|
||||
char *filename = (char *)(regs->r8);
|
||||
int flags = (int)(regs->r9);
|
||||
|
||||
long path_len = strnlen_user(filename, PAGE_4K_SIZE);
|
||||
|
||||
if (path_len <= 0) // 地址空间错误
|
||||
{
|
||||
return -EFAULT;
|
||||
}
|
||||
else if (path_len >= PAGE_4K_SIZE) // 名称过长
|
||||
{
|
||||
return -ENAMETOOLONG;
|
||||
}
|
||||
|
||||
// 为待拷贝文件路径字符串分配内存空间
|
||||
char *path = (char *)kmalloc(path_len, 0);
|
||||
if (path == NULL)
|
||||
return -ENOMEM;
|
||||
memset(path, 0, path_len);
|
||||
|
||||
strncpy_from_user(path, filename, path_len);
|
||||
|
||||
// 寻找文件
|
||||
struct vfs_dir_entry_t *dentry = vfs_path_walk(path, 0);
|
||||
kfree(path);
|
||||
|
||||
if (dentry != NULL)
|
||||
printk_color(ORANGE, BLACK, "Found %s\nDIR_FstClus:%#018lx\tDIR_FileSize:%#018lx\n", path, ((struct fat32_inode_info_t *)(dentry->dir_inode->private_inode_info))->first_clus, dentry->dir_inode->file_size);
|
||||
else
|
||||
printk_color(ORANGE, BLACK, "Can`t find file\n");
|
||||
|
||||
if (dentry == NULL)
|
||||
return -ENOENT;
|
||||
|
||||
// 暂时认为目标是目录是一种错误
|
||||
if (dentry->dir_inode->attribute == VFS_ATTR_DIR)
|
||||
return -EISDIR;
|
||||
|
||||
// 创建文件描述符
|
||||
struct vfs_file_t *file_ptr = (struct vfs_f2ile_t *)kmalloc(sizeof(struct vfs_file_t), 0);
|
||||
memset(file_ptr, 0, sizeof(struct vfs_file_t));
|
||||
|
||||
int errcode = -1;
|
||||
|
||||
file_ptr->dEntry = dentry;
|
||||
file_ptr->mode = flags;
|
||||
file_ptr->file_ops = dentry->dir_inode->file_ops;
|
||||
|
||||
// 如果文件系统实现了打开文件的函数
|
||||
if (file_ptr->file_ops && file_ptr->file_ops->open)
|
||||
errcode = file_ptr->file_ops->open(dentry->dir_inode, file_ptr);
|
||||
|
||||
if (errcode != VFS_SUCCESS)
|
||||
{
|
||||
kfree(file_ptr);
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
if (file_ptr->mode & O_TRUNC) // 清空文件
|
||||
file_ptr->dEntry->dir_inode->file_size = 0;
|
||||
|
||||
if (file_ptr->mode & O_APPEND)
|
||||
file_ptr->position = file_ptr->dEntry->dir_inode->file_size;
|
||||
else
|
||||
file_ptr->position = 0;
|
||||
|
||||
struct vfs_file_t **f = current_pcb->fds;
|
||||
|
||||
int fd_num = -1;
|
||||
|
||||
// 在指针数组中寻找空位
|
||||
// todo: 当pcb中的指针数组改为动态指针数组之后,需要更改这里(目前还是静态指针数组)
|
||||
for (int i = 0; i < PROC_MAX_FD_NUM; ++i)
|
||||
{
|
||||
if (f[i] == NULL) // 找到指针数组中的空位
|
||||
{
|
||||
fd_num = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// 指针数组没有空位了
|
||||
if (fd_num == -1)
|
||||
{
|
||||
kfree(file_ptr);
|
||||
return -EMFILE;
|
||||
}
|
||||
// 保存文件描述符
|
||||
f[fd_num] = file_ptr;
|
||||
|
||||
return fd_num;
|
||||
}
|
||||
|
||||
ul sys_ahci_end_req(struct pt_regs *regs)
|
||||
{
|
||||
ahci_end_request();
|
||||
@ -118,10 +216,10 @@ void do_syscall_int(struct pt_regs *regs, unsigned long error_code)
|
||||
regs->rax = ret; // 返回码
|
||||
}
|
||||
|
||||
|
||||
system_call_t system_call_table[MAX_SYSTEM_CALL_NUM] =
|
||||
{
|
||||
[0] = system_call_not_exists,
|
||||
[1] = sys_printf,
|
||||
[2 ... 254] = system_call_not_exists,
|
||||
[1] = sys_put_string,
|
||||
[2] = sys_open,
|
||||
[3 ... 254] = system_call_not_exists,
|
||||
[255] = sys_ahci_end_req};
|
||||
|
@ -11,5 +11,6 @@
|
||||
|
||||
#define SYS_NOT_EXISTS 0
|
||||
#define SYS_PUT_STRING 1
|
||||
#define SYS_OPEN 2
|
||||
|
||||
#define SYS_AHCI_END_REQ 255 // AHCI DMA请求结束end_request的系统调用
|
Loading…
x
Reference in New Issue
Block a user