From: acevest Date: Mon, 2 Sep 2024 11:43:06 +0000 (+0800) Subject: 完善path_walk逻辑;初步编写sysc_mkdir相关逻辑 X-Git-Url: http://zhaoyanbai.com/repos/%22http:/www.isc.org/icons/zpipe.c?a=commitdiff_plain;h=8c0bf9f22558243ffd9723b44ed63bb40e3324f7;p=kernel.git 完善path_walk逻辑;初步编写sysc_mkdir相关逻辑 --- diff --git a/fs/dentry.c b/fs/dentry.c index 7d07a5e..de7cdac 100644 --- a/fs/dentry.c +++ b/fs/dentry.c @@ -15,7 +15,7 @@ #include #define DENTRY_HASH_TABLE_SIZE 233 -static kmem_cache_t *dentry_kmem_cache = NULL; +static kmem_cache_t *g_dentry_kmem_cache = NULL; typedef struct { list_head_t list; mutex_t mutex; @@ -40,7 +40,7 @@ dentry_t *dentry_alloc(dentry_t *parent, const qstr_t *s) { assert(s->len > 0); assert(s->len < DENTRY_INLINE_NAME_LEN - 1); - dentry = kmem_cache_zalloc(dentry_kmem_cache, 0); + dentry = kmem_cache_zalloc(g_dentry_kmem_cache, 0); if (dentry == NULL) { panic("no mem for dentry"); return dentry; @@ -128,20 +128,23 @@ dentry_t *dentry_cached_lookup(dentry_t *parent, qstr_t *s) { mutex_unlock(&dhe->mutex); - return dentry; + return NULL; } int dentry_real_lookup(dentry_t *parent, qstr_t *s, dentry_t **dentry) { *dentry = NULL; int ret = 0; - down(&parent->d_inode->i_sem); + assert(parent->d_inode != NULL); + inode_t *dir = parent->d_inode; + + down(&dir->i_sem); // 在获得信号量后,需要再上cache中查找一遍 // 因为这个过程中当前进程可能会睡眠,当被唤醒后,其它进程已经在内存准备好了 *dentry = dentry_cached_lookup(parent, s); if (NULL != *dentry) { - up(&parent->d_inode->i_sem); + up(&dir->i_sem); return ret; } @@ -149,22 +152,29 @@ int dentry_real_lookup(dentry_t *parent, qstr_t *s, dentry_t **dentry) { if (new_dentry == NULL) { ret = -ENOMEM; } else { - *dentry = parent->d_inode->i_ops->lookup(parent->d_inode, new_dentry); - - // 如果找到了,刚分配的,就不用了 - if (*dentry != NULL) { + *dentry = dir->i_ops->lookup(dir, new_dentry); + // 返回 lookup 没有再分配一个dentry + // 否则就释放dentry_new使用lookup返回的dentry + if (dentry == NULL) { + *dentry = new_dentry; + } else { dentry_put(new_dentry); } + // if (ret == 0) { // 返回0才代表成功 + // *dentry = new_dentry; + // } else { + // dentry_put(new_dentry); + // } } - up(&parent->d_inode->i_sem); + up(&dir->i_sem); return ret; } void dentry_cache_init() { - kmem_cache_t *dentry_kmem_cache = kmem_cache_create("dentry_cache", sizeof(dentry_t), 4); - if (NULL == dentry_kmem_cache) { + g_dentry_kmem_cache = kmem_cache_create("dentry_cache", sizeof(dentry_t), 4); + if (NULL == g_dentry_kmem_cache) { panic("create dentry cache faild"); } diff --git a/fs/fs.c b/fs/fs.c index e7a13e2..cd800ad 100644 --- a/fs/fs.c +++ b/fs/fs.c @@ -48,6 +48,9 @@ void setup_fs() { void dentry_cache_init(); dentry_cache_init(); + void ramfs_init(); + ramfs_init(); + void init_mount(); init_mount(); } diff --git a/fs/fssysc.c b/fs/fssysc.c new file mode 100644 index 0000000..9f0e02b --- /dev/null +++ b/fs/fssysc.c @@ -0,0 +1,44 @@ +/* + * ------------------------------------------------------------------------ + * File Name: fssysc.c + * Author: Zhao Yanbai + * 2024-09-01 21:41:00 Sunday CST + * Description: none + * ------------------------------------------------------------------------ + */ + +#include "fs.h" +#include "system.h" + +////// +int vfs_mkdir() { + int ret = 0; + + return ret; +} + +__attribute__((regparm(0))) long sysc_mkdir(const char *path, int mode) { + int ret = 0; + + // TODO 检查参数 + + namei_t ni; + if (path_init(path, PATH_LOOKUP_PARENT, &ni)) { + ret = path_walk(path, &ni); + if (0 != ret) { + return ret; + } + } + + dentry_t *dentry; + dentry = path_lookup_create(&ni); + ret = PTR_ERR(dentry); + if (!IS_ERR(dentry)) { + ret = vfs_mkdir(ni.path.dentry, dentry, mode); + dentry_put(dentry); + } + + up(&ni.path.dentry->d_inode->i_sem); + + return ret; +} diff --git a/fs/inode.c b/fs/inode.c index c8a6bb9..26fd847 100644 --- a/fs/inode.c +++ b/fs/inode.c @@ -34,7 +34,7 @@ inode_t *alloc_inode(superblock_t *sb) { static file_operations_t empty_fops; static inode_operations_t empty_iops; inode->i_sb = sb; - // inode->i_sem; + semaphore_init(&inode->i_sem, 1); inode->i_fops = &empty_fops; inode->i_ops = &empty_iops; inode->i_size = 0; diff --git a/fs/mount.c b/fs/mount.c index 1022785..2e46261 100644 --- a/fs/mount.c +++ b/fs/mount.c @@ -13,6 +13,7 @@ #include "mm.h" #include "string.h" #include "system.h" +#include "task.h" kmem_cache_t *vfsmount_kmem_cache = 0; @@ -106,3 +107,18 @@ void init_mount() { } assert(bit1_cnt == 1); } + +void mount_root() { + fs_type_t *type = vfs_find_filesystem("ramfs"); + assert(type != NULL); + + vfsmount_t *mnt = vfs_kernel_mount(type, 0, "ramfs", NULL); + assert(mnt != NULL); + + assert(mnt->mnt_root != NULL); + + current->root.mnt = mnt; + current->root.dentry = mnt->mnt_root; + current->pwd.mnt = mnt; + current->pwd.dentry = mnt->mnt_root; +} diff --git a/fs/path.c b/fs/path.c index 6c23509..3ccdc24 100644 --- a/fs/path.c +++ b/fs/path.c @@ -19,18 +19,23 @@ bool path_init(const char *path, unsigned int flags, namei_t *ni) { } if (*path == '/') { - ni->mnt = current->mnt_root; - ni->dentry = current->dentry_root; + // ni->path.mnt = current->mnt_root; + // ni->path.dentry = current->dentry_root; + ni->path = current->root; return true; } - ni->mnt = current->mnt_pwd; - ni->dentry = current->dentry_pwd; + // ni->path.mnt = current->mnt_pwd; + // ni->path.dentry = current->dentry_pwd; + ni->path = current->pwd; return true; } void follow_dotdot(namei_t *ni) { +#if 1 + panic("not supported"); +#else while (1) { dentry_t *dentry = NULL; vfsmount_t *parent = NULL; @@ -90,6 +95,7 @@ void follow_dotdot(namei_t *ni) { // 分别产生 vfsmnt_a vfsmnt_b // 这两个vfsmnt都会挂载到dentry->d_vfsmnt链表上 } +#endif } uint64_t compute_qstr_hash(qstr_t *q) { @@ -139,7 +145,9 @@ int path_walk(const char *path, namei_t *ni) { } // 拿到当前目录的 inode - inode_t *inode = ni->dentry->d_inode; + inode_t *inode = ni->path.dentry->d_inode; + + uint32_t path_lookup_flags = ni->flags; while (true) { qstr_t this; @@ -147,13 +155,13 @@ int path_walk(const char *path, namei_t *ni) { do { path++; - } while (*path && (*path != '/')); + } while (*path != 0 && (*path != '/')); this.len = path - this.name; // 看是不是路径的最后一个文件名 if (*path == 0) { - // 当前是最后一个文件名,且文件名结尾没有带上 '/' + goto last_file_name; } // 继续解析路径,此时this.name肯定带上了 '/',现在就是要确定它是不是最后一个文件名 @@ -165,6 +173,7 @@ int path_walk(const char *path, namei_t *ni) { // 若路径是以'/'结尾的,则肯定是最后一个文件名 // 但这种情况下,最后这个文件名必需是文件夹名 if (*path == 0) { + goto last_file_name_with_slash; } // 若除了'/'又遇到了其它字符,则代表当前不是最后一个文件名 @@ -177,7 +186,7 @@ int path_walk(const char *path, namei_t *ni) { } else if (this.len == 2 && this.name[1] == '.') { // 跳到父目录 follow_dotdot(ni); - inode = ni->dentry->d_inode; + inode = ni->path.dentry->d_inode; continue; } } @@ -186,25 +195,169 @@ int path_walk(const char *path, namei_t *ni) { compute_qstr_hash(&this); // 根据该名字,先上dentry cache里找 - dentry = dentry_cached_lookup(ni->dentry, &this); + dentry = dentry_cached_lookup(ni->path.dentry, &this); // 如果找不到就上实际存储设备中去找 if (NULL == dentry) { - ret = dentry_real_lookup(ni->dentry, &this, &dentry); + ret = dentry_real_lookup(ni->path.dentry, &this, &dentry); if (0 != ret) { break; } } - // 找到了,先看看它是不是一个挂载点 - while (!list_empty(&dentry->d_vfsmnt)) { - // 如果是一个挂载点,则更进一步 + // 找到了,先看其是不是一个挂载点 + // TODO + if (dentry->d_flags & DENTRY_FLAGS_MOUNTED) { + panic("not supported"); + } + + // 不是挂载点 或已经处理完了挂载点 + ret = -ENOENT; + inode = dentry->d_inode; - // 这种解决的是先将/a 挂载到 /b - // 再将/b挂载到/c - // 读/c时,直接读到/a的dentry + if (inode == NULL) { + goto out_dput_entry; + } + + ret = -ENOTDIR; + if (!S_ISDIR(inode->i_mode)) { + goto out_dput_entry; + } + if (inode->i_ops == NULL) { + goto out_dput_entry; + } + + // TODO 判断 symlink + // ... + + dentry_put(ni->path.dentry); + ni->path.dentry = dentry; + assert(inode->i_ops->lookup != NULL); + + // 进入下轮解析 + continue; + + // ---------------- 以下处理其它逻辑 ---------------- + + last_file_name_with_slash: + path_lookup_flags |= PATH_LOOKUP_DIRECTORY; + last_file_name: + if (path_lookup_flags & PATH_LOOKUP_PARENT) { + ni->last = this; + ni->last_type = LAST_NORMAL; + if (this.len == 1 && this.name[0] == '.') { + ni->last_type = LAST_DOT; + } + if (this.len == 2 && this.name[0] == '.' && this.name[1] == '.') { + ni->last_type = LAST_DOTDOT; + } + goto ok; + } + + // 最后一个文件名可能是 '.' 或 '..' + if (this.len == 1 && this.name[0] == '.') { + goto ok; + } + + if (this.len == 2 && this.name[0] == '.' && this.name[1] == '.') { + follow_dotdot(ni); + inode = ni->path.dentry->d_inode; + goto ok; + } + + // 计算当前文件名的hash + compute_qstr_hash(&this); + + // 根据该名字,先上dentry cache里找 + dentry = dentry_cached_lookup(ni->path.dentry, &this); + + // 如果找不到就上实际存储设备中去找 + if (NULL == dentry) { + ret = dentry_real_lookup(ni->path.dentry, &this, &dentry); + if (0 != ret) { + break; + } } - } + // 找到了,先看其是不是一个挂载点 + // TODO + if (dentry->d_flags & DENTRY_FLAGS_MOUNTED) { + panic("not supported"); + } + + inode = dentry->d_inode; + // TODO 判断 symlink + // ... + + dentry_put(dentry); + ni->path.dentry = dentry; + + ret = -ENOENT; + if (inode == NULL) { + if (path_lookup_flags & (PATH_LOOKUP_DIRECTORY | PATH_LOOKUP_MUST_HAVE_INODE)) { + goto end; + } + + goto ok; + } + + if (path_lookup_flags & PATH_LOOKUP_MUST_HAVE_INODE) { + ret = -ENOTDIR; + if (inode->i_ops == NULL || inode->i_ops->lookup == NULL) { + goto end; + } + } + ok: + return 0; + } +out_dput_entry: + dentry_put(dentry); +end: return ret; } + +dentry_t *path_lookup_hash(dentry_t *base, qstr_t *name) { + dentry_t *dentry = NULL; + + inode_t *inode = base->d_inode; + + dentry = dentry_cached_lookup(base, name); + if (dentry != NULL) { + return dentry; + } + + dentry_t *dentry_new = dentry_alloc(base, name); + if (dentry_new == NULL) { + dentry = ERR_PTR(-ENOMEM); + return dentry; + } + + dentry = inode->i_ops->lookup(inode, dentry_new); + + if (dentry == NULL) { // 返回 lookup 没有再分配一个dentry + dentry = dentry_new; + } else { // 否则就释放dentry_new使用lookup返回的dentry + dentry_put(dentry_new); + } + + return dentry; +} + +dentry_t *path_lookup_create(namei_t *ni) { + dentry_t *dentry = NULL; + + // 在调用完path_lookup_create后调用 up 操作 + down(&ni->path.dentry->d_inode->i_sem); + + dentry = ERR_PTR(-EEXIST); + if (ni->last_type != LAST_NORMAL) { + return dentry; + } + + dentry = path_lookup_hash(ni->path.dentry, &ni->last); + if (IS_ERR(dentry)) { + return dentry; + } + + return dentry; +} diff --git a/fs/ramfs.c b/fs/ramfs.c index 2ab035b..281f301 100644 --- a/fs/ramfs.c +++ b/fs/ramfs.c @@ -45,8 +45,18 @@ static const inode_operations_t ramfs_file_inode_operations = { }; -static const inode_operations_t ramfs_dir_inode_operations = { +static const file_operations_t ramfs_dir_operations = { + +}; + +int ramfs_mkdir(inode_t *, dentry_t *, int) { + int ret = 0; + return ret; +} + +static const inode_operations_t ramfs_dir_inode_operations = { + .mkdir = ramfs_mkdir, }; inode_t *ramfs_get_inode(superblock_t *sb, umode_t mode, dev_t dev) { @@ -65,8 +75,8 @@ inode_t *ramfs_get_inode(superblock_t *sb, umode_t mode, dev_t dev) { inode->i_ops = &ramfs_file_inode_operations; break; case S_IFDIR: - panic("S_IFDIR: not implement"); - inode->i_fops = &simple_dir_operations; + // panic("S_IFDIR: not implement"); + inode->i_fops = &ramfs_dir_operations; inode->i_ops = &ramfs_dir_inode_operations; break; case S_IFLNK: @@ -77,7 +87,7 @@ inode_t *ramfs_get_inode(superblock_t *sb, umode_t mode, dev_t dev) { break; } - return NULL; + return inode; } static sb_operations_t ramfs_ops = { diff --git a/fs/super.c b/fs/super.c index 08875d4..0f8f334 100644 --- a/fs/super.c +++ b/fs/super.c @@ -32,19 +32,32 @@ static superblock_t *alloc_super(fs_type_t *type) { return s; } +static uint32_t __minor = 0; +int set_anonymous_super(superblock_t *s, void *data) { + s->sb_dev = MAKE_DEV(0, ++__minor); + return 0; +} + int read_super_for_nodev(fs_type_t *type, int flags, void *data, fill_super_cb_t fill_super, vfsmount_t *mnt) { int ret = 0; superblock_t *s = 0; // 分配superblock + s = sget(type, NULL, set_anonymous_super, NULL); + + assert(s != NULL); // s->sb_flags = flags; ret = fill_super(s, data); if (0 != ret) { + panic("ret: %d", ret); } + mnt->mnt_sb = s; + mnt->mnt_root = dentry_get(s->sb_root); + return ret; } diff --git a/fs/vfs.c b/fs/vfs.c index c6c3041..e7ceae4 100644 --- a/fs/vfs.c +++ b/fs/vfs.c @@ -65,16 +65,16 @@ fs_type_t *vfs_find_filesystem(const char *name) { return NULL; } -void ramfs_init(); -void vfs_init() { - ramfs_init(); - fs_type_t *fs = vfs_find_filesystem("ramfs"); - if (NULL == fs) { - panic("no ramfs"); - } +// 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); -} +// // superblock_t *sb = fs->read_super(NULL, NULL); +// } ///////// vfsmount_t *vfsmnt_get(vfsmount_t *m) { diff --git a/fs/vfs.h b/fs/vfs.h index a076ae0..989bbd7 100644 --- a/fs/vfs.h +++ b/fs/vfs.h @@ -29,6 +29,45 @@ typedef struct dentry_operations dentry_operations_t; typedef struct vfsmount vfsmount_t; typedef struct path path_t; +struct path { + dentry_t *dentry; + vfsmount_t *mnt; +}; + +#define PATH_LOOKUP_PARENT /* */ 0x00000001 +#define PATH_LOOKUP_DIRECTORY /* */ 0x00000002 +#define PATH_LOOKUP_MUST_HAVE_INODE 0x00000004 + +enum { + LAST_FORGET_INIT = 0, + LAST_NORMAL = 1, + LAST_ROOT, + LAST_DOT, + LAST_DOTDOT, +}; + +typedef struct namei { + path_t path; + qstr_t last; + uint32_t last_type; + uint32_t flags; +} namei_t; + +typedef struct file file_t; + +typedef struct file_operations { + int (*open)(inode_t *, file_t *); + int (*release)(inode_t *, file_t *); + ssize_t (*read)(file_t *, char *, size_t, loff_t *); + ssize_t (*write)(file_t *, const char *, size_t, loff_t *); +} file_operations_t; + +struct file { + // 多个打开的文件可能是同一个文件 + dentry_t *f_dentry; + file_operations_t *f_ops; +}; + // super block typedef struct superblock { // 该超级起的根目录的 dentry @@ -43,6 +82,8 @@ typedef struct superblock { list_head_t sb_list; list_head_t sb_instance; + + dev_t sb_dev; } superblock_t; // dentry和inode为什么不合二为一? @@ -77,7 +118,12 @@ struct inode { umode_t i_mode; // FILE DIR CHR BLK FIFO SOCK }; +// d_flags +#define DENTRY_FLAGS_MOUNTED 0x01 + +// d_inline_name #define DENTRY_INLINE_NAME_LEN 16 + struct dentry { // char *d_name; uint32_t d_flags; @@ -132,8 +178,22 @@ struct sb_operations { // }; struct inode_operations { - // - dentry_t *(*lookup)(inode_t *i, dentry_t *d); + // 用于在inode下找一个dentry->d_small_name的目录项 + dentry_t *(*lookup)(inode_t *, dentry_t *); + + // 在inode下创建一个dentry->d_small_name的文件 + int (*create)(inode_t *, dentry_t *, int, namei_t *); + + // 创建文件夹 + int (*mkdir)(inode_t *, dentry_t *, int); + + // link + // unlink + // symlink + // link 是普通连接 symlink是符号连接 + // 连接是指一个节点(文件或目录项)直接指向另一个节点,成为为该节点的一个代表 + // link必需处于同一个设备上,必需连接到一个真实的文件上 + // symlink可以处于不同的设备上,可以悬空,也就是没有连接到真实的文件上 }; struct dentry_operations { @@ -145,11 +205,6 @@ struct dentry_operations { // }; -struct path { - dentry_t *dentry; - vfsmount_t *mount; -}; - // 每当将一个存储设备安装到现有文件系统中的某个节点时,内核就要为之建立一个vfsmount结构 // 这个结构中即包含着该设备的有关信息,也包含了安装点的信息 // 系统中的每个文件系统,包括根设备的根文件系统,都要经过安装 @@ -198,7 +253,7 @@ struct fs_type { extern superblock_t *root_sb; int vfs_register_filesystem(fs_type_t *fs); - +fs_type_t *vfs_find_filesystem(const char *name); ///// inode_t *alloc_inode(superblock_t *sb); @@ -208,6 +263,7 @@ void init_special_inode(inode_t *inode, umode_t mode, dev_t rdev); dentry_t *dentry_cached_lookup(dentry_t *parent, qstr_t *s); int dentry_real_lookup(dentry_t *parent, qstr_t *s, dentry_t **dentry); dentry_t *dentry_alloc_root(inode_t *root_inode); +dentry_t *dentry_alloc(dentry_t *parent, const qstr_t *s); vfsmount_t *vfsmnt_get(vfsmount_t *m); void vfsmnt_put(vfsmount_t *m); @@ -219,3 +275,8 @@ void dentry_put(dentry_t *dentry); ///// extern const file_operations_t simple_dir_operations; + +// +bool path_init(const char *path, unsigned int flags, namei_t *ni); +int path_walk(const char *path, namei_t *ni); +dentry_t *path_lookup_create(namei_t *ni); diff --git a/gdbscript b/gdbscript index d5fe482..8ff45da 100644 --- a/gdbscript +++ b/gdbscript @@ -8,11 +8,13 @@ set confirm off #break *0x100000 -b block.c:63 +#b block.c:63 #b task_disk.c:94 #handle SIGINT nostop noprint +b root_task_entry + target remote localhost:1234 diff --git a/include/fs.h b/include/fs.h index b475b7d..be93260 100644 --- a/include/fs.h +++ b/include/fs.h @@ -56,77 +56,6 @@ enum { CHRDEV_CNSL, CHRDEV_SIZE }; extern chrdev_t *chrdev[]; -typedef struct file file_t; - -typedef struct file_operations { - int (*open)(inode_t *, file_t *); - int (*release)(inode_t *, file_t *); - ssize_t (*read)(file_t *, char *, size_t, loff_t *); - ssize_t (*write)(file_t *, const 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)) -#define NR_INODES (2 * NR_FILES) -#define NR_OPENS (2) /* 一个进程同时打开文件的限制数 */ -extern File file_table[NR_FILES]; -extern Inode inode_table[NR_INODES]; - - -typedef struct -{ - int count; - int ino_nr; - pInode inode; -} File, *pFile; - - -static inline int get_inode_nr(const char *path) -{ - return ext2_get_file_inode_nr(path); -} - -static inline int get_inode(unsigned int n, pInode inode) -{ - return ext2_read_inode(n, inode); -} - -static inline int read_file(const pInode inode, void *buf, size_t count) -{ - return ext2_read_file(inode, buf, count); -} - -/* 在多进程下这样肯定不行 - * 管不了这么多了,先这样写吧 - */ -static inline pInode find_empty_inode() -{ - int i; - pInode p = inode_table; - for(i=0; ii_size == 0) - { - p->i_size = 1; - return p; - } - } - - return NULL; -} -#endif - typedef int (*fill_super_cb_t)(superblock_t *sb, void *data); int read_super_for_nodev(fs_type_t *type, int flags, void *data, fill_super_cb_t fill_super, vfsmount_t *mnt); diff --git a/include/task.h b/include/task.h index f91562f..a68102a 100644 --- a/include/task.h +++ b/include/task.h @@ -77,11 +77,8 @@ typedef union task_union { task_files_t files; - dentry_t *dentry_root; - dentry_t *dentry_pwd; - - vfsmount_t *mnt_root; - vfsmount_t *mnt_pwd; + path_t root; + path_t pwd; list_head_t list; // 所有进程串成一个链表 diff --git a/kernel/setup.c b/kernel/setup.c index a44c169..cca48b3 100644 --- a/kernel/setup.c +++ b/kernel/setup.c @@ -58,6 +58,9 @@ void setup_kernel() { init_buffer(); + void init_mount(); + init_mount(); + // printk("kernel: %08x - %08x\n", system.kernel_begin, system.kernel_end); boot_delay(DEFAULT_BOOT_DELAY_TICKS); @@ -70,9 +73,14 @@ void setup_kernel() { const char *title = "KERNEL MONITOR"; printlxy(MPL_TITLE, (80 - strlen(title)) / 2, title); + setup_fs(); + setup_tasks(); boot_delay(DEFAULT_BOOT_DELAY_TICKS); + void mount_root(); + mount_root(); + setup_pci(); boot_delay(DEFAULT_BOOT_DELAY_TICKS); diff --git a/qemu.sh b/qemu.sh index e18cd69..50df4d3 100755 --- a/qemu.sh +++ b/qemu.sh @@ -19,6 +19,7 @@ set -m qemu-system-i386 \ -boot d \ + -m 128 \ -serial tcp::6666,server,nowait \ -drive file=HD.IMG,format=raw,index=0,media=disk \ -drive file=kernel.iso,index=1,media=cdrom \