fat_io_lib finally works, implement virtual partition devices, manage devices via string keys
All checks were successful
Build documentation / build-and-deploy (push) Successful in 3m35s

This commit is contained in:
2026-03-01 00:00:27 +01:00
parent baa13fb695
commit 0533c2705d
37 changed files with 619 additions and 139 deletions

View File

@@ -302,6 +302,9 @@ static void ls (const char* path_string) {
} }
size_t entries = desc.size; size_t entries = desc.size;
printf ("total entries: %zu\n", entries);
printf ("\n");
for (size_t entry_num = 0; entry_num < entries; entry_num++) { for (size_t entry_num = 0; entry_num < entries; entry_num++) {
read_dir_entry (path, &entry, entry_num); read_dir_entry (path, &entry, entry_num);
describe (entry.path, &desc); describe (entry.path, &desc);

19
include/devices.h Normal file
View File

@@ -0,0 +1,19 @@
#ifndef _DEVICES_H
#define _DEVICES_H
/* terminal device */
#define TERMINAL_PUTSTR 0
/* keyboard device */
#define KB_READ_KEY 0
/* drive devices */
#define XDRV_TYPE_RAMDRV 0
#define XDRV_TYPE_PARTDRV 1
#define XDRV_GET_SIZE 0
#define XDRV_GET_SECTOR_SIZE 1
#define XDRV_GET_DEVICE_TYPE 2
#define XDRV_READ 3
#define XDRV_WRITE 4
#endif // _DEVICES_H

View File

@@ -1,8 +0,0 @@
#ifndef _M_KB_DEVICE_H
#define _M_KB_DEVICE_H
#define KB_DEVICE 1
#define KB_READ_KEY 0
#endif // _M_KB_DEVICE_H

View File

@@ -1,6 +0,0 @@
#ifndef _M_RAMDISK_DEVICE_H
#define _M_RAMDISK_DEVICE_H
#define RAMDISK_DEVICE 100
#endif // _M_RAMDISK_DEVICE_H

View File

@@ -18,5 +18,8 @@
#define ST_TRY_AGAIN 14 #define ST_TRY_AGAIN 14
#define ST_NOT_DIR 15 #define ST_NOT_DIR 15
#define ST_DIR_NO_ENTRIES 16 #define ST_DIR_NO_ENTRIES 16
#define ST_FORMAT_ERROR 17
#define ST_NOT_DRV 18
#define ST_PARTITION_ERROR 19
#endif // _M_STATUS_H #endif // _M_STATUS_H

View File

@@ -1,8 +0,0 @@
#ifndef _M_TERMINAL_DEVICE_H
#define _M_TERMINAL_DEVICE_H
#define TERMINAL_DEVICE 0
#define TERMINAL_PUTSTR 0
#endif // _M_TERMINAL_DEVICE_H

View File

@@ -1,11 +0,0 @@
#ifndef _M_XDRV_DEVICE_H
#define _M_XDRV_DEVICE_H
#define XDRV_TYPE_RAMDRV 0
#define XDRV_GET_SIZE 0
#define XDRV_GET_SECTOR_SIZE 1
#define XDRV_GET_DEVICE_TYPE 2
#define XDRV_READ 3
#endif // _M_XDRV_DEVICE_H

View File

@@ -20,7 +20,7 @@ void receiver (void) {
} }
void app_main (void) { void app_main (void) {
int ce_pid = exec ("ramdisk", "ce"); int ce_pid = exec ("RD", "ce");
ce_pgid = get_procgroup (ce_pid); ce_pgid = get_procgroup (ce_pid);
process_spawn (&receiver, NULL); process_spawn (&receiver, NULL);

View File

@@ -122,7 +122,6 @@ void ioapic_route_irq (uint32_t vec, uint32_t irq, uint64_t flags, uint64_t lapi
uint32_t gsi = found_override ? override->gsi : irq; uint32_t gsi = found_override ? override->gsi : irq;
ioapic = ioapic_find (gsi); ioapic = ioapic_find (gsi);
DEBUG ("%p\n", ioapic);
if (ioapic == NULL) if (ioapic == NULL)
return; return;

View File

@@ -8,6 +8,8 @@
#include <amd64/msr.h> #include <amd64/msr.h>
#include <aux/compiler.h> #include <aux/compiler.h>
#include <device/device.h> #include <device/device.h>
#include <device/partitions.h>
#include <devices.h>
#include <fs/vfs.h> #include <fs/vfs.h>
#include <irq/irq.h> #include <irq/irq.h>
#include <libk/std.h> #include <libk/std.h>
@@ -17,7 +19,6 @@
#include <mm/pmm.h> #include <mm/pmm.h>
#include <proc/proc.h> #include <proc/proc.h>
#include <proc/reschedule.h> #include <proc/reschedule.h>
#include <ramdisk_device.h>
#include <sys/debug.h> #include <sys/debug.h>
#include <sys/mm.h> #include <sys/mm.h>
#include <sys/smp.h> #include <sys/smp.h>
@@ -55,14 +56,19 @@ void bootmain (void) {
devices_init (); devices_init ();
vfs_init (); vfs_init ();
struct device* ramdisk_device = device_find (RAMDISK_DEVICE); struct reschedule_ctx rctx = {.cpu = NULL, .reschedule = false};
struct reschedule_ctx rctx = {.cpu = thiscpu, .reschedule = false};
int ret = vfs_create_volume ("ramdisk", VFS_TARFS, ramdisk_device, NULL, &rctx);
if (ret < 0) { struct device* ramdisk = device_find ("RD");
DEBUG ("could not mount ramdisk! (%d)\n", ret); vfs_create_volume ("RD", VFS_TARFS, ramdisk);
spin ();
} struct device* vdisk = device_find ("VD");
device_probe_partitions (vdisk);
struct device* vdp0 = device_find ("VDp0");
vfs_create_volume ("VD", VFS_FAT32, vdp0);
vfs_volume_open (VFS_KERNEL, "VD", &rctx);
vfs_format (VFS_KERNEL, "VD");
vfs_volume_close (VFS_KERNEL, "VD", &rctx);
proc_pid_alloc_init (); proc_pid_alloc_init ();
procgroup_pgid_alloc_init (); procgroup_pgid_alloc_init ();

View File

@@ -177,6 +177,9 @@ void intr_handler (void* stack_ptr) {
struct saved_regs* regs = stack_ptr; struct saved_regs* regs = stack_ptr;
if (regs->trap <= 31) {
intr_exception (regs);
} else {
spin_lock (&thiscpu->lock); spin_lock (&thiscpu->lock);
struct proc* proc_current = thiscpu->proc_current; struct proc* proc_current = thiscpu->proc_current;
spin_lock (&proc_current->lock); spin_lock (&proc_current->lock);
@@ -186,9 +189,6 @@ void intr_handler (void* stack_ptr) {
spin_unlock (&proc_current->lock); spin_unlock (&proc_current->lock);
spin_unlock (&thiscpu->lock); spin_unlock (&thiscpu->lock);
if (regs->trap <= 31) {
intr_exception (regs);
} else {
lapic_eoi (); lapic_eoi ();
struct irq* irq = irq_find (regs->trap); struct irq* irq = irq_find (regs->trap);

View File

@@ -102,7 +102,7 @@ static void smp_bootstrap (struct limine_mp_info* mp_info) {
struct reschedule_ctx rctx = {.cpu = NULL, .reschedule = false}; struct reschedule_ctx rctx = {.cpu = NULL, .reschedule = false};
struct proc* spin_proc = proc_from_file (VFS_KERNEL, "ramdisk", "/spin", &rctx); struct proc* spin_proc = proc_from_file (VFS_KERNEL, "RD", "/spin", &rctx);
proc_register (spin_proc, thiscpu, NULL); proc_register (spin_proc, thiscpu, NULL);
spin_lock (&spin_proc->cpu->lock); spin_lock (&spin_proc->cpu->lock);

View File

@@ -1,28 +1,51 @@
#include <device/device.h> #include <device/device.h>
#include <device/dos.h>
#include <device/partdrv.h>
#include <device/partitions.h>
#include <device/ramdrv.h> #include <device/ramdrv.h>
#include <device/terminal.h> #include <device/terminal.h>
#include <kb_device.h> #include <devices.h>
#include <id/id_alloc.h>
#include <libk/align.h> #include <libk/align.h>
#include <libk/fieldlengthof.h> #include <libk/fieldlengthof.h>
#include <libk/hash.h>
#include <libk/rbtree.h> #include <libk/rbtree.h>
#include <libk/std.h> #include <libk/std.h>
#include <libk/string.h> #include <libk/string.h>
#include <limine/requests.h> #include <limine/requests.h>
#include <mm/liballoc.h> #include <mm/liballoc.h>
#include <ramdisk_device.h> #include <status.h>
#include <sync/spin_lock.h> #include <sync/spin_lock.h>
#include <sys/debug.h> #include <sys/debug.h>
#include <terminal_device.h>
#include <xdrv_device.h>
#if defined(__x86_64__) #if defined(__x86_64__)
#include <device/ps2_kb.h> #include <device/ps2_kb.h>
#endif #endif
static struct rb_node_link* device_tree = NULL; struct device_table {
static spin_lock_t device_tree_lock; struct hash_node_link* device_buckets[1024];
spin_lock_t lock;
};
struct device* device_create (int id, device_op_func_t* ops, size_t ops_len, static struct device_table device_table;
struct device* device_find (const char* key) {
struct hash_node_link* found_link = NULL;
size_t key_len = strlen_null (key);
uint32_t hash = hash_fnv32 (key, key_len);
spin_lock (&device_table.lock);
hash_find (&device_table, key, key_len, hash, lengthof (device_table.device_buckets),
device_buckets, struct device, device_table_link, key, found_link);
spin_unlock (&device_table.lock);
if (found_link == NULL)
return NULL;
return hash_entry (found_link, struct device, device_table_link);
}
struct device* device_create (const char* key, device_op_func_t* ops, size_t ops_len,
device_init_func_t init, device_fini_func_t fini, void* arg) { device_init_func_t init, device_fini_func_t fini, void* arg) {
if (ops_len >= fieldlengthof (struct device, ops)) if (ops_len >= fieldlengthof (struct device, ops))
return NULL; return NULL;
@@ -34,9 +57,9 @@ struct device* device_create (int id, device_op_func_t* ops, size_t ops_len,
memset (device, 0, sizeof (*device)); memset (device, 0, sizeof (*device));
device->id = id;
device->init = init; device->init = init;
device->fini = fini; device->fini = fini;
memcpy (device->key, key, strlen_null (key));
if (ops != NULL) if (ops != NULL)
memcpy (device->ops, ops, ops_len * sizeof (device_op_func_t)); memcpy (device->ops, ops, ops_len * sizeof (device_op_func_t));
@@ -46,32 +69,16 @@ struct device* device_create (int id, device_op_func_t* ops, size_t ops_len,
return NULL; return NULL;
} }
spin_lock (&device_tree_lock); uint32_t device_hash = hash_fnv32 (device->key, strlen_null (device->key));
rbtree_insert (struct device, &device_tree, &device->device_tree_link, device_tree_link, id);
spin_unlock (&device_tree_lock);
return device; spin_lock (&device_table.lock);
}
void device_delete (struct device* device) { hash_insert (&device_table, &device->device_table_link, device_hash,
spin_lock (&device_tree_lock); lengthof (device_table.device_buckets), device_buckets);
spin_lock (&device->lock);
rbtree_delete (&device_tree, &device->device_tree_link); spin_unlock (&device_table.lock);
spin_unlock (&device->lock); DEBUG ("Created device %s\n", device->key);
spin_unlock (&device_tree_lock);
device->fini (device);
free (device);
}
struct device* device_find (int id) {
struct device* device = NULL;
spin_lock (&device_tree_lock);
rbtree_find (struct device, &device_tree, id, device, device_tree_link, id);
spin_unlock (&device_tree_lock);
return device; return device;
} }
@@ -80,7 +87,7 @@ void terminal_device_init (void) {
device_op_func_t ops[] = { device_op_func_t ops[] = {
[TERMINAL_PUTSTR] = &terminal_putstr, [TERMINAL_PUTSTR] = &terminal_putstr,
}; };
device_create (TERMINAL_DEVICE, ops, lengthof (ops), &terminal_init, &terminal_fini, NULL); device_create ("TERMINAL", ops, lengthof (ops), &terminal_init, &terminal_fini, NULL);
} }
void ramdisk_device_init (void) { void ramdisk_device_init (void) {
@@ -89,6 +96,7 @@ void ramdisk_device_init (void) {
[XDRV_GET_SECTOR_SIZE] = &ramdrv_get_sector_size, [XDRV_GET_SECTOR_SIZE] = &ramdrv_get_sector_size,
[XDRV_GET_DEVICE_TYPE] = &ramdrv_get_device_type, [XDRV_GET_DEVICE_TYPE] = &ramdrv_get_device_type,
[XDRV_READ] = &ramdrv_read, [XDRV_READ] = &ramdrv_read,
[XDRV_WRITE] = &ramdrv_write,
}; };
struct limine_module_response* module = limine_module_request.response; struct limine_module_response* module = limine_module_request.response;
@@ -105,10 +113,43 @@ void ramdisk_device_init (void) {
struct ramdrv_init init = { struct ramdrv_init init = {
.total_size = file->size, .total_size = file->size,
.sector_size = 1024, .sector_size = 512,
.buffer = file->address, .buffer = file->address,
}; };
device_create (RAMDISK_DEVICE, ops, lengthof (ops), &ramdrv_init, &ramdrv_fini, &init); device_create ("RD", ops, lengthof (ops), &ramdrv_init, &ramdrv_fini, &init);
}
void vdisk_device_init (void) {
device_op_func_t ops[] = {
[XDRV_GET_SIZE] = &ramdrv_get_size,
[XDRV_GET_SECTOR_SIZE] = &ramdrv_get_sector_size,
[XDRV_GET_DEVICE_TYPE] = &ramdrv_get_device_type,
[XDRV_READ] = &ramdrv_read,
[XDRV_WRITE] = &ramdrv_write,
};
struct ramdrv_init init = {
.total_size = 1024 * 1024 * 50,
.sector_size = 512,
};
struct dos_mbr mbr;
memset (&mbr, 0, sizeof (mbr));
mbr.valid_sign[0] = 0x55;
mbr.valid_sign[1] = 0xAA;
mbr.ptes[0].start_lba = 0;
mbr.ptes[0].sector_count = div_align_up (init.total_size, init.sector_size);
struct device* vdisk =
device_create ("VD", ops, lengthof (ops), &ramdrv_init, &ramdrv_fini, &init);
size_t sector = 0;
size_t sector_count = 1;
spin_lock (&vdisk->lock);
device_op (vdisk, XDRV_WRITE, NULL, NULL, &sector, &sector_count, &mbr);
spin_unlock (&vdisk->lock);
} }
#if defined(__x86_64__) #if defined(__x86_64__)
@@ -116,13 +157,16 @@ void ps2kb_device_init (void) {
device_op_func_t ops[] = { device_op_func_t ops[] = {
[KB_READ_KEY] = &ps2kb_read_key, [KB_READ_KEY] = &ps2kb_read_key,
}; };
device_create (KB_DEVICE, ops, lengthof (ops), &ps2kb_init, &ps2kb_fini, NULL); device_create ("KB", ops, lengthof (ops), &ps2kb_init, &ps2kb_fini, NULL);
} }
#endif #endif
void devices_init (void) { void devices_init (void) {
memset (&device_table, 0, sizeof (device_table));
terminal_device_init (); terminal_device_init ();
ramdisk_device_init (); ramdisk_device_init ();
vdisk_device_init ();
#if defined(__x86_64__) #if defined(__x86_64__)
ps2kb_device_init (); ps2kb_device_init ();

View File

@@ -1,14 +1,16 @@
#ifndef _KERNEL_DEVICE_DEVICE_H #ifndef _KERNEL_DEVICE_DEVICE_H
#define _KERNEL_DEVICE_DEVICE_H #define _KERNEL_DEVICE_DEVICE_H
#include <libk/hash.h>
#include <libk/list.h> #include <libk/list.h>
#include <libk/rbtree.h>
#include <libk/std.h> #include <libk/std.h>
#include <proc/proc.h> #include <proc/proc.h>
#include <proc/reschedule.h> #include <proc/reschedule.h>
#include <sync/spin_lock.h> #include <sync/spin_lock.h>
#include <sys/smp.h> #include <sys/smp.h>
#define DEVICES_MAX 1024
#define device_op1(d, op, proc, rctx, a1, a2, a3, a4, ...) \ #define device_op1(d, op, proc, rctx, a1, a2, a3, a4, ...) \
(d)->ops[(op)]((d), (proc), (rctx), (void*)(a1), (void*)(a2), (void*)(a3), (void*)(a4)) (d)->ops[(op)]((d), (proc), (rctx), (void*)(a1), (void*)(a2), (void*)(a3), (void*)(a4))
@@ -24,19 +26,20 @@ typedef bool (*device_init_func_t) (struct device* device, void* arg);
typedef void (*device_fini_func_t) (struct device* device); typedef void (*device_fini_func_t) (struct device* device);
struct device { struct device {
int id; char key[0x100];
device_op_func_t ops[32]; device_op_func_t ops[32];
spin_lock_t lock; spin_lock_t lock;
struct rb_node_link device_tree_link; struct hash_node_link device_table_link;
device_init_func_t init; device_init_func_t init;
device_fini_func_t fini; device_fini_func_t fini;
void* udata; void* udata;
}; };
struct device* device_create (int id, device_op_func_t* ops, size_t ops_len, struct device* device_create (const char* key, device_op_func_t* ops, size_t ops_len,
device_init_func_t init, device_fini_func_t fini, void* arg); device_init_func_t init, device_fini_func_t fini, void* arg);
struct device* device_find (int id);
void device_delete (struct device* device); struct device* device_find (const char* key);
void devices_init (void); void devices_init (void);
#endif // _KERNEL_DEVICE_DEVICE_H #endif // _KERNEL_DEVICE_DEVICE_H

4
kernel/device/dos.h Normal file
View File

@@ -0,0 +1,4 @@
#ifndef _KERNEL_DEVICE_DOS_H
#define _KERNEL_DEVICE_DOS_H
#endif // _KERNEL_DEVICE_DOS_H

121
kernel/device/partdrv.c Normal file
View File

@@ -0,0 +1,121 @@
#include <device/device.h>
#include <device/partdrv.h>
#include <devices.h>
#include <libk/std.h>
#include <mm/liballoc.h>
#include <proc/proc.h>
#include <proc/reschedule.h>
#include <status.h>
bool partdrv_init (struct device* device, void* arg) {
struct partdrv_init* init = arg;
struct partdrv* partdrv = malloc (sizeof (*partdrv));
if (partdrv == NULL)
return false;
partdrv->start_sector = init->start_sector;
partdrv->super = init->super;
partdrv->total_size = init->total_size;
device->udata = partdrv;
return true;
}
void partdrv_fini (struct device* device) {
struct partdrv* partdrv = device->udata;
free (partdrv);
}
int partdrv_read (struct device* device, struct proc* proc, struct reschedule_ctx* rctx, void* a1,
void* a2, void* a3, void* a4) {
(void)proc, (void)rctx, (void)a4;
if (a1 == NULL || a2 == NULL || a3 == NULL)
return -ST_BAD_ADDRESS_SPACE;
struct partdrv* partdrv = device->udata;
struct device* super = partdrv->super;
size_t sector = *(size_t*)a1 + partdrv->start_sector;
size_t sector_count = *(size_t*)a2;
uint8_t* buffer = a3;
spin_lock (&super->lock);
int ret = device_op (super, XDRV_READ, NULL, NULL, &sector, &sector_count, buffer);
spin_unlock (&super->lock);
return ret;
}
int partdrv_write (struct device* device, struct proc* proc, struct reschedule_ctx* rctx, void* a1,
void* a2, void* a3, void* a4) {
(void)proc, (void)rctx, (void)a4;
if (a1 == NULL || a2 == NULL || a3 == NULL)
return -ST_BAD_ADDRESS_SPACE;
struct partdrv* partdrv = device->udata;
struct device* super = partdrv->super;
size_t sector = *(size_t*)a1 + partdrv->start_sector;
size_t sector_count = *(size_t*)a2;
uint8_t* buffer = a3;
spin_lock (&super->lock);
int ret = device_op (super, XDRV_WRITE, NULL, NULL, &sector, &sector_count, buffer);
spin_unlock (&super->lock);
return ret;
}
int partdrv_get_device_type (struct device* device, struct proc* proc, struct reschedule_ctx* rctx,
void* a1, void* a2, void* a3, void* a4) {
(void)proc, (void)rctx, (void)device, (void)a2, (void)a3, (void)a4;
if (a1 == NULL)
return -ST_BAD_ADDRESS_SPACE;
int* device_type = (int*)a1;
*device_type = XDRV_TYPE_PARTDRV;
return ST_OK;
}
int partdrv_get_sector_size (struct device* device, struct proc* proc, struct reschedule_ctx* rctx,
void* a1, void* a2, void* a3, void* a4) {
(void)proc, (void)rctx, (void)a2, (void)a3, (void)a4;
if (a1 == NULL)
return -ST_BAD_ADDRESS_SPACE;
size_t* secsize = (size_t*)a1;
struct partdrv* partdrv = device->udata;
spin_lock (&partdrv->super->lock);
device_op (partdrv->super, XDRV_GET_SECTOR_SIZE, NULL, NULL, secsize);
spin_unlock (&partdrv->super->lock);
return ST_OK;
}
int partdrv_get_size (struct device* device, struct proc* proc, struct reschedule_ctx* rctx,
void* a1, void* a2, void* a3, void* a4) {
(void)proc, (void)rctx, (void)a2, (void)a3, (void)a4;
if (a1 == NULL)
return -ST_BAD_ADDRESS_SPACE;
size_t* size = (size_t*)a1;
struct partdrv* partdrv = device->udata;
*size = partdrv->total_size;
return ST_OK;
}

41
kernel/device/partdrv.h Normal file
View File

@@ -0,0 +1,41 @@
#ifndef _KERNEL_DEVICE_PARTDRV_H
#define _KERNEL_DEVICE_PARTDRV_H
#include <libk/std.h>
#include <proc/proc.h>
#include <proc/reschedule.h>
struct device;
struct partdrv_init {
struct device* super;
size_t start_sector;
size_t total_size;
};
struct partdrv {
struct device* super;
size_t start_sector;
size_t total_size;
};
bool partdrv_init (struct device* device, void* arg);
void partdrv_fini (struct device* device);
int partdrv_read (struct device* device, struct proc* proc, struct reschedule_ctx* rctx, void* a1,
void* a2, void* a3, void* a4);
int partdrv_write (struct device* device, struct proc* proc, struct reschedule_ctx* rctx, void* a1,
void* a2, void* a3, void* a4);
int partdrv_get_device_type (struct device* device, struct proc* proc, struct reschedule_ctx* rctx,
void* a1, void* a2, void* a3, void* a4);
int partdrv_get_sector_size (struct device* device, struct proc* proc, struct reschedule_ctx* rctx,
void* a1, void* a2, void* a3, void* a4);
int partdrv_get_size (struct device* device, struct proc* proc, struct reschedule_ctx* rctx,
void* a1, void* a2, void* a3, void* a4);
#endif // _KERNEL_DEVICE_PARTDRV_H

View File

@@ -0,0 +1,65 @@
#include <device/device.h>
#include <device/partdrv.h>
#include <device/partitions.h>
#include <devices.h>
#include <libk/fieldsizeof.h>
#include <libk/lengthof.h>
#include <libk/printf.h>
#include <libk/std.h>
#include <libk/string.h>
#include <status.h>
#include <sys/debug.h>
static int device_probe_partitions_dos (struct device* device) {
struct dos_mbr mbr;
memset (&mbr, 0, sizeof (mbr));
size_t sector = 0;
size_t sector_count = 1;
size_t sector_size;
device_op_func_t ops[] = {
[XDRV_GET_SIZE] = &partdrv_get_size,
[XDRV_GET_SECTOR_SIZE] = &partdrv_get_sector_size,
[XDRV_GET_DEVICE_TYPE] = &partdrv_get_device_type,
[XDRV_READ] = &partdrv_read,
[XDRV_WRITE] = &partdrv_write,
};
spin_lock (&device->lock);
device_op (device, XDRV_GET_SECTOR_SIZE, NULL, NULL, &sector_size);
int ret = device_op (device, XDRV_READ, NULL, NULL, &sector, &sector_count, &mbr);
if (ret < 0) {
spin_unlock (&device->lock);
return ret;
}
if (!(mbr.valid_sign[0] == 0x55 && mbr.valid_sign[1] == 0xAA)) {
spin_unlock (&device->lock);
return -ST_PARTITION_ERROR;
}
for (size_t i = 0; i < lengthof (mbr.ptes); i++) {
struct dos_pte* pte = &mbr.ptes[i];
struct partdrv_init init = {
.start_sector = pte->start_lba,
.total_size = pte->sector_count * sector_size,
.super = device,
};
char key[fieldsizeof (struct device, key)];
memset (key, 0, sizeof (key));
snprintf (key, sizeof (key), "%sp%zu", device->key, i);
device_create (key, ops, lengthof (ops), &partdrv_init, &partdrv_fini, &init);
}
spin_unlock (&device->lock);
return ST_OK;
}
int device_probe_partitions (struct device* device) { return device_probe_partitions_dos (device); }

View File

@@ -0,0 +1,27 @@
#ifndef _KERNEL_DEVICE_PARTITIONS_H
#define _KERNEL_DEVICE_PARTITIONS_H
#include <aux/compiler.h>
#include <device/device.h>
#include <libk/std.h>
struct dos_pte {
uint8_t drive_attrs;
uint8_t chs_start_addr[3];
uint8_t part_type;
uint8_t chs_last_sect_addr[3];
uint32_t start_lba;
uint32_t sector_count;
} PACKED;
struct dos_mbr {
uint8_t boot_code[440];
uint8_t signature[4];
uint8_t resv[2];
struct dos_pte ptes[4];
uint8_t valid_sign[2];
} PACKED;
int device_probe_partitions (struct device* device);
#endif // _KERNEL_DEVICE_PARTITIONS_H

View File

@@ -3,8 +3,8 @@
#include <amd64/io.h> #include <amd64/io.h>
#include <device/device.h> #include <device/device.h>
#include <device/ps2_kb.h> #include <device/ps2_kb.h>
#include <devices.h>
#include <irq/irq.h> #include <irq/irq.h>
#include <kb_device.h>
#include <libk/ringbuffer.h> #include <libk/ringbuffer.h>
#include <libk/std.h> #include <libk/std.h>
#include <proc/capability.h> #include <proc/capability.h>

View File

@@ -1,12 +1,13 @@
#include <device/device.h> #include <device/device.h>
#include <device/partitions.h>
#include <device/ramdrv.h> #include <device/ramdrv.h>
#include <devices.h>
#include <libk/align.h> #include <libk/align.h>
#include <libk/std.h> #include <libk/std.h>
#include <libk/string.h> #include <libk/string.h>
#include <mm/liballoc.h> #include <mm/liballoc.h>
#include <status.h> #include <status.h>
#include <sys/debug.h> #include <sys/debug.h>
#include <xdrv_device.h>
bool ramdrv_init (struct device* device, void* arg) { bool ramdrv_init (struct device* device, void* arg) {
struct ramdrv_init* init = arg; struct ramdrv_init* init = arg;
@@ -45,7 +46,7 @@ void ramdrv_fini (struct device* device) {
int ramdrv_get_device_type (struct device* device, struct proc* proc, struct reschedule_ctx* rctx, int ramdrv_get_device_type (struct device* device, struct proc* proc, struct reschedule_ctx* rctx,
void* a1, void* a2, void* a3, void* a4) { void* a1, void* a2, void* a3, void* a4) {
(void)device, (void)a2, (void)a3, (void)a4; (void)proc, (void)rctx, (void)device, (void)a2, (void)a3, (void)a4;
if (a1 == NULL) if (a1 == NULL)
return -ST_BAD_ADDRESS_SPACE; return -ST_BAD_ADDRESS_SPACE;
@@ -59,7 +60,7 @@ int ramdrv_get_device_type (struct device* device, struct proc* proc, struct res
int ramdrv_get_size (struct device* device, struct proc* proc, struct reschedule_ctx* rctx, int ramdrv_get_size (struct device* device, struct proc* proc, struct reschedule_ctx* rctx,
void* a1, void* a2, void* a3, void* a4) { void* a1, void* a2, void* a3, void* a4) {
(void)a2, (void)a3, (void)a4; (void)proc, (void)rctx, (void)a2, (void)a3, (void)a4;
if (a1 == NULL) if (a1 == NULL)
return -ST_BAD_ADDRESS_SPACE; return -ST_BAD_ADDRESS_SPACE;
@@ -75,7 +76,7 @@ int ramdrv_get_size (struct device* device, struct proc* proc, struct reschedule
int ramdrv_get_sector_size (struct device* device, struct proc* proc, struct reschedule_ctx* rctx, int ramdrv_get_sector_size (struct device* device, struct proc* proc, struct reschedule_ctx* rctx,
void* a1, void* a2, void* a3, void* a4) { void* a1, void* a2, void* a3, void* a4) {
(void)a2, (void)a3, (void)a4; (void)proc, (void)rctx, (void)a2, (void)a3, (void)a4;
if (a1 == NULL) if (a1 == NULL)
return -ST_BAD_ADDRESS_SPACE; return -ST_BAD_ADDRESS_SPACE;
@@ -108,3 +109,23 @@ int ramdrv_read (struct device* device, struct proc* proc, struct reschedule_ctx
return ST_OK; return ST_OK;
} }
int ramdrv_write (struct device* device, struct proc* proc, struct reschedule_ctx* rctx, void* a1,
void* a2, void* a3, void* a4) {
(void)proc, (void)rctx, (void)a4;
if (a1 == NULL || a2 == NULL || a3 == NULL)
return -ST_BAD_ADDRESS_SPACE;
size_t sector = *(size_t*)a1;
size_t sector_count = *(size_t*)a2;
uint8_t* buffer = a3;
struct ramdrv* ramdrv = device->udata;
size_t pos = sector * ramdrv->sector_size;
size_t size = sector_count * ramdrv->sector_size;
memcpy ((void*)(((uintptr_t)ramdrv->buffer) + pos), buffer, size);
return ST_OK;
}

View File

@@ -7,7 +7,6 @@
#include <proc/reschedule.h> #include <proc/reschedule.h>
struct device; struct device;
struct device_op_ctx;
struct ramdrv_init { struct ramdrv_init {
size_t total_size; size_t total_size;
@@ -28,6 +27,9 @@ void ramdrv_fini (struct device* device);
int ramdrv_read (struct device* device, struct proc* proc, struct reschedule_ctx* rctx, void* a1, int ramdrv_read (struct device* device, struct proc* proc, struct reschedule_ctx* rctx, void* a1,
void* a2, void* a3, void* a4); void* a2, void* a3, void* a4);
int ramdrv_write (struct device* device, struct proc* proc, struct reschedule_ctx* rctx, void* a1,
void* a2, void* a3, void* a4);
int ramdrv_get_device_type (struct device* device, struct proc* proc, struct reschedule_ctx* rctx, int ramdrv_get_device_type (struct device* device, struct proc* proc, struct reschedule_ctx* rctx,
void* a1, void* a2, void* a3, void* a4); void* a1, void* a2, void* a3, void* a4);

View File

@@ -1,10 +1,14 @@
c += device/device.c \ c += device/device.c \
device/terminal.c \ device/terminal.c \
device/ramdrv.c device/ramdrv.c \
device/partdrv.c \
device/partitions.c
o += device/device.o \ o += device/device.o \
device/terminal.o \ device/terminal.o \
device/ramdrv.o device/ramdrv.o \
device/partdrv.o \
device/partitions.o
ifeq ($(platform),amd64) ifeq ($(platform),amd64)
c += device/ps2_kb.c c += device/ps2_kb.c

View File

@@ -1,4 +1,5 @@
#include <desc.h> #include <desc.h>
#include <devices.h>
#include <fs/fat1.h> #include <fs/fat1.h>
#include <fs/fatfs.h> #include <fs/fatfs.h>
#include <fs/fatfs_ctx.h> #include <fs/fatfs_ctx.h>
@@ -13,13 +14,15 @@
#include <path_defs.h> #include <path_defs.h>
#include <status.h> #include <status.h>
#include <sys/debug.h> #include <sys/debug.h>
#include <xdrv_device.h>
static int fat1_diskio_read (struct fatfs_ctx* ctx, uint32_t sector, uint8_t* buffer, static int fat1_diskio_read (struct fatfs_ctx* ctx, uint32_t sector, uint8_t* buffer,
uint32_t sector_count) { uint32_t sector_count) {
struct vfs_volume* volume = ctx->udata; struct vfs_volume* volume = ctx->udata;
struct device* back_device = volume->back_device; struct device* back_device = volume->back_device;
if (sector_count == 0)
return 0;
size_t sector_size; size_t sector_size;
size_t phys_sector, phys_sector_count; size_t phys_sector, phys_sector_count;
int ret; int ret;
@@ -29,7 +32,7 @@ static int fat1_diskio_read (struct fatfs_ctx* ctx, uint32_t sector, uint8_t* bu
ret = device_op (back_device, XDRV_GET_SECTOR_SIZE, NULL, NULL, &sector_size); ret = device_op (back_device, XDRV_GET_SECTOR_SIZE, NULL, NULL, &sector_size);
if (ret < 0) { if (ret < 0) {
spin_unlock (&back_device->lock); spin_unlock (&back_device->lock);
return -1; return 0;
} }
vfs_translate (sector, sector_count, FAT_SECTOR_SIZE, sector_size, &phys_sector, vfs_translate (sector, sector_count, FAT_SECTOR_SIZE, sector_size, &phys_sector,
@@ -38,33 +41,97 @@ static int fat1_diskio_read (struct fatfs_ctx* ctx, uint32_t sector, uint8_t* bu
ret = device_op (back_device, XDRV_READ, NULL, NULL, &phys_sector, &phys_sector_count, buffer); ret = device_op (back_device, XDRV_READ, NULL, NULL, &phys_sector, &phys_sector_count, buffer);
if (ret < 0) { if (ret < 0) {
spin_unlock (&back_device->lock); spin_unlock (&back_device->lock);
return -1; return 0;
} }
spin_unlock (&back_device->lock); spin_unlock (&back_device->lock);
if (ret < 0) if (ret < 0)
return -1;
return 0; return 0;
return 1;
} }
int fatfs_mount (struct vfs_volume* volume, struct proc* proc, struct reschedule_ctx* rctx) { static int fat1_diskio_write (struct fatfs_ctx* ctx, uint32_t sector, uint8_t* buffer,
(void)proc, (void)rctx; uint32_t sector_count) {
struct vfs_volume* volume = ctx->udata;
struct device* back_device = volume->back_device;
if (sector_count == 0)
return 0;
size_t sector_size;
size_t phys_sector, phys_sector_count;
int ret;
spin_lock (&back_device->lock);
ret = device_op (back_device, XDRV_GET_SECTOR_SIZE, NULL, NULL, &sector_size);
if (ret < 0) {
spin_unlock (&back_device->lock);
return 0;
}
vfs_translate (sector, sector_count, FAT_SECTOR_SIZE, sector_size, &phys_sector,
&phys_sector_count);
ret = device_op (back_device, XDRV_WRITE, NULL, NULL, &phys_sector, &phys_sector_count, buffer);
if (ret < 0) {
spin_unlock (&back_device->lock);
return 0;
}
spin_unlock (&back_device->lock);
if (ret < 0)
return 0;
return 1;
}
int fatfs_mount (struct vfs_volume* volume) {
struct fatfs_ctx* fatfs_ctx = malloc (sizeof (*fatfs_ctx)); struct fatfs_ctx* fatfs_ctx = malloc (sizeof (*fatfs_ctx));
int r;
if (fatfs_ctx == NULL) if (fatfs_ctx == NULL)
return -ST_OOM_ERROR; return -ST_OOM_ERROR;
memset (fatfs_ctx, 0, sizeof (*fatfs_ctx)); memset (fatfs_ctx, 0, sizeof (*fatfs_ctx));
fl_attach_media (fatfs_ctx, &fat1_diskio_read, NULL);
fatfs_ctx->udata = volume; fatfs_ctx->udata = volume;
volume->udata = fatfs_ctx; volume->udata = fatfs_ctx;
fl_init (fatfs_ctx);
fl_attach_media (fatfs_ctx, &fat1_diskio_read, &fat1_diskio_write);
return ST_OK; return ST_OK;
} }
int fatfs16_format (struct vfs_volume* volume) {
struct fatfs_ctx* fatfs_ctx = volume->udata;
struct device* back_device = volume->back_device;
size_t total_size;
spin_lock (&back_device->lock);
device_op (back_device, XDRV_GET_SIZE, NULL, NULL, &total_size);
spin_unlock (&back_device->lock);
size_t sectors = div_align_up (total_size, FAT_SECTOR_SIZE);
int r = fatfs_format_fat16 (fatfs_ctx, &fatfs_ctx->_fs, sectors, "mop3 fat16");
return r < 0 ? -ST_FORMAT_ERROR : ST_OK;
}
int fatfs32_format (struct vfs_volume* volume) {
struct fatfs_ctx* fatfs_ctx = volume->udata;
struct device* back_device = volume->back_device;
size_t total_size;
spin_lock (&back_device->lock);
device_op (back_device, XDRV_GET_SIZE, NULL, NULL, &total_size);
spin_unlock (&back_device->lock);
size_t sectors = div_align_up (total_size, FAT_SECTOR_SIZE);
int r = fatfs_format_fat32 (fatfs_ctx, &fatfs_ctx->_fs, sectors, "mop3 fat32");
return r < 0 ? -ST_FORMAT_ERROR : ST_OK;
}
int fatfs_describe (struct vfs_volume* volume, const char* path, struct desc* desc) { int fatfs_describe (struct vfs_volume* volume, const char* path, struct desc* desc) {
struct fatfs_ctx* fatfs_ctx = volume->udata; struct fatfs_ctx* fatfs_ctx = volume->udata;
@@ -114,6 +181,23 @@ int fatfs_read (struct vfs_volume* volume, const char* path, uint8_t* buffer, si
return ST_OK; return ST_OK;
} }
int fatfs_write (struct vfs_volume* volume, const char* path, uint8_t* buffer, size_t off,
size_t size) {
struct fatfs_ctx* fatfs_ctx = volume->udata;
FL_FILE* file = fl_fopen (fatfs_ctx, path, "wb+");
if (file == NULL)
return -ST_NOT_FOUND;
fl_fseek (fatfs_ctx, file, off, SEEK_SET);
fl_fwrite (fatfs_ctx, buffer, 1, size, file);
fl_fclose (fatfs_ctx, file);
return ST_OK;
}
int fatfs_read_dir_entry (struct vfs_volume* volume, const char* path, struct dir_entry* entry, int fatfs_read_dir_entry (struct vfs_volume* volume, const char* path, struct dir_entry* entry,
size_t entry_num) { size_t entry_num) {
struct fatfs_ctx* fatfs_ctx = volume->udata; struct fatfs_ctx* fatfs_ctx = volume->udata;

View File

@@ -10,13 +10,20 @@
struct vfs_volume; struct vfs_volume;
int fatfs_mount (struct vfs_volume* volume, struct proc* proc, struct reschedule_ctx* rctx); int fatfs_mount (struct vfs_volume* volume);
int fatfs16_format (struct vfs_volume* volume);
int fatfs32_format (struct vfs_volume* volume);
int fatfs_describe (struct vfs_volume* volume, const char* path, struct desc* desc); int fatfs_describe (struct vfs_volume* volume, const char* path, struct desc* desc);
int fatfs_read (struct vfs_volume* volume, const char* path, uint8_t* buffer, size_t off, int fatfs_read (struct vfs_volume* volume, const char* path, uint8_t* buffer, size_t off,
size_t size); size_t size);
int fatfs_write (struct vfs_volume* volume, const char* path, uint8_t* buffer, size_t off,
size_t size);
int fatfs_read_dir_entry (struct vfs_volume* volume, const char* path, struct dir_entry* entry, int fatfs_read_dir_entry (struct vfs_volume* volume, const char* path, struct dir_entry* entry,
size_t entry_num); size_t entry_num);

View File

@@ -1,4 +1,5 @@
#include <desc.h> #include <desc.h>
#include <devices.h>
#include <fs/path.h> #include <fs/path.h>
#include <fs/tarfs.h> #include <fs/tarfs.h>
#include <fs/vfs.h> #include <fs/vfs.h>
@@ -12,7 +13,6 @@
#include <path_defs.h> #include <path_defs.h>
#include <status.h> #include <status.h>
#include <sys/debug.h> #include <sys/debug.h>
#include <xdrv_device.h>
static struct tar_file* tar_get_file (struct tarfs* tarfs, const char* filename) { static struct tar_file* tar_get_file (struct tarfs* tarfs, const char* filename) {
for (size_t i = 0; i < TARFS_FILES_MAX; i++) { for (size_t i = 0; i < TARFS_FILES_MAX; i++) {
@@ -55,7 +55,7 @@ static size_t tar_parse (struct tarfs* tarfs, uint8_t* addr) {
return i; return i;
} }
int tarfs_mount (struct vfs_volume* volume, struct proc* proc, struct reschedule_ctx* rctx) { int tarfs_mount (struct vfs_volume* volume) {
struct tarfs* tarfs = malloc (sizeof (*tarfs)); struct tarfs* tarfs = malloc (sizeof (*tarfs));
if (tarfs == NULL) if (tarfs == NULL)
@@ -71,14 +71,14 @@ int tarfs_mount (struct vfs_volume* volume, struct proc* proc, struct reschedule
spin_lock (&back_device->lock); spin_lock (&back_device->lock);
ret = device_op (back_device, XDRV_GET_SIZE, proc, rctx, &total_size); ret = device_op (back_device, XDRV_GET_SIZE, NULL, NULL, &total_size);
if (ret < 0) { if (ret < 0) {
spin_unlock (&back_device->lock); spin_unlock (&back_device->lock);
free (volume->udata); free (volume->udata);
return ret; return ret;
} }
ret = device_op (back_device, XDRV_GET_SECTOR_SIZE, proc, rctx, &sector_size); ret = device_op (back_device, XDRV_GET_SECTOR_SIZE, NULL, NULL, &sector_size);
if (ret < 0) { if (ret < 0) {
spin_unlock (&back_device->lock); spin_unlock (&back_device->lock);
free (volume->udata); free (volume->udata);
@@ -96,7 +96,7 @@ int tarfs_mount (struct vfs_volume* volume, struct proc* proc, struct reschedule
size_t sector_count = 1; size_t sector_count = 1;
for (size_t sector = 0; sector < total_size / sector_size; sector++) { for (size_t sector = 0; sector < total_size / sector_size; sector++) {
uint8_t* dest = (uint8_t*)((uintptr_t)buffer + (sector * sector_size)); uint8_t* dest = (uint8_t*)((uintptr_t)buffer + (sector * sector_size));
ret = device_op (back_device, XDRV_READ, proc, rctx, &sector, &sector_count, dest); ret = device_op (back_device, XDRV_READ, NULL, NULL, &sector, &sector_count, dest);
} }
spin_unlock (&back_device->lock); spin_unlock (&back_device->lock);
@@ -113,6 +113,11 @@ int tarfs_mount (struct vfs_volume* volume, struct proc* proc, struct reschedule
return ret; return ret;
} }
int tarfs_format (struct vfs_volume* volume) {
(void)volume;
return ST_OK;
}
int tarfs_describe (struct vfs_volume* volume, const char* path, struct desc* desc) { int tarfs_describe (struct vfs_volume* volume, const char* path, struct desc* desc) {
struct tarfs* tarfs = volume->udata; struct tarfs* tarfs = volume->udata;
@@ -190,3 +195,9 @@ int tarfs_read_dir_entry (struct vfs_volume* volume, const char* path, struct di
return ST_DIR_NO_ENTRIES; return ST_DIR_NO_ENTRIES;
} }
int tarfs_write (struct vfs_volume* volume, const char* path, uint8_t* buffer, size_t off,
size_t size) {
(void)volume, (void)path, (void)buffer, (void)off, (void)size;
return ST_OK;
}

View File

@@ -34,13 +34,18 @@ struct tarfs {
struct vfs_volume; struct vfs_volume;
int tarfs_mount (struct vfs_volume* volume, struct proc* proc, struct reschedule_ctx* rctx); int tarfs_mount (struct vfs_volume* volume);
int tarfs_format (struct vfs_volume* volume);
int tarfs_describe (struct vfs_volume* volume, const char* path, struct desc* desc); int tarfs_describe (struct vfs_volume* volume, const char* path, struct desc* desc);
int tarfs_read (struct vfs_volume* volume, const char* path, uint8_t* buffer, size_t off, int tarfs_read (struct vfs_volume* volume, const char* path, uint8_t* buffer, size_t off,
size_t size); size_t size);
int tarfs_write (struct vfs_volume* volume, const char* path, uint8_t* buffer, size_t off,
size_t size);
int tarfs_read_dir_entry (struct vfs_volume* volume, const char* path, struct dir_entry* entry, int tarfs_read_dir_entry (struct vfs_volume* volume, const char* path, struct dir_entry* entry,
size_t entry_num); size_t entry_num);

View File

@@ -22,8 +22,8 @@ static struct vfs_volume_table volume_table;
static struct vfs_volume* vfs_find_volume (const char* volume) { static struct vfs_volume* vfs_find_volume (const char* volume) {
struct hash_node_link* found_link = NULL; struct hash_node_link* found_link = NULL;
size_t volume_len = strlen (volume); size_t volume_len = strlen_null (volume);
uint32_t hash = hash_fnv32 (volume, strlen (volume)); uint32_t hash = hash_fnv32 (volume, volume_len);
spin_lock (&volume_table.lock); spin_lock (&volume_table.lock);
hash_find (&volume_table, volume, volume_len, hash, lengthof (volume_table.volume_buckets), hash_find (&volume_table, volume, volume_len, hash, lengthof (volume_table.volume_buckets),
@@ -36,8 +36,7 @@ static struct vfs_volume* vfs_find_volume (const char* volume) {
return hash_entry (found_link, struct vfs_volume, volume_table_link); return hash_entry (found_link, struct vfs_volume, volume_table_link);
} }
int vfs_create_volume (const char* key, int fs_type, struct device* back_device, struct proc* proc, int vfs_create_volume (const char* key, int fs_type, struct device* back_device) {
struct reschedule_ctx* rctx) {
if (strlen_null (key) > VOLUME_MAX) if (strlen_null (key) > VOLUME_MAX)
return -ST_OOB_ERROR; return -ST_OOB_ERROR;
@@ -56,14 +55,26 @@ int vfs_create_volume (const char* key, int fs_type, struct device* back_device,
switch (volume->fs_type) { switch (volume->fs_type) {
case VFS_TARFS: case VFS_TARFS:
volume->driver_ops.mount = &tarfs_mount; volume->driver_ops.mount = &tarfs_mount;
volume->driver_ops.format = &tarfs_format;
volume->driver_ops.describe = &tarfs_describe; volume->driver_ops.describe = &tarfs_describe;
volume->driver_ops.read = &tarfs_read; volume->driver_ops.read = &tarfs_read;
volume->driver_ops.write = &tarfs_write;
volume->driver_ops.read_dir_entry = &tarfs_read_dir_entry; volume->driver_ops.read_dir_entry = &tarfs_read_dir_entry;
break; break;
case VFS_FAT16: case VFS_FAT16:
volume->driver_ops.mount = &fatfs_mount; volume->driver_ops.mount = &fatfs_mount;
volume->driver_ops.format = &fatfs16_format;
volume->driver_ops.describe = &fatfs_describe; volume->driver_ops.describe = &fatfs_describe;
volume->driver_ops.read = &fatfs_read; volume->driver_ops.read = &fatfs_read;
volume->driver_ops.write = &fatfs_write;
volume->driver_ops.read_dir_entry = &fatfs_read_dir_entry;
break;
case VFS_FAT32:
volume->driver_ops.mount = &fatfs_mount;
volume->driver_ops.format = &fatfs32_format;
volume->driver_ops.describe = &fatfs_describe;
volume->driver_ops.read = &fatfs_read;
volume->driver_ops.write = &fatfs_write;
volume->driver_ops.read_dir_entry = &fatfs_read_dir_entry; volume->driver_ops.read_dir_entry = &fatfs_read_dir_entry;
break; break;
default: default:
@@ -71,14 +82,14 @@ int vfs_create_volume (const char* key, int fs_type, struct device* back_device,
return -ST_MOUNT_ERROR; return -ST_MOUNT_ERROR;
} }
int ret = volume->driver_ops.mount (volume, proc, rctx); int ret = volume->driver_ops.mount (volume);
if (ret < 0) { if (ret < 0) {
free (volume); free (volume);
return ret; return ret;
} }
uint32_t mp_hash = hash_fnv32 (volume->key, strlen (volume->key)); uint32_t mp_hash = hash_fnv32 (volume->key, strlen_null (volume->key));
spin_lock (&volume_table.lock); spin_lock (&volume_table.lock);
@@ -135,7 +146,7 @@ int vfs_volume_close (struct proc* proc, const char* volume_name, struct resched
struct proc_sq_entry* sq_entry = list_entry (node, struct proc_sq_entry, sq_link); struct proc_sq_entry* sq_entry = list_entry (node, struct proc_sq_entry, sq_link);
struct proc* resumed_proc = sq_entry->proc; struct proc* resumed_proc = sq_entry->proc;
volume->owner = proc; volume->owner = resumed_proc;
volume->locked = true; volume->locked = true;
spin_unlock (&volume->sq.lock); spin_unlock (&volume->sq.lock);
@@ -154,6 +165,24 @@ int vfs_volume_close (struct proc* proc, const char* volume_name, struct resched
return ST_OK; return ST_OK;
} }
int vfs_format (struct proc* proc, const char* volume_name) {
struct vfs_volume* volume = vfs_find_volume (volume_name);
if (volume == NULL)
return -ST_NOT_FOUND;
spin_lock (&volume->lock);
if (volume->locked && volume->owner != proc) {
spin_unlock (&volume->lock);
return -ST_PERMISSION_ERROR;
}
spin_unlock (&volume->lock);
return volume->driver_ops.format (volume);
}
int vfs_read (struct proc* proc, const char* volume_name, const char* path, uint8_t* buffer, int vfs_read (struct proc* proc, const char* volume_name, const char* path, uint8_t* buffer,
size_t off, size_t size) { size_t off, size_t size) {
struct vfs_volume* volume = vfs_find_volume (volume_name); struct vfs_volume* volume = vfs_find_volume (volume_name);

View File

@@ -32,13 +32,18 @@ struct vfs_volume {
bool locked; bool locked;
struct proc_suspension_q sq; struct proc_suspension_q sq;
struct { struct {
int (*mount) (struct vfs_volume* volume, struct proc* proc, struct reschedule_ctx* rctx); int (*mount) (struct vfs_volume* volume);
int (*format) (struct vfs_volume* volume);
int (*describe) (struct vfs_volume* volume, const char* path, struct desc* desc); int (*describe) (struct vfs_volume* volume, const char* path, struct desc* desc);
int (*read) (struct vfs_volume* volume, const char* path, uint8_t* buffer, size_t off, int (*read) (struct vfs_volume* volume, const char* path, uint8_t* buffer, size_t off,
size_t size); size_t size);
int (*write) (struct vfs_volume* volume, const char* path, uint8_t* buffer, size_t off,
size_t size);
int (*read_dir_entry) (struct vfs_volume* volume, const char* path, struct dir_entry* entry, int (*read_dir_entry) (struct vfs_volume* volume, const char* path, struct dir_entry* entry,
size_t entry_num); size_t entry_num);
} driver_ops; } driver_ops;
@@ -51,13 +56,14 @@ struct vfs_volume_table {
spin_lock_t lock; spin_lock_t lock;
}; };
int vfs_create_volume (const char* key, int fs_type, struct device* back_device, struct proc* proc, int vfs_create_volume (const char* key, int fs_type, struct device* back_device);
struct reschedule_ctx* rctx);
int vfs_volume_open (struct proc* proc, const char* volume, struct reschedule_ctx* rctx); int vfs_volume_open (struct proc* proc, const char* volume, struct reschedule_ctx* rctx);
int vfs_volume_close (struct proc* proc, const char* volume, struct reschedule_ctx* rctx); int vfs_volume_close (struct proc* proc, const char* volume, struct reschedule_ctx* rctx);
int vfs_format (struct proc* proc, const char* volume_name);
int vfs_read (struct proc* proc, const char* volume, const char* path, uint8_t* buffer, size_t off, int vfs_read (struct proc* proc, const char* volume, const char* path, uint8_t* buffer, size_t off,
size_t size); size_t size);

View File

@@ -340,10 +340,10 @@ void proc_init (void) {
struct reschedule_ctx rctx = {.cpu = NULL, .reschedule = false}; struct reschedule_ctx rctx = {.cpu = NULL, .reschedule = false};
struct proc* spin_proc = proc_from_file (VFS_KERNEL, "ramdisk", "/spin", &rctx); struct proc* spin_proc = proc_from_file (VFS_KERNEL, "RD", "/spin", &rctx);
proc_register (spin_proc, thiscpu, NULL); proc_register (spin_proc, thiscpu, NULL);
struct proc* init = proc_from_file (VFS_KERNEL, "ramdisk", "/init", &rctx); struct proc* init = proc_from_file (VFS_KERNEL, "RD", "/init", &rctx);
init->procgroup->capabilities |= (PROC_CAP_TERMINAL | PROC_CAP_KB); init->procgroup->capabilities |= (PROC_CAP_TERMINAL | PROC_CAP_KB);
proc_register (init, thiscpu, NULL); proc_register (init, thiscpu, NULL);

View File

@@ -216,7 +216,7 @@ DEFINE_SYSCALL (sys_mail_receive) {
DEFINE_SYSCALL (sys_device_do) { DEFINE_SYSCALL (sys_device_do) {
struct limine_hhdm_response* hhdm = limine_hhdm_request.response; struct limine_hhdm_response* hhdm = limine_hhdm_request.response;
int device_id = (int)a1; uintptr_t uvaddr_key = a1;
int cmd = (int)a2; int cmd = (int)a2;
uintptr_t ua1 = a3, ka1 = 0; uintptr_t ua1 = a3, ka1 = 0;
uintptr_t ua2 = a4, ka2 = 0; uintptr_t ua2 = a4, ka2 = 0;
@@ -229,6 +229,15 @@ DEFINE_SYSCALL (sys_device_do) {
spin_lock (&proc->procgroup->lock); spin_lock (&proc->procgroup->lock);
out_paddr = mm_v2p (&proc->procgroup->pd, uvaddr_key);
if (out_paddr == 0) {
spin_unlock (&proc->procgroup->lock);
return SYSRESULT (-ST_BAD_ADDRESS_SPACE);
}
const char* key = (const char*)((uintptr_t)hhdm->offset + out_paddr);
out_paddr = mm_v2p (&proc->procgroup->pd, ua1); out_paddr = mm_v2p (&proc->procgroup->pd, ua1);
if (out_paddr != 0) if (out_paddr != 0)
ka1 = (uintptr_t)hhdm->offset + out_paddr; ka1 = (uintptr_t)hhdm->offset + out_paddr;
@@ -247,7 +256,7 @@ DEFINE_SYSCALL (sys_device_do) {
spin_unlock (&proc->procgroup->lock); spin_unlock (&proc->procgroup->lock);
struct device* device = device_find (device_id); struct device* device = device_find (key);
if (device == NULL) if (device == NULL)
return SYSRESULT (-ST_NOT_FOUND); return SYSRESULT (-ST_NOT_FOUND);

View File

@@ -1,12 +1,12 @@
#include <devices.h>
#include <kb.h> #include <kb.h>
#include <kb_device.h>
#include <status.h> #include <status.h>
#include <stdint.h> #include <stdint.h>
#include <system.h> #include <system.h>
int kb_read_key (void) { int kb_read_key (void) {
char ch = 0; char ch = 0;
int r = device_do (KB_DEVICE, KB_READ_KEY, &ch, NULL, NULL, NULL); int r = device_do ("KB", KB_READ_KEY, &ch, NULL, NULL, NULL);
if (r == ST_OK) if (r == ST_OK)
return (int)ch; return (int)ch;

View File

@@ -1,7 +1,7 @@
#ifndef _LIBKB_KB_H #ifndef _LIBKB_KB_H
#define _LIBKB_KB_H #define _LIBKB_KB_H
#include <kb_device.h> #include <devices.h>
#include <stdint.h> #include <stdint.h>
/* \brief Read key from keyboard /* \brief Read key from keyboard

View File

@@ -35,8 +35,8 @@ int mutex_unlock (int mutex_rid) { return do_syscall (SYS_MUTEX_UNLOCK, mutex_ri
void* argument_ptr (void) { return (void*)do_syscall (SYS_ARGUMENT_PTR, 0); } void* argument_ptr (void) { return (void*)do_syscall (SYS_ARGUMENT_PTR, 0); }
int device_do (int device_id, int cmd, void* a1, void* a2, void* a3, void* a4) { int device_do (const char* device_key, int cmd, void* a1, void* a2, void* a3, void* a4) {
return (int)do_syscall (SYS_DEVICE_DO, device_id, cmd, a1, a2, a3, a4); return (int)do_syscall (SYS_DEVICE_DO, device_key, cmd, a1, a2, a3, a4);
} }
int exec (const char* volume, const char* path) { return (int)do_syscall (SYS_EXEC, volume, path); } int exec (const char* volume, const char* path) { return (int)do_syscall (SYS_EXEC, volume, path); }

View File

@@ -49,7 +49,7 @@ int mutex_unlock (int mutex_rid);
void* argument_ptr (void); void* argument_ptr (void);
/* Call a device command */ /* Call a device command */
int device_do (int device_id, int cmd, void* a1, void* a2, void* a3, void* a4); int device_do (const char* device_key, int cmd, void* a1, void* a2, void* a3, void* a4);
/* Run external ELF program */ /* Run external ELF program */
int exec (const char* volume, const char* path); int exec (const char* volume, const char* path);

View File

@@ -3,5 +3,5 @@
#include <terminal.h> #include <terminal.h>
void terminal_print (const char* string, size_t len) { void terminal_print (const char* string, size_t len) {
device_do (TERMINAL_DEVICE, TERMINAL_PUTSTR, (void*)string, &len, NULL, NULL); device_do ("TERMINAL", TERMINAL_PUTSTR, (void*)string, &len, NULL, NULL);
} }

View File

@@ -1,8 +1,8 @@
#ifndef _LIBTERMINAL_TERMINAL_TERMINAL_H #ifndef _LIBTERMINAL_TERMINAL_TERMINAL_H
#define _LIBTERMINAL_TERMINAL_TERMINAL_H #define _LIBTERMINAL_TERMINAL_TERMINAL_H
#include <devices.h>
#include <stddef.h> #include <stddef.h>
#include <terminal_device.h>
/* Print a string onto a graphical terminal. Prints len chars */ /* Print a string onto a graphical terminal. Prints len chars */
void terminal_print (const char* string, size_t len); void terminal_print (const char* string, size_t len);