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
All checks were successful
Build documentation / build-and-deploy (push) Successful in 3m35s
This commit is contained in:
3
ce/ce.c
3
ce/ce.c
@@ -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
19
include/devices.h
Normal 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
|
||||||
@@ -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
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
#ifndef _M_RAMDISK_DEVICE_H
|
|
||||||
#define _M_RAMDISK_DEVICE_H
|
|
||||||
|
|
||||||
#define RAMDISK_DEVICE 100
|
|
||||||
|
|
||||||
#endif // _M_RAMDISK_DEVICE_H
|
|
||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
|
||||||
@@ -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
|
|
||||||
@@ -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);
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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 ();
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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, §or, §or_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 ();
|
||||||
|
|||||||
@@ -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
4
kernel/device/dos.h
Normal 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
121
kernel/device/partdrv.c
Normal 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, §or, §or_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, §or, §or_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
41
kernel/device/partdrv.h
Normal 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
|
||||||
65
kernel/device/partitions.c
Normal file
65
kernel/device/partitions.c
Normal 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, §or_size);
|
||||||
|
|
||||||
|
int ret = device_op (device, XDRV_READ, NULL, NULL, §or, §or_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); }
|
||||||
27
kernel/device/partitions.h
Normal file
27
kernel/device/partitions.h
Normal 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
|
||||||
@@ -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>
|
||||||
|
|||||||
@@ -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;
|
||||||
|
}
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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, §or_size);
|
ret = device_op (back_device, XDRV_GET_SECTOR_SIZE, NULL, NULL, §or_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, §or_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;
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|
||||||
|
|||||||
@@ -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, §or_size);
|
ret = device_op (back_device, XDRV_GET_SECTOR_SIZE, NULL, NULL, §or_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, §or, §or_count, dest);
|
ret = device_op (back_device, XDRV_READ, NULL, NULL, §or, §or_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;
|
||||||
|
}
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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); }
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
Reference in New Issue
Block a user