summaryrefslogtreecommitdiff
path: root/kernel
diff options
context:
space:
mode:
authorFreya Murphy <freya@freyacat.org>2025-04-21 11:41:34 -0400
committerFreya Murphy <freya@freyacat.org>2025-04-21 11:41:34 -0400
commit2ee0e24dfd5319f128ed49b4f47679b7c13b21bf (patch)
treed250af94c434acd54180a1b529b0407d8013890e /kernel
parentMerge branch 'main' of github.com:kenshineto/kern (diff)
downloadcomus-2ee0e24dfd5319f128ed49b4f47679b7c13b21bf.tar.gz
comus-2ee0e24dfd5319f128ed49b4f47679b7c13b21bf.tar.bz2
comus-2ee0e24dfd5319f128ed49b4f47679b7c13b21bf.zip
fs read/write functions, initrd
Diffstat (limited to 'kernel')
-rw-r--r--kernel/entry.S6
-rw-r--r--kernel/fs/fs.c158
-rw-r--r--kernel/include/comus/drivers/ata.h2
-rw-r--r--kernel/include/comus/fs.h31
-rw-r--r--kernel/include/comus/limits.h4
-rw-r--r--kernel/include/comus/mboot.h5
-rw-r--r--kernel/mboot/module.c24
7 files changed, 202 insertions, 28 deletions
diff --git a/kernel/entry.S b/kernel/entry.S
index e1b4767..aa4c38d 100644
--- a/kernel/entry.S
+++ b/kernel/entry.S
@@ -26,6 +26,7 @@ mb_start:
.short 1
.long 36
.long 1 # cmdline
+ .long 3 # module
.long 6 # mmap
.long 9 # elf section
.long 12 # efi64
@@ -46,6 +47,11 @@ mb_start:
.long 720 # width
.long 480 # height
.long 32 # bpp
+ # module align
+ .align 8
+ .short 6
+ .short 0
+ .long 8
# efi boot services
.align 8
.short 7
diff --git a/kernel/fs/fs.c b/kernel/fs/fs.c
index 4682e41..4b6bc5d 100644
--- a/kernel/fs/fs.c
+++ b/kernel/fs/fs.c
@@ -1,18 +1,49 @@
#include <lib.h>
#include <comus/fs.h>
+#include <comus/mboot.h>
-struct disk fs_disks[MAX_DISKS];
-struct file_system fs_loaded_file_systems[MAX_DISKS];
+struct disk fs_disks[N_DISKS];
+struct file_system fs_loaded_file_systems[N_DISKS];
void fs_init(void)
{
+ size_t idx = 0;
+
// zero structures
memsetv(fs_disks, 0, sizeof(fs_disks));
memsetv(fs_loaded_file_systems, 0, sizeof(fs_loaded_file_systems));
- // TODO: go though ide and/or sata drivers to load all disks into `fs_disks` structures
+ // check for initrd
+ size_t rd_len;
+ void *rd = mboot_get_initrd(&rd_len);
+ if (rd != NULL) {
+ assert(idx < N_DISKS, "Too many disks, limit is: %d\n", N_DISKS);
+ fs_disks[idx] = (struct disk) {
+ .present = 1,
+ .id = idx,
+ .type = DISK_TYPE_RAMDISK,
+ .rd.start = rd,
+ .rd.len = rd_len,
+ };
+ idx++;
+ }
+
+ // check for ide/ata devices
+ struct ide_devicelist ide_list = ide_devices_enumerate();
+ for (size_t i = 0; i < ide_list.num_devices; i++) {
+ assert(idx < N_DISKS, "Too many disks, limit is: %d\n", N_DISKS);
+ fs_disks[idx] = (struct disk) {
+ .present = 1,
+ .id = idx,
+ .type = DISK_TYPE_ATA,
+ .ide = ide_list.devices[i],
+ };
+ idx++;
+ }
+
+ INFO("loaded %zu disks\n", idx);
- // TODO: go though each disk and attempt to load a file system
+ // TODO: load filesystems on disks
}
struct disk *fs_get_root_disk(void)
@@ -20,7 +51,7 @@ struct disk *fs_get_root_disk(void)
// NOTE: currently im just getting the first disk
// found, is this fine?
- for (int i = 0; i < MAX_DISKS; i++) {
+ for (int i = 0; i < N_DISKS; i++) {
struct disk *disk = &fs_disks[i];
if (disk->present)
return disk;
@@ -34,7 +65,7 @@ struct file_system *fs_get_root_file_system(void)
// NOTE: currently im just getting the first file system
// found, is this fine?
- for (int i = 0; i < MAX_DISKS; i++) {
+ for (int i = 0; i < N_DISKS; i++) {
struct file_system *fs = &fs_loaded_file_systems[i];
if (fs->present)
return fs;
@@ -61,22 +92,117 @@ int fs_find_file_rel(struct file *rel, char *rel_path, struct file *res)
panic("fs_find_file_rel NOT YET IMPLEMENTED");
}
+static int disk_read_rd(struct disk *disk, size_t offset, size_t len, uint8_t *buffer)
+{
+ if (offset + len >= disk->rd.len) {
+ WARN("attempted to read past length of ramdisk");
+ return 1;
+ }
+
+ memcpy(buffer, disk->rd.start + offset, len);
+ return 0;
+}
+
+static int disk_read_ata(struct disk *disk, size_t offset, size_t len, uint8_t *buffer)
+{
+ static size_t atabuf_len = 0;
+ static uint16_t *atabuf = NULL;
+
+ uint32_t numsects = (len + ATA_SECT_SIZE - 1) / ATA_SECT_SIZE;
+ uint32_t err = offset % ATA_SECT_SIZE;
+ int ret = 0;
+
+ if (atabuf == NULL || atabuf_len < numsects*ATA_SECT_SIZE) {
+ if ((atabuf = krealloc(atabuf, numsects*ATA_SECT_SIZE)) == NULL)
+ return 1;
+ atabuf_len = numsects*ATA_SECT_SIZE;
+ }
+
+ // read sectors
+ if ((ret = ide_device_read_sectors(disk->ide, numsects, offset / ATA_SECT_SIZE, atabuf)))
+ return 1;
+
+ // copy over to buffer
+ memcpy(buffer, atabuf + err, len);
+
+ return ret;
+}
+
+
int disk_read(struct disk *disk, size_t offset, size_t len, uint8_t *buffer)
{
- (void)disk;
- (void)offset;
- (void)len;
- (void)buffer;
+ int ret = 0;
- panic("disk_read NOT YET IMPLEMENTED");
+ switch(disk->type) {
+ case DISK_TYPE_RAMDISK:
+ ret = disk_read_rd(disk, offset, len, buffer);
+ break;
+ case DISK_TYPE_ATA:
+ ret = disk_read_ata(disk, offset, len, buffer);
+ break;
+ default:
+ ERROR("attempted to read from disk with invalid type: %d\n", disk->type);
+ ret = 1;
+ }
+
+ return ret;
+}
+
+static int disk_write_rd(struct disk *disk, size_t offset, size_t len, uint8_t *buffer)
+{
+ if (offset + len >= disk->rd.len) {
+ WARN("attempted to write past length of ramdisk");
+ return 1;
+ }
+
+ memcpy(disk->rd.start + offset, buffer, len);
+ return 0;
+}
+
+static int disk_write_ata(struct disk *disk, size_t offset, size_t len, uint8_t *buffer)
+{
+ static size_t atabuf_len = 0;
+ static uint16_t *atabuf = NULL;
+
+ uint32_t numsects = (len + ATA_SECT_SIZE - 1) / ATA_SECT_SIZE;
+ uint32_t err = offset % ATA_SECT_SIZE;
+ int ret = 0;
+
+ if (atabuf == NULL || atabuf_len < numsects*ATA_SECT_SIZE) {
+ if ((atabuf = krealloc(atabuf, numsects*ATA_SECT_SIZE)) == NULL)
+ return 1;
+ atabuf_len = numsects*ATA_SECT_SIZE;
+ }
+
+ // read sectors what will be overwritten
+ if ((ret = ide_device_read_sectors(disk->ide, numsects, offset / ATA_SECT_SIZE, atabuf)))
+ return 1;
+
+ // copy custom data over
+ memcpy(atabuf + err, buffer, len);
+
+ // write back sectors
+ if ((ret = ide_device_write_sectors(disk->ide, numsects, offset / ATA_SECT_SIZE, atabuf)))
+ return 1;
+
+ return ret;
}
int disk_write(struct disk *disk, size_t offset, size_t len, uint8_t *buffer)
{
- (void)disk;
- (void)offset;
- (void)len;
- (void)buffer;
+ int ret = 0;
+
+ switch(disk->type) {
+ case DISK_TYPE_RAMDISK:
+ ret = disk_write_rd(disk, offset, len, buffer);
+ break;
+ case DISK_TYPE_ATA:
+ ret = disk_write_ata(disk, offset, len, buffer);
+ break;
+ default:
+ ERROR("attempted to write to disk with invalid type: %d\n", disk->type);
+ ret = 1;
+ }
- panic("disk_write NOT YET IMPLEMENTED");
+ return ret;
}
diff --git a/kernel/include/comus/drivers/ata.h b/kernel/include/comus/drivers/ata.h
index 66b3ba5..2f35e03 100644
--- a/kernel/include/comus/drivers/ata.h
+++ b/kernel/include/comus/drivers/ata.h
@@ -10,6 +10,8 @@
#ifndef ATA_H_
#define ATA_H_
+#define ATA_SECT_SIZE 512
+
#include <stdint.h>
#include <stdbool.h>
diff --git a/kernel/include/comus/fs.h b/kernel/include/comus/fs.h
index fe335ca..048c7c5 100644
--- a/kernel/include/comus/fs.h
+++ b/kernel/include/comus/fs.h
@@ -11,10 +11,13 @@
#include <stdint.h>
#include <stddef.h>
+#include <comus/limits.h>
+#include <comus/drivers/ata.h>
-// FIXME: aaaa
-#define MAX_DISKS 8
-#define MAX_FILE_NAME_LEN 256
+enum disk_type {
+ DISK_TYPE_ATA,
+ DISK_TYPE_RAMDISK,
+};
struct disk {
/// set to 1 in array to state that fs is defined
@@ -23,12 +26,16 @@ struct disk {
/// index into disks array
/// system use only
int id;
- /// TODO: pci? inb/outb?
- /// we need a structure to access disks and how to define them
- /// IDE / SATA / .... ???
- /// we should probable create ide_disk, or sata_disk, and so on
- /// then convert this part to a union with a tag specifier
- /// we then need drivers for ide and/or sata, ide is easier
+ /// disk type
+ enum disk_type type;
+ /// internal disk device
+ union {
+ struct {
+ char *start;
+ size_t len;
+ } rd;
+ ide_device_t ide;
+ };
};
/**
@@ -67,7 +74,7 @@ enum file_type {
struct file {
/// name of the file
- char name[MAX_FILE_NAME_LEN];
+ char name[N_FILE_NAME];
/// parent directory of the file
struct file_s *parent;
/// type of the file
@@ -159,10 +166,10 @@ struct file_system {
};
// list of all disks on the system
-extern struct disk fs_disks[MAX_DISKS];
+extern struct disk fs_disks[N_DISKS];
// list of all loaded file systems for each disk
-extern struct file_system fs_loaded_file_systems[MAX_DISKS];
+extern struct file_system fs_loaded_file_systems[N_DISKS];
/**
* Initalize file system structures
diff --git a/kernel/include/comus/limits.h b/kernel/include/comus/limits.h
index b6c596b..675df47 100644
--- a/kernel/include/comus/limits.h
+++ b/kernel/include/comus/limits.h
@@ -18,6 +18,10 @@
/// max memory entires
#define N_MMAP_ENTRY 256
+/// max fs limits
+#define N_FILE_NAME 256
+#define N_DISKS 8
+
/// length of terminal buffer
#define TERM_MAX_WIDTH 1920
#define TERM_MAX_HEIGHT 1080
diff --git a/kernel/include/comus/mboot.h b/kernel/include/comus/mboot.h
index 036cc40..aba3e4e 100644
--- a/kernel/include/comus/mboot.h
+++ b/kernel/include/comus/mboot.h
@@ -42,4 +42,9 @@ EFI_SYSTEM_TABLE *mboot_get_efi_st(void);
*/
EFI_HANDLE mboot_get_efi_hdl(void);
+/**
+ * Returns the pointer to the loaded init ram disk with size given by len
+ */
+void *mboot_get_initrd(size_t *len);
+
#endif /* mboot.h */
diff --git a/kernel/mboot/module.c b/kernel/mboot/module.c
new file mode 100644
index 0000000..7a64f2e
--- /dev/null
+++ b/kernel/mboot/module.c
@@ -0,0 +1,24 @@
+#include <comus/mboot.h>
+
+#include "mboot.h"
+
+#define MULTIBOOT_TAG_TYPE_MODULE 3
+
+struct multiboot_tag_module {
+ uint32_t type;
+ uint32_t size;
+ uint32_t mod_start;
+ uint32_t mod_end;
+ char cmdline[];
+};
+
+void *mboot_get_initrd(size_t *len)
+{
+ void *tag = locate_mboot_table(MULTIBOOT_TAG_TYPE_MODULE);
+ if (tag == NULL)
+ return NULL;
+
+ struct multiboot_tag_module *mod = (struct multiboot_tag_module *)tag;
+ *len = mod->mod_end - mod->mod_start;
+ return (void*) (uintptr_t) mod->mod_start;
+}