From 8256dc4ff8f7c0a1f76c2d3a601b92d67aa8acfe Mon Sep 17 00:00:00 2001 From: Ben Pfaff Date: Tue, 17 Aug 2004 03:06:47 +0000 Subject: [PATCH] Initial filesystem stub code. --- src/Makefile.inc | 36 +++--- src/filesys/Makefile | 3 + src/filesys/build/Makefile | 8 ++ src/filesys/file.c | 51 +++++++++ src/filesys/file.h | 16 +++ src/filesys/filesys-stub.c | 38 +++++++ src/filesys/filesys-stub.h | 7 ++ src/filesys/filesys.c | 37 +++++++ src/filesys/filesys.h | 11 ++ src/lib/backdoor.c | 218 +++++++++++++++++++++++++++++++++++++ src/lib/backdoor.h | 26 +++++ 11 files changed, 438 insertions(+), 13 deletions(-) create mode 100644 src/filesys/Makefile create mode 100644 src/filesys/build/Makefile create mode 100644 src/filesys/file.c create mode 100644 src/filesys/file.h create mode 100644 src/filesys/filesys-stub.c create mode 100644 src/filesys/filesys-stub.h create mode 100644 src/filesys/filesys.c create mode 100644 src/filesys/filesys.h create mode 100644 src/lib/backdoor.c create mode 100644 src/lib/backdoor.h diff --git a/src/Makefile.inc b/src/Makefile.inc index 20e96d7..338bb25 100644 --- a/src/Makefile.inc +++ b/src/Makefile.inc @@ -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 index 0000000..495615d --- /dev/null +++ b/src/filesys/Makefile @@ -0,0 +1,3 @@ +all: +%: + $(MAKE) -C build $@ diff --git a/src/filesys/build/Makefile b/src/filesys/build/Makefile new file mode 100644 index 0000000..281de9c --- /dev/null +++ b/src/filesys/build/Makefile @@ -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 index 0000000..b2a4942 --- /dev/null +++ b/src/filesys/file.c @@ -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 index 0000000..689aa6d --- /dev/null +++ b/src/filesys/file.h @@ -0,0 +1,16 @@ +#ifndef HEADER_FILE_H +#define HEADER_FILE_H 1 + +#include +#include + +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 index 0000000..23d133b --- /dev/null +++ b/src/filesys/filesys-stub.c @@ -0,0 +1,38 @@ +#include "filesys-stub.h" +#include +#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 index 0000000..1bc6c59 --- /dev/null +++ b/src/filesys/filesys-stub.h @@ -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 index 0000000..6b7710a --- /dev/null +++ b/src/filesys/filesys.c @@ -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 index 0000000..6f1e387 --- /dev/null +++ b/src/filesys/filesys.h @@ -0,0 +1,11 @@ +#ifndef HEADER_FILESYS_H +#define HEADER_FILESYS_H 1 + +#include + +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 index 0000000..ac90f3c --- /dev/null +++ b/src/lib/backdoor.c @@ -0,0 +1,218 @@ +#include "backdoor.h" +#include +#include +#include + +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 index 0000000..8205aa3 --- /dev/null +++ b/src/lib/backdoor.h @@ -0,0 +1,26 @@ +#ifndef HEADER_BACKDOOR_H +#define HEADER_BACKDOOR_H 1 + +#include +#include +#include + +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 */ -- 2.30.2