aboutsummaryrefslogtreecommitdiff
path: root/kernel/drivers
diff options
context:
space:
mode:
authorMarvin Borner2021-04-30 15:03:27 +0200
committerMarvin Borner2021-04-30 15:03:27 +0200
commit350748137b62e2aa15c62c53ebf4d30816e441f4 (patch)
treea4c1b1c443c1f0de4bd74336a9ceed9376ce694a /kernel/drivers
parent3a3d50d7eb0f4fdbb9beaf16bacfa98689cc448c (diff)
Added MBR driver and better disk creation
Diffstat (limited to 'kernel/drivers')
-rw-r--r--kernel/drivers/ide.c26
-rw-r--r--kernel/drivers/mbr.c67
2 files changed, 74 insertions, 19 deletions
diff --git a/kernel/drivers/ide.c b/kernel/drivers/ide.c
index 68e797f..bde72b7 100644
--- a/kernel/drivers/ide.c
+++ b/kernel/drivers/ide.c
@@ -5,6 +5,7 @@
#include <def.h>
#include <fs.h>
#include <ide.h>
+#include <mbr.h>
#include <mem.h>
#include <pci.h>
#include <print.h>
@@ -128,30 +129,17 @@ CLEAR static void ata_probe(void)
if (!ide_find(bus, drive))
continue;
- struct vfs_dev *dev = zalloc(sizeof(*dev));
- struct ata_data *data = malloc(sizeof(*data));
+ struct ata_data *data = zalloc(sizeof(*data));
data->drive = (bus << 1) | drive;
- char *str = zalloc(8);
- strlcpy(str, "hd", 8);
- str[2] = 'a' + i;
-
- dev->name = str;
+ struct vfs_dev *dev = zalloc(sizeof(*dev));
+ strlcpy(dev->name, "hd", 3);
+ dev->name[2] = 'a' + i;
dev->type = DEV_BLOCK;
dev->read = ata_read;
- vfs_add_dev(dev);
- if (vfs_mounted(dev, "/"))
- continue;
-
- // TODO: Check if ext2 first
- struct vfs *vfs = zalloc(sizeof(*vfs));
- vfs->type = VFS_EXT2;
- vfs->read = ext2_read;
- vfs->stat = ext2_stat;
- vfs->perm = ext2_perm;
- dev->vfs = vfs;
dev->data = data;
- vfs_mount(dev, "/");
+ vfs_add_dev(dev);
+ vfs_load(dev);
}
}
diff --git a/kernel/drivers/mbr.c b/kernel/drivers/mbr.c
new file mode 100644
index 0000000..c85061d
--- /dev/null
+++ b/kernel/drivers/mbr.c
@@ -0,0 +1,67 @@
+// MIT License, Copyright (c) 2021 Marvin Borner
+
+#include <def.h>
+#include <fs.h>
+#include <ide.h>
+#include <mbr.h>
+#include <mem.h>
+#include <print.h>
+#include <str.h>
+
+struct mbr_data {
+ struct mbr_entry mbr;
+ struct vfs_dev *dev;
+};
+
+static res mbr_read(void *buf, u32 lba, u32 sector_count, struct vfs_dev *part)
+{
+ struct mbr_data *data = part->data;
+ if (!data || !data->dev || !data->dev->read)
+ return -EINVAL;
+
+ return data->dev->read(buf, data->mbr.start + lba, sector_count, data->dev);
+}
+
+static res mbr_write(const void *buf, u32 lba, u32 sector_count, struct vfs_dev *part)
+{
+ struct mbr_data *data = part->data;
+ if (!data || !data->dev || !data->dev->write)
+ return -EINVAL;
+
+ return data->dev->write(buf, data->mbr.start + lba, sector_count, data->dev);
+}
+
+CLEAR u8 mbr_load(struct vfs_dev *dev)
+{
+ struct mbr mbr = { 0 };
+ dev->read(&mbr, 0, 1, dev); // Read first sector
+
+ if (mbr.magic != 0xaa55)
+ return 0;
+
+ for (u8 i = 0; i < 4; i++) {
+ struct mbr_entry *entry = &mbr.entries[i];
+ if (!entry->type || !entry->size)
+ continue;
+
+ struct mbr_data *data = zalloc(sizeof(*data));
+ memcpy(&data->mbr, entry, sizeof(*entry));
+ data->dev = dev;
+
+ struct vfs_dev *part = zalloc(sizeof(*part));
+ part->data = data;
+ strlcpy(part->name, dev->name, 4);
+ part->name[3] = '0' + i;
+ part->type = DEV_BLOCK;
+ part->read = mbr_read;
+ part->write = mbr_write;
+
+ /* printf("%s [start: %d; size: %dMiB; type: %d]\n", part->name, entry->start, */
+ /* (entry->size * SECTOR_SIZE) >> 20, entry->type); */
+
+ vfs_add_dev(part);
+ vfs_load(part);
+ }
+
+ return 1;
+}