libc: add disk management syscalls and expanded stdio support

This commit is contained in:
boreddevnl
2026-05-08 21:04:35 +02:00
parent 91edd3bc78
commit 5ae8c56d40
6 changed files with 382 additions and 95 deletions

View File

@@ -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);
}

View File

@@ -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

View File

@@ -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);

View File

@@ -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);
}

View File

@@ -3,6 +3,7 @@
#include <stdint.h>
#include <stddef.h>
#include <stdbool.h>
// 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