diff --git a/src/sys/syscall.c b/src/sys/syscall.c index 7566d28..d052058 100644 --- a/src/sys/syscall.c +++ b/src/sys/syscall.c @@ -25,6 +25,19 @@ #include "input/keycodes.h" #include "input/keymap.h" #include "app_metadata.h" +#include "disk.h" +#include "mkfs_fat32.h" + +#define SYSTEM_CMD_DISK_GET_COUNT 100 +#define SYSTEM_CMD_DISK_GET_INFO 101 +#define SYSTEM_CMD_DISK_WRITE_GPT 102 +#define SYSTEM_CMD_DISK_WRITE_MBR 103 +#define SYSTEM_CMD_DISK_MKFS_FAT32 104 +#define SYSTEM_CMD_DISK_MOUNT 105 +#define SYSTEM_CMD_DISK_UMOUNT 106 +#define SYSTEM_CMD_DISK_RESCAN 107 +#define SYSTEM_CMD_DISK_REPLACE_KERNEL 108 +#define SYSTEM_CMD_DISK_SYNC 109 #define SPAWN_FLAG_TERMINAL 0x1 #define SPAWN_FLAG_INHERIT_TTY 0x2 @@ -2125,7 +2138,235 @@ static uint64_t sys_cmd_get_keyboard_layout(const syscall_args_t *args) { return (uint64_t)keymap_get_current(); } -#define SYS_CMD_TABLE_SIZE 78 +typedef struct { + char devname[16]; + char label[32]; + uint32_t type; + uint32_t total_sectors; + bool is_partition; + bool is_fat32; + bool is_esp; + uint32_t lba_offset; +} k_disk_info_t; + +typedef struct { + uint32_t lba_start; + uint32_t sector_count; + uint8_t part_type; + uint8_t flags; + char label[36]; +} k_partition_spec_t; + +static void disk_k_strcpy(char *dst, const char *src, int max) { + int i = 0; + while (i < max - 1 && src[i]) { dst[i] = src[i]; i++; } + dst[i] = 0; +} + +static int disk_k_strcmp(const char *a, const char *b) { + while (*a && *a == *b) { a++; b++; } + return (unsigned char)*a - (unsigned char)*b; +} + +static uint64_t sys_cmd_disk_get_count(const syscall_args_t *args) { + (void)args; + return (uint64_t)disk_get_count(); +} + +static uint64_t sys_cmd_disk_get_info(const syscall_args_t *args) { + int index = (int)args->arg2; + k_disk_info_t *out = (k_disk_info_t *)args->arg3; + if (!out) return (uint64_t)-1; + Disk *d = disk_get_by_index(index); + if (!d) return (uint64_t)-1; + disk_k_strcpy(out->devname, d->devname, 16); + disk_k_strcpy(out->label, d->label, 32); + out->type = (uint32_t)d->type; + out->total_sectors = d->total_sectors; + out->is_partition = d->is_partition; + out->is_fat32 = d->is_fat32; + out->is_esp = d->is_esp; + out->lba_offset = d->partition_lba_offset; + return 0; +} + +static uint64_t sys_cmd_disk_write_gpt(const syscall_args_t *args) { + const char *devname = (const char *)args->arg2; + k_partition_spec_t *parts = (k_partition_spec_t *)args->arg3; + int count = (int)args->arg4; + if (!devname || !parts) return (uint64_t)-1; + Disk *d = disk_get_by_name(devname); + if (!d) return (uint64_t)-1; + return (uint64_t)disk_write_gpt(d, (disk_partition_spec_t *)parts, count); +} + +static uint64_t sys_cmd_disk_write_mbr(const syscall_args_t *args) { + const char *devname = (const char *)args->arg2; + k_partition_spec_t *parts = (k_partition_spec_t *)args->arg3; + int count = (int)args->arg4; + if (!devname || !parts) return (uint64_t)-1; + Disk *d = disk_get_by_name(devname); + if (!d) return (uint64_t)-1; + return (uint64_t)disk_write_mbr(d, (disk_partition_spec_t *)parts, count); +} + +static uint64_t sys_cmd_disk_mkfs_fat32(const syscall_args_t *args) { + extern int mkfs_fat32_format(Disk *disk, uint32_t sector_count, const char *label); + const char *devname = (const char *)args->arg2; + const char *label = (const char *)args->arg3; + if (!devname) return (uint64_t)-1; + Disk *d = disk_get_by_name(devname); + if (!d) return (uint64_t)-1; + int ret = mkfs_fat32_format(d, d->total_sectors, label); + if (ret == 0) d->is_fat32 = true; + return (uint64_t)ret; +} + +static uint64_t sys_cmd_disk_mount(const syscall_args_t *args) { + const char *devname = (const char *)args->arg2; + const char *mountpoint = (const char *)args->arg3; + if (!devname || !mountpoint) return (uint64_t)-1; + Disk *d = disk_get_by_name(devname); + if (!d || !d->is_fat32) return (uint64_t)-1; + void *vol = fat32_mount_volume(d); + if (!vol) return (uint64_t)-1; + if (!vfs_mount(mountpoint, devname, "fat32", fat32_get_realfs_ops(), vol)) return (uint64_t)-1; + wm_notify_fs_change(); + return 0; +} + +static uint64_t sys_cmd_disk_umount(const syscall_args_t *args) { + const char *mountpoint = (const char *)args->arg2; + if (!mountpoint) return (uint64_t)-1; + return vfs_umount(mountpoint) ? 0 : (uint64_t)-1; +} + +static uint64_t sys_cmd_disk_rescan(const syscall_args_t *args) { + const char *devname = (const char *)args->arg2; + if (!devname) return (uint64_t)-1; + Disk *d = disk_get_by_name(devname); + if (!d) return (uint64_t)-1; + return (uint64_t)disk_rescan(d); +} + +static uint64_t sys_cmd_disk_sync(const syscall_args_t *args) { + const char *mountpoint = (const char *)args->arg2; + if (!mountpoint) return (uint64_t)-1; + int mc = vfs_get_mount_count(); + for (int i = 0; i < mc; i++) { + vfs_mount_t *m = vfs_get_mount(i); + if (m && m->active && disk_k_strcmp(m->path, mountpoint) == 0) { + Disk *d = disk_get_by_name(m->device); + if (d) return (uint64_t)disk_sync(d); + } + } + return (uint64_t)-1; +} + +static uint64_t sys_cmd_disk_replace_kernel(const syscall_args_t *args) { + extern void serial_write(const char *str); + const char *src_path = (const char *)args->arg2; + const char *esp_mountpoint = (const char *)args->arg3; + if (!src_path || !esp_mountpoint) return (uint64_t)-1; + + char dest_path[256]; + int mi = 0; + while (mi < 255 && esp_mountpoint[mi]) { dest_path[mi] = esp_mountpoint[mi]; mi++; } + const char *suffix = "/boredos.elf"; + for (int i = 0; suffix[i] && mi < 255; i++) dest_path[mi++] = suffix[i]; + dest_path[mi] = 0; + + if (disk_k_strcmp(src_path, dest_path) == 0) { + serial_write("[KUP] Error: source and destination are the same file\n"); + return (uint64_t)-1; + } + + vfs_file_t *src = vfs_open(src_path, "r"); + if (!src) { serial_write("[KUP] Error: source not found\n"); return (uint64_t)-1; } + + uint32_t src_size = vfs_file_size(src); + if (src_size > 100 * 1024 * 1024) { + serial_write("[KUP] Error: source > 100 MB\n"); + vfs_close(src); return (uint64_t)-1; + } + + uint8_t magic[4]; + vfs_read(src, magic, 4); + if (magic[0] != 0x7F || magic[1] != 'E' || magic[2] != 'L' || magic[3] != 'F') { + serial_write("[KUP] Error: not an ELF file\n"); + vfs_close(src); return (uint64_t)-1; + } + vfs_seek(src, 0, 0); + + char bak_path[256]; + mi = 0; + while (mi < 255 && esp_mountpoint[mi]) { bak_path[mi] = esp_mountpoint[mi]; mi++; } + const char *bak_suffix = "/boredos.elf.bak"; + for (int i = 0; bak_suffix[i] && mi < 255; i++) bak_path[mi++] = bak_suffix[i]; + bak_path[mi] = 0; + + vfs_file_t *existing = vfs_open(dest_path, "r"); + if (existing) { + vfs_file_t *bakf = vfs_open(bak_path, "w"); + if (bakf) { + uint8_t *cbuf = (uint8_t *)kmalloc(4096); + if (cbuf) { + int n; + while ((n = vfs_read(existing, cbuf, 4096)) > 0) + vfs_write(bakf, cbuf, n); + kfree(cbuf); + } + vfs_close(bakf); + } else { + serial_write("[KUP] Warning: could not create backup\n"); + } + vfs_close(existing); + } + + vfs_file_t *dst = vfs_open(dest_path, "w"); + if (!dst) { + serial_write("[KUP] Error: could not open destination for write\n"); + vfs_close(src); return (uint64_t)-1; + } + + uint8_t *buf = (uint8_t *)kmalloc(4096); + if (!buf) { vfs_close(src); vfs_close(dst); return (uint64_t)-1; } + + uint32_t bytes_written = 0; + int n; + while ((n = vfs_read(src, buf, 4096)) > 0) { + int written = vfs_write(dst, buf, n); + if (written != n) { + serial_write("[KUP] Error: write failed mid-copy\n"); + kfree(buf); vfs_close(src); vfs_close(dst); return (uint64_t)-1; + } + bytes_written += (uint32_t)written; + } + + kfree(buf); + vfs_close(src); + vfs_close(dst); + + if (bytes_written != src_size) { + serial_write("[KUP] Error: incomplete write (size mismatch)\n"); + return (uint64_t)-1; + } + + serial_write("[KUP] Kernel replaced ("); + { + char numstr[16]; int ni = 15; + numstr[ni] = 0; + uint32_t v = bytes_written; + if (v == 0) { numstr[--ni] = '0'; } else { + while (v > 0) { numstr[--ni] = '0' + (v % 10); v /= 10; } + } + serial_write(numstr + ni); + } + serial_write(" bytes). Backup at boredos.elf.bak. Reboot required.\n"); + return 0; +} + +#define SYS_CMD_TABLE_SIZE 110 static const syscall_handler_fn sys_cmd_table[SYS_CMD_TABLE_SIZE] = { [SYSTEM_CMD_SET_BG_COLOR] = sys_cmd_set_bg_color, [SYSTEM_CMD_SET_BG_PATTERN] = sys_cmd_set_bg_pattern, @@ -2192,6 +2433,16 @@ static const syscall_handler_fn sys_cmd_table[SYS_CMD_TABLE_SIZE] = { [SYSTEM_CMD_SIGPENDING] = sys_cmd_sigpending, [SYSTEM_CMD_GET_ELF_METADATA] = sys_cmd_get_elf_metadata, [SYSTEM_CMD_GET_ELF_PRIMARY_IMAGE] = sys_cmd_get_elf_primary_image, + [SYSTEM_CMD_DISK_GET_COUNT] = sys_cmd_disk_get_count, + [SYSTEM_CMD_DISK_GET_INFO] = sys_cmd_disk_get_info, + [SYSTEM_CMD_DISK_WRITE_GPT] = sys_cmd_disk_write_gpt, + [SYSTEM_CMD_DISK_WRITE_MBR] = sys_cmd_disk_write_mbr, + [SYSTEM_CMD_DISK_MKFS_FAT32] = sys_cmd_disk_mkfs_fat32, + [SYSTEM_CMD_DISK_MOUNT] = sys_cmd_disk_mount, + [SYSTEM_CMD_DISK_UMOUNT] = sys_cmd_disk_umount, + [SYSTEM_CMD_DISK_RESCAN] = sys_cmd_disk_rescan, + [SYSTEM_CMD_DISK_REPLACE_KERNEL] = sys_cmd_disk_replace_kernel, + [SYSTEM_CMD_DISK_SYNC] = sys_cmd_disk_sync, }; static uint64_t handle_sys_write(const syscall_args_t *args) { diff --git a/src/userland/libc/stdio.c b/src/userland/libc/stdio.c index 510d589..9003df9 100644 --- a/src/userland/libc/stdio.c +++ b/src/userland/libc/stdio.c @@ -13,9 +13,9 @@ static FILE boredos_stdin_obj = {0, 0, 0, 0, 0}; static FILE boredos_stdout_obj = {1, 0, 0, 0, 0}; static FILE boredos_stderr_obj = {2, 0, 0, 0, 0}; -__attribute__((weak)) FILE *stdin = &boredos_stdin_obj; -__attribute__((weak)) FILE *stdout = &boredos_stdout_obj; -__attribute__((weak)) FILE *stderr = &boredos_stderr_obj; +FILE *stdin = &boredos_stdin_obj; +FILE *stdout = &boredos_stdout_obj; +FILE *stderr = &boredos_stderr_obj; static int _b_streq(const char *a, const char *b) { while (*a && *b) { @@ -55,7 +55,7 @@ static char *_b_tmpname_generate(char *out, size_t out_cap) { return NULL; } -__attribute__((weak)) FILE *fopen(const char *path, const char *mode) { +FILE *fopen(const char *path, const char *mode) { int fd = sys_open(path, mode); FILE *f; if (fd < 0) { @@ -76,7 +76,7 @@ __attribute__((weak)) FILE *fopen(const char *path, const char *mode) { return f; } -__attribute__((weak)) FILE *freopen(const char *path, const char *mode, FILE *stream) { +FILE *freopen(const char *path, const char *mode, FILE *stream) { int fd; if (!stream) { return fopen(path, mode); @@ -97,7 +97,7 @@ __attribute__((weak)) FILE *freopen(const char *path, const char *mode, FILE *st return stream; } -__attribute__((weak)) int fclose(FILE *stream) { +int fclose(FILE *stream) { if (!stream) { return EOF; } @@ -110,7 +110,7 @@ __attribute__((weak)) int fclose(FILE *stream) { return 0; } -__attribute__((weak)) size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream) { +size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream) { size_t total; int n; if (!stream || !ptr || size == 0 || nmemb == 0) { @@ -132,7 +132,7 @@ __attribute__((weak)) size_t fread(void *ptr, size_t size, size_t nmemb, FILE *s return (size_t)n / size; } -__attribute__((weak)) size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream) { +size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream) { size_t total; int n; if (!stream || !ptr || size == 0 || nmemb == 0) { @@ -151,7 +151,7 @@ __attribute__((weak)) size_t fwrite(const void *ptr, size_t size, size_t nmemb, return (size_t)n / size; } -__attribute__((weak)) int fseek(FILE *stream, long offset, int whence) { +int fseek(FILE *stream, long offset, int whence) { if (!stream) { return -1; } @@ -164,14 +164,14 @@ __attribute__((weak)) int fseek(FILE *stream, long offset, int whence) { return 0; } -__attribute__((weak)) long ftell(FILE *stream) { +long ftell(FILE *stream) { if (!stream) { return -1; } return (long)sys_tell(stream->fd); } -__attribute__((weak)) int getc(FILE *stream) { +int getc(FILE *stream) { unsigned char ch; int n; if (!stream) { @@ -193,7 +193,7 @@ __attribute__((weak)) int getc(FILE *stream) { return (int)ch; } -__attribute__((weak)) int ungetc(int c, FILE *stream) { +int ungetc(int c, FILE *stream) { if (!stream || c == EOF) { return EOF; } @@ -203,7 +203,7 @@ __attribute__((weak)) int ungetc(int c, FILE *stream) { return c; } -__attribute__((weak)) char *fgets(char *s, int n, FILE *stream) { +char *fgets(char *s, int n, FILE *stream) { int i; if (!s || n <= 0 || !stream) { return NULL; @@ -226,7 +226,7 @@ __attribute__((weak)) char *fgets(char *s, int n, FILE *stream) { return s; } -__attribute__((weak)) int fputs(const char *s, FILE *stream) { +int fputs(const char *s, FILE *stream) { size_t len; size_t written; if (!s || !stream) { @@ -237,31 +237,31 @@ __attribute__((weak)) int fputs(const char *s, FILE *stream) { return (written == len) ? (int)len : EOF; } -__attribute__((weak)) int feof(FILE *stream) { +int feof(FILE *stream) { return stream ? stream->eof : 1; } -__attribute__((weak)) int ferror(FILE *stream) { +int ferror(FILE *stream) { return stream ? stream->err : 1; } -__attribute__((weak)) void clearerr(FILE *stream) { +void clearerr(FILE *stream) { if (stream) { stream->eof = 0; stream->err = 0; } } -__attribute__((weak)) int fflush(FILE *stream) { +int fflush(FILE *stream) { (void)stream; return 0; } -__attribute__((weak)) int remove(const char *path) { +int remove(const char *path) { return sys_delete(path); } -__attribute__((weak)) int rename(const char *oldpath, const char *newpath) { +int rename(const char *oldpath, const char *newpath) { FILE *src; FILE *dst; char buf[1024]; @@ -317,7 +317,7 @@ __attribute__((weak)) int rename(const char *oldpath, const char *newpath) { return 0; } -__attribute__((weak)) FILE *tmpfile(void) { +FILE *tmpfile(void) { char path[FILENAME_MAX]; if (!_b_tmpname_generate(path, sizeof(path))) { return NULL; @@ -325,7 +325,7 @@ __attribute__((weak)) FILE *tmpfile(void) { return fopen(path, "w+"); } -__attribute__((weak)) char *tmpnam(char *s) { +char *tmpnam(char *s) { char *dst = s ? s : _b_tmpname_buf; return _b_tmpname_generate(dst, FILENAME_MAX); } @@ -734,7 +734,7 @@ __attribute__((weak)) int sprintf(char *str, const char *fmt, ...) { return n; } -__attribute__((weak)) int fprintf(FILE *stream, const char *fmt, ...) { +int fprintf(FILE *stream, const char *fmt, ...) { char buf[1024]; int len; va_list ap; @@ -754,6 +754,7 @@ __attribute__((weak)) int fprintf(FILE *stream, const char *fmt, ...) { } __attribute__((weak)) int vfprintf(FILE *stream, const char *fmt, va_list ap) { + if (!stream) return 0; char buf[1024]; int len = vsnprintf(buf, sizeof(buf), fmt, ap); if (len <= 0) { @@ -768,7 +769,7 @@ __attribute__((weak)) int vfprintf(FILE *stream, const char *fmt, va_list ap) { return len; } -__attribute__((weak)) int fputc(int c, FILE *stream) { +int fputc(int c, FILE *stream) { unsigned char ch = (unsigned char)c; if (!stream) { return EOF; @@ -783,7 +784,7 @@ __attribute__((weak)) int putchar(int c) { return fputc(c, stdout); } -__attribute__((weak)) long filelength(FILE *f) { +long filelength(FILE *f) { if (!f) { return -1; } @@ -1032,7 +1033,7 @@ static int _b_vsscanf_core(const char *str, const char *fmt, va_list ap) { return assigned; } -__attribute__((weak)) int sscanf(const char *str, const char *fmt, ...) { +int sscanf(const char *str, const char *fmt, ...) { int n; va_list ap; if (!str || !fmt) { @@ -1044,3 +1045,16 @@ __attribute__((weak)) int sscanf(const char *str, const char *fmt, ...) { va_end(ap); return n; } + +__attribute__((weak)) void puts(const char *s) { + if (!s) return; + fputs(s, stdout); + fputc('\n', stdout); +} + +__attribute__((weak)) void printf(const char *fmt, ...) { + va_list ap; + va_start(ap, fmt); + vfprintf(stdout, fmt, ap); + va_end(ap); +} diff --git a/src/userland/libc/stdio.h b/src/userland/libc/stdio.h index 4d8447f..9c4b9b0 100644 --- a/src/userland/libc/stdio.h +++ b/src/userland/libc/stdio.h @@ -53,4 +53,7 @@ int rename(const char *oldpath, const char *newpath); FILE *tmpfile(void); char *tmpnam(char *s); +void puts(const char *s); +void printf(const char *fmt, ...); + #endif diff --git a/src/userland/libc/stdlib.c b/src/userland/libc/stdlib.c index a471ec4..c3d317b 100644 --- a/src/userland/libc/stdlib.c +++ b/src/userland/libc/stdlib.c @@ -255,74 +255,6 @@ void itoa(int n, char *buf) { } } -// IO functions -void puts(const char *s) { - sys_write(1, s, strlen(s)); - sys_write(1, "\n", 1); -} - -void printf(const char *fmt, ...) { - __builtin_va_list args; - __builtin_va_start(args, fmt); - char buf[1024]; - int buf_idx = 0; - - while (*fmt) { - if (*fmt == '%') { - fmt++; - // Flush current buffer - if (buf_idx > 0) { - sys_write(1, buf, buf_idx); - buf_idx = 0; - } - - if (*fmt == 's') { - char *s = __builtin_va_arg(args, char *); - if (s) sys_write(1, s, strlen(s)); - else sys_write(1, "(null)", 6); - } else if (*fmt == 'd') { - int d = __builtin_va_arg(args, int); - char ibuf[32]; - itoa(d, ibuf); - sys_write(1, ibuf, strlen(ibuf)); - } else if (*fmt == 'X' || *fmt == 'x') { - uint32_t val = __builtin_va_arg(args, uint32_t); - char xbuf[16]; - int xi = 0; - if (val == 0) xbuf[xi++] = '0'; - else { - while (val > 0) { - uint32_t rem = val % 16; - xbuf[xi++] = (rem < 10) ? (rem + '0') : (rem - 10 + 'A'); - val /= 16; - } - } - while (xi > 0) { - char c = xbuf[--xi]; - sys_write(1, &c, 1); - } - } else if (*fmt == 'c') { - char c = (char)__builtin_va_arg(args, int); - sys_write(1, &c, 1); - } else if (*fmt == '%') { - char c = '%'; - sys_write(1, &c, 1); - } - } else { - buf[buf_idx++] = *fmt; - if (buf_idx >= 1024) { - sys_write(1, buf, buf_idx); - buf_idx = 0; - } - } - fmt++; - } - if (buf_idx > 0) { - sys_write(1, buf, buf_idx); - } - __builtin_va_end(args); -} - // System/Process functions int chdir(const char *path) { return sys_chdir(path); diff --git a/src/userland/libc/syscall.c b/src/userland/libc/syscall.c index dc99981..b8fe4d6 100644 --- a/src/userland/libc/syscall.c +++ b/src/userland/libc/syscall.c @@ -346,3 +346,42 @@ int sys_get_elf_primary_image(const char *path, char *out_path, size_t out_path_ (uint64_t)path, (uint64_t)out_path, (uint64_t)out_path_size, 0); } +int sys_disk_get_count(void) { + return (int)syscall2(SYS_SYSTEM, SYSTEM_CMD_DISK_GET_COUNT, 0); +} + +int sys_disk_get_info(int index, disk_info_t *out) { + return (int)syscall3(SYS_SYSTEM, SYSTEM_CMD_DISK_GET_INFO, (uint64_t)index, (uint64_t)out); +} + +int sys_disk_write_gpt(const char *devname, partition_spec_t *parts, int count) { + return (int)syscall4(SYS_SYSTEM, SYSTEM_CMD_DISK_WRITE_GPT, (uint64_t)devname, (uint64_t)parts, (uint64_t)count); +} + +int sys_disk_write_mbr(const char *devname, partition_spec_t *parts, int count) { + return (int)syscall4(SYS_SYSTEM, SYSTEM_CMD_DISK_WRITE_MBR, (uint64_t)devname, (uint64_t)parts, (uint64_t)count); +} + +int sys_disk_mkfs_fat32(const char *devname, const char *label) { + return (int)syscall3(SYS_SYSTEM, SYSTEM_CMD_DISK_MKFS_FAT32, (uint64_t)devname, (uint64_t)label); +} + +int sys_disk_mount(const char *devname, const char *mountpoint) { + return (int)syscall3(SYS_SYSTEM, SYSTEM_CMD_DISK_MOUNT, (uint64_t)devname, (uint64_t)mountpoint); +} + +int sys_disk_umount(const char *mountpoint) { + return (int)syscall2(SYS_SYSTEM, SYSTEM_CMD_DISK_UMOUNT, (uint64_t)mountpoint); +} + +int sys_disk_sync(const char *mountpoint) { + return (int)syscall2(SYS_SYSTEM, SYSTEM_CMD_DISK_SYNC, (uint64_t)mountpoint); +} + +int sys_disk_rescan(const char *devname) { + return (int)syscall2(SYS_SYSTEM, SYSTEM_CMD_DISK_RESCAN, (uint64_t)devname); +} + +int sys_disk_replace_kernel(const char *src_path, const char *esp_mountpoint) { + return (int)syscall3(SYS_SYSTEM, SYSTEM_CMD_DISK_REPLACE_KERNEL, (uint64_t)src_path, (uint64_t)esp_mountpoint); +} diff --git a/src/userland/libc/syscall.h b/src/userland/libc/syscall.h index 4250f83..135f2f0 100644 --- a/src/userland/libc/syscall.h +++ b/src/userland/libc/syscall.h @@ -3,6 +3,7 @@ #include #include +#include // Standard syscalls available from Kernel mode #define SYS_EXIT 0 @@ -241,4 +242,51 @@ void sys_yield(void); int sys_get_elf_metadata(const char *path, boredos_app_metadata_t *out_metadata); int sys_get_elf_primary_image(const char *path, char *out_path, size_t out_path_size); +// Disk Management Syscalls + +#define SYSTEM_CMD_DISK_GET_COUNT 100 +#define SYSTEM_CMD_DISK_GET_INFO 101 +#define SYSTEM_CMD_DISK_MOUNT 105 +#define SYSTEM_CMD_DISK_UMOUNT 106 +#define SYSTEM_CMD_DISK_RESCAN 107 +#define SYSTEM_CMD_DISK_SYNC 109 + +#define SYSTEM_CMD_DISK_WRITE_GPT 102 +#define SYSTEM_CMD_DISK_WRITE_MBR 103 +#define SYSTEM_CMD_DISK_MKFS_FAT32 104 +#define SYSTEM_CMD_DISK_REPLACE_KERNEL 108 + +typedef struct { + char devname[16]; + char label[32]; + uint32_t type; + uint32_t total_sectors; + bool is_partition; + bool is_fat32; + bool is_esp; + uint32_t lba_offset; +} disk_info_t; + +typedef struct { + uint32_t lba_start; + uint32_t sector_count; + uint8_t part_type; + uint8_t flags; + char label[36]; +} partition_spec_t; + +#define PART_FLAG_ESP 0x01 +#define MIN_INSTALL_SECTORS 2097152 + +int sys_disk_get_count(void); +int sys_disk_get_info(int index, disk_info_t *out); +int sys_disk_write_gpt(const char *devname, partition_spec_t *parts, int count); +int sys_disk_write_mbr(const char *devname, partition_spec_t *parts, int count); +int sys_disk_mkfs_fat32(const char *devname, const char *label); +int sys_disk_mount(const char *devname, const char *mountpoint); +int sys_disk_umount(const char *mountpoint); +int sys_disk_sync(const char *mountpoint); +int sys_disk_rescan(const char *devname); +int sys_disk_replace_kernel(const char *src_path, const char *esp_mountpoint); + #endif