aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLiu Aleaxander <Aleaxander@gmail.com>2009-06-11 10:47:04 +0800
committerLiu Aleaxander <Aleaxander@gmail.com>2009-06-11 10:47:04 +0800
commit03fa0653f5546b01c793126359bb8e56838e711c (patch)
tree6c1fcd0da672e14fd27b313b16d3ec32ff9e0810
parent5bae1d2de9f1f271750d9c0479ec5a68effa2da6 (diff)
downloadsyslinux-03fa0653f5546b01c793126359bb8e56838e711c.tar.gz
syslinux-03fa0653f5546b01c793126359bb8e56838e711c.tar.xz
syslinux-03fa0653f5546b01c793126359bb8e56838e711c.zip
Core: add the skeleton fo VFS-like system
Two new files added; they are: fs.h defines some basic vfs objects fs.c defines the basic functions Note: for now, it's just a skeleton, in another word, it can't compiled.
-rw-r--r--core/fs.c123
-rw-r--r--core/include/fs.h76
2 files changed, 199 insertions, 0 deletions
diff --git a/core/fs.c b/core/fs.c
new file mode 100644
index 00000000..f0946900
--- /dev/null
+++ b/core/fs.c
@@ -0,0 +1,123 @@
+#include <stdio.h>
+#include <string.h>
+#include "fs.h"
+#include "cache.h"
+
+
+/* The this pointer */
+struct fs_info *this_fs;
+struct fs_info fs;
+struct device dev;
+
+
+void load_config(com32sys_t *regs)
+{
+ this_fs->fs_ops->load_config(regs);
+}
+
+void mangle_name(com32sys_t *regs)
+{
+ char *src = (char *)MK_PTR(regs->ds, regs->esi.w[0]);
+ char *dst = (char *)MK_PTR(regs->es, regs->edi.w[0]);
+
+ this_fs->fs_ops->mangle_name(dst, src);
+}
+
+/****
+void unmangle_name(com32sys_t *regs)
+{
+
+}
+****/
+
+void getfssec(com32sys_t *regs)
+{
+ int sectors;
+ int have_more;
+ uint32_t bytes_read;
+ char *buf;
+ struct file file;
+
+ sectors = regs->ecx.w[0];
+ buf = (char *)MK_PTR(regs->es, regs->ebx.w[0]);
+ file.open_file = MK_PTR(regs->ds, regs->esi.w[0]);
+ file.fs = this_fs;
+
+ bytes_read = this_fs->fs_ops->getfssec(buf, file.open_file, sectors, &have_more);
+
+ /* if we reach the EOF, set the si to be NULL */
+ if (!have_more)
+ regs->esi.w[0] = 0;
+
+ regs->ecx.l = bytes_read;
+}
+
+
+void searchdir(com32sys_t *regs)
+{
+ char *filename = (char *)MK_PTR(regs->ds, regs->edi.w[0]);
+ struct file file;
+
+ memset(&file, 0, sizeof file);
+ file.fs = this_fs;
+
+ this_fs->fs_ops->searchdir(filename, &file);
+ regs->esi.w[0] = OFFS_WRT(file.open_file, 0);
+ regs->eax.l = file.file_len;
+}
+
+/*
+ * initialize the device structure
+ */
+void device_init(struct device *dev, uint8_t drive_num,
+ uint8_t type, sector_t offset)
+{
+ dev->device_number = drive_num;
+ dev->part_start = offset;
+ dev->type = type;
+
+ /*
+ * check if we use cache or not, for now I just know ISO fs
+ * does not use the cache, and I hope the USE_CACHE can detect
+ * it correctly.
+ *
+ */
+ if ( USE_CACHE(dev->device_number) ) {
+ static __lowmem char cache_buf[65536];
+ dev->cache_data = cache_buf;
+ } else
+ dev->cache_data = NULL;
+
+ /* I just considered the floppy and disk now */
+ dev->read_sectors = read_sectors;
+}
+
+
+/*
+ * it will do:
+ * initialize the device structure;
+ * set up the vfs fs structure;
+ * invoke the fs-specific init function;
+ * finally, initialize the cache
+ *
+ */
+void fs_init(com32sys_t *regs)
+{
+ int blk_shift;
+ struct fs_ops *ops = (struct fs_ops*)regs->eax.l;
+
+ device_init(&dev, regs->edx.b[0], regs->edx.b[1], regs->ecx.l);
+
+ /* set up the fs stucture */
+ fs.fs_name = ops->fs_name;
+ fs.fs_ops = ops;
+ fs.fs_dev = &dev;
+ this_fs = &fs;
+
+ /* invoke the fs-specific init code */
+ blk_shift = fs.fs_ops->fs_init();
+
+ /* initialize the cache */
+ if (dev.cache_data)
+ cache_init(&dev, blk_shift);
+}
diff --git a/core/include/fs.h b/core/include/fs.h
new file mode 100644
index 00000000..6805b3b9
--- /dev/null
+++ b/core/include/fs.h
@@ -0,0 +1,76 @@
+#ifndef FS_H
+#define FS_H
+
+#include <com32.h>
+#include "core.h"
+#include "disk.h"
+
+#define USE_CACHE(device_num) (device_num > 0x00 && device_num < 0xfe)
+
+
+struct fs_info {
+ char *fs_name;
+ struct fs_ops *fs_ops;
+ struct device *fs_dev;
+};
+
+struct file{
+ void* open_file; /* points to the fs-specific open_file_t */
+ struct fs_info *fs;
+ uint32_t file_len;
+};
+
+
+struct fs_ops {
+ /* in fact, we use fs_ops structure to find the right fs */
+ char *fs_name;
+
+ int (*fs_init)(void);
+ void (*searchdir)(char *, struct file *);
+ uint32_t (*getfssec)(char *, void * , int, int *);
+ void (*mangle_name)(char *, char *);
+ void (*unmangle_name)(void);
+ void (*load_config)(com32sys_t *);
+};
+
+//enum dev_type {CHS, EDD};
+
+/*
+ * Struct device should have all the information about a specific disk
+ * structure, and contain either a pointer to the metadata cache or
+ * actually contain the cache itself.
+ *
+ * All the information in this case is stuff like BIOS device number,
+ * type of access (CHS, EDD, ...), geometry, partition offset, and
+ * sector size.
+ *
+ * It would be usefull and much easier to implement the C version getlinsec
+ * later(I have not much time to implement it now, so I will leave it for
+ * a while, maybe a long while).
+ */
+struct device {
+ /* the device numger (in BIOS style ) */
+ uint8_t device_number;
+
+ /* type of access (CHS or EDD ) */
+ uint8_t type;
+
+ /* the sector size, 512B for disk and floppy, 2048B for CD */
+ uint16_t sector_size;
+
+ /* the start address of this partition(in sectors) */
+ sector_t part_start;
+
+ void (*read_sectors)(char *, sector_t, int );
+
+ /*
+ * I think we still need the cache_data filed here, 'cause hpa said
+ * different device has diffrent cache buffer
+ */
+ void *cache_data;
+ struct cache_struct *cache_head;
+};
+
+
+
+#endif /* FS_H */