--- /dev/null
+/*
+ * ------------------------------------------------------------------------
+ * File Name: dentry.c
+ * Author: Zhao Yanbai
+ * 2024-05-15 20:32:49 Wednesday CST
+ * Description: none
+ * ------------------------------------------------------------------------
+ */
+
+#include <errno.h>
+#include <mm.h>
+#include <semaphore.h>
+#include <string.h>
+#include <system.h>
+#include <vfs.h>
+#define DENTRY_HASH_TABLE_SIZE 233
+
+typedef struct {
+ list_head_t list;
+ mutex_t mutex;
+} dentry_hash_entry_t;
+
+dentry_hash_entry_t dentry_hash_table[DENTRY_HASH_TABLE_SIZE] = {
+ 0,
+};
+
+uint32_t mod64(uint64_t x, uint32_t y) {
+ uint32_t mod;
+
+ asm("div %3;" : "=d"(mod) : "a"((uint32_t)x), "d"((uint32_t)(x >> 32)), "r"(y) : "cc");
+
+ return mod;
+}
+
+dentry_t *dentry_alloc(dentry_t *parent, qstr_t *s) {
+ dentry_t *dentry = NULL;
+ atomic_set(&dentry->d_count, 1);
+ panic("to do");
+ return dentry;
+}
+
+dentry_t *dentry_cached_lookup(dentry_t *parent, qstr_t *s) {
+ int index = mod64(s->hash, DENTRY_HASH_TABLE_SIZE);
+ assert(index < DENTRY_HASH_TABLE_SIZE);
+
+ dentry_hash_entry_t *dhe = dentry_hash_table + index;
+
+ dentry_t *dentry = NULL;
+
+ mutex_lock(&dhe->mutex);
+
+ list_head_t *p;
+ list_for_each(p, &dhe->list) {
+ dentry = list_entry(p, dentry_t, d_hash);
+ assert(dentry != NULL);
+
+ if (dentry->d_name.hash != s->hash) {
+ continue;
+ }
+
+ if (dentry->d_name.len != s->len) {
+ continue;
+ }
+
+ if (dentry->d_parent != parent) {
+ continue;
+ }
+
+ if (memcmp(dentry->d_name.name, s->name, s->len) != 0) {
+ continue;
+ }
+
+ dentry_get_locked(dentry);
+
+ break;
+ }
+
+ mutex_unlock(&dhe->mutex);
+
+ return dentry;
+}
+int dentry_real_lookup(dentry_t *parent, qstr_t *s, dentry_t **dentry) {
+ *dentry = NULL;
+ int ret = 0;
+
+ down(&parent->d_inode->i_sem);
+
+ // 在获得信号量后,需要再上cache中查找一遍
+ // 因为这个过程中当前进程可能会睡眠,当被唤醒后,其它进程已经在内存准备好了
+ *dentry = dentry_cached_lookup(parent, s);
+
+ if (NULL != *dentry) {
+ up(&parent->d_inode->i_sem);
+ return ret;
+ }
+
+ dentry_t *new_dentry = dentry_alloc(parent, s);
+ if (new_dentry == NULL) {
+ ret = -ENOMEM;
+ } else {
+ *dentry = parent->d_inode->i_ops->lookup(parent->d_inode, new_dentry);
+
+ // 如果找到了,刚分配的,就不用了
+ if (*dentry != NULL) {
+ dentry_put(new_dentry);
+ }
+ }
+
+ up(&parent->d_inode->i_sem);
+
+ return ret;
+}
+
+kmem_cache_t *dentry_kmem_cache = NULL;
+
+void dentry_cache_init() {
+ kmem_cache_t *dentry_kmem_cache = kmem_cache_create("dentry_cache", sizeof(dentry_t), 4);
+ if (NULL == dentry_kmem_cache) {
+ panic("create dentry cache faild");
+ }
+
+ for (int i = 0; i < DENTRY_HASH_TABLE_SIZE; i++) {
+ dentry_hash_entry_t *dhe = dentry_hash_table + i;
+ list_init(&dhe->list);
+ mutex_init(&dhe->mutex);
+ }
+}
+
+dentry_t *dentry_get(dentry_t *dentry) {
+ assert(dentry != NULL);
+ atomic_inc(&dentry->d_count);
+ return dentry;
+}
+
+void dentry_get_locked(dentry_t *dentry) {}
+
+void dentry_put(dentry_t *dentry) { panic("todo"); }
+
+// static __inline__ struct dentry * dget(struct dentry *dentry)
+// {
+// if (dentry) {
+// if (!atomic_read(&dentry->d_count))
+// BUG();
+// atomic_inc(&dentry->d_count);
+// }
+// return dentry;
+// }
+
+// static inline struct dentry * __dget_locked(struct dentry *dentry)
+// {
+// atomic_inc(&dentry->d_count);
+// if (atomic_read(&dentry->d_count) == 1) {
+// dentry_stat.nr_unused--;
+// list_del(&dentry->d_lru);
+// INIT_LIST_HEAD(&dentry->d_lru); /* make "list_empty()" work */
+// }
+// return dentry;
+// }
+
+// struct dentry * dget_locked(struct dentry *dentry)
+// {
+// return __dget_locked(dentry);
+// }
superblock_t *ext2_read_super(superblock_t *sb, void *data) { return sb; }
fs_type_t ext2_fs_type = {
- "ext2",
- ext2_read_super,
- 0,
+ .name = "ext2",
+ .read_super = ext2_read_super,
+ .next = 0,
};
+void ext2_setup() { vfs_register_filesystem(&ext2_fs_type); }
+
+//--------------------------------------------------------------------------
struct {
ext2_sb_t ext2_sb;
ext2_gd_t *ext2_gd;
extern void blk_rw(dev_t dev, u64_t offset, u32_t scnt, char *buf);
extern void kmem_cache_free(kmem_cache_t *cache, void *addr);
-#define BLKRW(blkid, blkcnt, buf) \
- do { \
- blk_rw(system.root_dev, 1ULL * (blkid)*EXT2_BLOCK_SIZE, (blkcnt)*EXT2_BLOCK_SIZE, buf); \
+#define BLKRW(blkid, blkcnt, buf) \
+ do { \
+ blk_rw(system.root_dev, 1ULL * (blkid) * EXT2_BLOCK_SIZE, (blkcnt) * EXT2_BLOCK_SIZE, buf); \
} while (0)
kmem_cache_t *ext2_block_cache;
memset(&ext2_fs, 0, sizeof(ext2_fs));
char *buf = kmalloc(EXT2_BLOCK_SIZE, 0);
- if (buf == 0) panic("out of memory");
+ if (buf == 0) {
+ panic("out of memory");
+ }
BLKRW(1, 1, buf); // now blocksize == 1024, so blkid == 1
#include <printk.h>
#include <system.h>
+// void ramfs_setup();
+// void ext2_setup();
+
+// void setup_fs() {
+// ramfs_setup();
+
+// // ext2_setup();
+// }
+
+//--------------------------------------------------------------------------
+
extern chrdev_t cnsl_chrdev;
chrdev_t *chrdev[CHRDEV_SIZE] = {&cnsl_chrdev};
-void ext2_setup_fs();
+// void ext2_setup_fs();
unsigned int ext2_search_inpath(const char *path);
-void setup_fs() { ext2_setup_fs(); }
+// void setup_fs() {
+// ext2_setup_fs();
+// }
unsigned int namei(const char *path) { return ext2_search_inpath(path); }
--- /dev/null
+/*
+ * ------------------------------------------------------------------------
+ * File Name: inode.c
+ * Author: Zhao Yanbai
+ * 2024-05-15 20:32:55 Wednesday CST
+ * Description: none
+ * ------------------------------------------------------------------------
+ */
#include <syscall.h>
#include <types.h>
-int sysc_open(const char *path, int flags, mode_t mode) { return 0; }
+int get_unused_fd() {
+ int fd;
+ task_files_t *files = &(current->files);
+
+ for (int i = 0; i < NR_TASK_OPEN_CNT; i++) {
+ if (files->fds[i] == 0) {
+ return i;
+ }
+ }
+
+ printk("too many open files for %s\n", current->name);
+ return -EMFILE;
+}
+
+file_t *filp_open(const char *path, int flags, mode_t mode) {
+ int ret = 0;
+
+ // ret = open_path(path, flags, mode, nd);
+
+ return NULL;
+}
+
+int sysc_open(const char *path, int flags, mode_t mode) {
+ int fd = 0;
+
+ fd = get_unused_fd();
+
+ if (fd < 0) {
+ return fd;
+ }
+
+ file_t *fp = filp_open(path, flags, mode);
+
+ current->files.fds[fd] = fp;
+
+ return 0;
+}
--- /dev/null
+/*
+ * ------------------------------------------------------------------------
+ * File Name: path.c
+ * Author: Zhao Yanbai
+ * 2024-04-20 19:24:42 Saturday CST
+ * Description: none
+ * ------------------------------------------------------------------------
+ */
+
+#include <errno.h>
+#include <fs.h>
+#include <sched.h>
+#include <types.h>
+#include <vfs.h>
+
+bool path_init(const char *path, unsigned int flags, namei_t *ni) {
+ if (path == NULL) {
+ return false;
+ }
+
+ if (*path == '/') {
+ ni->mnt = current->mnt_root;
+ ni->dentry = current->dentry_root;
+ }
+
+ ni->mnt = current->mnt_pwd;
+ ni->dentry = current->dentry_pwd;
+
+ return true;
+}
+
+void follow_dotdot(namei_t *ni) {
+ while (1) {
+ dentry_t *dentry = NULL;
+ vfsmount_t *parent = NULL;
+
+ // 如果当前目录已经是根目录
+ if (ni->dentry == current->dentry_root) {
+ assert(ni->mnt == current->mnt_root);
+ // do nothing
+ return;
+ }
+
+ // 如果当前目录不是挂载的根目录
+ if (ni->dentry != ni->mnt->mnt_root) {
+ dentry = ni->dentry->d_parent;
+ ni->dentry = dentry;
+ return;
+ }
+
+ // 当前目录是挂载的根目录,这就需要找到挂载点的上一层目录
+ // 所以先找到挂载点的父挂载点vfsmount
+ parent = ni->mnt->mnt_parent;
+
+ // 如果当前挂载点已经是最开始的挂载点vfsmount了
+ if (ni->mnt == parent) {
+ return;
+ }
+
+ // 如果当前挂载点有父挂载点
+ // 就记录当前挂载点的dentry和它所在的挂载vfsmount
+ dentry = ni->mnt->mnt_point;
+ ni->dentry = dentry;
+ ni->mnt = parent;
+
+ // 此时有两种情况
+ // 1. dentry 是根目录,就需要继续往上找
+ // 2. dentry 不是根目录,也需要再往上找一层dentry
+
+ // 关于这个循环可能处理的情况举例如下:
+
+ // case1
+ // 以 /root/aa/.. 为例 代表的是 /root
+ // 如果 挂载一个目录到 /root/aa/
+ // 这时 dentry 指向的是 aa
+ // 还需要再往上走一层
+
+ // case2
+ // 假设 /mnt/a 挂载到 /mnt/b 后, /mnt/b 再挂载到 /mnt/c
+ // 分别产生vfsmnt_a vfsmnt_b
+ // 对于路径/mnt/c/..当读到c时,对于它的dentry,会最终读到a的dentry
+ // 对于..
+ // 第一次循环 dentry为b的dentry,mnt为 vfsmnt_b
+ // 第二次循环 dentry为c的dentry, mnt为 vfsmnt_a
+ // 第三次循环,dentry为mnt的dentry,mnt为mnt_root
+
+ // case3
+ // 假设 /mnt/a 挂载到 /mnt/c 后, /mnt/b 再挂载到 /mnt/c
+ // 分别产生 vfsmnt_a vfsmnt_b
+ // 这两个vfsmnt都会挂载到dentry->d_vfsmnt链表上
+ }
+}
+
+uint64_t compute_qstr_hash(qstr_t *q) {
+ q->hash = 0;
+ for (int i = 0; i < q->len; i++) {
+ uint64_t x = (uint64_t)(q->name[i]);
+ q->hash = (x << 4) | (x >> (8 * sizeof(q->hash) - 4));
+ }
+
+ q->hash += q->hash >> (4 * sizeof(q->hash));
+
+ return q->hash;
+}
+
+int follow_down(dentry_t **dentry, vfsmount_t **vfsmnt) {
+ assert(*dentry != NULL);
+ assert(*vfsmnt != NULL);
+
+ list_head_t *pos;
+ list_for_each(pos, &((*dentry)->d_vfsmnt)) {
+ vfsmount_t *tmp_mnt = list_entry(pos, vfsmount_t, mnt_clash);
+ if (*vfsmnt == tmp_mnt->mnt_parent) {
+ *vfsmnt = vfsmnt_get(tmp_mnt);
+ vfsmnt_put(tmp_mnt->mnt_parent);
+
+ dentry_put(*dentry);
+ *dentry = dentry_get(tmp_mnt->mnt_root);
+ }
+ }
+}
+
+int path_walk(const char *path, namei_t *ni) {
+ dentry_t *dentry;
+ int ret = 0;
+ if (path == NULL) {
+ return -EINVAL;
+ }
+
+ // 先跳过最开始的 '/'
+ while (*path == '/') {
+ path++;
+ }
+
+ // 所有连续'/'之后立即就是'\0'
+ if (*path == 0) {
+ return 0;
+ }
+
+ // 拿到当前目录的 inode
+ inode_t *inode = ni->dentry->d_inode;
+
+ while (true) {
+ qstr_t this;
+ this.name = path;
+
+ do {
+ path++;
+ } while (*path && (*path != '/'));
+
+ this.len = path - this.name;
+
+ // 看是不是路径的最后一个文件名
+ if (*path == 0) {
+ //
+ }
+
+ // 跳过所有连续的 '/'
+ while (*path == '/') {
+ path++;
+ }
+
+ // 看是不是路径其实是以'/'结尾的
+ if (*path == 0) {
+ //
+ }
+
+ // 开始解析name(到这里这个name后跟着的所有的'/'都已经跳过了)
+ if (this.name[0] == '.') {
+ if (this.len == 1) {
+ // 目录无变化,继续下一轮解析
+ continue;
+ } else if (this.len == 2 && this.name[1] == '.') {
+ follow_dotdot(ni);
+ inode = ni->dentry->d_inode;
+ continue;
+ }
+ }
+
+ //
+ compute_qstr_hash(&this);
+
+ // 根据该名字,先上dentry cache里找
+ dentry = dentry_cached_lookup(ni->dentry, &this);
+
+ // 如果找不到就上实际存储设备中去找
+ if (NULL == dentry) {
+ ret = dentry_real_lookup(ni->dentry, &this, &dentry);
+ if (0 != ret) {
+ break;
+ }
+ }
+
+ // 找到了,先看看它是不是一个挂载点
+ while (!list_empty(&dentry->d_vfsmnt)) {
+ // 如果是一个挂载点,则更进一步
+
+ // 这种解决的是先将/a 挂载到 /b
+ // 再将/b挂载到/c
+ // 读/c时,直接读到/a的dentry
+ }
+ }
+
+ return ret;
+}
--- /dev/null
+/*
+ * ------------------------------------------------------------------------
+ * File Name: ramfs.c
+ * Author: Zhao Yanbai
+ * 2024-04-13 23:43:49 Saturday CST
+ * Description: none
+ * ------------------------------------------------------------------------
+ */
+
+#include "ramfs.h"
+
+#include "fs.h"
+#include "mm.h"
+#include "string.h"
+#include "system.h"
+#include "vfs.h"
+
+superblock_t *ramfs_read_super(superblock_t *sb, void *data);
+fs_type_t ramfs_type = {
+ .name = "ramfs",
+ .read_super = ramfs_read_super,
+ .next = 0,
+};
+
+typedef struct ramfs_superblock {
+ //
+} ramfs_superblock_t;
+
+typedef struct ramfs_dentry {
+ // d
+
+} ramfs_dentry_t;
+
+typedef struct ramfs_inode {
+ // d
+} ramfs_inode_t;
+
+void ramfs_init() { vfs_register_filesystem(&ramfs_type); }
+
+superblock_t *ramfs_read_super(superblock_t *sb, void *data) { return sb; }
--- /dev/null
+/*
+ * ------------------------------------------------------------------------
+ * File Name: ramfs.h
+ * Author: Zhao Yanbai
+ * 2024-04-13 23:43:53 Saturday CST
+ * Description: none
+ * ------------------------------------------------------------------------
+ */
+
+#pragma once
*/
#include <string.h>
+#include <system.h>
#include <vfs.h>
// 要访问一个文件就必需先访问一个目录,才能根据文件名从目录中找到该文件的目录项,进而找到其inode
add->next = fs;
fs->next = 0;
}
+
+fs_type_t *vfs_find_filesystem(const char *name) {
+ for (fs_type_t *fs = &file_systems; fs != 0; fs = fs->next) {
+ if (strcmp(fs->name, name) == 0) {
+ return fs;
+ }
+ }
+
+ return NULL;
+}
+
+void ramfs_init();
+void vfs_init() {
+ ramfs_init();
+ fs_type_t *fs = vfs_find_filesystem("ramfs");
+ if (NULL == fs) {
+ panic("no ramfs");
+ }
+
+ superblock_t *sb = fs->read_super(NULL, NULL);
+}
+
+/////////
+vfsmount_t *vfsmnt_get(vfsmount_t *m) {
+ panic("todo");
+ return NULL;
+}
+void vfsmnt_put(vfsmount_t *m) {
+ //
+ panic("todo");
+}
#pragma once
+#include <atomic.h>
#include <list.h>
+#include <semaphore.h>
+#include <types.h>
+
+typedef struct qstr {
+ const char *name;
+ unsigned int len;
+ uint64_t hash;
+} qstr_t;
typedef struct dentry dentry_t;
// super block
typedef struct superblock {
- //
+ // 该超级起的根目录的 dentry
dentry_t *sb_root;
+ //
void *sb_private;
+ //
sb_operations_t *sb_ops;
} superblock_t;
void *i_private;
+ semaphore_t i_sem;
+
// fops - file ops 的副本
file_operations_t *i_fops;
// 缓存的pages
list_head_t i_pages;
+
+ dev_t i_dev; // inode存储在该设备上
+ dev_t i_rdev; // inode所代表的设备号
+
+ loff_t i_size;
} inode_t;
+#define DENTRY_INLINE_NAME_LEN 16
struct dentry {
- char *d_name;
+ // char *d_name;
+ qstr_t d_name;
+ char d_inline_name[DENTRY_INLINE_NAME_LEN];
+
+ atomic_t d_count;
//
dentry_t *d_parent;
list_head_t d_child;
list_head_t d_subdirs;
+ list_head_t d_hash;
+
//
superblock_t *d_sb;
// 但多个dentry可以指向同一个inode(不实现)
inode_t *d_inode;
+ // 需要一个标记自己已经成为挂载点的标志?
+ // uint32_t d_flags;
+ // 也可以用一个指向vfsmount的指针,非0表示挂载?
+ // 貌似应该搞个链表,因为一个点可以重复挂N次,N个文件系统
+ list_head_t d_vfsmnt; // 所有挂载到这个目录的挂载点
+
//
dentry_operations_t *d_ops;
};
struct sb_operations {
- //
+ // read_inode
};
-struct file_operations {
- // open
- // close
- // read
- // write
- // lseek
- // ioctl
-};
+// struct file_operations {
+// // open
+// // close
+// // read
+// // write
+// // lseek
+// // ioctl
+
+// };
struct inode_operations {
//
+ dentry_t *(*lookup)(inode_t *i, dentry_t *d);
};
struct dentry_operations {
//
// hash
// compare
+ // d_release 关闭文件
+ // d_delete 删除文件
+ //
};
// 每当将一个存储设备安装到现有文件系统中的某个节点时,内核就要为之建立一个vfsmount结构
// 这个结构中即包含着该设备的有关信息,也包含了安装点的信息
// 系统中的每个文件系统,包括根设备的根文件系统,都要经过安装
+//
+// 在安装文件系统时内核主要做如下的事情
+// 创建一个vfsmount
+// 为被安装的设备创建一个superblock,并由该设备对应的文件系统来设置这个superblock
+// 为被安装的设备的根目录创建一个dentry
+// 为被安装的设备的根目录创建一个inode,由sb->sb_ops->read_inode来实现
+// 将superblock与被安装设备根目录的dentry关联
+// 将vfsmount与被安装设备的根目录dentry关联
typedef struct vfsmount {
+ dentry_t *mnt_point; // 挂载点 dentry
+ dentry_t *mnt_root; // 设备根目录 dentry
+ superblock_t *mnt_sb; // 被安装的设备的superblock
+ struct vfsmount *mnt_parent; // 如果多个设备挂载到同一个目录,则每个vfsmount的parent都指向同一个vfsmount
+ // sb->sb_ops->read_inode得到被安装设备根目录的inode
+
+ list_head_t mnt_list; // vfsmount 链表
+
+ list_head_t mnt_clash;
+
+ // 先简单实现:不支持一个设备挂载多次,或一个目录被挂载多次
} vfsmount_t;
typedef struct fs_type {
const char *name;
superblock_t *(*read_super)(superblock_t *, void *);
struct fs_type *next;
+ list_head_t sbs; // 同属于这个文件系统的所有超级块链表
} fs_type_t;
extern superblock_t *root_sb;
void vfs_register_filesystem(fs_type_t *fs);
+
+/////
+
+dentry_t *dentry_cached_lookup(dentry_t *parent, qstr_t *s);
+int dentry_real_lookup(dentry_t *parent, qstr_t *s, dentry_t **dentry);
+
+vfsmount_t *vfsmnt_get(vfsmount_t *m);
+void vfsmnt_put(vfsmount_t *m);
+
+dentry_t *dentry_get(dentry_t *dentry);
+void dentry_get_locked(dentry_t *dentry);
+
+void dentry_put(dentry_t *dentry);
#include <page.h>
#include <types.h>
+#include <vfs.h>
/* 分区表开始的位置 */
#define PARTS_POS 0x1BE
#define DEV_MINOR_MASK ((1UL << DEV_MAJOR_BITS) - 1)
#define MAKE_DEV(major, minor) ((major) << DEV_MAJOR_BITS | minor)
-#define MAKE_DISK_DEV(drv_no, part_no) MAKE_DEV(DEV_MAJOR_DISK, (((drv_no)&0x03) << 8) | (((part_no)&0xFF) << 0))
+#define MAKE_DISK_DEV(drv_no, part_no) MAKE_DEV(DEV_MAJOR_DISK, (((drv_no) & 0x03) << 8) | (((part_no) & 0xFF) << 0))
#define DEV_MAJOR(dev) ((unsigned int)((dev) >> DEV_MAJOR_BITS))
-#define DEV_MINOR(dev) ((unsigned int)((dev)&DEV_MINOR_MASK))
+#define DEV_MINOR(dev) ((unsigned int)((dev) & DEV_MINOR_MASK))
// #define MAX_SUPT_FILE_SIZE (1)
#define NR_FILES (1)
extern chrdev_t *chrdev[];
-typedef struct {
-} file_t;
+typedef struct file file_t;
+
+typedef struct file_operations {
+ int (*open)(inode_t *, file_t *);
+ ssize_t (*read)(file_t *, char *, size_t, loff_t *);
+} file_operations_t;
+
+struct file {
+ // 多个打开的文件可能是同一个文件
+ dentry_t *f_dentry;
+ file_operations_t *f_ops;
+};
+
+typedef struct namei {
+ vfsmount_t *mnt;
+ dentry_t *dentry;
+} namei_t;
#if 0
#define NR_FILES (PAGE_SIZE / sizeof(File))
}
#endif
-typedef uint32_t dev_t;
-
#endif //_FS_H
#pragma once
-#include <irq.h>
#include <list.h>
-#include <task.h>
typedef struct semaphore {
volatile unsigned int cnt;
(ptr)->cnt = 1; \
INIT_LIST_HEAD(&((ptr)->wait_list)); \
} while (0)
+void mutex_init(mutex_t *);
void mutex_lock(mutex_t *);
void mutex_unlock(mutex_t *);
#include <processor.h>
#include <system.h>
#include <types.h>
+#include <vfs.h>
// #include <wait.h>
enum {
#define TASK_MAGIC 0xAABBCCDD11223344
+#define NR_TASK_OPEN_CNT 32
+typedef struct task_files {
+ // 暂时先不用bitmap,直接线性搜索
+ file_t *fds[NR_TASK_OPEN_CNT];
+} task_files_t;
+
typedef union task_union {
struct {
uint32_t esp0; /* kernel stack */
char name[TASK_NAME_SIZE];
+ task_files_t files;
+
+ dentry_t *dentry_root;
+ dentry_t *dentry_pwd;
+
+ vfsmount_t *mnt_root;
+ vfsmount_t *mnt_pwd;
+
list_head_t list; // 所有进程串成一个链表
list_head_t pend; // 某些条件串成一个链表
typedef unsigned long long uint64_t;
typedef long long int64_t;
+typedef uint64_t loff_t;
+
+typedef uint32_t dev_t;
+
typedef unsigned long pid_t;
typedef unsigned long mode_t;
assert(reenter >= 0);
assert(reenter <= 1);
+ // TODO 判断打断的是否是内核态代码
+
// 屏蔽当前中断
p->chip->disable(irq);
wrmsr(MSR_SYSENTER_ESP, root_task.esp0, 0);
#endif
+ for (i = 0; i < NR_TASK_OPEN_CNT; i++) {
+ root_task.files.fds[i] = NULL;
+ }
+
printk("init_root_task tss.esp0 %08x\n", tss.esp0);
}
#include <irq.h>
#include <sched.h>
#include <semaphore.h>
+#include <task.h>
typedef struct semaphore_waiter {
list_head_t list;
irq_restore(iflags);
}
+void mutex_init(mutex_t *s) { INIT_MUTEX(s); }
void mutex_lock(semaphore_t *s) { down(s); }
void mutex_unlock(semaphore_t *s) { up(s); }
irq_save(flags);
current->state = TASK_WAIT;
- current->reason = "sleep_on";
+ current->reason = "wait_on";
list_add_tail(&wait.entry, &head->task_list);