Initial filesystem stub code.
authorBen Pfaff <blp@cs.stanford.edu>
Tue, 17 Aug 2004 03:06:47 +0000 (03:06 +0000)
committerBen Pfaff <blp@cs.stanford.edu>
Tue, 17 Aug 2004 03:06:47 +0000 (03:06 +0000)
src/Makefile.inc
src/filesys/Makefile [new file with mode: 0644]
src/filesys/build/Makefile [new file with mode: 0644]
src/filesys/file.c [new file with mode: 0644]
src/filesys/file.h [new file with mode: 0644]
src/filesys/filesys-stub.c [new file with mode: 0644]
src/filesys/filesys-stub.h [new file with mode: 0644]
src/filesys/filesys.c [new file with mode: 0644]
src/filesys/filesys.h [new file with mode: 0644]
src/lib/backdoor.c [new file with mode: 0644]
src/lib/backdoor.h [new file with mode: 0644]

index 20e96d7d9887056747b6388c0246d91ea8fea37b..338bb25eac42efbd802e0f3ead5d49f69a812083 100644 (file)
@@ -1,5 +1,10 @@
+# -*- makefile -*-
+
 SHELL = /bin/sh
-VPATH = $(TOP_SRCDIR)/threads:$(TOP_SRCDIR)/devices:$(TOP_SRCDIR)/lib
+VPATH := $(TOP_SRCDIR)/threads
+VPATH := $(VPATH):$(TOP_SRCDIR)/devices
+VPATH := $(VPATH):$(TOP_SRCDIR)/lib
+VPATH := $(VPATH):$(TOP_SRCDIR)/filesys
 
 -include *.d
 
@@ -9,21 +14,21 @@ CFLAGS = -g -O3 -MMD $(WARNINGS) $(INCLUDES) $(DEFINES)
 ASFLAGS = $(INCLUDES) $(DEFINES)
 
 # Core kernel.
-THREADS_SRC  = start.S # Must be first.
-THREADS_SRC += init.c  # Start-up code.
-THREADS_SRC += thread.c        # Thread management core.
-THREADS_SRC += switch.S        # Thread switch routine.
+THREADS_SRC  = start.S         # Must be linked first.
+THREADS_SRC += init.c          # Start-up code.
+THREADS_SRC += thread.c                # Thread management core.
+THREADS_SRC += switch.S                # Thread switch routine.
 THREADS_SRC += interrupt.c     # Interrupt core.
 THREADS_SRC += intr-stubs.S    # Interrupt stubs.
-THREADS_SRC += synch.c # Synchronization.
-THREADS_SRC += palloc.c        # Page allocator.
-THREADS_SRC += malloc.c        # Subpage allocator.
+THREADS_SRC += synch.c         # Synchronization.
+THREADS_SRC += palloc.c                # Page allocator.
+THREADS_SRC += malloc.c                # Subpage allocator.
 
 # Device driver code.
-DEVICES_SRC  = timer.c # Timer device.
-DEVICES_SRC += kbd.c   # Keyboard device.
-DEVICES_SRC += vga.c   # Video device.
-DEVICES_SRC += serial.c        # Serial port device.
+DEVICES_SRC  = timer.c         # Timer device.
+DEVICES_SRC += kbd.c           # Keyboard device.
+DEVICES_SRC += vga.c           # Video device.
+DEVICES_SRC += serial.c                # Serial port device.
 
 # Library code.
 LIB_SRC  = debug.c             # Debug helpers.
@@ -31,6 +36,12 @@ LIB_SRC += lib.c             # Standard C library.
 LIB_SRC += random.c            # Pseudo-random numbers.
 LIB_SRC += list.c              # Doubly-linked lists.
 LIB_SRC += bitmap.c            # Bitmaps.
+LIB_SRC += backdoor.c          # Backdoor IPC.
+
+# Filesystem code.
+FILESYS_SRC  = filesys.c       # Filesystem core.
+FILESYS_SRC += file.c          # Individual files.
+FILESYS_SRC += filesys-stub.c  # Stub helper code.
 
 # Objects.
 OBJECTS = $(patsubst %.c,%.o,$(patsubst %.S,%.o,$(SOURCES)))
@@ -41,7 +52,6 @@ intr-stubs.S: $(TOP_SRCDIR)/threads/intr-stubs.pl
        $< > $@.tmp && mv $@.tmp $@
 
 kernel.o: $(OBJECTS)
-       echo $(OBJECTS)
        ld -T $(TOP_SRCDIR)/threads/kernel.lds -o $@ $^ \
                `$(CC) -print-libgcc-file-name`
 
diff --git a/src/filesys/Makefile b/src/filesys/Makefile
new file mode 100644 (file)
index 0000000..495615d
--- /dev/null
@@ -0,0 +1,3 @@
+all:
+%:
+       $(MAKE) -C build $@
diff --git a/src/filesys/build/Makefile b/src/filesys/build/Makefile
new file mode 100644 (file)
index 0000000..281de9c
--- /dev/null
@@ -0,0 +1,8 @@
+TOP_SRCDIR = ../..
+DEFINES = -DFILESYS_STUB
+SOURCES = $(THREADS_SRC) $(DEVICES_SRC) $(LIB_SRC) $(FILESYS_SRC)
+INCLUDES = -I$(TOP_SRCDIR)/threads -I$(TOP_SRCDIR)/devices \
+          -I$(TOP_SRCDIR)/lib -I$(TOP_SRCDIR)/filesys
+
+include ../../Makefile.inc
+
diff --git a/src/filesys/file.c b/src/filesys/file.c
new file mode 100644 (file)
index 0000000..b2a4942
--- /dev/null
@@ -0,0 +1,51 @@
+#include "file.h"
+
+#ifdef FILESYS_STUB
+off_t
+file_read (struct file *file, void *buffer, off_t size) 
+{
+  int32_t retval = -1;
+  filesys_stub_send ("s'read' i i", (int32_t) file, (int32_t) size);
+  filesys_stub_receive ("s'read' i", &retval);
+  if (retval > 0) 
+    {
+      if (!filesys_stub_receive ("B", buffer, (size_t) retval))
+        retval = -1;
+    }
+  return retval;
+}
+
+off_t
+file_write (struct file *file, const void *buffer, off_t size) 
+{
+  int32_t retval = -1;
+  filesys_stub_send ("s'write' i B", (int32_t) file, buffer, (size_t) size);
+  filesys_stub_receive ("s'write' i", &retval);
+  return retval;
+}
+
+off_t
+file_length (struct file *file) 
+{
+  int32_t length = -1;
+  filesys_stub_send ("s'length' i", (int32_t) file);
+  filesys_stub_receive ("s'length' i", &length);
+  return length;
+}
+
+void
+file_seek (struct file *file, off_t pos) 
+{
+  filesys_stub_send ("s'seek' i i", (int32_t) file, (int32_t) pos);
+  filesys_stub_receive ("s'seek'");
+}
+
+off_t
+file_tell (struct file *file) 
+{
+  int32_t pos = -1;
+  filesys_stub_send ("s'tell' i", (int32_t) file);
+  filesys_stub_receive ("s'tell'", &pos);
+  return pos;
+}
+#endif /* FILESYS_STUB */
diff --git a/src/filesys/file.h b/src/filesys/file.h
new file mode 100644 (file)
index 0000000..689aa6d
--- /dev/null
@@ -0,0 +1,16 @@
+#ifndef HEADER_FILE_H
+#define HEADER_FILE_H 1
+
+#include <stdint.h>
+#include <stddef.h>
+
+typedef int32_t off_t;
+
+struct file;
+off_t file_read (struct file *, void *, off_t);
+off_t file_write (struct file *, const void *, off_t);
+off_t file_length (struct file *);
+void file_seek (struct file *, off_t);
+off_t file_tell (struct file *);
+
+#endif /* file.h */
diff --git a/src/filesys/filesys-stub.c b/src/filesys/filesys-stub.c
new file mode 100644 (file)
index 0000000..23d133b
--- /dev/null
@@ -0,0 +1,38 @@
+#include "filesys-stub.h"
+#include <stdarg.h>
+#include "backdoor.h"
+#include "debug.h"
+#include "io.h"
+
+static void
+out_byte (uint8_t byte, void *aux UNUSED) 
+{
+  outb (0x8901, byte);
+}
+
+void
+filesys_stub_send (const char *types, ...) 
+{
+  va_list args;
+
+  va_start (args, types);
+  backdoor_vmarshal (types, args, out_byte, NULL);
+  va_end (args);
+}
+
+static bool
+in_byte (uint8_t *byte, void *aux UNUSED) 
+{
+  *byte = inb (0x8901);
+  return true;
+}
+
+void
+filesys_stub_receive (const char *types, ...) 
+{
+  va_list args;
+
+  va_start (args, types);
+  backdoor_vunmarshal (types, args, in_byte, NULL);
+  va_end (args);
+}
diff --git a/src/filesys/filesys-stub.h b/src/filesys/filesys-stub.h
new file mode 100644 (file)
index 0000000..1bc6c59
--- /dev/null
@@ -0,0 +1,7 @@
+#ifndef HEADER_FILESYS_STUB_H
+#define HEADER_FILESYS_STUB_H 1
+
+void filesys_stub_send (const char *types, ...);
+void filesys_stub_receive (const char *types, ...);
+
+#endif /* filesys-stub.h */
diff --git a/src/filesys/filesys.c b/src/filesys/filesys.c
new file mode 100644 (file)
index 0000000..6b7710a
--- /dev/null
@@ -0,0 +1,37 @@
+#include "filesys.h"
+
+#ifdef FILESYS_STUB
+void
+filesys_init (bool reformat) 
+{
+  if (reformat)
+    printk ("filesystem stubs don't support formatting\n");
+}
+
+bool
+filesys_create (const char *name) 
+{
+  bool success = false;
+  filesys_stub_send ("s'create' s", name);
+  filesys_stub_receive ("s'create' b", &success);
+  return success;
+}
+
+struct file *
+filesys_open (const char *name) 
+{
+  int32_t handle = -1;
+  filesys_stub_stub ("s'open' i", name);
+  filesys_stub_receive ("s'open' i", &handle);
+  return handle == -1 ? NULL : (struct file *) handle;
+}
+
+bool
+filesys_remove (const char *name) 
+{
+  bool success = false;
+  filesys_stub_send ("s'create' s", name);
+  filesys_stub_receive ("s'create' b", &success);
+  return success;
+}
+#endif /* FILESYS_STUB */
diff --git a/src/filesys/filesys.h b/src/filesys/filesys.h
new file mode 100644 (file)
index 0000000..6f1e387
--- /dev/null
@@ -0,0 +1,11 @@
+#ifndef HEADER_FILESYS_H
+#define HEADER_FILESYS_H 1
+
+#include <stdbool.h>
+
+void filesys_init (bool reformat);
+bool filesys_create (const char *name);
+struct file *filesys_open (const char *name);
+bool filesys_remove (const char *name);
+
+#endif /* filesys.h */
diff --git a/src/lib/backdoor.c b/src/lib/backdoor.c
new file mode 100644 (file)
index 0000000..ac90f3c
--- /dev/null
@@ -0,0 +1,218 @@
+#include "backdoor.h"
+#include <stdbool.h>
+#include <stdlib.h>
+#include <string.h>
+
+static void
+marshal_int32 (int32_t value, void (*out) (uint8_t, void *aux), void *aux) 
+{
+  out ((value >> 24) & 0xff, aux);
+  out ((value >> 16) & 0xff, aux);
+  out ((value >> 8) & 0xff, aux);
+  out (value & 0xff, aux);
+}
+
+static void
+marshal_bytes (const void *buffer, size_t cnt,
+               void (*out) (uint8_t, void *aux), void *aux) 
+{
+  const uint8_t *p = buffer;
+  size_t i;
+
+  for (i = 0; i < cnt; i++)
+    out (p[i], aux);
+}
+
+enum backdoor_error
+backdoor_vmarshal (const char *types, va_list args,
+                   void (*out) (uint8_t, void *aux), void *aux) 
+{
+  const char *p = types;
+
+  for (;;) 
+    {
+      /* Find next type character. */
+      while (*p == ' ')
+        p++;
+      if (*p == '\0')
+        return BACKDOOR_OK;
+      
+      out (*p, aux);
+      switch (*p++) 
+        {
+        case 's':
+          if (*p == '\'') 
+            {
+              const char *end = strchr (++p, '\'');
+              marshal_int32 (end - p, out, aux);
+              marshal_bytes (p, end - p, out, aux);
+              p = end + 1;
+            }
+          else
+            {
+              const char *s = va_arg (args, const char *);
+              marshal_int32 (strlen (s), out, aux);
+              marshal_bytes (s, strlen (s), out, aux);
+            }
+          break;
+
+        case 'i':
+          marshal_int32 (va_arg (args, int32_t), out, aux);
+          break;
+
+        case 'B':
+          {
+            const void *buffer = va_arg (args, const void *);
+            size_t size = va_arg (args, size_t);
+            marshal_int32 (size, out, aux);
+            marshal_bytes (buffer, size, out, aux);
+          }
+          break;
+
+        case 'b':
+          marshal_int32 (va_arg (args, int), out, aux);
+          break;
+
+        default:
+          return BACKDOOR_BAD_TYPE;
+        }
+    }
+}
+
+static bool
+unmarshal_int32 (int32_t *value, 
+                 bool (*in) (uint8_t *, void *aux), void *aux) 
+{
+  int32_t tmp;
+  int i;
+
+  tmp = 0;
+  for (i = 0; i < 4; i++) 
+    {
+      uint8_t b;
+      if (!in (&b, aux))
+        return false;
+
+      tmp = (tmp << 8) | b;
+    }
+  *value = tmp;
+  return true;
+}
+
+static bool
+unmarshal_bytes (void *buffer, size_t cnt,
+                 bool (*in) (uint8_t *, void *aux), void *aux) 
+{
+  uint8_t *p = buffer;
+  size_t i;
+
+  for (i = 0; i < cnt; i++) 
+    if (!in (&p[i], aux))
+      return false;
+  return true;
+}
+
+enum backdoor_error
+backdoor_vunmarshal (const char *types, va_list args,
+                     bool (*in) (uint8_t *, void *aux), void *aux) 
+{
+  const char *p = types;
+
+  for (;;) 
+    {
+      uint8_t c;
+      
+      /* Find next type character. */
+      while (*p == ' ')
+        p++;
+      if (*p == '\0')
+        return BACKDOOR_OK;
+
+      /* Check type character in input. */
+      if (!in (&c, aux))
+        return BACKDOOR_UNEXPECTED_EOF;
+      if (c != *p++)
+        return BACKDOOR_TYPE_MISMATCH;
+
+      switch (c) 
+        {
+        case 's': 
+          {
+            int32_t length;
+            
+            if (!unmarshal_int32 (&length, in, aux))
+              return BACKDOOR_UNEXPECTED_EOF;
+            if (length < 0)
+              return BACKDOOR_NEGATIVE_SIZE;
+            if (*p == '\'')
+              {
+                const char *end = strchr (++p, '\'');
+                if (length != end - p)
+                  return BACKDOOR_STRING_MISMATCH;
+                while (p < end) 
+                  {
+                    uint8_t q;
+                    if (!in (&q, aux))
+                      return BACKDOOR_UNEXPECTED_EOF;
+                    if (q != *p++)
+                      return BACKDOOR_STRING_MISMATCH; 
+                  }
+                p++;
+              }
+            else
+              {
+                char *s = malloc (length + 1);
+                if (s == NULL)
+                  return BACKDOOR_NOMEM;
+                if (!unmarshal_bytes (s, length, in, aux)) 
+                  {
+                    free (s);
+                    return BACKDOOR_UNEXPECTED_EOF;
+                  }
+                s[length] = '\0';
+                *va_arg (args, char **) = s;
+              }
+          }
+          break;
+
+        case 'i':
+          if (!unmarshal_int32 (va_arg (args, int32_t *), in, aux))
+            return BACKDOOR_UNEXPECTED_EOF;
+          break;
+
+        case 'B':
+          {
+            int32_t size;
+            void *buffer;
+
+            if (!unmarshal_int32 (&size, in, aux))
+              return BACKDOOR_UNEXPECTED_EOF;
+            if (size < 0)
+              return BACKDOOR_NEGATIVE_SIZE;
+            buffer = malloc (size);
+            if (size > 0 && buffer == NULL)
+              return BACKDOOR_NOMEM;
+            if (!unmarshal_bytes (buffer, size, in, aux))
+              {
+                free (buffer);
+                return BACKDOOR_UNEXPECTED_EOF;
+              }
+            *va_arg (args, size_t *) = size;
+            *va_arg (args, void **) = buffer;
+          }
+          break;
+
+        case 'b':
+          {
+            int32_t b;
+            if (!unmarshal_int32 (&b, in, aux))
+              return BACKDOOR_UNEXPECTED_EOF;
+            *va_arg (args, bool *) = b;
+          }
+          break;
+
+        default:
+          return BACKDOOR_BAD_TYPE;
+        }
+    }
+}
diff --git a/src/lib/backdoor.h b/src/lib/backdoor.h
new file mode 100644 (file)
index 0000000..8205aa3
--- /dev/null
@@ -0,0 +1,26 @@
+#ifndef HEADER_BACKDOOR_H
+#define HEADER_BACKDOOR_H 1
+
+#include <stdint.h>
+#include <stdarg.h>
+#include <stdbool.h>
+
+enum backdoor_error 
+  {
+    BACKDOOR_OK = 0,
+    BACKDOOR_NOMEM = -100,
+    BACKDOOR_BAD_TYPE,
+    BACKDOOR_TYPE_MISMATCH,
+    BACKDOOR_STRING_MISMATCH,
+    BACKDOOR_NEGATIVE_SIZE,
+    BACKDOOR_UNEXPECTED_EOF
+  };
+
+enum backdoor_error
+backdoor_vmarshal (const char *types, va_list args,
+                   void (*) (uint8_t, void *aux), void *aux);
+enum backdoor_error
+backdoor_vunmarshal (const char *types, va_list args,
+                     bool (*) (uint8_t *, void *aux), void *aux);
+
+#endif /* backdoor.h */