// 构建命令头(Command Header)和命令表(Command Table)
struct hba_cmdh* cmd_header = &port->cmdlst[slot];
- struct hba_cmdt* cmd_table = vcalloc_dma(sizeof(struct hba_cmdt));
+ struct hba_cmdt* cmd_table = vzalloc_dma(sizeof(struct hba_cmdt));
memset(cmd_header, 0, sizeof(*cmd_header));
uint16_t sector_count);
int
-sata_read_buffer(struct hba_port* port,
+sata_read_buffer(struct hba_device* dev,
uint64_t lba,
void* buffer,
uint32_t size);
int
-sata_write_buffer(struct hba_port* port,
+sata_write_buffer(struct hba_device* dev,
uint64_t lba,
void* buffer,
uint32_t size);
uint32_t alloc_size);
void
-scsi_read_buffer(struct hba_port* port,
+scsi_read_buffer(struct hba_device* dev,
uint64_t lba,
void* buffer,
uint32_t size);
void
-scsi_write_buffer(struct hba_port* port,
+scsi_write_buffer(struct hba_device* dev,
uint64_t lba,
void* buffer,
uint32_t size);
--- /dev/null
+#ifndef __LUNAIX_DIRENT_H
+#define __LUNAIX_DIRENT_H
+
+struct dirent
+{
+ unsigned int d_type;
+ unsigned int d_offset;
+ unsigned int d_nlen;
+ char* d_name;
+};
+
+#endif /* __LUNAIX_DIRENT_H */
--- /dev/null
+#ifndef __LUNAIX_FCTRL_H
+#define __LUNAIX_FCTRL_H
+
+#include <lunaix/dirent.h>
+#include <lunaix/syscall.h>
+
+__LXSYSCALL2(int, open, const char*, path, int, options);
+
+__LXSYSCALL1(int, close, int, fd);
+
+__LXSYSCALL1(int, mkdir, const char*, path);
+
+__LXSYSCALL2(int, readdir, int, fd, struct dirent*, dent);
+
+#endif /* __LUNAIX_FCTRL_H */
--- /dev/null
+#ifndef __LUNAIX_FOPTIONS_H
+#define __LUNAIX_FOPTIONS_H
+
+#define FO_CREATE 0x1
+#define FO_APPEND 0x2
+
+#endif /* __LUNAIX_FOPTIONS_H */
#include <lunaix/ds/hashtable.h>
#include <lunaix/ds/hstr.h>
#include <lunaix/ds/llist.h>
+#include <lunaix/status.h>
#define VFS_NAME_MAXLEN 128
#define VFS_MAX_FD 32
#define VFS_INODE_TYPE_FILE 0x2
#define VFS_INODE_TYPE_DEVICE 0x4
-#define VFS_ETOOLONG -1
#define VFS_ENOFS -2
#define VFS_EBADMNT -3
-#define VFS_ENODIR -4
+
#define VFS_EENDOFDIR -5
-#define VFS_ENOTFOUND -6
-#define VFS_ENOOPS -7
+
#define VFS_EINVLD -8
#define VFS_EEOF -9
#define VFS_WALK_MKPARENT 0x1
#define VFS_WALK_FSRELATIVE 0x2
-#define VFS_WALK_MKDIR 0x4
+#define VFS_WALK_PARENT 0x4
#define VFS_IOBUF_FDIRTY 0x1
void* cb_data;
void (*read_complete_callback)(struct dir_context* dctx,
const char* name,
+ const int len,
const int dtype);
};
uint64_t lb_addr;
uint32_t ref_count;
uint32_t lb_usage;
+ uint32_t fsize;
void* data; // 允许底层FS绑定他的一些专有数据
struct
{
+ int (*create)(struct v_inode* inode, struct v_file* file);
int (*open)(struct v_inode* inode, struct v_file* file);
int (*sync)(struct v_inode* inode);
int (*mkdir)(struct v_inode* inode, struct v_dnode* dnode);
struct filesystem*
fsm_get(const char* fs_name);
+void
+vfs_init();
+
struct v_dnode*
vfs_dcache_lookup(struct v_dnode* parent, struct hstr* str);
vfs_walk(struct v_dnode* start,
const char* path,
struct v_dnode** dentry,
+ struct hstr* component,
int walk_options);
int
-vfs_mount(const char* fs_name, bdev_t device, struct v_dnode* mnt_point);
+vfs_mount(const char* target, const char* fs_name, bdev_t device);
+
+int
+vfs_unmount(const char* target);
+
+int
+vfs_mount_at(const char* fs_name, bdev_t device, struct v_dnode* mnt_point);
int
-vfs_unmount(struct v_dnode* mnt_point);
+vfs_unmount_at(struct v_dnode* mnt_point);
int
-vfs_mkdir(const char* parent_path,
- const char* component,
- struct v_dnode** dentry);
+vfs_mkdir(const char* path, struct v_dnode** dentry);
int
vfs_open(struct v_dnode* dnode, struct v_file** file);
struct twifs_node
{
+ struct v_inode* inode;
struct hstr name;
uint32_t itype;
struct llist_header children;
twifs_init();
struct twifs_node*
-twifs_child_node(struct twifs_node* parent, const char* name, int name_len);
+twifs_file_node(struct twifs_node* parent, const char* name, int name_len);
+
+struct twifs_node*
+twifs_dir_node(struct twifs_node* parent, const char* name, int name_len);
struct twifs_node*
twifs_toplevel_node(const char* name, int name_len);
#include <arch/x86/interrupts.h>
#include <lunaix/clock.h>
+#include <lunaix/fs.h>
#include <lunaix/mm/mm.h>
#include <lunaix/signal.h>
#include <lunaix/timer.h>
sigset_t sig_inprogress;
int flags;
void* sig_handler[_SIG_NUM];
+ struct v_fdtable* fdtable;
pid_t pgid;
};
#define MIN(a, b) ((a) < (b) ? (a) : (b))
#define MAX(a, b) ((a) > (b) ? (a) : (b))
+/**
+ * @brief Fast log base 2 for integer, utilizing constant unfolding.
+ * Adopted from
+ * https://elixir.bootlin.com/linux/v4.4/source/include/linux/log2.h#L85
+ *
+ */
+#define ILOG2(x) \
+ __builtin_constant_p(x) ? ((x) == 0 ? 0 \
+ : ((x) & (1ul << 31)) ? 31 \
+ : ((x) & (1ul << 30)) ? 30 \
+ : ((x) & (1ul << 29)) ? 29 \
+ : ((x) & (1ul << 28)) ? 28 \
+ : ((x) & (1ul << 27)) ? 27 \
+ : ((x) & (1ul << 26)) ? 26 \
+ : ((x) & (1ul << 25)) ? 25 \
+ : ((x) & (1ul << 24)) ? 24 \
+ : ((x) & (1ul << 23)) ? 23 \
+ : ((x) & (1ul << 22)) ? 22 \
+ : ((x) & (1ul << 21)) ? 21 \
+ : ((x) & (1ul << 20)) ? 20 \
+ : ((x) & (1ul << 19)) ? 19 \
+ : ((x) & (1ul << 18)) ? 18 \
+ : ((x) & (1ul << 17)) ? 17 \
+ : ((x) & (1ul << 16)) ? 16 \
+ : ((x) & (1ul << 15)) ? 15 \
+ : ((x) & (1ul << 14)) ? 14 \
+ : ((x) & (1ul << 13)) ? 13 \
+ : ((x) & (1ul << 12)) ? 12 \
+ : ((x) & (1ul << 11)) ? 11 \
+ : ((x) & (1ul << 10)) ? 10 \
+ : ((x) & (1ul << 9)) ? 9 \
+ : ((x) & (1ul << 8)) ? 8 \
+ : ((x) & (1ul << 7)) ? 7 \
+ : ((x) & (1ul << 6)) ? 6 \
+ : ((x) & (1ul << 5)) ? 5 \
+ : ((x) & (1ul << 4)) ? 4 \
+ : ((x) & (1ul << 3)) ? 3 \
+ : ((x) & (1ul << 2)) ? 2 \
+ : ((x) & (1ul << 1)) ? 1 \
+ : 0) \
+ : (31 - __builtin_clz(x))
+
#define __USER__ __attribute__((section(".usrtext")))
inline static void
#define LXHEAPFULL -(2)
#define LXINVLDPTR -(2)
#define LXOUTOFMEM -(3)
-#define LXINVLDPID -(4)
#define LXSEGFAULT -(5)
-#define LXINVL -(6)
+#define EINVAL -(6)
#define EINTR -(7)
+#define EMFILE -8
+#define ENOENT -9
+#define ENAMETOOLONG -10
+#define ENOTDIR -11
+#define EEXIST -12
+#define EBADF -13
+#define ENOTSUP -14
+
#endif /* __LUNAIX_CODE_H */
#define __SYSCALL_sigpending 17
#define __SYSCALL_sigsuspend 18
+#define __SYSCALL_open 19
+#define __SYSCALL_close 20
+#define __SYSCALL_read 21
+#define __SYSCALL_write 22
+#define __SYSCALL_readdir 23
+#define __SYSCALL_mkdir 24
+
#define __SYSCALL_MAX 0x100
#ifndef __ASM__
+
+#define SYSCALL_ESTATUS(errno) -(errno != 0)
+
void
syscall_install();
.long __lxsys_alarm
.long __lxsys_sigpending
.long __lxsys_sigsuspend
+ .long __lxsys_open
+ .long __lxsys_close
+ // .long __lxsys_read
+ // .long __lxsys_write
+ .long __lxsys_readdir
+ .long __lxsys_mkdir
2:
.rept __SYSCALL_MAX - (2b - 1b)/4
.long 0
void
fsm_register(struct filesystem* fs)
{
- hstr_rehash(&fs->fs_name, HASH_BUCKET_BITS);
+ hstr_rehash(&fs->fs_name, HSTR_FULL_HASH);
hashtable_hash_in(fs_registry, &fs->fs_list, fs->fs_name.hash);
}
{
struct filesystem *pos, *next;
struct hstr str = HSTR(fs_name, 0);
- hstr_rehash(&str, HASH_BUCKET_BITS);
+ hstr_rehash(&str, HSTR_FULL_HASH);
hashtable_hash_foreach(fs_registry, str.hash, pos, next, fs_list)
{
#include <lunaix/mm/cake.h>
#include <lunaix/mm/valloc.h>
-static struct twifs_node fs_root;
+static struct twifs_node* fs_root;
static struct cake_pile* twi_pile;
struct twifs_node*
__twifs_get_node(struct twifs_node* parent, struct hstr* name);
+struct v_inode*
+__twifs_create_inode(struct twifs_node* twi_node);
+
+int
+__twifs_mount(struct v_superblock* vsb, struct v_dnode* mount_point);
+
void
twifs_init()
{
fsm_register(twifs);
- memset(&fs_root, 0, sizeof(fs_root));
- llist_init_head(&fs_root.children);
+ fs_root = twifs_dir_node(NULL, NULL, 0);
// 预备一些常用的类别
twifs_toplevel_node("kernel", 6);
}
struct twifs_node*
-twifs_child_node(struct twifs_node* parent, const char* name, int name_len)
+__twifs_new_node(struct twifs_node* parent, const char* name, int name_len)
{
struct hstr hname = HSTR(name, name_len);
hstr_rehash(&hname, HSTR_FULL_HASH);
node->name = hname;
llist_init_head(&node->children);
- llist_append(&parent->children, &node->siblings);
+
+ if (parent) {
+ llist_append(&parent->children, &node->siblings);
+ }
return node;
}
+struct twifs_node*
+twifs_file_node(struct twifs_node* parent, const char* name, int name_len)
+{
+ struct twifs_node* twi_node = __twifs_new_node(parent, name, name_len);
+ twi_node->itype = VFS_INODE_TYPE_FILE;
+
+ struct v_inode* twi_inode = __twifs_create_inode(twi_node);
+ twi_node->inode = twi_inode;
+
+ return twi_inode;
+}
+
+struct twifs_node*
+twifs_dir_node(struct twifs_node* parent, const char* name, int name_len)
+{
+ struct twifs_node* twi_node = __twifs_new_node(parent, name, name_len);
+ twi_node->itype = VFS_INODE_TYPE_DIR;
+
+ struct v_inode* twi_inode = __twifs_create_inode(twi_node);
+ struct twifs_node* dot = __twifs_new_node(twi_node, ".", 1);
+ struct twifs_node* ddot = __twifs_new_node(twi_node, "..", 2);
+
+ dot->itype = VFS_INODE_TYPE_DIR;
+ ddot->itype = VFS_INODE_TYPE_DIR;
+
+ twi_node->inode = twi_inode;
+ dot->inode = twi_inode;
+ ddot->inode = parent->inode;
+
+ return twi_node;
+}
+
struct twifs_node*
twifs_toplevel_node(const char* name, int name_len)
{
- return twifs_child_node(&fs_root, name, name_len);
+ return twifs_dir_node(fs_root, name, name_len);
}
-void
+int
__twifs_mount(struct v_superblock* vsb, struct v_dnode* mount_point)
{
- mount_point->inode = __twifs_create_inode(&fs_root);
+ mount_point->inode = fs_root->inode;
+ return 0;
}
struct v_inode*
.ref_count = 0 };
inode->ops.dir_lookup = __twifs_dirlookup;
inode->ops.open = __twifs_openfile;
+
+ return inode;
}
struct twifs_node*
__twifs_get_node(struct twifs_node* parent, struct hstr* name)
{
+ if (!parent)
+ return NULL;
+
struct twifs_node *pos, *n;
llist_for_each(pos, n, &parent->children, siblings)
{
struct twifs_node* child_node = __twifs_get_node(twi_node, &dnode->name);
if (child_node) {
- dnode->inode = __twifs_create_inode(child_node);
+ dnode->inode = child_node->inode;
return 0;
}
- return VFS_ENODIR;
+ return ENOENT;
}
int
{
if (counter++ >= dctx->index) {
dctx->index = counter;
- dctx->read_complete_callback(dctx, pos->name.value, pos->itype);
- return 0;
+ dctx->read_complete_callback(
+ dctx, pos->name.value, pos->name.len, pos->itype);
+ return 1;
}
}
- return VFS_EENDOFDIR;
+ return 0;
}
int
struct twifs_node* twi_node = (struct twifs_node*)inode->data;
if (twi_node) {
file->ops = twi_node->fops;
- return 1;
+ return 0;
}
- return 0;
+ return ENOTSUP;
}
+/**
+ * @file vfs.c
+ * @author Lunaixsky (zelong56@gmail.com)
+ * @brief Lunaix virtual file system - an abstraction layer for all file system.
+ * @version 0.1
+ * @date 2022-07-24
+ *
+ * @copyright Copyright (c) 2022
+ *
+ */
+
#include <klibc/string.h>
+#include <lunaix/dirent.h>
+#include <lunaix/foptions.h>
#include <lunaix/fs.h>
#include <lunaix/mm/cake.h>
#include <lunaix/mm/page.h>
#include <lunaix/mm/valloc.h>
+#include <lunaix/process.h>
#include <lunaix/spike.h>
+#include <lunaix/syscall.h>
#define PATH_DELIM '/'
#define DNODE_HASHTABLE_BITS 10
static struct cake_pile* inode_pile;
static struct cake_pile* file_pile;
static struct cake_pile* superblock_pile;
+static struct cake_pile* fd_pile;
static struct v_superblock* root_sb;
static struct hbucket* dnode_cache;
// 为他们专门创建一个蛋糕堆,而不使用valloc,这样我们可以最小化内碎片的产生
dnode_pile = cake_new_pile("dnode_cache", sizeof(struct v_dnode), 1, 0);
inode_pile = cake_new_pile("inode_cache", sizeof(struct v_inode), 1, 0);
- inode_pile = cake_new_pile("file_cache", sizeof(struct v_file), 1, 0);
+ file_pile = cake_new_pile("file_cache", sizeof(struct v_file), 1, 0);
+ fd_pile = cake_new_pile("fd_cache", sizeof(struct v_fd), 1, 0);
superblock_pile =
cake_new_pile("sb_cache", sizeof(struct v_superblock), 1, 0);
- dnode_cache = valloc(DNODE_HASHTABLE_SIZE * sizeof(struct hbucket));
+ dnode_cache = vzalloc(DNODE_HASHTABLE_SIZE * sizeof(struct hbucket));
- // 挂载Lunaix的根文件系统,TwiFS!
- struct filesystem* rootfs = fsm_get("twifs");
+ // 创建一个根superblock,用来蕴含我们的根目录。
root_sb = vfs_sb_alloc();
- rootfs->mount(root_sb, NULL);
+ root_sb->root = vfs_d_alloc();
}
inline struct hbucket*
vfs_walk(struct v_dnode* start,
const char* path,
struct v_dnode** dentry,
+ struct hstr* component,
int walk_options)
{
int errno = 0;
int i = 0, j = 0;
if (path[0] == PATH_DELIM) {
- if ((walk_options & VFS_WALK_FSRELATIVE)) {
+ if ((walk_options & VFS_WALK_FSRELATIVE) && start) {
start = start->super_block->root;
} else {
start = root_sb->root;
lookahead = path[i++];
if (current != PATH_DELIM) {
if (j >= VFS_NAME_MAXLEN - 1) {
- return VFS_ETOOLONG;
+ return ENAMETOOLONG;
}
if (!VFS_VALID_CHAR(current)) {
return VFS_EINVLD;
name_content[j] = 0;
hstr_rehash(&name, HSTR_FULL_HASH);
+ if (!lookahead && (walk_options & VFS_WALK_PARENT)) {
+ if (component) {
+ component->hash = name.hash;
+ component->len = j;
+ strcpy(component->value, name_content);
+ }
+ break;
+ }
+
dnode = vfs_dcache_lookup(current_level, &name);
if (!dnode) {
errno =
current_level->inode->ops.dir_lookup(current_level->inode, dnode);
- if (errno == VFS_ENOTFOUND &&
- ((walk_options & VFS_WALK_MKPARENT) ||
- ((walk_options & VFS_WALK_MKDIR) && !lookahead))) {
- /*
- 两种创建文件夹的情况:
- 1) VFS_WALK_MKPARENT:沿路创建所有不存在的文件夹
- 2) VFS_WALK_MKDIR:仅创建路径最后一级的不存在文件夹
- */
+ if (errno == ENOENT && (walk_options & VFS_WALK_MKPARENT)) {
if (!current_level->inode->ops.mkdir) {
- errno = VFS_ENOOPS;
+ errno = ENOTSUP;
} else {
errno = current_level->inode->ops.mkdir(
current_level->inode, dnode);
}
int
-vfs_mount(const char* fs_name, bdev_t device, struct v_dnode* mnt_point)
+vfs_mount(const char* target, const char* fs_name, bdev_t device)
+{
+ int errno;
+ struct v_dnode* mnt;
+
+ if (!(errno = vfs_walk(NULL, target, &mnt, NULL, 0))) {
+ errno = vfs_mount_at(fs_name, device, mnt);
+ }
+
+ return errno;
+}
+
+int
+vfs_unmount(const char* target)
+{
+ int errno;
+ struct v_dnode* mnt;
+
+ if (!(errno = vfs_walk(NULL, target, &mnt, NULL, 0))) {
+ errno = vfs_unmount_at(mnt);
+ }
+
+ return errno;
+}
+
+int
+vfs_mount_at(const char* fs_name, bdev_t device, struct v_dnode* mnt_point)
{
struct filesystem* fs = fsm_get(fs_name);
if (!fs)
}
int
-vfs_mkdir(const char* parent_path,
- const char* component,
- struct v_dnode** dentry)
-{
- return vfs_walk(root_sb->root, parent_path, dentry, VFS_WALK_MKDIR);
-}
-
-int
-vfs_unmount(struct v_dnode* mnt_point)
+vfs_unmount_at(struct v_dnode* mnt_point)
{
int errno = 0;
struct v_superblock* sb = mnt_point->super_block;
vfs_open(struct v_dnode* dnode, struct v_file** file)
{
if (!dnode->inode || !dnode->inode->ops.open) {
- return VFS_ENOOPS;
+ return ENOTSUP;
}
struct v_file* vfile = cake_grab(file_pile);
vfs_close(struct v_file* file)
{
if (!file->ops.close) {
- return VFS_ENOOPS;
+ return ENOTSUP;
}
int errno = file->ops.close(file);
int
vfs_fsync(struct v_file* file)
{
- int errno = VFS_ENOOPS;
+ int errno = ENOTSUP;
if (file->ops.sync) {
errno = file->ops.sync(file);
}
return errno;
}
+int
+vfs_alloc_fdslot(int* fd)
+{
+ for (size_t i = 0; i < VFS_MAX_FD; i++) {
+ if (!__current->fdtable->fds[i]) {
+ *fd = i;
+ return 0;
+ }
+ }
+ return EMFILE;
+}
+
struct v_superblock*
vfs_sb_alloc()
{
{
cake_release(inode_pile, inode);
}
+
+__DEFINE_LXSYSCALL2(int, open, const char*, path, int, options)
+{
+ char name_str[VFS_NAME_MAXLEN];
+ struct hstr name = HSTR(name_str, 0);
+ struct v_dnode *dentry, *file;
+ int errno, fd;
+ if ((errno = vfs_walk(NULL, path, &dentry, &name, VFS_WALK_PARENT))) {
+ return -1;
+ }
+
+ struct v_file* opened_file = 0;
+ if (!(file = vfs_dcache_lookup(dentry, &name)) && (options & FO_CREATE)) {
+ errno = dentry->inode->ops.create(dentry->inode, opened_file);
+ } else if (!file) {
+ errno = EEXIST;
+ } else {
+ errno = vfs_open(file, &opened_file);
+ }
+
+ __current->k_status = errno;
+
+ if (!errno && !(errno = vfs_alloc_fdslot(&fd))) {
+ struct v_fd* fd_s = vzalloc(sizeof(*fd_s));
+ fd_s->file = opened_file;
+ fd_s->pos = file->inode->fsize & -((options & FO_APPEND) == 0);
+ __current->fdtable->fds[fd] = fd_s;
+ }
+
+ return SYSCALL_ESTATUS(errno);
+}
+
+__DEFINE_LXSYSCALL1(int, close, int, fd)
+{
+ struct v_fd* fd_s;
+ int errno;
+ if (fd < 0 || fd >= VFS_MAX_FD || !(fd_s = __current->fdtable->fds[fd])) {
+ errno = EBADF;
+ } else if (!(errno = vfs_close(fd_s->file))) {
+ vfree(fd_s);
+ }
+
+ __current->k_status = errno;
+
+ return SYSCALL_ESTATUS(errno);
+}
+
+void
+__vfs_readdir_callback(struct dir_context* dctx,
+ const char* name,
+ const int len,
+ const int dtype)
+{
+ struct dirent* dent = (struct dirent*)dctx->cb_data;
+ strcpy(dent->d_name, name);
+ dent->d_nlen = len;
+ dent->d_type = dtype;
+}
+
+__DEFINE_LXSYSCALL2(int, readdir, int, fd, struct dirent*, dent)
+{
+ struct v_fd* fd_s;
+ int errno;
+ if (fd < 0 || fd >= VFS_MAX_FD || !(fd_s = __current->fdtable->fds[fd])) {
+ errno = EBADF;
+ } else if (!(fd_s->file->inode->itype & VFS_INODE_TYPE_DIR)) {
+ errno = ENOTDIR;
+ } else {
+ struct dir_context dctx =
+ (struct dir_context){ .cb_data = dent,
+ .index = dent->d_offset,
+ .read_complete_callback =
+ __vfs_readdir_callback };
+ if (!(errno = fd_s->file->ops.readdir(fd_s->file, &dctx))) {
+ dent->d_offset++;
+ }
+ }
+
+ __current->k_status = errno;
+ return SYSCALL_ESTATUS(errno);
+}
+
+__DEFINE_LXSYSCALL1(int, mkdir, const char*, path)
+{
+ struct v_dnode *parent, *dir;
+ struct hstr component = HSTR(valloc(VFS_NAME_MAXLEN), 0);
+ int errno =
+ vfs_walk(root_sb->root, path, &parent, &component, VFS_WALK_PARENT);
+ if (errno) {
+ goto done;
+ }
+
+ if (!parent->inode->ops.mkdir) {
+ errno = ENOTSUP;
+ } else if (!(parent->inode->itype & VFS_INODE_TYPE_DIR)) {
+ errno = ENOTDIR;
+ } else {
+ dir = vfs_d_alloc();
+ dir->name = component;
+ if (!(errno = parent->inode->ops.mkdir(parent->inode, dir))) {
+ llist_append(&parent->children, &dir->siblings);
+ } else {
+ vfs_d_free(dir);
+ vfree(component.value);
+ }
+ }
+
+done:
+ __current->k_status = errno;
+ return SYSCALL_ESTATUS(errno);
+}
\ No newline at end of file
{
lxconsole_init();
+ cake_init();
+ valloc_init();
+
kprintf(KINFO "[MM] Allocated %d pages for stack start at %p\n",
KSTACK_SIZE >> PG_SIZE_BITS,
KSTACK_START);
(piece_size + sizeof(piece_index_t)),
.pg_per_cake = pg_per_cake };
- unsigned int overhead_size =
- sizeof(struct cake_s) + pile->pieces_per_cake * sizeof(piece_index_t);
+ unsigned int free_list_size = pile->pieces_per_cake * sizeof(piece_index_t);
- pile->offset = ROUNDUP(overhead_size, offset);
+ pile->offset = ROUNDUP(sizeof(struct cake_s) + free_list_size, offset);
+ pile->pieces_per_cake -= ICEIL((pile->offset - free_list_size), piece_size);
strncpy(&pile->pile_name, name, PILE_NAME_MAXLEN);
#include <lunaix/mm/cake.h>
#include <lunaix/mm/valloc.h>
-#define MAX_CLASS 6
+#define CLASS_LEN(class) (sizeof(class) / sizeof(class[0]))
-static char piles_names[MAX_CLASS][PILE_NAME_MAXLEN] = {
- "valloc_16", "valloc_32", "valloc_64",
- "valloc_128", "valloc_256", "valloc_512"
+static char piles_names[][PILE_NAME_MAXLEN] = {
+ "valloc_8", "valloc_16", "valloc_32", "valloc_64", "valloc_128",
+ "valloc_256", "valloc_512", "valloc_1k", "valloc_2k", "valloc_4k"
};
-static char piles_names_dma[MAX_CLASS][PILE_NAME_MAXLEN] = {
+static char piles_names_dma[][PILE_NAME_MAXLEN] = {
"valloc_dma_128", "valloc_dma_256", "valloc_dma_512",
"valloc_dma_1k", "valloc_dma_2k", "valloc_dma_4k"
};
-static struct cake_pile* piles[MAX_CLASS];
-static struct cake_pile* piles_dma[MAX_CLASS];
+static struct cake_pile* piles[CLASS_LEN(piles_names)];
+static struct cake_pile* piles_dma[CLASS_LEN(piles_names_dma)];
void
valloc_init()
{
- for (size_t i = 0; i < MAX_CLASS; i++) {
- int size = 1 << (i + 4);
- piles[i] = cake_new_pile(&piles_names[i], size, 1, 0);
+ for (size_t i = 0; i < CLASS_LEN(piles_names); i++) {
+ int size = 1 << (i + 3);
+ piles[i] = cake_new_pile(&piles_names[i], size, size > 1024 ? 4 : 1, 0);
}
// DMA 内存保证128字节对齐
- for (size_t i = 0; i < MAX_CLASS; i++) {
+ for (size_t i = 0; i < CLASS_LEN(piles_names_dma); i++) {
int size = 1 << (i + 7);
piles_dma[i] = cake_new_pile(
- &piles_names_dma[i], size, size > 1024 ? 8 : 1, PILE_CACHELINE);
+ &piles_names_dma[i], size, size > 1024 ? 4 : 1, PILE_CACHELINE);
}
}
void*
-__valloc(unsigned int size, struct cake_pile** segregate_list)
+__valloc(unsigned int size, struct cake_pile** segregate_list, size_t len)
{
size_t i = 0;
- for (; i < MAX_CLASS; i++) {
+ for (; i < len; i++) {
if (segregate_list[i]->piece_size >= size) {
goto found_class;
}
}
void
-__vfree(void* ptr, struct cake_pile** segregate_list)
+__vfree(void* ptr, struct cake_pile** segregate_list, size_t len)
{
size_t i = 0;
- for (; i < MAX_CLASS; i++) {
+ for (; i < len; i++) {
if (cake_release(segregate_list[i], ptr)) {
return;
}
void*
valloc(unsigned int size)
{
- return __valloc(size, &piles);
+ return __valloc(size, &piles, CLASS_LEN(piles_names));
}
void*
vzalloc(unsigned int size)
{
- void* ptr = __valloc(size, &piles);
+ void* ptr = __valloc(size, &piles, CLASS_LEN(piles_names));
memset(ptr, 0, size);
return ptr;
}
return 0;
}
- void* ptr = __valloc(alloc_size, &piles);
+ void* ptr = __valloc(alloc_size, &piles, CLASS_LEN(piles_names));
memset(ptr, 0, alloc_size);
return ptr;
}
void
vfree(void* ptr)
{
- __vfree(ptr, &piles);
+ __vfree(ptr, &piles, CLASS_LEN(piles_names));
}
void*
valloc_dma(unsigned int size)
{
- return __valloc(size, &piles_dma);
+ return __valloc(size, &piles_dma, CLASS_LEN(piles_names_dma));
}
void*
vzalloc_dma(unsigned int size)
{
- void* ptr = __valloc(size, &piles_dma);
+ void* ptr = __valloc(size, &piles_dma, CLASS_LEN(piles_names_dma));
memset(ptr, 0, size);
return ptr;
}
void
vfree_dma(void* ptr)
{
- __vfree(ptr, &piles_dma);
+ __vfree(ptr, &piles_dma, CLASS_LEN(piles_names_dma));
}
\ No newline at end of file
#include <arch/x86/boot/multiboot.h>
#include <lunaix/common.h>
+#include <lunaix/fs.h>
+#include <lunaix/fs/twifs.h>
#include <lunaix/lunistd.h>
#include <lunaix/lxconsole.h>
#include <lunaix/mm/cake.h>
__test_disk_io()
{
struct hba_port* port = ahci_get_port(0);
+ struct hba_device* dev = port->device;
char* buffer = vzalloc_dma(port->device->block_size);
strcpy(buffer, test_sequence);
kprintf("WRITE: %s\n", buffer);
int result;
// 写入第一扇区 (LBA=0)
- result =
- port->device->ops.write_buffer(port, 0, buffer, port->device->block_size);
+ result = dev->ops.write_buffer(dev, 0, buffer, dev->block_size);
if (!result) {
- kprintf(KWARN "fail to write: %x\n", port->device->last_error);
+ kprintf(KWARN "fail to write: %x\n", dev->last_error);
}
- memset(buffer, 0, port->device->block_size);
+ memset(buffer, 0, dev->block_size);
// 读出我们刚刚写的内容!
- result =
- port->device->ops.read_buffer(port, 0, buffer, port->device->block_size);
+ result = dev->ops.read_buffer(dev, 0, buffer, dev->block_size);
kprintf(KDEBUG "%x, %x\n", port->regs[HBA_RPxIS], port->regs[HBA_RPxTFD]);
if (!result) {
- kprintf(KWARN "fail to read: %x\n", port->device->last_error);
+ kprintf(KWARN "fail to read: %x\n", dev->last_error);
} else {
kprint_hex(buffer, 256);
}
// 锁定所有系统预留页(内存映射IO,ACPI之类的),并且进行1:1映射
lock_reserved_memory();
- cake_init();
-
assert_msg(kalloc_init(), "Fail to initialize heap");
- valloc_init();
acpi_init(_k_init_mb_info);
apic_init();
ps2_kbd_init();
pci_init();
ahci_init();
- ahci_list_device();
+ // ahci_list_device();
+
+ fsm_init();
+ vfs_init();
+ twifs_init();
+
+ vfs_mount("/", "twifs", -1);
- __test_disk_io();
+ //__test_disk_io();
- cake_stats();
+ // cake_stats();
syscall_install();
struct proc_info* proc = pid ? get_process(pid) : __current;
if (!proc) {
- __current->k_status = LXINVL;
+ __current->k_status = EINVAL;
return -1;
}
struct proc_info* gruppenfuhrer = get_process(pgid);
if (!gruppenfuhrer || proc->pgid == proc->pid) {
- __current->k_status = LXINVL;
+ __current->k_status = EINVAL;
return -1;
}
#include <lunaix/mm/kalloc.h>
#include <lunaix/mm/pmm.h>
+#include <lunaix/mm/valloc.h>
#include <lunaix/mm/vmm.h>
#include <lunaix/process.h>
#include <lunaix/sched.h>
proc->pid = i;
proc->created = clock_systime();
proc->pgid = proc->pid;
+ proc->fdtable = vzalloc(sizeof(struct v_fdtable));
llist_init_head(&proc->mm.regions);
llist_init_head(&proc->children);
assert(process == &sched_ctx._procs[process->pid]);
if (process->state != PS_CREATED) {
- __current->k_status = LXINVL;
+ __current->k_status = EINVAL;
return;
}
{
int index = pid;
if (index <= 0 || index > sched_ctx.ptable_len) {
- __current->k_status = LXINVLDPID;
+ __current->k_status = EINVAL;
return;
}
struct proc_info* proc = &sched_ctx._procs[index];
signal_send(pid_t pid, int signum)
{
if (signum < 0 || signum >= _SIG_NUM) {
- __current->k_status = LXINVL;
+ __current->k_status = EINVAL;
return -1;
}
} else {
// TODO: send to all process.
// But I don't want to support it yet.
- __current->k_status = LXINVL;
+ __current->k_status = EINVAL;
return -1;
}
send_single:
if (PROC_TERMINATED(proc->state)) {
- __current->k_status = LXINVL;
+ __current->k_status = EINVAL;
return -1;
}
__SIGSET(proc->sig_pending, signum);
unsigned int
crc32b(unsigned char* data, unsigned int size)
{
- int i = 0;
- unsigned int crc = (unsigned int)-1;
+ unsigned int crc = (unsigned int)-1, i = 0;
while (i < size) {
crc = (crc >> 8) ^ crc32_tab[(crc ^ data[i]) & 0xff];
uint32_t
strhash_32(unsigned char* str, uint32_t truncate_to)
{
+ if (!str)
+ return 0;
+
uint32_t hash = 5381;
int c;
- while (c = *str++)
+ while ((c = *str++))
hash = ((hash << 5) + hash) + c; /* hash * 33 + c */
return hash >> (HASH_SIZE_BITS - truncate_to);