From abd85744cc72664713c38d70bd772ad2933d2baa Mon Sep 17 00:00:00 2001 From: kamkow1 Date: Sun, 1 Mar 2026 01:52:09 +0100 Subject: [PATCH] Add create_file syscall, CE mkfile command, FatFS formatting fixes --- ce/ce.c | 31 +++++++++++++++++++++++++++++-- include/syscall_defs.h | 1 + kernel/amd64/bootmain.c | 7 ++----- kernel/device/device.c | 5 +++-- kernel/fs/fatfs.c | 27 +++++++++++++++++++++++++-- kernel/fs/fatfs.h | 4 +++- kernel/fs/tarfs.c | 9 ++++++++- kernel/fs/tarfs.h | 4 +++- kernel/fs/vfs.c | 25 +++++++++++++++++++++++-- kernel/fs/vfs.h | 8 ++++++-- kernel/syscall/syscall.c | 25 +++++++++++++++++++++++++ libsystem/system.c | 2 ++ libsystem/system.h | 3 +++ 13 files changed, 133 insertions(+), 18 deletions(-) diff --git a/ce/ce.c b/ce/ce.c index 0863110..95e8d4c 100644 --- a/ce/ce.c +++ b/ce/ce.c @@ -19,7 +19,7 @@ static struct arena arena; #define LINE_BUFFER_MAX 1024 #define TOKEN_MAX 64 #define CMD_ARGS_MAX 64 -#define PROMPT "ce $ " +#define PROMPT "$ " #define TOKEN_CLASS_OPAREN 0 #define TOKEN_CLASS_CPAREN 1 @@ -235,7 +235,31 @@ static void parse_tokens (struct list_node_link* tokens) { static void echo (char** strings, size_t strings_count) { for (size_t i = 0; i < strings_count; i++) - printf ("%s\n", strings[i]); + printf ("%s ", strings[i]); +} + +static void mkfile (char** file_paths, size_t files_count) { + char volume[VOLUME_MAX]; + const char* path; + int ret; + + for (size_t i = 0; i < files_count; i++) { + const char* file_path = file_paths[i]; + + if (!path_parse (file_path, volume, &path)) { + printf ("ERROR bad path '%s'\n", file_path); + continue; + } + + if ((ret = volume_open (volume)) < 0) { + printf ("ERROR could not open volume '%s': %s\n", volume, str_status[-ret]); + continue; + } + + create_file (path); + + volume_close (); + } } static void cat (char** file_paths, size_t files_count) { @@ -328,6 +352,7 @@ static void help (void) { printf ("help\n"); printf ("cat \n"); printf ("ls \n"); + printf ("mkfile \n"); printf ("quit\n"); } @@ -342,6 +367,8 @@ static void execute_cmd (struct ast_cmd* cmd) { ls (cmd->args[0]); } else if (strcmp (cmd->name, "quit") == 0) { quit1 (); + } else if (strcmp (cmd->name, "mkfile") == 0) { + mkfile (cmd->args, cmd->arg_count); } else { printf ("ERROR unknown command '%s'\n", cmd->name); } diff --git a/include/syscall_defs.h b/include/syscall_defs.h index c898ce9..d2d0f71 100644 --- a/include/syscall_defs.h +++ b/include/syscall_defs.h @@ -23,5 +23,6 @@ #define SYS_GET_PROCGROUP 20 #define SYS_GET_EXEC_PID 21 #define SYS_READ_DIR_ENTRY 22 +#define SYS_CREATE_FILE 23 #endif // _M_SYSCALL_DEFS_H diff --git a/kernel/amd64/bootmain.c b/kernel/amd64/bootmain.c index 0be73c9..fcb643a 100644 --- a/kernel/amd64/bootmain.c +++ b/kernel/amd64/bootmain.c @@ -59,16 +59,13 @@ void bootmain (void) { struct reschedule_ctx rctx = {.cpu = NULL, .reschedule = false}; struct device* ramdisk = device_find ("RD"); - vfs_create_volume ("RD", VFS_TARFS, ramdisk); + vfs_create_volume ("RD", VFS_TARFS, ramdisk, false); 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); + vfs_create_volume ("VD", VFS_FAT32, vdp0, true); proc_pid_alloc_init (); procgroup_pgid_alloc_init (); diff --git a/kernel/device/device.c b/kernel/device/device.c index 93ffd0a..f94ea12 100644 --- a/kernel/device/device.c +++ b/kernel/device/device.c @@ -138,8 +138,9 @@ void vdisk_device_init (void) { 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); + mbr.ptes[0].drive_attrs = (1 << 7); + mbr.ptes[0].start_lba = 1; + mbr.ptes[0].sector_count = div_align_up (init.total_size, init.sector_size) - 1; struct device* vdisk = device_create ("VD", ops, lengthof (ops), &ramdrv_init, &ramdrv_fini, &init); diff --git a/kernel/fs/fatfs.c b/kernel/fs/fatfs.c index 04601d0..0626d8e 100644 --- a/kernel/fs/fatfs.c +++ b/kernel/fs/fatfs.c @@ -87,7 +87,7 @@ static int fat1_diskio_write (struct fatfs_ctx* ctx, uint32_t sector, uint8_t* b return 1; } -int fatfs_mount (struct vfs_volume* volume) { +int fatfs_mount (struct vfs_volume* volume, bool format) { struct fatfs_ctx* fatfs_ctx = malloc (sizeof (*fatfs_ctx)); int r; @@ -99,7 +99,18 @@ int fatfs_mount (struct vfs_volume* volume) { volume->udata = fatfs_ctx; fl_init (fatfs_ctx); - fl_attach_media (fatfs_ctx, &fat1_diskio_read, &fat1_diskio_write); + fatfs_ctx->_fs.disk_io.read_media = &fat1_diskio_read; + fatfs_ctx->_fs.disk_io.write_media = &fat1_diskio_write; + + if (format) { + r = volume->driver_ops.format (volume); + if (r < 0) + return -ST_FORMAT_ERROR; + } + + r = fl_attach_media (fatfs_ctx, &fat1_diskio_read, &fat1_diskio_write); + if (r < 0) + return -ST_MOUNT_ERROR; return ST_OK; } @@ -221,3 +232,15 @@ int fatfs_read_dir_entry (struct vfs_volume* volume, const char* path, struct di fl_closedir (fatfs_ctx, &dir); return ST_OK; } + +int fatfs_create_file (struct vfs_volume* volume, const char* path) { + struct fatfs_ctx* fatfs_ctx = volume->udata; + + FL_FILE* file = fl_fopen (fatfs_ctx, path, "wb+"); + + if (file == NULL) + return -ST_NOT_FOUND; + + fl_fclose (fatfs_ctx, file); + return ST_OK; +} diff --git a/kernel/fs/fatfs.h b/kernel/fs/fatfs.h index 834b4ea..803c4bc 100644 --- a/kernel/fs/fatfs.h +++ b/kernel/fs/fatfs.h @@ -10,7 +10,7 @@ struct vfs_volume; -int fatfs_mount (struct vfs_volume* volume); +int fatfs_mount (struct vfs_volume* volume, bool format); int fatfs16_format (struct vfs_volume* volume); @@ -27,4 +27,6 @@ int fatfs_write_file (struct vfs_volume* volume, const char* path, uint8_t* buff int fatfs_read_dir_entry (struct vfs_volume* volume, const char* path, struct dir_entry* entry, size_t entry_num); +int fatfs_create_file (struct vfs_volume* volume, const char* path); + #endif // _KERNEL_FS_FATFS_H diff --git a/kernel/fs/tarfs.c b/kernel/fs/tarfs.c index fdbe25d..cb850ff 100644 --- a/kernel/fs/tarfs.c +++ b/kernel/fs/tarfs.c @@ -55,7 +55,9 @@ static size_t tar_parse (struct tarfs* tarfs, uint8_t* addr) { return i; } -int tarfs_mount (struct vfs_volume* volume) { +int tarfs_mount (struct vfs_volume* volume, bool format) { + (void)format; + struct tarfs* tarfs = malloc (sizeof (*tarfs)); if (tarfs == NULL) @@ -201,3 +203,8 @@ int tarfs_write_file (struct vfs_volume* volume, const char* path, uint8_t* buff (void)volume, (void)path, (void)buffer, (void)off, (void)size; return ST_OK; } + +int tarfs_create_file (struct vfs_volume* volume, const char* path) { + (void)volume, (void)path; + return ST_OK; +} diff --git a/kernel/fs/tarfs.h b/kernel/fs/tarfs.h index ab487dc..4e0c488 100644 --- a/kernel/fs/tarfs.h +++ b/kernel/fs/tarfs.h @@ -34,7 +34,7 @@ struct tarfs { struct vfs_volume; -int tarfs_mount (struct vfs_volume* volume); +int tarfs_mount (struct vfs_volume* volume, bool format); int tarfs_format (struct vfs_volume* volume); @@ -49,4 +49,6 @@ int tarfs_write_file (struct vfs_volume* volume, const char* path, uint8_t* buff int tarfs_read_dir_entry (struct vfs_volume* volume, const char* path, struct dir_entry* entry, size_t entry_num); +int tarfs_create_file (struct vfs_volume* volume, const char* path); + #endif // _KERNEL_FS_TARFS_H diff --git a/kernel/fs/vfs.c b/kernel/fs/vfs.c index 6164c69..5b09029 100644 --- a/kernel/fs/vfs.c +++ b/kernel/fs/vfs.c @@ -36,7 +36,7 @@ static struct vfs_volume* vfs_find_volume (const char* volume) { 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) { +int vfs_create_volume (const char* key, int fs_type, struct device* back_device, bool format) { if (strlen_null (key) > VOLUME_MAX) return -ST_OOB_ERROR; @@ -60,6 +60,7 @@ int vfs_create_volume (const char* key, int fs_type, struct device* back_device) volume->driver_ops.read_file = &tarfs_read_file; volume->driver_ops.write_file = &tarfs_write_file; volume->driver_ops.read_dir_entry = &tarfs_read_dir_entry; + volume->driver_ops.create_file = &tarfs_create_file; break; case VFS_FAT16: volume->driver_ops.mount = &fatfs_mount; @@ -68,6 +69,7 @@ int vfs_create_volume (const char* key, int fs_type, struct device* back_device) volume->driver_ops.read_file = &fatfs_read_file; volume->driver_ops.write_file = &fatfs_write_file; volume->driver_ops.read_dir_entry = &fatfs_read_dir_entry; + volume->driver_ops.create_file = &fatfs_create_file; break; case VFS_FAT32: volume->driver_ops.mount = &fatfs_mount; @@ -76,13 +78,14 @@ int vfs_create_volume (const char* key, int fs_type, struct device* back_device) volume->driver_ops.read_file = &fatfs_read_file; volume->driver_ops.write_file = &fatfs_write_file; volume->driver_ops.read_dir_entry = &fatfs_read_dir_entry; + volume->driver_ops.create_file = &fatfs_create_file; break; default: free (volume); return -ST_MOUNT_ERROR; } - int ret = volume->driver_ops.mount (volume); + int ret = volume->driver_ops.mount (volume, format); if (ret < 0) { free (volume); @@ -202,6 +205,24 @@ int vfs_read_file (struct proc* proc, const char* volume_name, const char* path, return volume->driver_ops.read_file (volume, path, buffer, off, size); } +int vfs_create_file (struct proc* proc, const char* volume_name, const char* path) { + 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.create_file (volume, path); +} + int vfs_describe (struct proc* proc, const char* volume_name, const char* path, struct desc* desc) { struct vfs_volume* volume = vfs_find_volume (volume_name); diff --git a/kernel/fs/vfs.h b/kernel/fs/vfs.h index de5e36b..1147897 100644 --- a/kernel/fs/vfs.h +++ b/kernel/fs/vfs.h @@ -32,7 +32,7 @@ struct vfs_volume { bool locked; struct proc_suspension_q sq; struct { - int (*mount) (struct vfs_volume* volume); + int (*mount) (struct vfs_volume* volume, bool format); int (*format) (struct vfs_volume* volume); @@ -46,6 +46,8 @@ struct vfs_volume { int (*read_dir_entry) (struct vfs_volume* volume, const char* path, struct dir_entry* entry, size_t entry_num); + + int (*create_file) (struct vfs_volume* volume, const char* path); } driver_ops; struct device* back_device; void* udata @@ -56,7 +58,7 @@ struct vfs_volume_table { spin_lock_t lock; }; -int vfs_create_volume (const char* key, int fs_type, struct device* back_device); +int vfs_create_volume (const char* key, int fs_type, struct device* back_device, bool format); int vfs_volume_open (struct proc* proc, const char* volume, struct reschedule_ctx* rctx); @@ -72,6 +74,8 @@ int vfs_describe (struct proc* proc, const char* volume, const char* path, struc int vfs_read_dir_entry (struct proc* proc, const char* volume, const char* path, struct dir_entry* entry, size_t entry_num); +int vfs_create_file (struct proc* proc, const char* volume_name, const char* path); + void vfs_init (void); void vfs_translate (size_t fs_block, size_t fs_block_count, size_t fs_block_size, diff --git a/kernel/syscall/syscall.c b/kernel/syscall/syscall.c index 12bb594..701e7d9 100644 --- a/kernel/syscall/syscall.c +++ b/kernel/syscall/syscall.c @@ -459,6 +459,30 @@ DEFINE_SYSCALL (sys_read_dir_entry) { return SYSRESULT (ret); } +/* int create_file (char* path) */ +DEFINE_SYSCALL (sys_create_file) { + uintptr_t uvaddr_path = a1; + + struct limine_hhdm_response* hhdm = limine_hhdm_request.response; + + uintptr_t out_paddr; + + spin_lock (&proc->procgroup->lock); + out_paddr = mm_v2p (&proc->procgroup->pd, uvaddr_path); + spin_unlock (&proc->procgroup->lock); + + if (out_paddr == 0) + return SYSRESULT (-ST_BAD_ADDRESS_SPACE); + + const char* path = (const char*)((uintptr_t)hhdm->offset + out_paddr); + + spin_lock (&proc->lock); + int ret = vfs_create_file (proc, proc->cwv, path); + spin_unlock (&proc->lock); + + return SYSRESULT (ret); +} + /* int get_exec_pid (void) */ DEFINE_SYSCALL (sys_get_exec_pid) { return SYSRESULT (proc->exec_pid); } @@ -485,6 +509,7 @@ static syscall_handler_func_t handler_table[] = { [SYS_GET_PROCGROUP] = &sys_get_procgroup, [SYS_GET_EXEC_PID] = &sys_get_exec_pid, [SYS_READ_DIR_ENTRY] = &sys_read_dir_entry, + [SYS_CREATE_FILE] = &sys_create_file, }; syscall_handler_func_t syscall_find_handler (int syscall_num) { diff --git a/libsystem/system.c b/libsystem/system.c index af3c63b..4a84478 100644 --- a/libsystem/system.c +++ b/libsystem/system.c @@ -68,3 +68,5 @@ int get_exec_pid (void) { return (int)do_syscall (SYS_GET_EXEC_PID, 0); } int read_dir_entry (const char* path, struct dir_entry* entry, size_t entry_num) { return (int)do_syscall (SYS_READ_DIR_ENTRY, path, entry, entry_num); } + +int create_file (const char* path) { return (int)do_syscall (SYS_CREATE_FILE, path); } diff --git a/libsystem/system.h b/libsystem/system.h index 2834ee2..c93f676 100644 --- a/libsystem/system.h +++ b/libsystem/system.h @@ -81,4 +81,7 @@ int get_exec_pid (void); /* Read directory entry */ int read_dir_entry (const char* path, struct dir_entry* entry, size_t entry_num); +/* create a file */ +int create_file (const char* path); + #endif // _LIBMSL_M_SYSTEM_H