🆕 sys_open系统调用

This commit is contained in:
fslongjin 2022-04-27 00:39:02 +08:00
parent d94d92f5ee
commit 966d67fcde
14 changed files with 343 additions and 144 deletions

View File

@ -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
View 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

View File

@ -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 bytesbyte搬运
*
*
*/
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 bytesbyte搬运
*
*
*/
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;
}

View File

@ -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;
}
}

View File

@ -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);

View File

@ -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

View File

@ -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文件系统的超级块

View File

@ -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();

View File

@ -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

View File

@ -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;

View File

@ -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"); \

View File

@ -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();
}
/**

View File

@ -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};

View File

@ -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的系统调用