mirror of
https://github.com/DragonOS-Community/DragonOS.git
synced 2025-06-09 19:36:47 +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",
|
"cinttypes": "c",
|
||||||
"cstdbool": "c",
|
"cstdbool": "c",
|
||||||
"typeinfo": "c",
|
"typeinfo": "c",
|
||||||
"x86_64_ipi.h": "c"
|
"x86_64_ipi.h": "c",
|
||||||
|
"unistd.h": "c",
|
||||||
|
"syscall_num.h": "c"
|
||||||
},
|
},
|
||||||
"C_Cpp.errorSquiggles": "Enabled",
|
"C_Cpp.errorSquiggles": "Enabled",
|
||||||
"esbonio.sphinx.confDir": ""
|
"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
|
@ -509,3 +509,49 @@ static inline uint64_t copy_to_user(void *dst, void *src, uint64_t size)
|
|||||||
: "r"(size & 7), "0"(size >> 3), "1"(dst), "2"(src));
|
: "r"(size & 7), "0"(size >> 3), "1"(dst), "2"(src));
|
||||||
return size;
|
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 "VFS.h"
|
||||||
#include <common/kprint.h>
|
#include <common/kprint.h>
|
||||||
|
#include <mm/slab.h>
|
||||||
|
|
||||||
// 为filesystem_type_t结构体实例化一个链表头
|
// 为filesystem_type_t结构体实例化一个链表头
|
||||||
static struct vfs_filesystem_type_t vfs_fs = {"filesystem", 0};
|
static struct vfs_filesystem_type_t vfs_fs = {"filesystem", 0};
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief 挂载文件系统
|
* @brief 挂载文件系统
|
||||||
*
|
*
|
||||||
@ -60,7 +60,78 @@ uint64_t vfs_unregister_filesystem(struct vfs_filesystem_type_t *fs)
|
|||||||
fs->next = NULL;
|
fs->next = NULL;
|
||||||
return VFS_SUCCESS;
|
return VFS_SUCCESS;
|
||||||
}
|
}
|
||||||
else p = p->next;
|
else
|
||||||
|
p = p->next;
|
||||||
}
|
}
|
||||||
return VFS_E_FS_NOT_EXIST;
|
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;
|
void *private_inode_info;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 文件描述符
|
||||||
|
*
|
||||||
|
*/
|
||||||
struct vfs_file_t
|
struct vfs_file_t
|
||||||
{
|
{
|
||||||
long position;
|
long position;
|
||||||
uint64_t mode;
|
uint64_t mode;
|
||||||
|
|
||||||
struct vfs_dir_entry_t *dEntry;
|
struct vfs_dir_entry_t *dEntry;
|
||||||
struct vfs_file_opeartions_t *file_ops;
|
struct vfs_file_operations_t *file_ops;
|
||||||
void *private_data;
|
void *private_data;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -148,3 +152,13 @@ uint64_t vfs_unregister_filesystem(struct vfs_filesystem_type_t *fs);
|
|||||||
* @return struct vfs_superblock_t*
|
* @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;
|
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文件系统的超级块
|
* @brief 创建fat32文件系统的超级块
|
||||||
@ -610,6 +540,7 @@ struct vfs_dir_entry_operations_t fat32_dEntry_ops =
|
|||||||
// todo: open
|
// todo: open
|
||||||
long fat32_open(struct vfs_index_node_t *inode, struct vfs_file_t *file_ptr)
|
long fat32_open(struct vfs_index_node_t *inode, struct vfs_file_t *file_ptr)
|
||||||
{
|
{
|
||||||
|
return VFS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
// todo: close
|
// 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);
|
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文件系统的超级块
|
* @brief 创建fat32文件系统的超级块
|
||||||
|
@ -156,8 +156,8 @@ void system_initialize()
|
|||||||
|
|
||||||
process_init();
|
process_init();
|
||||||
HPET_init();
|
HPET_init();
|
||||||
fat32_init();
|
// fat32_init();
|
||||||
|
// 系统初始化到此结束,剩下的初始化功能应当放在初始内核线程中执行
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -185,19 +185,20 @@ void Start_Kernel(void)
|
|||||||
|
|
||||||
system_initialize();
|
system_initialize();
|
||||||
|
|
||||||
|
/*
|
||||||
// int part_id = fat32_register_partition(0, 0, 0);
|
// 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)
|
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);
|
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
|
else
|
||||||
printk_color(ORANGE, BLACK, "Can`t find file\n");
|
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)
|
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);
|
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
|
else
|
||||||
printk_color(ORANGE, BLACK, "Can`t find file\n");
|
printk_color(ORANGE, BLACK, "Can`t find file\n");
|
||||||
|
*/
|
||||||
// show_welcome();
|
// show_welcome();
|
||||||
// test_mm();
|
// test_mm();
|
||||||
|
|
||||||
|
@ -7,8 +7,9 @@
|
|||||||
#define PTRS_PER_PGT 512
|
#define PTRS_PER_PGT 512
|
||||||
|
|
||||||
// 内核层的起始地址
|
// 内核层的起始地址
|
||||||
#define PAGE_OFFSET ((unsigned long)0xffff800000000000)
|
#define PAGE_OFFSET (0xffff800000000000UL)
|
||||||
#define KERNEL_BASE_LINEAR_ADDR ((unsigned long)0xffff800000000000)
|
#define KERNEL_BASE_LINEAR_ADDR (0xffff800000000000UL)
|
||||||
|
#define USER_MAX_LINEAR_ADDR 0x00007fffffffffffUL;
|
||||||
|
|
||||||
#define PAGE_4K_SHIFT 12
|
#define PAGE_4K_SHIFT 12
|
||||||
#define PAGE_2M_SHIFT 21
|
#define PAGE_2M_SHIFT 21
|
||||||
|
@ -7,6 +7,7 @@
|
|||||||
#include "../syscall/syscall_num.h"
|
#include "../syscall/syscall_num.h"
|
||||||
#include <mm/slab.h>
|
#include <mm/slab.h>
|
||||||
#include <sched/sched.h>
|
#include <sched/sched.h>
|
||||||
|
#include <filesystem/fat32/fat32.h>
|
||||||
|
|
||||||
extern void system_call(void);
|
extern void system_call(void);
|
||||||
extern void kernel_thread_func(void);
|
extern void kernel_thread_func(void);
|
||||||
@ -72,16 +73,9 @@ void user_level_function()
|
|||||||
long ret = 0;
|
long ret = 0;
|
||||||
// printk_color(RED,BLACK,"user_level_function task is running\n");
|
// 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"
|
// 测试sys put string
|
||||||
"movq %%rsp, %%rcx \n\t"
|
char string[] = "User level process.\n";
|
||||||
"sysenter \n\t"
|
|
||||||
"sysexit_return_address: \n\t"
|
|
||||||
: "=a"(ret)
|
|
||||||
: "0"(1), "D"(string)
|
|
||||||
: "memory");
|
|
||||||
*/
|
|
||||||
long err_code = 1;
|
long err_code = 1;
|
||||||
ul addr = (ul)string;
|
ul addr = (ul)string;
|
||||||
__asm__ __volatile__(
|
__asm__ __volatile__(
|
||||||
@ -90,19 +84,26 @@ void user_level_function()
|
|||||||
: "=a"(err_code)
|
: "=a"(err_code)
|
||||||
: "a"(SYS_PUT_STRING), "m"(addr)
|
: "a"(SYS_PUT_STRING), "m"(addr)
|
||||||
: "memory", "r8");
|
: "memory", "r8");
|
||||||
if (err_code == 0)
|
*/
|
||||||
{
|
|
||||||
char str[] = "errno is 0\n";
|
// 测试sys_open
|
||||||
addr = (ul)str;
|
char string[] = "/xx/12.png";
|
||||||
|
long err_code = 1;
|
||||||
|
int zero = 0;
|
||||||
|
uint64_t addr = (ul)string;
|
||||||
__asm__ __volatile__(
|
__asm__ __volatile__(
|
||||||
"movq %2, %%r8 \n\t"
|
"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"
|
"int $0x80 \n\t"
|
||||||
: "=a"(err_code)
|
: "=a"(err_code)
|
||||||
: "a"(SYS_PUT_STRING), "m"(addr)
|
: "a"(SYS_OPEN), "m"(addr), "m"(zero), "m"(zero), "m"(zero), "m"(zero), "m"(zero), "m"(zero), "m"(zero)
|
||||||
: "memory", "r8");
|
: "memory", "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15", "rcx", "rdx");
|
||||||
}
|
|
||||||
// enter_syscall_int(SYS_PRINTF, (ul) "test_sys_printf\n", 0, 0, 0, 0, 0, 0, 0);
|
|
||||||
// kinfo("Return from syscall id 15...");
|
|
||||||
|
|
||||||
while (1)
|
while (1)
|
||||||
pause();
|
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);
|
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))
|
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);
|
memcpy((void *)0x800000, user_level_function, 1024);
|
||||||
|
|
||||||
@ -168,6 +169,7 @@ ul do_execve(struct pt_regs *regs)
|
|||||||
ul initial_kernel_thread(ul arg)
|
ul initial_kernel_thread(ul arg)
|
||||||
{
|
{
|
||||||
// kinfo("initial proc running...\targ:%#018lx", arg);
|
// kinfo("initial proc running...\targ:%#018lx", arg);
|
||||||
|
fat32_init();
|
||||||
|
|
||||||
struct pt_regs *regs;
|
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));
|
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->rbp = (ul)tsk + STACK_SIZE;
|
||||||
thd->rip = regs->rip;
|
thd->rip = regs->rip;
|
||||||
|
@ -16,6 +16,11 @@
|
|||||||
#include "../syscall/syscall.h"
|
#include "../syscall/syscall.h"
|
||||||
#include "ptrace.h"
|
#include "ptrace.h"
|
||||||
|
|
||||||
|
#include <filesystem/VFS/VFS.h>
|
||||||
|
|
||||||
|
// 进程最大可拥有的文件描述符数量
|
||||||
|
#define PROC_MAX_FD_NUM 16
|
||||||
|
|
||||||
// 进程的内核栈大小 32K
|
// 进程的内核栈大小 32K
|
||||||
#define STACK_SIZE 32768
|
#define STACK_SIZE 32768
|
||||||
|
|
||||||
@ -116,6 +121,10 @@ struct process_control_block
|
|||||||
long pid;
|
long pid;
|
||||||
long priority; // 优先级
|
long priority; // 优先级
|
||||||
long virtual_runtime; // 虚拟运行时间
|
long virtual_runtime; // 虚拟运行时间
|
||||||
|
|
||||||
|
// 进程拥有的文件描述符的指针数组
|
||||||
|
// todo: 改用动态指针数组
|
||||||
|
struct vfs_file_t *fds[PROC_MAX_FD_NUM];
|
||||||
};
|
};
|
||||||
|
|
||||||
// 将进程的pcb和内核栈融合到一起,8字节对齐
|
// 将进程的pcb和内核栈融合到一起,8字节对齐
|
||||||
@ -138,7 +147,8 @@ union proc_union
|
|||||||
.signal = 0, \
|
.signal = 0, \
|
||||||
.priority = 2, \
|
.priority = 2, \
|
||||||
.preempt_count = 0, \
|
.preempt_count = 0, \
|
||||||
.cpu_id = 0 \
|
.cpu_id = 0, \
|
||||||
|
.fds = { 0 } \
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -211,8 +221,7 @@ struct process_control_block *get_current_pcb()
|
|||||||
#define switch_proc(prev, next) \
|
#define switch_proc(prev, next) \
|
||||||
do \
|
do \
|
||||||
{ \
|
{ \
|
||||||
__asm__ __volatile__("cli \n\t" \
|
__asm__ __volatile__("pushq %%rbp \n\t" \
|
||||||
"pushq %%rbp \n\t" \
|
|
||||||
"pushq %%rax \n\t" \
|
"pushq %%rax \n\t" \
|
||||||
"movq %%rsp, %0 \n\t" \
|
"movq %%rsp, %0 \n\t" \
|
||||||
"movq %2, %%rsp \n\t" \
|
"movq %2, %%rsp \n\t" \
|
||||||
@ -223,7 +232,6 @@ struct process_control_block *get_current_pcb()
|
|||||||
"switch_proc_ret_addr: \n\t" \
|
"switch_proc_ret_addr: \n\t" \
|
||||||
"popq %%rax \n\t" \
|
"popq %%rax \n\t" \
|
||||||
"popq %%rbp \n\t" \
|
"popq %%rbp \n\t" \
|
||||||
"sti \n\t" \
|
|
||||||
: "=m"(prev->thread->rsp), "=m"(prev->thread->rip) \
|
: "=m"(prev->thread->rsp), "=m"(prev->thread->rip) \
|
||||||
: "m"(next->thread->rsp), "m"(next->thread->rip), "D"(prev), "S"(next) \
|
: "m"(next->thread->rsp), "m"(next->thread->rip), "D"(prev), "S"(next) \
|
||||||
: "memory"); \
|
: "memory"); \
|
||||||
|
@ -50,7 +50,7 @@ void sched_cfs_enqueue(struct process_control_block *pcb)
|
|||||||
*/
|
*/
|
||||||
void sched_cfs()
|
void sched_cfs()
|
||||||
{
|
{
|
||||||
|
cli();
|
||||||
current_pcb->flags &= ~PROC_NEED_SCHED;
|
current_pcb->flags &= ~PROC_NEED_SCHED;
|
||||||
struct process_control_block *proc = sched_cfs_dequeue();
|
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/gate.h>
|
||||||
#include <exception/irq.h>
|
#include <exception/irq.h>
|
||||||
#include <driver/disk/ahci/ahci.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中
|
// 导出系统调用入口函数,定义在entry.S中
|
||||||
extern void system_call(void);
|
extern void system_call(void);
|
||||||
@ -23,8 +27,6 @@ SYSCALL_COMMON(0, system_call_not_exists); // 导出system_call_not_exists函
|
|||||||
*/
|
*/
|
||||||
#define SYSCALL_COMMON(syscall_num, symbol) [syscall_num] = symbol,
|
#define SYSCALL_COMMON(syscall_num, symbol) [syscall_num] = symbol,
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief sysenter的系统调用函数,从entry.S中跳转到这里
|
* @brief sysenter的系统调用函数,从entry.S中跳转到这里
|
||||||
*
|
*
|
||||||
@ -44,7 +46,7 @@ void syscall_init()
|
|||||||
{
|
{
|
||||||
kinfo("Initializing syscall...");
|
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 背景色
|
* @param arg2 背景色
|
||||||
* @return ul 返回值
|
* @return ul 返回值
|
||||||
*/
|
*/
|
||||||
ul sys_printf(struct pt_regs *regs)
|
ul sys_put_string(struct pt_regs *regs)
|
||||||
{
|
{
|
||||||
|
|
||||||
if (regs->r9 == 0 && regs->r10 == 0)
|
if (regs->r9 == 0 && regs->r10 == 0)
|
||||||
@ -104,6 +106,102 @@ ul sys_printf(struct pt_regs *regs)
|
|||||||
return 0;
|
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)
|
ul sys_ahci_end_req(struct pt_regs *regs)
|
||||||
{
|
{
|
||||||
ahci_end_request();
|
ahci_end_request();
|
||||||
@ -118,10 +216,10 @@ void do_syscall_int(struct pt_regs *regs, unsigned long error_code)
|
|||||||
regs->rax = ret; // 返回码
|
regs->rax = ret; // 返回码
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
system_call_t system_call_table[MAX_SYSTEM_CALL_NUM] =
|
system_call_t system_call_table[MAX_SYSTEM_CALL_NUM] =
|
||||||
{
|
{
|
||||||
[0] = system_call_not_exists,
|
[0] = system_call_not_exists,
|
||||||
[1] = sys_printf,
|
[1] = sys_put_string,
|
||||||
[2 ... 254] = system_call_not_exists,
|
[2] = sys_open,
|
||||||
|
[3 ... 254] = system_call_not_exists,
|
||||||
[255] = sys_ahci_end_req};
|
[255] = sys_ahci_end_req};
|
||||||
|
@ -11,5 +11,6 @@
|
|||||||
|
|
||||||
#define SYS_NOT_EXISTS 0
|
#define SYS_NOT_EXISTS 0
|
||||||
#define SYS_PUT_STRING 1
|
#define SYS_PUT_STRING 1
|
||||||
|
#define SYS_OPEN 2
|
||||||
|
|
||||||
#define SYS_AHCI_END_REQ 255 // AHCI DMA请求结束end_request的系统调用
|
#define SYS_AHCI_END_REQ 255 // AHCI DMA请求结束end_request的系统调用
|
Loading…
x
Reference in New Issue
Block a user