summaryrefslogtreecommitdiff
path: root/kernel/ramdisk.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/ramdisk.c')
-rw-r--r--kernel/ramdisk.c45
1 files changed, 45 insertions, 0 deletions
diff --git a/kernel/ramdisk.c b/kernel/ramdisk.c
new file mode 100644
index 0000000..9901294
--- /dev/null
+++ b/kernel/ramdisk.c
@@ -0,0 +1,45 @@
+//
+// ramdisk that uses the disk image loaded by qemu -rdinit fs.img
+//
+
+#include "types.h"
+#include "riscv.h"
+#include "defs.h"
+#include "param.h"
+#include "memlayout.h"
+#include "spinlock.h"
+#include "sleeplock.h"
+#include "fs.h"
+#include "buf.h"
+
+void
+ramdiskinit(void)
+{
+}
+
+// If B_DIRTY is set, write buf to disk, clear B_DIRTY, set B_VALID.
+// Else if B_VALID is not set, read buf from disk, set B_VALID.
+void
+ramdiskrw(struct buf *b)
+{
+ if(!holdingsleep(&b->lock))
+ panic("ramdiskrw: buf not locked");
+ if((b->flags & (B_VALID|B_DIRTY)) == B_VALID)
+ panic("ramdiskrw: nothing to do");
+
+ if(b->blockno >= FSSIZE)
+ panic("ramdiskrw: blockno too big");
+
+ uint64 diskaddr = b->blockno * BSIZE;
+ char *addr = (char *)RAMDISK + diskaddr;
+
+ if(b->flags & B_DIRTY){
+ // write
+ memmove(addr, b->data, BSIZE);
+ b->flags &= ~B_DIRTY;
+ } else {
+ // read
+ memmove(b->data, addr, BSIZE);
+ b->flags |= B_VALID;
+ }
+}