Compare commits

...

11 Commits

58 changed files with 1506 additions and 797 deletions

View File

@ -1,3 +1,4 @@
print 'this is an init script!' print 'this is an init script!\n'
base:/bin/pctl ls $tb -m runfile -f base:/scripts/mount.tb
base:/bin/tb -m interactive -preload base:/scripts/rc.tb $pctl ls
$tb -m interactive

2
base/scripts/mount.tb Normal file
View File

@ -0,0 +1,2 @@
print 'Mounting filesystems...\n'
$fs mount -mp system -fs LittleFS -dev atasd-mst -fmt no

View File

@ -72,7 +72,7 @@ int32_t littlefs_vobj_write(struct VfsObj *vobj, const uint8_t *const buffer, si
return E_OK; return E_OK;
} }
int32_t littlefs_stat(struct VfsMountPoint *vmp, const char *path, IoctlStat *statbuf) { int32_t littlefs_stat(struct VfsMountPoint *vmp, const char *path, FsStat *statbuf) {
struct lfs_info info; struct lfs_info info;
spinlock_acquire(&vmp->spinlock); spinlock_acquire(&vmp->spinlock);
@ -84,10 +84,10 @@ int32_t littlefs_stat(struct VfsMountPoint *vmp, const char *path, IoctlStat *st
} }
if (info.type == LFS_TYPE_REG) { if (info.type == LFS_TYPE_REG) {
statbuf->type = IOCTLSTAT_FILE; statbuf->type = FSSTAT_FILE;
statbuf->size = info.size; statbuf->size = info.size;
} else if (info.type == LFS_TYPE_DIR) { } else if (info.type == LFS_TYPE_DIR) {
statbuf->type = IOCTLSTAT_DIR; statbuf->type = FSSTAT_DIR;
statbuf->size = 0; statbuf->size = 0;
// TODO: find a better way than this... !!! // TODO: find a better way than this... !!!
lfs_dir_t dir; lfs_dir_t dir;
@ -170,7 +170,7 @@ struct VfsObj *littlefs_open(struct VfsMountPoint *vmp, const char *path, uint32
return vobj; return vobj;
} }
int32_t littlefs_fetchdirent(struct VfsMountPoint *vmp, const char *path, IoctlDirent *direntbuf, size_t idx) { int32_t littlefs_fetchdirent(struct VfsMountPoint *vmp, const char *path, FsDirent *direntbuf, size_t idx) {
size_t i = 0; size_t i = 0;
struct lfs_info statinfo; struct lfs_info statinfo;
int ok; int ok;
@ -199,10 +199,10 @@ int32_t littlefs_fetchdirent(struct VfsMountPoint *vmp, const char *path, IoctlD
while (lfs_dir_read(&vmp->fs.littlefs.instance, &dir, &entinfo) > 0) { while (lfs_dir_read(&vmp->fs.littlefs.instance, &dir, &entinfo) > 0) {
if (i == idx) { if (i == idx) {
if (entinfo.type == LFS_TYPE_REG) { if (entinfo.type == LFS_TYPE_REG) {
direntbuf->stat.type = IOCTLSTAT_FILE; direntbuf->stat.type = FSSTAT_FILE;
direntbuf->stat.size = entinfo.size; direntbuf->stat.size = entinfo.size;
} else if (entinfo.type == LFS_TYPE_DIR) { } else if (entinfo.type == LFS_TYPE_DIR) {
direntbuf->stat.type = IOCTLSTAT_DIR; direntbuf->stat.type = FSSTAT_DIR;
} }
hal_memcpy(direntbuf->name, entinfo.name, sizeof(direntbuf->name)); hal_memcpy(direntbuf->name, entinfo.name, sizeof(direntbuf->name));
@ -219,13 +219,27 @@ int32_t littlefs_fetchdirent(struct VfsMountPoint *vmp, const char *path, IoctlD
int portlfs_read(const struct lfs_config *c, lfs_block_t block, lfs_off_t off, void *buffer, lfs_size_t size) { int portlfs_read(const struct lfs_config *c, lfs_block_t block, lfs_off_t off, void *buffer, lfs_size_t size) {
VfsMountPoint *vmp = c->context; VfsMountPoint *vmp = c->context;
vmp->backingsd->read(vmp->backingsd, buffer, size, block * LITTLEFS_BLOCK_SIZE + off);
uint64_t byteaddr = (uint64_t)block * c->block_size + off;
ptrdiff_t sector = byteaddr / vmp->backingsd->sectorsize;
ptrdiff_t sector_off = byteaddr % vmp->backingsd->sectorsize;
int32_t ret = vmp->backingsd->read(vmp->backingsd, (uint8_t *const)buffer, sector, sector_off, size);
if (ret != E_OK)
return LFS_ERR_IO;
return 0; return 0;
} }
int portlfs_prog(const struct lfs_config *c, lfs_block_t block, lfs_off_t off, const void *buffer, lfs_size_t size) { int portlfs_prog(const struct lfs_config *c, lfs_block_t block, lfs_off_t off, const void *buffer, lfs_size_t size) {
VfsMountPoint *vmp = c->context; VfsMountPoint *vmp = c->context;
vmp->backingsd->write(vmp->backingsd, buffer, size, block * LITTLEFS_BLOCK_SIZE + off);
uint64_t byteaddr = (uint64_t)block * c->block_size + off;
ptrdiff_t sector = byteaddr / vmp->backingsd->sectorsize;
ptrdiff_t sector_off = byteaddr % vmp->backingsd->sectorsize;
int32_t ret = vmp->backingsd->write(vmp->backingsd, (const uint8_t *)buffer, sector, sector_off, size);
if (ret != E_OK)
return LFS_ERR_IO;
return 0; return 0;
} }

View File

@ -4,9 +4,9 @@
#include <stdint.h> #include <stdint.h>
#include <stdbool.h> #include <stdbool.h>
#include "fs/littlefs/lfs.h" #include "fs/littlefs/lfs.h"
#include "sysdefs/ioctl.h" #include "sysdefs/fs.h"
#define LITTLEFS_BLOCK_SIZE 4096 #define LITTLEFS_BLOCK_SIZE 512
struct VfsMountPoint; struct VfsMountPoint;
struct VfsObj; struct VfsObj;
@ -17,8 +17,8 @@ typedef struct {
int32_t littlefs_cleanup(struct VfsMountPoint *vmp); int32_t littlefs_cleanup(struct VfsMountPoint *vmp);
struct VfsObj *littlefs_open(struct VfsMountPoint *vmp, const char *path, uint32_t flags); struct VfsObj *littlefs_open(struct VfsMountPoint *vmp, const char *path, uint32_t flags);
int32_t littlefs_stat(struct VfsMountPoint *vmp, const char *path, IoctlStat *statbuf); int32_t littlefs_stat(struct VfsMountPoint *vmp, const char *path, FsStat *statbuf);
int32_t littlefs_fetchdirent(struct VfsMountPoint *vmp, const char *path, IoctlDirent *direntbuf, size_t idx); int32_t littlefs_fetchdirent(struct VfsMountPoint *vmp, const char *path, FsDirent *direntbuf, size_t idx);
int32_t littlefs_mkdir(struct VfsMountPoint *vmp, const char *path); int32_t littlefs_mkdir(struct VfsMountPoint *vmp, const char *path);
int portlfs_read(const struct lfs_config *c, lfs_block_t block, lfs_off_t off, void *buffer, lfs_size_t size); int portlfs_read(const struct lfs_config *c, lfs_block_t block, lfs_off_t off, void *buffer, lfs_size_t size);

View File

@ -26,3 +26,21 @@ uint32_t io_in32(uint16_t port) {
void io_out32(uint16_t port, uint32_t value) { void io_out32(uint16_t port, uint32_t value) {
asm volatile("outl %%eax, %%dx" :: "d"(port), "a"(value)); asm volatile("outl %%eax, %%dx" :: "d"(port), "a"(value));
} }
void io_ins16(uint16_t port, void *addr, int cnt) {
asm volatile(
"cld; rep insw"
: "+D"(addr), "+c"(cnt)
: "d"(port)
: "memory", "cc"
);
}
void io_outs16(uint16_t port, const void *addr, int cnt) {
asm volatile(
"cld; rep outsw"
: "+S"(addr), "+c"(cnt)
: "d"(port)
: "memory", "cc"
);
}

View File

@ -12,4 +12,7 @@ void io_out16(uint16_t port, uint16_t value);
uint32_t io_in32(uint16_t port); uint32_t io_in32(uint16_t port);
void io_out32(uint16_t port, uint32_t value); void io_out32(uint16_t port, uint32_t value);
void io_ins16(uint16_t port, void *addr, int cnt);
void io_outs16(uint16_t port, const void *addr, int cnt);
#endif // HAL_IO_H_ #endif // HAL_IO_H_

View File

@ -14,37 +14,6 @@
#include "dev/dev.h" #include "dev/dev.h"
#include "randcrypto/randcrypto.h" #include "randcrypto/randcrypto.h"
const char *human_size(uint64_t bytes, char *buf, size_t bufsize) {
static const char *units[] = { "B", "KiB", "MiB", "GiB", "TiB", "PiB" };
int unit = 0;
// Scale down until value fits nicely
uint64_t rem = 0;
while (bytes >= 1024 && unit < (int)(sizeof(units)/sizeof(units[0])) - 1) {
rem = bytes % 1024;
bytes /= 1024;
unit++;
}
if (unit == 0) {
// Just bytes
ksnprintf(buf, bufsize, "%llu %s", (unsigned long long)bytes, units[unit]);
} else {
// Show one decimal place without using floats
// Multiply remainder by 10 to get first decimal digit
uint64_t frac = (rem * 10 + 512) / 1024; // rounded
if (frac == 10) { // handle carry, e.g. 1023.9 -> 1024.0
bytes++;
frac = 0;
}
if (frac > 0) ksnprintf(buf, bufsize, "%llu.%llu %s", (unsigned long long)bytes, (unsigned long long)frac, units[unit]);
else ksnprintf(buf, bufsize, "%llu %s", (unsigned long long)bytes, units[unit]);
}
return buf;
}
void log_bootinfo(void) { void log_bootinfo(void) {
char buf[100]; char buf[100];
LOG("kmain", "Memory total = %s\n", human_size(BOOT_INFO.memmap_total, buf, sizeof(buf))); LOG("kmain", "Memory total = %s\n", human_size(BOOT_INFO.memmap_total, buf, sizeof(buf)));

View File

@ -13,8 +13,8 @@
#include "vfs/vfs.h" #include "vfs/vfs.h"
#include "bootinfo/bootinfo.h" #include "bootinfo/bootinfo.h"
#include "ipc/pipe/pipe.h" #include "ipc/pipe/pipe.h"
#include "sysdefs/processctl.h" #include "sysdefs/proc.h"
#include "sysdefs/ioctl.h" #include "sysdefs/fs.h"
#define PROC_REAPER_FREQ 30 #define PROC_REAPER_FREQ 30
@ -75,12 +75,12 @@ ElfAuxval proc_load_elf_segs(Proc *proc, uint8_t *data) {
} }
Proc *proc_spawnuser(char *mountpoint, char *path) { Proc *proc_spawnuser(char *mountpoint, char *path) {
IoctlStat stat; FsStat stat;
if (vfs_stat(mountpoint, path, &stat) != E_OK) { if (vfs_stat(mountpoint, path, &stat) != E_OK) {
return NULL; return NULL;
} }
if (stat.type != IOCTLSTAT_FILE) { if (stat.type != FSSTAT_FILE) {
return NULL; return NULL;
} }

View File

@ -7,7 +7,7 @@
#include "bitmap/bitmap.h" #include "bitmap/bitmap.h"
#include "vfs/vfs.h" #include "vfs/vfs.h"
#include "ipc/pipe/pipe.h" #include "ipc/pipe/pipe.h"
#include "sysdefs/processctl.h" #include "sysdefs/proc.h"
#include "dev/dev.h" #include "dev/dev.h"
#define PROC_NAME_MAX 0x100 #define PROC_NAME_MAX 0x100

223
kernel/storedev/atasd.c Normal file
View File

@ -0,0 +1,223 @@
#include <stdint.h>
#include <stddef.h>
#include <stdbool.h>
#include "atasd.h"
#include "storedev.h"
#include "hal/hal.h"
#include "util/util.h"
#include "kprintf.h"
#include "errors.h"
#include "hshtb.h"
#include "vfs/vfs.h"
#define ATA_REG_DATA 0x1f0
#define ATA_REG_ERROR 0x1f1
#define ATA_REG_SECCOUNT0 0x1f2
#define ATA_REG_LBA0 0x1f3
#define ATA_REG_LBA1 0x1f4
#define ATA_REG_LBA2 0x1f5
#define ATA_REG_DRIVE 0x1f6
#define ATA_REG_STATUS 0x1f7
#define ATA_REG_COMMAND 0x1f7
#define ATA_REG_CTRL 0x3f6
#define ATA_BSY 0x80
#define ATA_DRDY 0x40
#define ATA_DF 0x20
#define ATA_ERR 0x01
#define ATA_DRQ 0x08
#define ATA_CMD_READ_PIO_EXT 0x24
#define ATA_CMD_WRITE_PIO_EXT 0x34
#define ATA_CMD_CACHE_FLUSH_EXT 0xEA
#define ATA_CMD_IDENTIFY 0xEC
#define ATA_MASTER 0x00
#define ATA_SLAVE 0x01
int ata_wait(uint32_t timeout, bool require_drq, int checkerr) {
uint32_t i = 0;
uint8_t st;
for(;;) {
st = io_in8(ATA_REG_STATUS);
if (!(st & ATA_BSY))
break;
if (++i >= timeout)
return -1;
}
if (require_drq) {
i = 0;
while (!(st & ATA_DRQ)) {
if (st & ATA_ERR)
return -1;
st = io_in8(ATA_REG_STATUS);
if (++i >= timeout)
return -1;
}
}
if (checkerr && (st & (ATA_DF | ATA_ERR)))
return -1;
return 0;
}
void ata_delay400ns(void) {
io_in8(ATA_REG_CTRL);
io_in8(ATA_REG_CTRL);
io_in8(ATA_REG_CTRL);
io_in8(ATA_REG_CTRL);
}
// caller must synchronize
uint64_t ata_probesize_bytes(int devno) {
uint16_t identifydata[0x100];
io_out8(ATA_REG_DRIVE, 0xA0 | (devno << 4));
ata_delay400ns();
io_out8(ATA_REG_SECCOUNT0, 0);
io_out8(ATA_REG_LBA0, 0);
io_out8(ATA_REG_LBA1, 0);
io_out8(ATA_REG_LBA2, 0);
io_out8(ATA_REG_COMMAND, ATA_CMD_IDENTIFY);
if (ata_wait(100000, false, 0) < 0)
return 0;
uint8_t st = io_in8(ATA_REG_STATUS);
if (st == 0)
return 0;
if (ata_wait(100000, true, 1) < 0)
return 0;
io_ins16(ATA_REG_DATA, identifydata, 256);
bool lba48 = (identifydata[83] & (1<<10)) != 0;
if (lba48) {
uint64_t sectors = (uint64_t)identifydata[100]
| ((uint64_t)identifydata[101] << 16)
| ((uint64_t)identifydata[102] << 32)
| ((uint64_t)identifydata[103] << 48);
return sectors * (uint64_t)STOREDEV_ATASD_SECTORSIZE;
} else {
uint64_t sectors = (uint64_t)identifydata[60]
| ((uint64_t)identifydata[61] << 16);
return sectors * (uint64_t)STOREDEV_ATASD_SECTORSIZE;
}
}
bool ata_probe1(int drive) {
io_out8(ATA_REG_DRIVE, 0xA0 | (drive << 4));
for (int i = 0; i < 1000; i++) {
uint8_t status = io_in8(ATA_REG_STATUS);
if (status != 0 && status != 0xFF)
return true; // got something
}
return false;
}
void ata_probe(void) {
if (ata_probe1(ATA_MASTER)) {
uint64_t probesize = ata_probesize_bytes(ATA_MASTER);
char hs[20];
LOG("ata", "found ATA Master, size = %s\n", human_size(probesize, hs, sizeof(hs)));
AtaSdInitExtra extra = {
.devno = ATA_MASTER,
.capacity = probesize,
};
StoreDev *sd = storedev_create(STOREDEV_ATASD, (void *)&extra);
}
}
void ata_setup(int devno, uint16_t sectors, uint64_t lba) {
io_out8(ATA_REG_CTRL, 0x02);
io_out8(ATA_REG_DRIVE, 0x40 | (devno << 4));
ata_delay400ns();
io_out8(ATA_REG_SECCOUNT0, (sectors >> 8) & 0xFF);
io_out8(ATA_REG_LBA0, (lba >> 24) & 0xFF);
io_out8(ATA_REG_LBA1, (lba >> 32) & 0xFF);
io_out8(ATA_REG_LBA2, (lba >> 40) & 0xFF);
io_out8(ATA_REG_SECCOUNT0, sectors & 0xFF);
io_out8(ATA_REG_LBA0, (uint8_t)(lba & 0xFF));
io_out8(ATA_REG_LBA1, (uint8_t)((lba >> 8) & 0xFF));
io_out8(ATA_REG_LBA2, (uint8_t)((lba >> 16) & 0xFF));
}
int32_t atasd_init(struct StoreDev *sd, void *extra) {
AtaSdInitExtra *e = (AtaSdInitExtra *)extra;
sd->sd.atasd.devno = e->devno;
sd->sd.atasd.capacity = e->capacity;
return E_OK;
}
int32_t atasd_read(struct StoreDev *sd, uint8_t *const buffer, ptrdiff_t sector, ptrdiff_t off, size_t size) {
int32_t ret;
spinlock_acquire(&sd->spinlock);
AtaSd *ata = &sd->sd.atasd;
uint64_t lba = (uint64_t)(sector * (ptrdiff_t)sd->sectorsize + off) / (uint64_t)STOREDEV_ATASD_SECTORSIZE;
size_t sectors = size / STOREDEV_ATASD_SECTORSIZE;
if (size % STOREDEV_ATASD_SECTORSIZE) sectors++;
ata_setup(ata->devno, sectors, lba);
io_out8(ATA_REG_COMMAND, ATA_CMD_READ_PIO_EXT);
for (size_t s = 0; s < sectors; s++) {
if (ata_wait(100000, true, 1) < 0) { ret = E_BADIO; goto done; }
io_ins16(ATA_REG_DATA, (uint16_t *)(buffer + s * STOREDEV_ATASD_SECTORSIZE), STOREDEV_ATASD_SECTORSIZE/2);
}
ret = E_OK;
done:
spinlock_release(&sd->spinlock);
return ret;
}
int32_t atasd_write(struct StoreDev *sd, const uint8_t *const buffer, ptrdiff_t sector, ptrdiff_t off, size_t size) {
int32_t ret;
spinlock_acquire(&sd->spinlock);
AtaSd *ata = &sd->sd.atasd;
uint64_t lba = (uint64_t)(sector * (ptrdiff_t)sd->sectorsize + off) / (uint64_t)STOREDEV_ATASD_SECTORSIZE;
size_t sectors = size / STOREDEV_ATASD_SECTORSIZE;
if (size % STOREDEV_ATASD_SECTORSIZE) sectors++;
ata_setup(ata->devno, sectors, lba);
io_out8(ATA_REG_COMMAND, ATA_CMD_WRITE_PIO_EXT);
for (size_t s = 0; s < sectors; s++) {
if (ata_wait(100000, true, 1) < 0) { ret = E_BADIO; goto done; }
io_outs16(ATA_REG_DATA, (uint16_t *)(buffer + s * STOREDEV_ATASD_SECTORSIZE), STOREDEV_ATASD_SECTORSIZE/2);
}
io_out8(ATA_REG_COMMAND, ATA_CMD_CACHE_FLUSH_EXT);
if (ata_wait(100000, false, 1) < 0) { ret = E_BADIO; goto done; }
ret = E_OK;
done:
spinlock_release(&sd->spinlock);
return ret;
}
int32_t atasd_cleanup(struct StoreDev *sd) {
return E_OK;
}
size_t atasd_capacity(struct StoreDev *sd) {
size_t c = 0;
spinlock_acquire(&sd->spinlock);
c = sd->sd.atasd.capacity;
spinlock_release(&sd->spinlock);
return c;
}

30
kernel/storedev/atasd.h Normal file
View File

@ -0,0 +1,30 @@
#ifndef STOREDEV_ATASD_H_
#define STOREDEV_ATASD_H_
#include <stdint.h>
#include <stddef.h>
#include <stdbool.h>
#define STOREDEV_ATASD_SECTORSIZE 512
struct StoreDev;
typedef struct {
int devno;
size_t capacity;
} AtaSdInitExtra;
typedef struct {
int devno;
size_t capacity;
} AtaSd;
int32_t atasd_init(struct StoreDev *sd, void *extra);
int32_t atasd_read(struct StoreDev *sd, uint8_t *const buffer, ptrdiff_t sector, ptrdiff_t off, size_t size);
int32_t atasd_write(struct StoreDev *sd, const uint8_t *const buffer, ptrdiff_t sector, ptrdiff_t off, size_t size);
int32_t atasd_cleanup(struct StoreDev *sd);
size_t atasd_capacity(struct StoreDev *sd);
void ata_probe(void);
#endif // STOREDEV_ATASD_H_

View File

@ -23,16 +23,18 @@ int32_t ramsd_init(struct StoreDev *sd, void *extra) {
return E_OK; return E_OK;
} }
int32_t ramsd_read(struct StoreDev *sd, uint8_t *const buffer, size_t n, size_t off) { int32_t ramsd_read(struct StoreDev *sd, uint8_t *const buffer, ptrdiff_t sector, ptrdiff_t off, size_t size) {
RamSd *ramsd = &sd->sd.ramsd;
spinlock_acquire(&sd->spinlock); spinlock_acquire(&sd->spinlock);
hal_memcpy(buffer, sd->sd.ramsd.buffer + off, MIN(n, sd->sd.ramsd.capacity - off)); hal_memcpy(buffer, ramsd->buffer + (sector * sd->sectorsize + off), size);
spinlock_release(&sd->spinlock); spinlock_release(&sd->spinlock);
return E_OK; return E_OK;
} }
int32_t ramsd_write(struct StoreDev *sd, const uint8_t *const buffer, size_t n, size_t off) { int32_t ramsd_write(struct StoreDev *sd, const uint8_t *const buffer, ptrdiff_t sector, ptrdiff_t off, size_t size) {
RamSd *ramsd = &sd->sd.ramsd;
spinlock_acquire(&sd->spinlock); spinlock_acquire(&sd->spinlock);
hal_memcpy(sd->sd.ramsd.buffer + off, buffer, MIN(n, sd->sd.ramsd.capacity - off)); hal_memcpy(ramsd->buffer + (sector * sd->sectorsize + off), buffer, size);
spinlock_release(&sd->spinlock); spinlock_release(&sd->spinlock);
return E_OK; return E_OK;
} }

View File

@ -4,6 +4,8 @@
#include <stdint.h> #include <stdint.h>
#include <stddef.h> #include <stddef.h>
#define STOREDEV_RAMSD_SECTORSIZE 512
struct StoreDev; struct StoreDev;
typedef struct { typedef struct {
@ -17,8 +19,8 @@ typedef struct {
} RamSdInitExtra; } RamSdInitExtra;
int32_t ramsd_init(struct StoreDev *sd, void *extra); int32_t ramsd_init(struct StoreDev *sd, void *extra);
int32_t ramsd_read(struct StoreDev *sd, uint8_t *const buffer, size_t n, size_t off); int32_t ramsd_read(struct StoreDev *sd, uint8_t *const buffer, ptrdiff_t sector, ptrdiff_t off, size_t size);
int32_t ramsd_write(struct StoreDev *sd, const uint8_t *const buffer, size_t n, size_t off); int32_t ramsd_write(struct StoreDev *sd, const uint8_t *const buffer, ptrdiff_t sector, ptrdiff_t off, size_t size);
int32_t ramsd_cleanup(struct StoreDev *sd); int32_t ramsd_cleanup(struct StoreDev *sd);
size_t ramsd_capacity(struct StoreDev *sd); size_t ramsd_capacity(struct StoreDev *sd);

View File

@ -6,6 +6,7 @@
#include "errors.h" #include "errors.h"
#include "dlmalloc/malloc.h" #include "dlmalloc/malloc.h"
#include "ramsd.h" #include "ramsd.h"
#include "atasd.h"
#include "util/util.h" #include "util/util.h"
#include "dev/dev.h" #include "dev/dev.h"
#include "hshtb.h" #include "hshtb.h"
@ -19,16 +20,20 @@ void storedev_init(void) {
STOREDEV_LIST.head = NULL; STOREDEV_LIST.head = NULL;
LOG("storedev", "init\n"); LOG("storedev", "init\n");
ata_probe();
} }
void storedev_register_dev_entry(StoreDev *sd, int32_t sdtype) { void storedev_register_dev_entry(StoreDev *sd, int32_t sdtype) {
char uniq[5];
randcrypto_gen_uniqid(uniq, 4);
char key[20]; char key[20];
hal_memset(key, 0, sizeof(key)); hal_memset(key, 0, sizeof(key));
if (sdtype == STOREDEV_RAMSD) { if (sdtype == STOREDEV_RAMSD) {
char uniq[5];
randcrypto_gen_uniqid(uniq, 4);
ksprintf(key, "ramsd-%s", uniq); ksprintf(key, "ramsd-%s", uniq);
} else if (sdtype == STOREDEV_ATASD) {
ksprintf(key, "atasd-%s", sd->sd.atasd.devno == 0x00 ? "mst" : "slv");
} }
spinlock_acquire(&DEVTABLE.spinlock); spinlock_acquire(&DEVTABLE.spinlock);
@ -70,18 +75,29 @@ StoreDev *storedev_create(int32_t sdtype, void *extra) {
sd->read = &ramsd_read; sd->read = &ramsd_read;
sd->write = &ramsd_write; sd->write = &ramsd_write;
sd->capacity = &ramsd_capacity; sd->capacity = &ramsd_capacity;
sd->sectorsize = STOREDEV_RAMSD_SECTORSIZE;
int32_t err = sd->init(sd, extra); } break;
if (err != E_OK) { case STOREDEV_ATASD: {
spinlock_release(&STOREDEV_LIST.spinlock); spinlock_init(&sd->spinlock);
return NULL; sd->sdtype = STOREDEV_ATASD;
} sd->init = &atasd_init;
LL_APPEND(STOREDEV_LIST.head, sd); sd->cleanup = &atasd_cleanup;
sd->read = &atasd_read;
sd->write = &atasd_write;
sd->capacity = &atasd_capacity;
sd->sectorsize = STOREDEV_ATASD_SECTORSIZE;
} break; } break;
default: default:
spinlock_release(&STOREDEV_LIST.spinlock); spinlock_release(&STOREDEV_LIST.spinlock);
return NULL; return NULL;
} }
int32_t err = sd->init(sd, extra);
if (err != E_OK) {
dlfree(sd);
spinlock_release(&STOREDEV_LIST.spinlock);
return NULL;
}
LL_APPEND(STOREDEV_LIST.head, sd);
spinlock_release(&STOREDEV_LIST.spinlock); spinlock_release(&STOREDEV_LIST.spinlock);
storedev_register_dev_entry(sd, sdtype); storedev_register_dev_entry(sd, sdtype);

View File

@ -5,6 +5,7 @@
#include <stddef.h> #include <stddef.h>
#include "spinlock/spinlock.h" #include "spinlock/spinlock.h"
#include "ramsd.h" #include "ramsd.h"
#include "atasd.h"
#include "compiler/attr.h" #include "compiler/attr.h"
#include "dev/dev.h" #include "dev/dev.h"
@ -12,25 +13,28 @@
enum { enum {
STOREDEV_RAMSD, STOREDEV_RAMSD,
STOREDEV_ATASD,
}; };
UNUSED static const char *storedev_strings[] = { UNUSED static const char *storedev_strings[] = {
"RAMSD", "RAMSD", "ATASD"
}; };
typedef struct StoreDev { typedef struct StoreDev {
uint32_t _magic; uint32_t _magic;
struct StoreDev *next; struct StoreDev *next;
int32_t sdtype; int32_t sdtype;
size_t sectorsize;
int32_t (*init)(struct StoreDev *sd, void *extra); int32_t (*init)(struct StoreDev *sd, void *extra);
int32_t (*read)(struct StoreDev *sd, uint8_t *const buffer, size_t n, size_t off); int32_t (*read)(struct StoreDev *sd, uint8_t *const buffer, ptrdiff_t sector, ptrdiff_t off, size_t size);
int32_t (*write)(struct StoreDev *sd, const uint8_t *const buffer, size_t n, size_t off); int32_t (*write)(struct StoreDev *sd, const uint8_t *const buffer, ptrdiff_t sector, ptrdiff_t off, size_t size);
int32_t (*cleanup)(struct StoreDev *sd); int32_t (*cleanup)(struct StoreDev *sd);
size_t (*capacity)(struct StoreDev *sd); size_t (*capacity)(struct StoreDev *sd);
union { union {
RamSd ramsd; RamSd ramsd;
AtaSd atasd;
} sd; } sd;
SpinLock spinlock; SpinLock spinlock;
} StoreDev; } StoreDev;

228
kernel/syscall/fs.c Normal file
View File

@ -0,0 +1,228 @@
#include <stdint.h>
#include <stddef.h>
#include "syscall.h"
#include "sysdefs/fs.h"
#include "errors.h"
#include "path/path.h"
#include "vfs/vfs.h"
#include "kprintf.h"
#include "proc/proc.h"
#include "spinlock/spinlock.h"
#define _MP_MAX 0xff
#define _PATH_MAX VFS_PATH_MAX
int32_t SYSCALL2(sys_fs_openf, opath1, oflags1) {
int32_t ret = E_BADIO;
const char *opath = (const char *)opath1;
uint64_t oflags = oflags1;
if (opath == NULL) {
ret = E_INVALIDARGUMENT;
goto done;
}
char mp[_MP_MAX];
char path[_PATH_MAX];
path_parse(opath, mp, path);
VfsObj *vobj = vfs_open(mp, path, oflags);
if (vobj == NULL) {
ret = E_NOENTRY;
goto done;
}
spinlock_acquire(&PROCS.spinlock);
Proc *proc = PROCS.current;
spinlock_release(&PROCS.spinlock);
if (proc->vobjcnt < PROC_VFSHANDLES_MAX) {
for (size_t i = 0; i < PROC_VFSHANDLES_MAX; i++) {
if (proc->vobjs[i] == NULL) {
proc->vobjs[i] = vobj;
ret = i;
break;
}
}
} else {
ret = E_NOMEMORY;
}
done:
return ret;
}
int32_t SYSCALL1(sys_fs_closef, fsh1) {
uint64_t fsh = fsh1;
int32_t ret = E_BADIO;
if (fsh >= PROC_VFSHANDLES_MAX) {
ret = E_INVALIDARGUMENT;
goto done;
}
spinlock_acquire(&PROCS.spinlock);
Proc *proc = PROCS.current;
spinlock_release(&PROCS.spinlock);
VfsObj *vobj = proc->vobjs[fsh];
if (vobj == NULL) {
ret = E_INVALIDARGUMENT;
goto done;
}
vfs_close(vobj);
proc->vobjs[fsh] = NULL;
ret = E_OK;
done:
return ret;
}
int32_t SYSCALL4(sys_fs_write, fsh1, buffer1, len1, off1) {
uint64_t fsh = fsh1;
int32_t ret = E_BADIO;
const uint8_t *const buffer = (const uint8_t *const)buffer1;
size_t len = (size_t)len1;
size_t off = (size_t)off1;
if (buffer == NULL) {
ret = E_INVALIDARGUMENT;
goto done;
}
if (fsh >= PROC_VFSHANDLES_MAX) {
ret = E_INVALIDARGUMENT;
goto done;
}
spinlock_acquire(&PROCS.spinlock);
Proc *proc = PROCS.current;
spinlock_release(&PROCS.spinlock);
VfsObj *vobj = proc->vobjs[fsh];
if (vobj == NULL) {
ret = E_INVALIDARGUMENT;
goto done;
}
ret = vobj->write(vobj, buffer, len, off);
done:
return ret;
}
int32_t SYSCALL4(sys_fs_read, fsh1, buffer1, len1, off1) {
uint64_t fsh = fsh1;
int32_t ret = E_BADIO;
uint8_t *const buffer = (uint8_t *const)buffer1;
size_t len = (size_t)len1;
size_t off = (size_t)off1;
if (buffer == NULL) {
ret = E_INVALIDARGUMENT;
goto done;
}
if (fsh >= PROC_VFSHANDLES_MAX) {
ret = E_INVALIDARGUMENT;
goto done;
}
spinlock_acquire(&PROCS.spinlock);
Proc *proc = PROCS.current;
spinlock_release(&PROCS.spinlock);
VfsObj *vobj = proc->vobjs[fsh];
if (vobj == NULL) {
ret = E_INVALIDARGUMENT;
goto done;
}
ret = vobj->read(vobj, buffer, len, off);
done:
return ret;
}
int32_t SYSCALL2(sys_fs_stat, opath1, fsstat1) {
int32_t ret = E_BADIO;
const char *opath = (const char *)opath1;
if (opath == NULL) {
ret = E_INVALIDARGUMENT;
goto done;
}
FsStat *fsstat = (FsStat *)fsstat1;
if (fsstat == NULL) {
ret = E_INVALIDARGUMENT;
goto done;
}
char mp[_MP_MAX];
char path[_PATH_MAX];
path_parse(opath, mp, path);
ret = vfs_stat(mp, path, fsstat);
done:
return ret;
}
int32_t SYSCALL3(sys_fs_fetchdirent, opath1, direntbuf1, idx1) {
int32_t ret = E_BADIO;
const char *opath = (const char *)opath1;
if (opath == NULL) {
ret = E_INVALIDARGUMENT;
goto done;
}
FsDirent *direntbuf = (FsDirent *)direntbuf1;
if (direntbuf == NULL) {
ret = E_INVALIDARGUMENT;
goto done;
}
size_t idx = (size_t)idx1;
char mp[_MP_MAX];
char path[_PATH_MAX];
path_parse(opath, mp, path);
ret = vfs_fetchdirent(mp, path, direntbuf, idx);
done:
return ret;
}
int32_t SYSCALL1(sys_fs_mkdir, opath1) {
int32_t ret = E_BADIO;
const char *opath = (const char *)opath1;
if (opath == NULL) {
ret = E_INVALIDARGUMENT;
goto done;
}
char mp[_MP_MAX];
char path[_PATH_MAX];
path_parse(opath, mp, path);
ret = vfs_mkdir(mp, path);
done:
return ret;
}

16
kernel/syscall/fs.h Normal file
View File

@ -0,0 +1,16 @@
#ifndef SYSCALL_FS_H_
#define SYSCALL_FS_H_
#include <stdint.h>
#include <stddef.h>
#include "syscall.h"
int32_t SYSCALL2(sys_fs_openf, opath1, oflags1);
int32_t SYSCALL1(sys_fs_closef, fsh1);
int32_t SYSCALL4(sys_fs_write, fsh1, buffer1, len1, off1);
int32_t SYSCALL4(sys_fs_read, fsh1, buffer1, len1, off1);
int32_t SYSCALL2(sys_fs_stat, opath1, fsstat1);
int32_t SYSCALL3(sys_fs_fetchdirent, opath1, direntbuf1, idx1);
int32_t SYSCALL1(sys_fs_mkdir, opath1);
#endif // SYSCALL_FS_H_

View File

@ -1,205 +0,0 @@
#include <stdint.h>
#include <stddef.h>
#include "syscall.h"
#include "sysdefs/ioctl.h"
#include "errors.h"
#include "path/path.h"
#include "vfs/vfs.h"
#include "kprintf.h"
#include "proc/proc.h"
#include "spinlock/spinlock.h"
#define IOCTL_MP_MAX 0xff
#define IOCTL_PATH_MAX VFS_PATH_MAX
int32_t SYSCALL5(sys_ioctl, ioh1, cmd1, arg1, arg2, arg3) {
uint64_t ioh = ioh1;
uint64_t cmd = cmd1;
int32_t ret = E_BADIO;
switch (cmd) {
case IOCTL_OPENF: {
const char *opath = (const char *)arg1;
uint64_t oflags = arg2;
if (opath == NULL) {
ret = E_INVALIDARGUMENT;
goto done;
}
char mp[IOCTL_MP_MAX];
char path[IOCTL_PATH_MAX];
path_parse(opath, mp, path);
VfsObj *vobj = vfs_open(mp, path, oflags);
if (vobj == NULL) {
ret = E_NOENTRY;
goto done;
}
spinlock_acquire(&PROCS.spinlock);
Proc *proc = PROCS.current;
spinlock_release(&PROCS.spinlock);
if (proc->vobjcnt < PROC_VFSHANDLES_MAX) {
proc->vobjs[proc->vobjcnt++] = vobj;
ret = proc->vobjcnt - 1;
} else {
ret = E_NOMEMORY;
}
} break;
case IOCTL_CLOSEF: {
if (ioh >= PROC_VFSHANDLES_MAX) {
ret = E_INVALIDARGUMENT;
goto done;
}
spinlock_acquire(&PROCS.spinlock);
Proc *proc = PROCS.current;
spinlock_release(&PROCS.spinlock);
VfsObj *vobj = proc->vobjs[ioh];
if (vobj == NULL) {
ret = E_INVALIDARGUMENT;
goto done;
}
size_t i = 0;
for (; i < PROC_VFSHANDLES_MAX; i++) {
if (proc->vobjs[i] == vobj) {
break;
}
}
vfs_close(vobj);
proc->vobjs[i] = NULL;
ret = E_OK;
} break;
case IOCTL_WRITE: {
const uint8_t *const buffer = (const uint8_t *const)arg1;
size_t len = (size_t)arg2;
size_t off = (size_t)arg3;
if (buffer == NULL) {
ret = E_INVALIDARGUMENT;
goto done;
}
if (ioh >= PROC_VFSHANDLES_MAX) {
ret = E_INVALIDARGUMENT;
goto done;
}
spinlock_acquire(&PROCS.spinlock);
Proc *proc = PROCS.current;
spinlock_release(&PROCS.spinlock);
VfsObj *vobj = proc->vobjs[ioh];
if (vobj == NULL) {
ret = E_INVALIDARGUMENT;
goto done;
}
ret = vobj->write(vobj, buffer, len, off);
} break;
case IOCTL_READ: {
uint8_t *const buffer = (uint8_t *const)arg1;
size_t len = (size_t)arg2;
size_t off = (size_t)arg3;
if (buffer == NULL) {
ret = E_INVALIDARGUMENT;
goto done;
}
if (ioh >= PROC_VFSHANDLES_MAX) {
ret = E_INVALIDARGUMENT;
goto done;
}
spinlock_acquire(&PROCS.spinlock);
Proc *proc = PROCS.current;
spinlock_release(&PROCS.spinlock);
VfsObj *vobj = proc->vobjs[ioh];
if (vobj == NULL) {
ret = E_INVALIDARGUMENT;
goto done;
}
ret = vobj->read(vobj, buffer, len, off);
} break;
case IOCTL_STAT: {
const char *opath = (const char *)arg2;
if (opath == NULL) {
ret = E_INVALIDARGUMENT;
goto done;
}
IoctlStat *iostat = (IoctlStat *)arg1;
if (iostat == NULL) {
ret = E_INVALIDARGUMENT;
goto done;
}
char mp[IOCTL_MP_MAX];
char path[IOCTL_PATH_MAX];
path_parse(opath, mp, path);
ret = vfs_stat(mp, path, iostat);
} break;
case IOCTL_FETCHDIRENT: {
const char *opath = (const char *)arg1;
if (opath == NULL) {
ret = E_INVALIDARGUMENT;
goto done;
}
IoctlDirent *direntbuf = (IoctlDirent *)arg2;
if (direntbuf == NULL) {
ret = E_INVALIDARGUMENT;
goto done;
}
size_t idx = (size_t)arg3;
char mp[IOCTL_MP_MAX];
char path[IOCTL_PATH_MAX];
path_parse(opath, mp, path);
ret = vfs_fetchdirent(mp, path, direntbuf, idx);
} break;
case IOCTL_MKDIR: {
const char *opath = (const char *)arg1;
if (opath == NULL) {
ret = E_INVALIDARGUMENT;
goto done;
}
size_t idx = (size_t)arg3;
char mp[IOCTL_MP_MAX];
char path[IOCTL_PATH_MAX];
path_parse(opath, mp, path);
ret = vfs_mkdir(mp, path);
} break;
default: {
ret = E_INVALIDARGUMENT;
goto done;
} break;
}
done:
return ret;
}

View File

@ -1,9 +0,0 @@
#ifndef SYSCALL_IOCTL_H_
#define SYSCALL_IOCTL_H_
#include <stdint.h>
#include "syscall.h"
int32_t SYSCALL5(sys_ioctl, ioh1, cmd1, arg1, arg2, arg3);
#endif // SYSCALL_IOCTL_H_

View File

@ -2,7 +2,6 @@
#include <stdint.h> #include <stdint.h>
#include "ipcpipe.h" #include "ipcpipe.h"
#include "ipc/pipe/pipe.h" #include "ipc/pipe/pipe.h"
#include "sysdefs/ipcpipe.h"
#include "dlmalloc/malloc.h" #include "dlmalloc/malloc.h"
#include "proc/proc.h" #include "proc/proc.h"
#include "spinlock/spinlock.h" #include "spinlock/spinlock.h"
@ -10,13 +9,12 @@
#include "util/util.h" #include "util/util.h"
#include "kprintf.h" #include "kprintf.h"
int32_t SYSCALL5(sys_ipcpipe, pid1, pipenum1, cmd1, buffer1, len1) { int32_t SYSCALL4(sys_ipc_piperead, pid1, pipenum1, buffer1, len1) {
uint64_t pid = pid1; uint64_t pid = pid1;
uint64_t pipenum = pipenum1; uint64_t pipenum = pipenum1;
uint64_t cmd = cmd1;
int32_t ret = E_OK; int32_t ret = E_OK;
if (pid == -1) { if (pid == (uint64_t)-1) {
pid = PROCS.current->pid; pid = PROCS.current->pid;
} }
@ -30,139 +28,193 @@ int32_t SYSCALL5(sys_ipcpipe, pid1, pipenum1, cmd1, buffer1, len1) {
goto done; goto done;
} }
switch (cmd) { if (pipenum >= PROC_PIPEHANDLES_MAX) {
case IPCPIPE_MAKE: { ret = E_INVALIDARGUMENT;
if (pipenum >= PROC_PIPEHANDLES_MAX) { goto done;
ret = E_NOMEMORY;
goto done;
}
IpcPipe *pipe = dlmalloc(sizeof(*pipe));
if (pipe == NULL) {
ret = E_NOMEMORY;
goto done;
}
if ((ret = ipc_pipeinit(pipe, proc->pid)) < 0) {
ret = E_NOMEMORY;
goto done;
}
spinlock_acquire(&proc->pipes_spinlock);
if (proc->pipes[pipenum] != NULL) {
spinlock_release(&proc->pipes_spinlock);
ipc_pipefree(pipe);
dlfree(pipe);
ret = E_RESOURCEAVAIL;
goto done;
}
proc->pipes[pipenum] = pipe;
spinlock_release(&proc->pipes_spinlock);
ret = E_OK;
} break;
case IPCPIPE_DELETE: {
if (pipenum >= PROC_PIPEHANDLES_MAX) {
ret = E_NOMEMORY;
goto done;
}
spinlock_acquire(&proc->pipes_spinlock);
if (proc->pipes[pipenum] != NULL && proc->pid == proc->pipes[pipenum]->ownerpid) {
ipc_pipefree(proc->pipes[pipenum]);
dlfree(proc->pipes[pipenum]);
}
proc->pipes[pipenum] = NULL;
spinlock_release(&proc->pipes_spinlock);
ret = E_OK;
} break;
case IPCPIPE_WRITE: {
if (pipenum >= PROC_PIPEHANDLES_MAX) {
ret = E_INVALIDARGUMENT;
goto done;
}
const uint8_t *const buffer = (const uint8_t *const)buffer1;
if (buffer == NULL) {
ret = E_INVALIDARGUMENT;
goto done;
}
spinlock_acquire(&proc->pipes_spinlock);
IpcPipe *pipe = proc->pipes[pipenum];
spinlock_release(&proc->pipes_spinlock);
if (pipe == NULL) {
ret = E_INVALIDARGUMENT;
goto done;
}
ret = ipc_pipewrite(pipe, buffer, len1);
} break;
case IPCPIPE_READ: {
if (pipenum >= PROC_PIPEHANDLES_MAX) {
ret = E_INVALIDARGUMENT;
goto done;
}
uint8_t *const buffer = (uint8_t *const)buffer1;
if (buffer == NULL) {
ret = E_INVALIDARGUMENT;
goto done;
}
spinlock_acquire(&proc->pipes_spinlock);
IpcPipe *pipe = proc->pipes[pipenum];
spinlock_release(&proc->pipes_spinlock);
if (pipe == NULL) {
ret = E_INVALIDARGUMENT;
goto done;
}
ret = ipc_piperead(pipe, buffer, len1);
} break;
case IPCPIPE_REPLACE: {
if (pipenum >= PROC_PIPEHANDLES_MAX) {
ret = E_NOMEMORY;
goto done;
}
uint64_t pid2 = buffer1;
uint64_t pipenum2 = len1;
spinlock_acquire(&PROCS.spinlock);
Proc *proc2 = NULL;
LL_FINDPROP(PROCS.procs, proc2, pid, pid2);
spinlock_release(&PROCS.spinlock);
if (proc2 == NULL) {
ret = E_INVALIDARGUMENT;
goto done;
}
if (pipenum2 >= PROC_PIPEHANDLES_MAX) {
ret = E_NOMEMORY;
goto done;
}
spinlock_acquire(&proc2->pipes_spinlock);
spinlock_acquire(&proc->pipes_spinlock);
if (proc->pipes[pipenum] != NULL && proc->pid == proc->pipes[pipenum]->ownerpid) {
ipc_pipefree(proc->pipes[pipenum]);
dlfree(proc->pipes[pipenum]);
}
proc->pipes[pipenum] = proc2->pipes[pipenum2];
spinlock_release(&proc->pipes_spinlock);
spinlock_release(&proc2->pipes_spinlock);
} break;
default: {
ret = E_INVALIDARGUMENT;
} break;
} }
uint8_t *const buffer = (uint8_t *const)buffer1;
if (buffer == NULL) {
ret = E_INVALIDARGUMENT;
goto done;
}
spinlock_acquire(&proc->pipes_spinlock);
IpcPipe *pipe = proc->pipes[pipenum];
spinlock_release(&proc->pipes_spinlock);
if (pipe == NULL) {
ret = E_INVALIDARGUMENT;
goto done;
}
ret = ipc_piperead(pipe, buffer, len1);
done:
return ret;
}
int32_t SYSCALL4(sys_ipc_pipewrite, pid1, pipenum1, buffer1, len1) {
uint64_t pid = pid1;
uint64_t pipenum = pipenum1;
int32_t ret = E_OK;
if (pid == (uint64_t)-1) {
pid = PROCS.current->pid;
}
spinlock_acquire(&PROCS.spinlock);
Proc *proc = NULL;
LL_FINDPROP(PROCS.procs, proc, pid, pid);
spinlock_release(&PROCS.spinlock);
if (proc == NULL) {
ret = E_INVALIDARGUMENT;
goto done;
}
if (pipenum >= PROC_PIPEHANDLES_MAX) {
ret = E_INVALIDARGUMENT;
goto done;
}
const uint8_t *const buffer = (const uint8_t *const)buffer1;
if (buffer == NULL) {
ret = E_INVALIDARGUMENT;
goto done;
}
spinlock_acquire(&proc->pipes_spinlock);
IpcPipe *pipe = proc->pipes[pipenum];
spinlock_release(&proc->pipes_spinlock);
if (pipe == NULL) {
ret = E_INVALIDARGUMENT;
goto done;
}
ret = ipc_pipewrite(pipe, buffer, len1);
done:
return ret;
}
int32_t SYSCALL1(sys_ipc_pipemake, pipenum1) {
uint64_t pipenum = pipenum1;
int32_t ret = E_OK;
spinlock_acquire(&PROCS.spinlock);
Proc *proc = PROCS.current;
spinlock_release(&PROCS.spinlock);
if (pipenum >= PROC_PIPEHANDLES_MAX) {
ret = E_NOMEMORY;
goto done;
}
IpcPipe *pipe = dlmalloc(sizeof(*pipe));
if (pipe == NULL) {
ret = E_NOMEMORY;
goto done;
}
if ((ret = ipc_pipeinit(pipe, proc->pid)) < 0) {
ret = E_NOMEMORY;
goto done;
}
spinlock_acquire(&proc->pipes_spinlock);
if (proc->pipes[pipenum] != NULL) {
spinlock_release(&proc->pipes_spinlock);
ipc_pipefree(pipe);
dlfree(pipe);
ret = E_RESOURCEAVAIL;
goto done;
}
proc->pipes[pipenum] = pipe;
spinlock_release(&proc->pipes_spinlock);
ret = E_OK;
done:
return ret;
}
int32_t SYSCALL1(sys_ipc_pipedelete, pipenum1) {
uint64_t pipenum = pipenum1;
int32_t ret = E_OK;
spinlock_acquire(&PROCS.spinlock);
Proc *proc = PROCS.current;
spinlock_release(&PROCS.spinlock);
if (pipenum >= PROC_PIPEHANDLES_MAX) {
ret = E_NOMEMORY;
goto done;
}
spinlock_acquire(&proc->pipes_spinlock);
if (proc->pipes[pipenum] != NULL && proc->pid == proc->pipes[pipenum]->ownerpid) {
ipc_pipefree(proc->pipes[pipenum]);
dlfree(proc->pipes[pipenum]);
}
proc->pipes[pipenum] = NULL;
spinlock_release(&proc->pipes_spinlock);
ret = E_OK;
done:
return ret;
}
int32_t SYSCALL4(sys_ipc_pipeconnect, pid1, pipenum1, pid2, pipenum2) {
uint64_t pid = pid1;
uint64_t pipenum = pipenum1;
int32_t ret = E_OK;
if (pid == (uint64_t)-1) {
pid = PROCS.current->pid;
}
spinlock_acquire(&PROCS.spinlock);
Proc *proc = NULL;
LL_FINDPROP(PROCS.procs, proc, pid, pid);
spinlock_release(&PROCS.spinlock);
if (proc == NULL) {
ret = E_INVALIDARGUMENT;
goto done;
}
if (pipenum >= PROC_PIPEHANDLES_MAX) {
ret = E_NOMEMORY;
goto done;
}
spinlock_acquire(&PROCS.spinlock);
Proc *proc2 = NULL;
LL_FINDPROP(PROCS.procs, proc2, pid, pid2);
spinlock_release(&PROCS.spinlock);
if (proc2 == NULL) {
ret = E_INVALIDARGUMENT;
goto done;
}
if (pipenum2 >= PROC_PIPEHANDLES_MAX) {
ret = E_NOMEMORY;
goto done;
}
spinlock_acquire(&proc2->pipes_spinlock);
spinlock_acquire(&proc->pipes_spinlock);
if (proc->pipes[pipenum] != NULL && proc->pid == proc->pipes[pipenum]->ownerpid) {
ipc_pipefree(proc->pipes[pipenum]);
dlfree(proc->pipes[pipenum]);
}
proc->pipes[pipenum] = proc2->pipes[pipenum2];
spinlock_release(&proc->pipes_spinlock);
spinlock_release(&proc2->pipes_spinlock);
done: done:
return ret; return ret;
} }

View File

@ -3,6 +3,10 @@
#include "syscall.h" #include "syscall.h"
int32_t SYSCALL5(sys_ipcpipe, pid1, pipenum1, cmd1, buffer1, len1); int32_t SYSCALL4(sys_ipc_piperead, pid1, pipenum1, buffer1, len1);
int32_t SYSCALL4(sys_ipc_pipewrite, pid1, pipenum1, buffer1, len1);
int32_t SYSCALL1(sys_ipc_pipemake, pipenum1);
int32_t SYSCALL1(sys_ipc_pipedelete, pipenum1);
int32_t SYSCALL4(sys_ipc_pipeconnect, pid1, pipenum1, pid2, pipenum2);
#endif // SYSCALL_IPCPIPE_H_ #endif // SYSCALL_IPCPIPE_H_

237
kernel/syscall/proc.c Normal file
View File

@ -0,0 +1,237 @@
#include <stdint.h>
#include <stddef.h>
#include "syscall.h"
#include "proc/proc.h"
#include "spinlock/spinlock.h"
#include "errors.h"
#include "util/util.h"
#include "sysdefs/proc.h"
#include "vfs/vfs.h"
#include "path/path.h"
#include "kprintf.h"
#include "dlmalloc/malloc.h"
#include "ipc/pipe/pipe.h"
#define _MP_MAX 0xff
#define _PATH_MAX VFS_PATH_MAX
int32_t SYSCALL1(sys_proc_kill, pid1) {
uint64_t pid = pid1;
int32_t ret = E_OK;
if (pid == (uint64_t)-1) {
pid = PROCS.current->pid;
}
spinlock_acquire(&PROCS.spinlock);
Proc *proc = NULL;
LL_FINDPROP(PROCS.procs, proc, pid, pid);
spinlock_release(&PROCS.spinlock);
proc_kill(proc);
ret = E_DOSCHEDULING;
return ret;
}
int32_t SYSCALL3(sys_proc_spawn, opath1, args1, argslen1) {
int32_t ret = E_OK;
spinlock_acquire(&PROCS.spinlock);
Proc *proc = PROCS.current;
spinlock_release(&PROCS.spinlock);
const char *opath = (const char *)opath1;
if (opath == NULL) {
ret = E_INVALIDARGUMENT;
goto done;
}
char mp[_MP_MAX];
char path[_PATH_MAX];
path_parse(opath, mp, path);
Proc *newproc = proc_spawnuser(mp, path);
if (newproc == NULL) {
ret = E_SPAWNERROR;
goto done;
}
size_t argslen = argslen1;
char **args = (char **)args1;
if (args != NULL && argslen > 0) {
for (size_t i = 0; i < argslen; i++) {
PROC_ARG(newproc, args[i]);
}
}
for (size_t i = 0; i < PROC_PIPEHANDLES_MAX; i++) {
if (newproc->pipes[i] != NULL) {
ipc_pipefree(newproc->pipes[i]);
dlfree(newproc->pipes[i]);
}
newproc->pipes[i] = proc->pipes[i];
}
proc_register(newproc);
ret = newproc->pid;
done:
return ret;
}
int32_t SYSCALL1(sys_proc_pollstate, pid1) {
uint64_t pid = pid1;
int32_t ret = E_OK;
if (pid == (uint64_t)-1) {
pid = PROCS.current->pid;
}
spinlock_acquire(&PROCS.spinlock);
Proc *proc = NULL;
LL_FINDPROP(PROCS.procs, proc, pid, pid);
spinlock_release(&PROCS.spinlock);
if (proc == NULL) {
ret = PROC_DIED;
goto done;
}
ret = proc->state;
done:
return ret;
}
int32_t SYSCALL0(sys_proc_getpid) {
int32_t ret = E_OK;
spinlock_acquire(&PROCS.spinlock);
Proc *proc = PROCS.current;
spinlock_release(&PROCS.spinlock);
ret = proc->pid;
return ret;
}
int32_t SYSCALL1(sys_proc_run, pid1) {
uint64_t pid = pid1;
int32_t ret = E_OK;
spinlock_acquire(&PROCS.spinlock);
Proc *proc = NULL;
LL_FINDPROP(PROCS.procs, proc, pid, pid);
spinlock_release(&PROCS.spinlock);
if (proc == NULL) {
ret = E_INVALIDARGUMENT;
goto done;
}
proc->state = PROC_READY;
done:
return ret;
}
int32_t SYSCALL1(sys_proc_arglen, pid1) {
uint64_t pid = pid1;
int32_t ret = E_OK;
if (pid == (uint64_t)-1) {
pid = PROCS.current->pid;
}
spinlock_acquire(&PROCS.spinlock);
Proc *proc = NULL;
LL_FINDPROP(PROCS.procs, proc, pid, pid);
spinlock_release(&PROCS.spinlock);
ret = proc->procargs.len;
return ret;
}
int32_t SYSCALL4(sys_proc_argv, pid1, argslen1, argbuf1, maxargs1) {
uint64_t pid = pid1;
int32_t ret = E_OK;
if (pid == (uint64_t)-1) {
pid = PROCS.current->pid;
}
spinlock_acquire(&PROCS.spinlock);
Proc *proc = NULL;
LL_FINDPROP(PROCS.procs, proc, pid, pid);
spinlock_release(&PROCS.spinlock);
size_t *argslen = (size_t *)argslen1;
char **argbuf = (char **)argbuf1;
if (argbuf == NULL) {
ret = E_INVALIDARGUMENT;
goto done;
}
size_t maxargs = (size_t)maxargs1;
ProcArg *arg, *argtmp;
size_t i;
LL_FOREACH_SAFE_IDX_LIMIT(proc->procargs.list, arg, argtmp, i, maxargs) {
if (argbuf[i] == NULL) {
ret = E_INVALIDARGUMENT;
goto done;
}
hal_strcpy(argbuf[i], arg->string);
}
*argslen = i;
ret = E_OK;
done:
return ret;
}
int32_t SYSCALL0(sys_proc_listsize) {
int32_t ret;
Proc *p, *ptmp;
size_t i;
spinlock_acquire(&PROCS.spinlock);
LL_FOREACH_SAFE_IDX(PROCS.procs, p, ptmp, i);
spinlock_release(&PROCS.spinlock);
ret = i;
return ret;
}
int32_t SYSCALL2(sys_proc_stat, pidx, pstat1) {
int32_t ret;
ProcStat *stat = (ProcStat *)pstat1;
if (stat == NULL) {
ret = E_INVALIDARGUMENT;
goto done;
}
Proc *p, *ptmp;
size_t i;
spinlock_acquire(&PROCS.spinlock);
LL_FOREACH_SAFE_IDX(PROCS.procs, p, ptmp, i) {
if (i == pidx) {
stat->pid = p->pid;
hal_strcpy(stat->name, p->name);
stat->state = p->state;
VasRange *vas, *vastmp;
LL_FOREACH_SAFE(p->vas, vas, vastmp) {
stat->usemem += vas->size;
}
break;
}
}
spinlock_release(&PROCS.spinlock);
ret = E_OK;
done:
return ret;
}

18
kernel/syscall/proc.h Normal file
View File

@ -0,0 +1,18 @@
#ifndef SYSCALL_PROC_H_
#define SYSCALL_PROC_H_
#include <stdint.h>
#include <stddef.h>
#include "syscall.h"
int32_t SYSCALL1(sys_proc_kill, pid1);
int32_t SYSCALL3(sys_proc_spawn, opath1, args1, argslen1);
int32_t SYSCALL1(sys_proc_pollstate, pid1);
int32_t SYSCALL0(sys_proc_getpid);
int32_t SYSCALL1(sys_proc_run, pid1);
int32_t SYSCALL1(sys_proc_arglen, pid1);
int32_t SYSCALL4(sys_proc_argv, pid1, argslen1, argbuf1, maxargs1);
int32_t SYSCALL0(sys_proc_listsize);
int32_t SYSCALL2(sys_proc_stat, pidx, pstat1);
#endif // SYSCALL_PROC_H_

View File

@ -1,160 +0,0 @@
#include <stdint.h>
#include "syscall.h"
#include "proc/proc.h"
#include "spinlock/spinlock.h"
#include "errors.h"
#include "util/util.h"
#include "sysdefs/processctl.h"
#include "vfs/vfs.h"
#include "path/path.h"
#include "kprintf.h"
#include "dlmalloc/malloc.h"
#include "ipc/pipe/pipe.h"
#define PCTL_MP_MAX 0xff
#define PCTL_PATH_MAX VFS_PATH_MAX
int32_t SYSCALL5(sys_processctl, pid1, cmd1, arg1, arg2, arg3) {
uint64_t pid = pid1;
uint64_t cmd = cmd1;
int32_t ret = E_OK;
if (pid == (uint64_t)-1) {
pid = PROCS.current->pid;
}
spinlock_acquire(&PROCS.spinlock);
Proc *proc = NULL;
LL_FINDPROP(PROCS.procs, proc, pid, pid);
spinlock_release(&PROCS.spinlock);
if (proc == NULL) {
if (cmd == PCTL_POLLSTATE) {
ret = PROC_DIED;
goto done;
}
ret = E_INVALIDARGUMENT;
goto done;
}
switch (cmd) {
case PCTL_KILL: {
proc_kill(proc);
ret = E_DOSCHEDULING;
} break;
case PCTL_SPAWN: {
const char *opath = (const char *)arg1;
if (opath == NULL) {
ret = E_INVALIDARGUMENT;
goto done;
}
char mp[PCTL_MP_MAX];
char path[PCTL_PATH_MAX];
path_parse(opath, mp, path);
Proc *newproc = proc_spawnuser(mp, path);
if (newproc == NULL) {
ret = E_SPAWNERROR;
goto done;
}
size_t argslen = arg3;
char **args = (char **)arg2;
if (args != NULL && argslen > 0) {
for (size_t i = 0; i < argslen; i++) {
PROC_ARG(newproc, args[i]);
}
}
for (size_t i = 0; i < PROC_PIPEHANDLES_MAX; i++) {
if (newproc->pipes[i] != NULL) {
ipc_pipefree(newproc->pipes[i]);
dlfree(newproc->pipes[i]);
}
newproc->pipes[i] = proc->pipes[i];
}
proc_register(newproc);
ret = newproc->pid;
} break;
case PCTL_POLLSTATE: {
ret = proc->state;
} break;
case PCTL_RUN: {
proc->state = PROC_READY;
} break;
case PCTL_GETPID: {
ret = proc->pid;
} break;
case PCTL_ARGLEN: {
ret = proc->procargs.len;
} break;
case PCTL_ARGV: {
size_t *argslen = (size_t *)arg1;
char **argbuf = (char **)arg2;
if (argbuf == NULL) {
ret = E_INVALIDARGUMENT;
goto done;
}
size_t maxargs = (size_t)arg3;
ProcArg *arg, *argtmp;
size_t i;
LL_FOREACH_SAFE_IDX_LIMIT(proc->procargs.list, arg, argtmp, i, maxargs) {
if (argbuf[i] == NULL) {
ret = E_INVALIDARGUMENT;
goto done;
}
hal_strcpy(argbuf[i], arg->string);
}
*argslen = i;
ret = E_OK;
} break;
case PCTL_PLS_SZ: {
Proc *p, *ptmp;
size_t i;
spinlock_acquire(&PROCS.spinlock);
LL_FOREACH_SAFE_IDX(PROCS.procs, p, ptmp, i);
spinlock_release(&PROCS.spinlock);
ret = i;
} break;
case PCTL_PLS_STAT: {
uint64_t pidx = arg1;
ProcStat *stat = (ProcStat *)arg2;
if (stat == NULL) {
ret = E_INVALIDARGUMENT;
goto done;
}
Proc *p, *ptmp;
size_t i;
spinlock_acquire(&PROCS.spinlock);
LL_FOREACH_SAFE_IDX(PROCS.procs, p, ptmp, i) {
if (i == pidx) {
stat->pid = p->pid;
hal_strcpy(stat->name, p->name);
stat->state = p->state;
VasRange *vas, *vastmp;
LL_FOREACH_SAFE(p->vas, vas, vastmp) {
stat->usemem += vas->size;
}
break;
}
}
spinlock_release(&PROCS.spinlock);
ret = E_OK;
} break;
default: {
ret = E_INVALIDARGUMENT;
} break;
}
done:
return ret;
}

View File

@ -1,9 +0,0 @@
#ifndef SYSCALL_PROCESSCTL_H_
#define SYSCALL_PROCESSCTL_H_
#include <stdint.h>
#include "syscall.h"
int32_t SYSCALL5(sys_processctl, pid1, cmd1, arg1, arg2, arg3);
#endif // SYSCALL_PROCESSCTL_H_

View File

@ -2,14 +2,15 @@
#include "syscall.h" #include "syscall.h"
#include "errors.h" #include "errors.h"
#include "kprintf.h" #include "kprintf.h"
#include "processctl.h"
#include "sysdefs/syscall.h" #include "sysdefs/syscall.h"
#include "ioctl.h"
#include "ipcpipe.h" #include "ipcpipe.h"
#include "mman.h" #include "mman.h"
#include "sched.h" #include "sched.h"
#include "devctl.h" #include "devctl.h"
#include "randcrypto.h" #include "randcrypto.h"
#include "vfs.h"
#include "proc.h"
#include "fs.h"
int32_t SYSCALL1(sys_debugprint, string) { int32_t SYSCALL1(sys_debugprint, string) {
char *p = (char *)string; char *p = (char *)string;
@ -19,12 +20,32 @@ int32_t SYSCALL1(sys_debugprint, string) {
SyscallFn SYSCALL_TABLE[SYSCALLS_MAX] = { SyscallFn SYSCALL_TABLE[SYSCALLS_MAX] = {
[SYS_DEBUGPRINT] = &sys_debugprint, [SYS_DEBUGPRINT] = &sys_debugprint,
[SYS_PROCESSCTL] = &sys_processctl,
[SYS_IOCTL] = &sys_ioctl,
[SYS_IPCPIPE] = &sys_ipcpipe,
[SYS_MMAN_MAP] = &sys_mman_map, [SYS_MMAN_MAP] = &sys_mman_map,
[SYS_MMAN_UNMAP] = &sys_mman_unmap, [SYS_MMAN_UNMAP] = &sys_mman_unmap,
[SYS_SCHEDRELEASE] = &sys_schedrelease, [SYS_SCHEDRELEASE] = &sys_schedrelease,
[SYS_DEVCTL] = &sys_devctl, [SYS_DEVCTL] = &sys_devctl,
[SYS_RAND] = &sys_rand, [SYS_RAND] = &sys_rand,
[SYS_VFSMOUNT] = &sys_vfsmount,
[SYS_VFSUNMOUNT] = &sys_vfsunmount,
[SYS_IPC_PIPEREAD] = &sys_ipc_piperead,
[SYS_IPC_PIPEWRITE] = &sys_ipc_pipewrite,
[SYS_IPC_PIPEMAKE] = &sys_ipc_pipemake,
[SYS_IPC_PIPEDELETE] = &sys_ipc_pipedelete,
[SYS_IPC_PIPECONNECT] = &sys_ipc_pipeconnect,
[SYS_PROC_KILL] = &sys_proc_kill,
[SYS_PROC_SPAWN] = &sys_proc_spawn,
[SYS_PROC_POLLSTATE] = &sys_proc_pollstate,
[SYS_PROC_GETPID] = &sys_proc_getpid,
[SYS_PROC_RUN] = &sys_proc_run,
[SYS_PROC_ARGLEN] = &sys_proc_arglen,
[SYS_PROC_ARGV] = &sys_proc_argv,
[SYS_PROC_LISTSIZE] = &sys_proc_listsize,
[SYS_PROC_STAT] = &sys_proc_stat,
[SYS_FS_OPENF] = &sys_fs_openf,
[SYS_FS_CLOSEF] = &sys_fs_closef,
[SYS_FS_READ] = &sys_fs_read,
[SYS_FS_WRITE] = &sys_fs_write,
[SYS_FS_STAT] = &sys_fs_stat,
[SYS_FS_FETCHDIRENT] = &sys_fs_fetchdirent,
[SYS_FS_MKDIR] = &sys_fs_mkdir,
}; };

63
kernel/syscall/vfs.c Normal file
View File

@ -0,0 +1,63 @@
#include <stdint.h>
#include <stddef.h>
#include <stdbool.h>
#include "hal/hal.h"
#include "syscall.h"
#include "vfs.h"
#include "errors.h"
#include "sysdefs/devctl.h"
#include "vfs/vfs.h"
#include "spinlock/spinlock.h"
#include "dev/dev.h"
#include "proc/proc.h"
#include "storedev/storedev.h"
int32_t SYSCALL4(sys_vfsmount, mountpoint1, fstypestr1, devid1, format1) {
int32_t ret = E_OK;
char *mountpoint = (char *)mountpoint1;
char *fstypestr = (char *)fstypestr1;
Dev_t *dev = (Dev_t *)devid1;
bool format = (bool)format1;
if (mountpoint == NULL) { ret = E_INVALIDARGUMENT; goto done; }
if (fstypestr == NULL) { ret = E_INVALIDARGUMENT; goto done; }
if (dev == NULL) { ret = E_INVALIDARGUMENT; goto done; }
if (*dev >= PROC_DEVHANDLES_MAX) { ret = E_INVALIDARGUMENT; goto done; }
int32_t fstype;
if (hal_strcmp(fstypestr, "LittleFS") == 0) {
fstype = VFS_LITTLEFS;
} else {
ret = E_INVALIDARGUMENT;
goto done;
}
spinlock_acquire(&PROCS.spinlock);
Proc *proc = PROCS.current;
spinlock_release(&PROCS.spinlock);
Dev *dp = proc->devs[*dev];
if (dp == NULL) { ret = E_NOENTRY; goto done; }
StoreDev *sd = (StoreDev *)dp->extra;
if (sd != NULL && sd->_magic != STOREDEV_MAGIC) { ret = E_NOENTRY; goto done; }
ret = vfs_mount(mountpoint, fstype, sd, format);
done:
return ret;
}
int32_t SYSCALL1(sys_vfsunmount, mountpoint1) {
int32_t ret = E_OK;
char *mountpoint = (char *)mountpoint1;
if (mountpoint == NULL) { ret = E_INVALIDARGUMENT; goto done; }
ret = vfs_unmount(mountpoint);
done:
return ret;
}

11
kernel/syscall/vfs.h Normal file
View File

@ -0,0 +1,11 @@
#ifndef SYSCALL_VFS_H_
#define SYSCALL_VFS_H_
#include <stdint.h>
#include <stddef.h>
#include "syscall.h"
int32_t SYSCALL4(sys_vfsmount, mountpoint1, fstypestr1, devid1, format1);
int32_t SYSCALL1(sys_vfsunmount, mountpoint1);
#endif // SYSCALL_VFS_H_

View File

@ -1,3 +1,6 @@
#include <stdint.h>
#include <stddef.h>
#include "kprintf.h"
#include "util.h" #include "util.h"
char *util_get_filename(char *path) { char *util_get_filename(char *path) {
@ -13,3 +16,33 @@ char *util_get_filename(char *path) {
return lastslash; return lastslash;
} }
const char *human_size(uint64_t bytes, char *buf, size_t bufsize) {
static const char *units[] = { "B", "KiB", "MiB", "GiB", "TiB", "PiB" };
int unit = 0;
// Scale down until value fits nicely
uint64_t rem = 0;
while (bytes >= 1024 && unit < (int)(sizeof(units)/sizeof(units[0])) - 1) {
rem = bytes % 1024;
bytes /= 1024;
unit++;
}
if (unit == 0) {
// Just bytes
ksnprintf(buf, bufsize, "%llu %s", (unsigned long long)bytes, units[unit]);
} else {
// Show one decimal place without using floats
// Multiply remainder by 10 to get first decimal digit
uint64_t frac = (rem * 10 + 512) / 1024; // rounded
if (frac == 10) { // handle carry, e.g. 1023.9 -> 1024.0
bytes++;
frac = 0;
}
if (frac > 0) ksnprintf(buf, bufsize, "%llu.%llu %s", (unsigned long long)bytes, (unsigned long long)frac, units[unit]);
else ksnprintf(buf, bufsize, "%llu %s", (unsigned long long)bytes, units[unit]);
}
return buf;
}

View File

@ -1,6 +1,9 @@
#ifndef UTIL_UTIL_H_ #ifndef UTIL_UTIL_H_
#define UTIL_UTIL_H_ #define UTIL_UTIL_H_
#include <stdint.h>
#include <stddef.h>
#define _DIV_ROUNDUP(num, div) ((num + div - 1) / div) #define _DIV_ROUNDUP(num, div) ((num + div - 1) / div)
#define MAX(a, b) (((a) > (b)) ? (a) : (b)) #define MAX(a, b) (((a) > (b)) ? (a) : (b))
#define MIN(a, b) (((a) < (b)) ? (a) : (b)) #define MIN(a, b) (((a) < (b)) ? (a) : (b))
@ -74,5 +77,6 @@
var = tmp, tmp = (var ? var->next : NULL), (idx)++) var = tmp, tmp = (var ? var->next : NULL), (idx)++)
char *util_get_filename(char *path); char *util_get_filename(char *path);
const char *human_size(uint64_t bytes, char *buf, size_t bufsize);
#endif // UTIL_UTIL_H_ #endif // UTIL_UTIL_H_

View File

@ -25,11 +25,11 @@ void vfs_init_littlefs(VfsMountPoint *mp, bool format) {
cfg->sync = &portlfs_sync; cfg->sync = &portlfs_sync;
cfg->block_size = LITTLEFS_BLOCK_SIZE; cfg->block_size = LITTLEFS_BLOCK_SIZE;
cfg->block_count = mp->backingsd->capacity(mp->backingsd) / LITTLEFS_BLOCK_SIZE; cfg->block_count = mp->backingsd->capacity(mp->backingsd) / LITTLEFS_BLOCK_SIZE;
cfg->read_size = 64; cfg->read_size = LITTLEFS_BLOCK_SIZE;
cfg->prog_size = 64; cfg->prog_size = LITTLEFS_BLOCK_SIZE;
cfg->block_cycles = 16; cfg->block_cycles = 16;
cfg->cache_size = 64; cfg->cache_size = LITTLEFS_BLOCK_SIZE;
cfg->lookahead_size = 64; cfg->lookahead_size = LITTLEFS_BLOCK_SIZE;
cfg->read_buffer = NULL; cfg->read_buffer = NULL;
cfg->prog_buffer = NULL; cfg->prog_buffer = NULL;
cfg->lookahead_buffer = NULL; cfg->lookahead_buffer = NULL;
@ -51,7 +51,7 @@ void vfs_init_littlefs(VfsMountPoint *mp, bool format) {
mp->mkdir = &littlefs_mkdir; mp->mkdir = &littlefs_mkdir;
} }
int32_t vfs_stat(char *mountpoint, const char *path, IoctlStat *stat) { int32_t vfs_stat(char *mountpoint, const char *path, FsStat *stat) {
VfsMountPoint *mp = NULL; VfsMountPoint *mp = NULL;
spinlock_acquire(&VFS_TABLE.spinlock); spinlock_acquire(&VFS_TABLE.spinlock);
@ -79,7 +79,7 @@ int32_t vfs_mkdir(char *mountpoint, const char *path) {
return mp->mkdir(mp, path); return mp->mkdir(mp, path);
} }
int32_t vfs_fetchdirent(char *mountpoint, const char *path, IoctlDirent *direntbuf, size_t idx) { int32_t vfs_fetchdirent(char *mountpoint, const char *path, FsDirent *direntbuf, size_t idx) {
VfsMountPoint *mp = NULL; VfsMountPoint *mp = NULL;
spinlock_acquire(&VFS_TABLE.spinlock); spinlock_acquire(&VFS_TABLE.spinlock);

View File

@ -7,7 +7,7 @@
#include "spinlock/spinlock.h" #include "spinlock/spinlock.h"
#include "fs/portlfs/portlfs.h" #include "fs/portlfs/portlfs.h"
#include "storedev/storedev.h" #include "storedev/storedev.h"
#include "sysdefs/ioctl.h" #include "sysdefs/fs.h"
#include "compiler/attr.h" #include "compiler/attr.h"
#define VFS_MOUNTPOINT_LABEL_MAX 128 #define VFS_MOUNTPOINT_LABEL_MAX 128
@ -50,8 +50,8 @@ typedef struct VfsMountPoint {
VfsObj *(*open)(struct VfsMountPoint *vmp, const char *path, uint32_t flags); VfsObj *(*open)(struct VfsMountPoint *vmp, const char *path, uint32_t flags);
int32_t (*cleanup)(struct VfsMountPoint *vmp); int32_t (*cleanup)(struct VfsMountPoint *vmp);
int32_t (*stat)(struct VfsMountPoint *vmp, const char *path, IoctlStat *statbuf); int32_t (*stat)(struct VfsMountPoint *vmp, const char *path, FsStat *statbuf);
int32_t (*fetchdirent)(struct VfsMountPoint *vmp, const char *path, IoctlDirent *direntbuf, size_t idx); int32_t (*fetchdirent)(struct VfsMountPoint *vmp, const char *path, FsDirent *direntbuf, size_t idx);
int32_t (*mkdir)(struct VfsMountPoint *vmp, const char *path); int32_t (*mkdir)(struct VfsMountPoint *vmp, const char *path);
union { union {
@ -72,8 +72,8 @@ int32_t vfs_unmount(char *mountpoint);
int32_t vfs_mount(char *mountpoint, int32_t fstype, StoreDev *backingsd, bool format); int32_t vfs_mount(char *mountpoint, int32_t fstype, StoreDev *backingsd, bool format);
void vfs_close(VfsObj *vobj); void vfs_close(VfsObj *vobj);
VfsObj *vfs_open(char *mountpoint, const char *path, uint32_t flags); VfsObj *vfs_open(char *mountpoint, const char *path, uint32_t flags);
int32_t vfs_stat(char *mountpoint, const char *path, IoctlStat *stat); int32_t vfs_stat(char *mountpoint, const char *path, FsStat *stat);
int32_t vfs_fetchdirent(char *mountpoint, const char *path, IoctlDirent *direntbuf, size_t idx); int32_t vfs_fetchdirent(char *mountpoint, const char *path, FsDirent *direntbuf, size_t idx);
int32_t vfs_mkdir(char *mountpoint, const char *path); int32_t vfs_mkdir(char *mountpoint, const char *path);
#endif // VFS_VFS_H_ #endif // VFS_VFS_H_

View File

@ -2,4 +2,4 @@
rm -f base.img rm -f base.img
cat user/FILES.txt | while read line; do cp -v $line base/bin; done cat user/FILES.txt | while read line; do cp -v $line base/bin; done
mklittlefs -c base -b 4096 -s $((1<<20)) base.img mklittlefs -c base -b 512 -s $((1<<20)) base.img

24
share/sysdefs/fs.h Normal file
View File

@ -0,0 +1,24 @@
#ifndef SHARE_SYSDEFS_FS_H_
#define SHARE_SYSDEFS_FS_H_
#define FS_OF_READ (1<<0)
#define FS_OF_WRITE (1<<1)
#define FS_OF_MAKE (1<<2)
#define FSSTAT_DIR 0
#define FSSTAT_FILE 1
#include <stdint.h>
#include <stddef.h>
typedef struct {
size_t size;
int32_t type;
} FsStat;
typedef struct {
FsStat stat;
char name[0x100];
} FsDirent;
#endif // SHARE_SYSDEFS_FS_H_

View File

@ -1,40 +0,0 @@
#ifndef SHARE_SYSDEFS_IOCTL_H_
#define SHARE_SYSDEFS_IOCTL_H_
#define IOCTL_NOHANDLE (-1)
#define IOCTL_OPENF 0
#define IOCTL_CLOSEF 1
#define IOCTL_READ 2
#define IOCTL_STAT 3
#define IOCTL_WRITE 4
#define IOCTL_FETCHDIRENT 5
#define IOCTL_MKDIR 6
#define IOCTL_F_READ (1<<0)
#define IOCTL_F_WRITE (1<<1)
#define IOCTL_F_MAKE (1<<2)
#define IOCTLSTAT_DIR 0
#define IOCTLSTAT_FILE 1
#if !defined(__ASSEMBLER__)
#include <stdint.h>
#include <stddef.h>
typedef struct IoctlStat {
size_t size;
int32_t type;
} IoctlStat;
typedef struct IoctlDirent {
IoctlStat stat;
char name[0x100];
} IoctlDirent;
typedef int32_t IOH;
#endif
#endif // SHARE_SYSDEFS_IOCTL_H_

View File

@ -1,18 +0,0 @@
#ifndef SHARE_SYSDEFS_IPCPIPE_H_
#define SHARE_SYSDEFS_IPCPIPE_H_
#include <stdint.h>
#include <stddef.h>
#define IPCPIPE_SELFPID (-1)
#define IPCPIPE_OUT (0)
#define IPCPIPE_IN (1)
#define IPCPIPE_MAKE 0
#define IPCPIPE_READ 1
#define IPCPIPE_WRITE 2
#define IPCPIPE_REPLACE 4
#define IPCPIPE_DELETE 5
#endif // SHARE_SYSDEFS_IPCPIPE_H_

15
share/sysdefs/proc.h Normal file
View File

@ -0,0 +1,15 @@
#ifndef SHARE_SYSDEFS_PROC_H_
#define SHARE_SYSDEFS_PROC_H_
#define PROC_ARG_MAX 128
typedef struct {
uint64_t pid;
char name[0x100];
uint8_t state;
size_t usemem;
} ProcStat;
typedef uint64_t PID_t;
#endif // SHARE_SYSDEFS_PROC_H_

View File

@ -1,29 +0,0 @@
#ifndef SHARE_HDRS_PROCESSCTL_H_
#define SHARE_HDRS_PROCESSCTL_H_
#define PROC_ARG_MAX 128
#define PCTL_KILL 0
#define PCTL_SPAWN 1
#define PCTL_POLLSTATE 2
#define PCTL_RUN 3
#define PCTL_GETPID 4
#define PCTL_ARGLEN 5
#define PCTL_ARGV 6
#define PCTL_PLS_SZ 7
#define PCTL_PLS_STAT 8
#if !defined(__ASSEMBLER__)
typedef struct {
uint64_t pid;
char name[0x100];
uint8_t state;
size_t usemem;
} ProcStat;
typedef uint64_t PID_t;
#endif
#endif // SHARE_HDRS_PROCESSCTL_H_

View File

@ -2,13 +2,35 @@
#define SHARE_HDRS_SYSCALL_H_ #define SHARE_HDRS_SYSCALL_H_
#define SYS_DEBUGPRINT 1 #define SYS_DEBUGPRINT 1
#define SYS_PROCESSCTL 2
#define SYS_IOCTL 3 #define SYS_IOCTL 3
#define SYS_IPCPIPE 4
#define SYS_MMAN_MAP 5 #define SYS_MMAN_MAP 5
#define SYS_MMAN_UNMAP 6 #define SYS_MMAN_UNMAP 6
#define SYS_SCHEDRELEASE 7 #define SYS_SCHEDRELEASE 7
#define SYS_DEVCTL 8 #define SYS_DEVCTL 8
#define SYS_RAND 9 #define SYS_RAND 9
#define SYS_VFSMOUNT 10
#define SYS_VFSUNMOUNT 11
#define SYS_IPC_PIPEREAD 12
#define SYS_IPC_PIPEWRITE 13
#define SYS_IPC_PIPEMAKE 14
#define SYS_IPC_PIPEDELETE 15
#define SYS_IPC_PIPECONNECT 16
#define SYS_PROC_KILL 17
#define SYS_PROC_SPAWN 18
#define SYS_PROC_POLLSTATE 19
#define SYS_PROC_RUN 20
#define SYS_PROC_GETPID 21
#define SYS_PROC_ARGLEN 22
#define SYS_PROC_ARGV 23
#define SYS_PROC_LISTSIZE 24
#define SYS_PROC_STAT 25
#define SYS_FS_OPENF 26
#define SYS_FS_CLOSEF 27
#define SYS_FS_READ 28
#define SYS_FS_STAT 29
#define SYS_FS_WRITE 30
#define SYS_FS_FETCHDIRENT 31
#define SYS_FS_MKDIR 32
#endif // SHARE_HDRS_SYSCALL_H_ #endif // SHARE_HDRS_SYSCALL_H_

View File

@ -1,7 +1,7 @@
#include <stdint.h> #include <stdint.h>
#include <stddef.h> #include <stddef.h>
#include <system/system.h> #include <system/system.h>
#include <sysdefs/processctl.h> #include <sysdefs/proc.h>
#include <errors.h> #include <errors.h>
#include <uprintf.h> #include <uprintf.h>
#include <log.h> #include <log.h>
@ -40,8 +40,9 @@ void _premain(void) {
_args[i] = umalloc(PROC_ARG_MAX); _args[i] = umalloc(PROC_ARG_MAX);
} }
processctl(-1, PCTL_ARGV, (uint64_t)&_argslen, (uint64_t)_args, MAX_ARGS); proc_argv(-1, &_argslen, _args, MAX_ARGS);
main(); main();
proc_kill(proc_getpid());
} }

View File

@ -5,9 +5,3 @@
.global _start .global _start
_start: _start:
call _premain call _premain
movq $2, %rax // sys processctl
movq $-1, %rdi // self magic num
movq $0, %rsi // kill cmd
int $0x80

View File

@ -1,8 +1,7 @@
#include <stdint.h> #include <stdint.h>
#include <system/system.h> #include <system/system.h>
#include <sysdefs/ipcpipe.h>
#include <printf/printf.h> #include <printf/printf.h>
void putchar_(char c) { void putchar_(char c) {
ipcpipe(-1, IPCPIPE_OUT, IPCPIPE_WRITE, (uint8_t *)&c, 1); ipc_pipewrite(-1, 0, (uint8_t *const)&c, 1);
} }

View File

@ -2,9 +2,8 @@
#include <system/system.h> #include <system/system.h>
#include <syscall/syscall.h> #include <syscall/syscall.h>
#include <sysdefs/syscall.h> #include <sysdefs/syscall.h>
#include <sysdefs/ioctl.h> #include <sysdefs/fs.h>
#include <sysdefs/processctl.h> #include <sysdefs/proc.h>
#include <sysdefs/ipcpipe.h>
#include <sysdefs/devctl.h> #include <sysdefs/devctl.h>
#include <uprintf.h> #include <uprintf.h>
@ -12,18 +11,6 @@ void debugprint(const char *string) {
syscall(SYS_DEBUGPRINT, (uint64_t)string, 0, 0, 0, 0, 0); syscall(SYS_DEBUGPRINT, (uint64_t)string, 0, 0, 0, 0, 0);
} }
int32_t ioctl(uint64_t ioh, uint64_t cmd, uint64_t arg1, uint64_t arg2, uint64_t arg3) {
return syscall(SYS_IOCTL, ioh, cmd, arg1, arg2, arg3, 0);
}
int32_t processctl(uint64_t pid, uint64_t cmd, uint64_t arg1, uint64_t arg2, uint64_t arg3) {
return syscall(SYS_PROCESSCTL, pid, cmd, arg1, arg2, arg3, 0);
}
int32_t ipcpipe(uint64_t pid, uint64_t pipenum, uint64_t cmd, uint8_t *buffer, size_t len) {
return syscall(SYS_IPCPIPE, pid, pipenum, cmd, (uint64_t)buffer, (uint64_t)len, 0);
}
int32_t mman_map(uint8_t *addr, size_t size, uint64_t prot, uint64_t flags, uint8_t **out) { int32_t mman_map(uint8_t *addr, size_t size, uint64_t prot, uint64_t flags, uint8_t **out) {
return syscall(SYS_MMAN_MAP, (uint64_t)addr, (uint64_t)size, prot, flags, (uint64_t)out, 0); return syscall(SYS_MMAN_MAP, (uint64_t)addr, (uint64_t)size, prot, flags, (uint64_t)out, 0);
} }
@ -43,3 +30,95 @@ int32_t devctl(Dev_t *devh, uint64_t cmd, uint8_t *buffer, size_t len, uint64_t
int32_t rand(void) { int32_t rand(void) {
return syscall(SYS_RAND, 0, 0, 0, 0, 0, 0); return syscall(SYS_RAND, 0, 0, 0, 0, 0, 0);
} }
int32_t vfsmount(char *mountpoint, char *fstype, Dev_t *dev, bool format) {
return syscall(SYS_VFSMOUNT, (uint64_t)mountpoint, (uint64_t)fstype, (uint64_t)dev, (uint64_t)format, 0, 0);
}
int32_t vfsunmount(char *mountpoint) {
return syscall(SYS_VFSUNMOUNT, (uint64_t)mountpoint, 0, 0, 0, 0, 0);
}
int32_t ipc_piperead(PID_t pid, uint64_t pipenum, uint8_t *const buffer, size_t len) {
return syscall(SYS_IPC_PIPEREAD, (uint64_t)pid, (uint64_t)pipenum, (uint64_t)buffer, (uint64_t)len, 0, 0);
}
int32_t ipc_pipewrite(PID_t pid, uint64_t pipenum, const uint8_t *buffer, size_t len) {
return syscall(SYS_IPC_PIPEWRITE, (uint64_t)pid, (uint64_t)pipenum, (uint64_t)buffer, (uint64_t)len, 0, 0);
}
int32_t ipc_pipemake(uint64_t pipenum) {
return syscall(SYS_IPC_PIPEMAKE, pipenum, 0, 0, 0, 0, 0);
}
int32_t ipc_pipedelete(uint64_t pipenum) {
return syscall(SYS_IPC_PIPEDELETE, pipenum, 0, 0, 0, 0, 0);
}
int32_t ipc_pipeconnect(PID_t pid1, uint64_t pipenum1, PID_t pid2, uint64_t pipenum2) {
return syscall(SYS_IPC_PIPECONNECT, pid1, pipenum1, pid2, pipenum2, 0, 0);
}
int32_t proc_kill(PID_t pid) {
return syscall(SYS_PROC_KILL, (uint64_t)pid, 0, 0, 0, 0, 0);
}
int32_t proc_spawn(char *path, char **args1, size_t argslen1) {
return syscall(SYS_PROC_SPAWN, (uint64_t)path, (uint64_t)args1, (uint64_t)argslen1, 0, 0, 0);
}
int32_t proc_pollstate(PID_t pid) {
return syscall(SYS_PROC_POLLSTATE, (uint64_t)pid, 0, 0, 0, 0, 0);
}
int32_t proc_getpid(void) {
return syscall(SYS_PROC_GETPID, 0, 0, 0, 0, 0, 0);
}
int32_t proc_run(PID_t pid) {
return syscall(SYS_PROC_RUN, (uint64_t)pid, 0, 0, 0, 0, 0);
}
int32_t proc_arglen(PID_t pid) {
return syscall(SYS_PROC_ARGLEN, (uint64_t)pid, 0, 0, 0, 0, 0);
}
int32_t proc_argv(PID_t pid, size_t *argslen1, char **argbuf1, size_t maxargs) {
return syscall(SYS_PROC_ARGV, (uint64_t)pid, (uint64_t)argslen1, (uint64_t)argbuf1, (uint64_t)maxargs, 0, 0);
}
int32_t proc_listsize(void) {
return syscall(SYS_PROC_LISTSIZE, 0, 0, 0, 0, 0, 0);
}
int32_t proc_stat(size_t idx, ProcStat *pstat) {
return syscall(SYS_PROC_STAT, (uint64_t)idx, (uint64_t)pstat, 0, 0, 0, 0);
}
int32_t fs_openf(char *path, uint64_t flags) {
return syscall(SYS_FS_OPENF, (uint64_t)path, flags, 0, 0, 0, 0);
}
int32_t fs_closef(int32_t fsh) {
return syscall(SYS_FS_CLOSEF, (uint64_t)fsh, 0, 0, 0, 0, 0);
}
int32_t fs_write(int32_t fsh, const uint8_t *buffer, size_t len, size_t off) {
return syscall(SYS_FS_WRITE, (uint64_t)fsh, (uint64_t)buffer, (uint64_t)len, (uint64_t)off, 0, 0);
}
int32_t fs_read(int32_t fsh, uint8_t *const buffer, size_t len, size_t off) {
return syscall(SYS_FS_READ, (uint64_t)fsh, (uint64_t)buffer, (uint64_t)len, (uint64_t)off, 0, 0);
}
int32_t fs_stat(char *path, FsStat *statbuf) {
return syscall(SYS_FS_STAT, (uint64_t)path, (uint64_t)statbuf, 0, 0, 0, 0);
}
int32_t fs_fetchdirent(char *path, FsDirent *direntbuf, size_t idx) {
return syscall(SYS_FS_FETCHDIRENT, (uint64_t)path, (uint64_t)direntbuf, (uint64_t)idx, 0, 0, 0);
}
int32_t fs_mkdir(char *path) {
return syscall(SYS_FS_MKDIR, (uint64_t)path, 0, 0, 0, 0, 0);
}

View File

@ -3,16 +3,39 @@
#include <stdint.h> #include <stdint.h>
#include <stddef.h> #include <stddef.h>
#include <stdbool.h>
#include <sysdefs/devctl.h> #include <sysdefs/devctl.h>
#include <sysdefs/proc.h>
#include <sysdefs/fs.h>
void debugprint(const char *string); void debugprint(const char *string);
int32_t ioctl(uint64_t ioh, uint64_t cmd, uint64_t arg1, uint64_t arg2, uint64_t arg3);
int32_t processctl(uint64_t pid, uint64_t cmd, uint64_t arg1, uint64_t arg2, uint64_t arg3);
int32_t ipcpipe(uint64_t pid, uint64_t pipenum, uint64_t cmd, uint8_t *buffer, size_t len);
int32_t mman_map(uint8_t *addr, size_t size, uint64_t prot, uint64_t flags, uint8_t **out); int32_t mman_map(uint8_t *addr, size_t size, uint64_t prot, uint64_t flags, uint8_t **out);
int32_t mman_unmap(uint8_t *addr); int32_t mman_unmap(uint8_t *addr);
int32_t schedrelease(void); int32_t schedrelease(void);
int32_t devctl(Dev_t *devh, uint64_t cmd, uint8_t *buffer, size_t len, uint64_t extra); int32_t devctl(Dev_t *devh, uint64_t cmd, uint8_t *buffer, size_t len, uint64_t extra);
int32_t rand(void); int32_t rand(void);
int32_t vfsmount(char *mountpoint, char *fstype, Dev_t *dev, bool format);
int32_t vfsunmount(char *mountpoint);
int32_t ipc_piperead(PID_t pid, uint64_t pipenum, uint8_t *const buffer, size_t len);
int32_t ipc_pipewrite(PID_t pid, uint64_t pipenum, const uint8_t *buffer, size_t len);
int32_t ipc_pipemake(uint64_t pipenum);
int32_t ipc_pipedelete(uint64_t pipenum);
int32_t ipc_pipeconnect(PID_t pid1, uint64_t pipenum1, PID_t pid2, uint64_t pipenum2);
int32_t proc_kill(PID_t pid);
int32_t proc_spawn(char *path, char **args1, size_t argslen1);
int32_t proc_pollstate(PID_t pid);
int32_t proc_getpid(void);
int32_t proc_run(PID_t pid);
int32_t proc_arglen(PID_t pid);
int32_t proc_argv(PID_t pid, size_t *argslen1, char **argbuf1, size_t maxargs);
int32_t proc_listsize(void);
int32_t proc_stat(size_t idx, ProcStat *pstat);
int32_t fs_openf(char *path, uint64_t flags);
int32_t fs_closef(int32_t fsh);
int32_t fs_write(int32_t fsh, const uint8_t *buffer, size_t len, size_t off);
int32_t fs_read(int32_t fsh, uint8_t *const buffer, size_t len, size_t off);
int32_t fs_stat(char *path, FsStat *statbuf);
int32_t fs_fetchdirent(char *path, FsDirent *direntbuf, size_t idx);
int32_t fs_mkdir(char *path);
#endif // ULIB_SYSTEM_SYSTEM_H_ #endif // ULIB_SYSTEM_SYSTEM_H_

View File

@ -20,10 +20,9 @@
#include <dlinklist.h> #include <dlinklist.h>
#include <errors.h> #include <errors.h>
#include <sysdefs/ioctl.h> #include <sysdefs/fs.h>
#include <sysdefs/ipcpipe.h>
#include <sysdefs/mman.h> #include <sysdefs/mman.h>
#include <sysdefs/processctl.h> #include <sysdefs/proc.h>
#include <sysdefs/sched.h> #include <sysdefs/sched.h>
#include <sysdefs/syscall.h> #include <sysdefs/syscall.h>

View File

@ -1,6 +1,5 @@
#include <system/system.h> #include <system/system.h>
#include <sysdefs/processctl.h>
void quit(void) { void quit(void) {
processctl(-1, PCTL_KILL, 0, 0, 0); proc_kill(proc_getpid());
} }

View File

@ -44,15 +44,15 @@ void fs_fetch(void) {
FS_FETCH_CONFIG.types = false; FS_FETCH_CONFIG.types = false;
} }
IoctlStat statbuf; ZERO(&statbuf); FsStat statbuf; ZERO(&statbuf);
if (ioctl(IOCTL_NOHANDLE, IOCTL_STAT, (uint64_t)&statbuf, (uint64_t)path, 0) != E_OK) { if (fs_stat(path, &statbuf) != E_OK) {
uprintf("fs: could not stat %s\n", path); uprintf("fs: could not stat %s\n", path);
return; return;
} }
if (statbuf.type == IOCTLSTAT_FILE) { if (statbuf.type == FSSTAT_FILE) {
IOH ioh = ioctl(IOCTL_NOHANDLE, IOCTL_OPENF, (uint64_t)path, IOCTL_F_READ, 0); int32_t h = fs_openf(path, FS_OF_READ);
if (ioh < 0) { if (h < 0) {
uprintf("fs: could not open %s\n", path); uprintf("fs: could not open %s\n", path);
return; return;
} }
@ -60,7 +60,7 @@ void fs_fetch(void) {
uint8_t *buf = umalloc(statbuf.size+1); uint8_t *buf = umalloc(statbuf.size+1);
string_memset(buf, 0, statbuf.size+1); string_memset(buf, 0, statbuf.size+1);
if (ioctl(ioh, IOCTL_READ, (uint64_t)buf, statbuf.size, 0) < 0) { if (fs_read(h, buf, statbuf.size, 0)) {
uprintf("fs: coult not read %s\n", path); uprintf("fs: coult not read %s\n", path);
goto donefile; goto donefile;
return; return;
@ -69,14 +69,14 @@ void fs_fetch(void) {
uprintf("%s", buf); uprintf("%s", buf);
donefile: donefile:
ufree(buf); ufree(buf);
ioctl(ioh, IOCTL_CLOSEF, 0, 0, 0); fs_closef(h);
} else if (statbuf.type == IOCTLSTAT_DIR) { } else if (statbuf.type == FSSTAT_DIR) {
IoctlDirent *dirents = (IoctlDirent *)umalloc(statbuf.size * sizeof(*dirents)); FsDirent *dirents = (FsDirent *)umalloc(statbuf.size * sizeof(*dirents));
for (size_t i = 0; i < statbuf.size; i++) { for (size_t i = 0; i < statbuf.size; i++) {
ioctl(IOCTL_NOHANDLE, IOCTL_FETCHDIRENT, (uint64_t)path, (uint64_t)&dirents[i], i); fs_fetchdirent(path, &dirents[i], i);
IoctlDirent *dirent = &dirents[i]; FsDirent *dirent = &dirents[i];
if (FS_FETCH_CONFIG.names) { if (FS_FETCH_CONFIG.names) {
if (FS_FETCH_CONFIG.plain) { if (FS_FETCH_CONFIG.plain) {
@ -87,7 +87,7 @@ void fs_fetch(void) {
} }
if (FS_FETCH_CONFIG.sizes) { if (FS_FETCH_CONFIG.sizes) {
if (dirent->stat.type == IOCTLSTAT_FILE) { if (dirent->stat.type == FSSTAT_FILE) {
if (FS_FETCH_CONFIG.humsz) { if (FS_FETCH_CONFIG.humsz) {
char *membuf = umalloc(20); char *membuf = umalloc(20);
@ -105,7 +105,7 @@ void fs_fetch(void) {
uprintf("%-15zu ", dirent->stat.size); uprintf("%-15zu ", dirent->stat.size);
} }
} }
} else if (dirent->stat.type == IOCTLSTAT_DIR) { } else if (dirent->stat.type == FSSTAT_DIR) {
if (FS_FETCH_CONFIG.plain) { if (FS_FETCH_CONFIG.plain) {
uprintf("- "); uprintf("- ");
} else { } else {
@ -115,9 +115,9 @@ void fs_fetch(void) {
} }
if (FS_FETCH_CONFIG.types) { if (FS_FETCH_CONFIG.types) {
if (dirent->stat.type == IOCTLSTAT_FILE) { if (dirent->stat.type == FSSTAT_FILE) {
uprintf("%c ", 'F'); uprintf("%c ", 'F');
} else if (dirent->stat.type == IOCTLSTAT_DIR) { } else if (dirent->stat.type == FSSTAT_DIR) {
uprintf("%c ", 'D'); uprintf("%c ", 'D');
} }
} }

View File

@ -2,9 +2,9 @@
#include <stddef.h> #include <stddef.h>
#include <ulib.h> #include <ulib.h>
#define CMDS(X) \ #define CMDS(X) \
X(fetch) X(mkf) X(mkd) \ X(fetch) X(mkf) X(mkd) \
X(tree) X(tree) X(mount)
void main(void) { void main(void) {
if (argslen() == 0) { if (argslen() == 0) {

View File

@ -10,7 +10,7 @@ void fs_mkd(void) {
char *path = *(args()+1); char *path = *(args()+1);
int32_t r = ioctl(IOCTL_NOHANDLE, IOCTL_MKDIR, (uint64_t)path, 0, 0); int32_t r = fs_mkdir(path);
if (r != E_OK) { if (r != E_OK) {
uprintf("fs: could not create %s\n", path); uprintf("fs: could not create %s\n", path);
} }

View File

@ -26,11 +26,15 @@ void fs_mkf(void) {
uprintf("fs mkf: Could not parse args: %d\n", ret); uprintf("fs mkf: Could not parse args: %d\n", ret);
} }
IOH ioh = ioctl(IOCTL_NOHANDLE, IOCTL_OPENF, (uint64_t)path, IOCTL_F_MAKE | IOCTL_F_WRITE, 0); int32_t h = fs_openf(path, FS_OF_MAKE | FS_OF_WRITE);
if (h < 0) {
uprintf("fs mkf: could not create %s\n", path);
return;
}
if (FS_MKF_CONFIG.write != NULL) { if (FS_MKF_CONFIG.write != NULL) {
if (ioctl(ioh, IOCTL_WRITE, (uint64_t)FS_MKF_CONFIG.write, string_len(FS_MKF_CONFIG.write), 0) < 0) { if (fs_write(h, (const uint8_t *)FS_MKF_CONFIG.write, string_len(FS_MKF_CONFIG.write), 0) < 0) {
uprintf("fs mkf: could not write to %s\n", path); uprintf("fs mkf: could not write to %s\n", path);
} }
} }
ioctl(ioh, IOCTL_CLOSEF, 0, 0, 0); fs_closef(h);
} }

56
user/fs/mount.c Normal file
View File

@ -0,0 +1,56 @@
#include <stddef.h>
#include <stdint.h>
#include <ulib.h>
struct {
char *mountpoint;
char *fstype;
char *devname;
bool format;
} FS_MOUNT_CONFIG = {0};
static Arg ARGS[] = {
ARG("-mp", ARG_STRING, &FS_MOUNT_CONFIG.mountpoint),
ARG("-fs", ARG_STRING, &FS_MOUNT_CONFIG.fstype),
ARG("-dev", ARG_STRING, &FS_MOUNT_CONFIG.devname),
ARG("-fmt", ARG_BOOL, &FS_MOUNT_CONFIG.format),
ARG_END(),
};
void fs_mount(void) {
int32_t ret;
if ((ret = parse_args(args()+1, argslen()-1, ARGS)) < 0) {
uprintf("fs: could not parse args: %d\n", ret);
return;
}
if (FS_MOUNT_CONFIG.mountpoint == NULL) {
uprintf("fs: mountpoint missing\n");
return;
}
if (FS_MOUNT_CONFIG.fstype == NULL) {
uprintf("fs: filesystem type missing\n");
return;
}
if (FS_MOUNT_CONFIG.devname == NULL) {
uprintf("fs: device name missing\n");
return;
}
Dev_t dev;
ret = devctl(&dev, DEVCTL_GET_HANDLE, (uint8_t *)FS_MOUNT_CONFIG.devname, 0, 0);
if (ret != E_OK) {
uprintf("fs: device %s not found\n", FS_MOUNT_CONFIG.devname);
return;
}
ret = vfsmount(FS_MOUNT_CONFIG.mountpoint, FS_MOUNT_CONFIG.fstype, &dev, FS_MOUNT_CONFIG.format);
if (ret != E_OK) {
uprintf("fs: mount error %s\n", ERRSTRING(ret));
return;
} else {
uprintf("OK %s\n", FS_MOUNT_CONFIG.mountpoint);
}
}

View File

@ -5,8 +5,8 @@
int showtree(char *root, int indent) { int showtree(char *root, int indent) {
#define INDENT() for (size_t i = 0; i < indent; i++) uprintf(" ") #define INDENT() for (size_t i = 0; i < indent; i++) uprintf(" ")
IoctlStat statbuf; ZERO(&statbuf); FsStat statbuf; ZERO(&statbuf);
if (ioctl(IOCTL_NOHANDLE, IOCTL_STAT, (uint64_t)&statbuf, (uint64_t)root, 0) != E_OK) { if (fs_stat(root, &statbuf) != E_OK) {
uprintf("fs: could not stat %s\n", root); uprintf("fs: could not stat %s\n", root);
return -1; return -1;
} }
@ -18,16 +18,16 @@ int showtree(char *root, int indent) {
} }
if (statbuf.type == IOCTLSTAT_FILE) { if (statbuf.type == FSSTAT_FILE) {
return 0; return 0;
} }
if (statbuf.type == IOCTLSTAT_DIR) { if (statbuf.type == FSSTAT_DIR) {
IoctlDirent *dirents = (IoctlDirent *)umalloc(statbuf.size * sizeof(*dirents)); FsDirent *dirents = (FsDirent *)umalloc(statbuf.size * sizeof(*dirents));
for (size_t i = 0; i < statbuf.size; i++) { for (size_t i = 0; i < statbuf.size; i++) {
ioctl(IOCTL_NOHANDLE, IOCTL_FETCHDIRENT, (uint64_t)root, (uint64_t)&dirents[i], i); fs_fetchdirent(root, &dirents[i], i);
IoctlDirent *dirent = &dirents[i]; FsDirent *dirent = &dirents[i];
if (string_strcmp(dirent->name, ".") == 0 || string_strcmp(dirent->name, "..") == 0) { if (string_strcmp(dirent->name, ".") == 0 || string_strcmp(dirent->name, "..") == 0) {
continue; continue;

View File

@ -8,17 +8,17 @@ Dev_t termdev;
void tb_runinitscript(void) { void tb_runinitscript(void) {
devctl(&termdev, DEVCTL_GET_HANDLE, (uint8_t *)"termdev", 0, 0); devctl(&termdev, DEVCTL_GET_HANDLE, (uint8_t *)"termdev", 0, 0);
char *tbargs[] = { "-m", "runfile", "-f", "base:/scripts/init.tb", "-logcmds", "yes" }; char *tbargs[] = { "-m", "runfile", "-f", "base:/scripts/init.tb" };
int32_t tb = processctl(-1, PCTL_SPAWN, (uint64_t)"base:/bin/tb", (uint64_t)(char **)tbargs, ARRLEN(tbargs)); int32_t tb = proc_spawn("base:/bin/tb", tbargs, ARRLEN(tbargs));
processctl(tb, PCTL_RUN, 0, 0, 0); proc_run(tb);
while(processctl(tb, PCTL_POLLSTATE, 0, 0, 0) != 4) { while(proc_pollstate(tb) != 4) {
int32_t r; int32_t r;
char buf[100]; char buf[100];
string_memset(buf, 0, sizeof(buf)); string_memset(buf, 0, sizeof(buf));
r = ipcpipe(tb, IPCPIPE_OUT, IPCPIPE_READ, (uint8_t *)buf, sizeof(buf)-1); r = ipc_piperead(tb, 0, (uint8_t *const)buf, sizeof(buf)-1);
if (r > 0) { if (r > 0) {
devctl(&termdev, DEV_TERMDEV_PUTCH, (uint8_t *)buf, string_len(buf), 0); devctl(&termdev, DEV_TERMDEV_PUTCH, (uint8_t *)buf, string_len(buf), 0);
} else { } else {
@ -28,7 +28,7 @@ void tb_runinitscript(void) {
} }
void main(void) { void main(void) {
PID = (uint64_t)processctl(-1, PCTL_GETPID, 0, 0, 0); PID = proc_getpid();
devctl(&ps2kbdev, DEVCTL_GET_HANDLE, (uint8_t *)"ps2kbdev", 0, 0); devctl(&ps2kbdev, DEVCTL_GET_HANDLE, (uint8_t *)"ps2kbdev", 0, 0);
devctl(&ps2kbdev, DEV_PS2KBDEV_ATTCHCONS, (uint8_t *)PID, 0, 0); devctl(&ps2kbdev, DEV_PS2KBDEV_ATTCHCONS, (uint8_t *)PID, 0, 0);

View File

@ -22,6 +22,6 @@ void pctl_kill(void) {
} }
if (PCTL_KILL_CONFIG.pid != -1) { if (PCTL_KILL_CONFIG.pid != -1) {
processctl(PCTL_KILL_CONFIG.pid, PCTL_KILL, 0, 0, 0); proc_kill(PCTL_KILL_CONFIG.pid);
} }
} }

View File

@ -26,7 +26,7 @@ void pctl_ls(void) {
static const char *states[] = {"embryo", "ready", "zombie", "waiting", "died"}; static const char *states[] = {"embryo", "ready", "zombie", "waiting", "died"};
uint64_t procslen = processctl(-1, PCTL_PLS_SZ, 0, 0, 0); int32_t procslen = proc_listsize();
char *namebuf = umalloc(34); char *namebuf = umalloc(34);
char *membuf = umalloc(20); char *membuf = umalloc(20);
@ -38,7 +38,7 @@ void pctl_ls(void) {
string_memset(namebuf, 0, 34); string_memset(namebuf, 0, 34);
string_memset(membuf, 0, 20); string_memset(membuf, 0, 20);
int32_t r = processctl(-1, PCTL_PLS_STAT, i, (uint64_t)&stat, 0); int32_t r = proc_stat(i, &stat);
if (r == E_OK) { if (r == E_OK) {
if (PCTL_LS_CONFIG.specificproc != NULL if (PCTL_LS_CONFIG.specificproc != NULL
&& string_strcmp(stat.name, PCTL_LS_CONFIG.specificproc) != 0) { && string_strcmp(stat.name, PCTL_LS_CONFIG.specificproc) != 0) {

View File

@ -206,20 +206,20 @@ bool interp_runstring(char *string, InterpResult **res, bool logcmds, bool inter
string_memcpy(args1[i], argtk->str, MIN(string_len(argtk->str), PROC_ARG_MAX)); string_memcpy(args1[i], argtk->str, MIN(string_len(argtk->str), PROC_ARG_MAX));
} }
int32_t app = processctl(-1, PCTL_SPAWN, (uint64_t)cmdtk->str, (uint64_t)args1, argslen1); int32_t app = proc_spawn(cmdtk->str, args1, argslen1);
if (app < 0) { if (app < 0) {
usprintf(RES.errmsg, "Could not run %s: %s\n", cmdtk->str, ERRSTRING(app)); usprintf(RES.errmsg, "Could not run %s: %s\n", cmdtk->str, ERRSTRING(app));
ok = false; ok = false;
goto cleanup; goto cleanup;
} }
processctl(app, PCTL_RUN, 0, 0, 0); proc_run(app);
while(processctl(app, PCTL_POLLSTATE, 0, 0, 0) != 4) { while(proc_pollstate(app) != 4) {
if (interactive) { if (interactive) {
int32_t key = devctl(&ps2kbdev, DEV_PS2KBDEV_READCH, (uint8_t *)PID, 0, 0); int32_t key = devctl(&ps2kbdev, DEV_PS2KBDEV_READCH, (uint8_t *)PID, 0, 0);
if (key > 0 && (uint8_t)key == C('S')) { if (key > 0 && (uint8_t)key == C('S')) {
processctl(app, PCTL_KILL, 0, 0, 0); proc_kill(app);
goto cleanup; goto cleanup;
} }
} }

View File

@ -21,8 +21,6 @@ struct {
bool logcmds; bool logcmds;
char *preloadpath;
char *runstring; char *runstring;
} CONFIG; } CONFIG;
@ -30,7 +28,6 @@ static Arg ARGS[] = {
ARG("-m", ARG_STRING, &CONFIG.modestr), ARG("-m", ARG_STRING, &CONFIG.modestr),
ARG("-f", ARG_STRING, &CONFIG.filepath), ARG("-f", ARG_STRING, &CONFIG.filepath),
ARG("-logcmds", ARG_BOOL, &CONFIG.logcmds), ARG("-logcmds", ARG_BOOL, &CONFIG.logcmds),
ARG("-preload", ARG_STRING, &CONFIG.preloadpath),
ARG("-rs", ARG_STRING, &CONFIG.runstring), ARG("-rs", ARG_STRING, &CONFIG.runstring),
ARG_END(), ARG_END(),
}; };
@ -59,26 +56,24 @@ void set_config(void) {
} }
void do_file(char *filepath) { void do_file(char *filepath) {
int32_t ret; int32_t h = fs_openf(filepath, FS_OF_READ);
if (h < 0) {
int32_t ioh = ioctl(IOCTL_NOHANDLE, IOCTL_OPENF, (uint64_t)filepath, IOCTL_F_READ, 0); LOG(LOG_ERR, "Could not open %s: %s\n", filepath, ERRSTRING(h));
if (ioh < 0) {
LOG(LOG_ERR, "Could not open %s: %s\n", filepath, ERRSTRING(ioh));
return; return;
} }
IoctlStat statbuf; ZERO(&statbuf); FsStat statbuf; ZERO(&statbuf);
ioctl(ioh, IOCTL_STAT, (uint64_t)&statbuf, (uint64_t)filepath, 0); fs_stat(filepath, &statbuf);
if (statbuf.type != IOCTLSTAT_FILE) { if (statbuf.type != FSSTAT_FILE) {
LOG(LOG_ERR, "%s is not a file (%d)\n", filepath, statbuf.type); LOG(LOG_ERR, "%s is not a file (%d)\n", filepath, statbuf.type);
return; return;
} }
uint8_t *buf = umalloc(statbuf.size+1); uint8_t *buf = umalloc(statbuf.size+1);
string_memset(buf, 0, statbuf.size+1); string_memset(buf, 0, statbuf.size+1);
if ((ret = ioctl(ioh, IOCTL_READ, (uint64_t)buf, statbuf.size, 0)) < 0) { if (fs_read(h, buf, statbuf.size, 0) < 0) {
LOG(LOG_ERR, "Could not read %s (%d): %s\n", filepath, ioh, ERRSTRING(ioh)); LOG(LOG_ERR, "Could not read %s (%d): %s\n", filepath, h, ERRSTRING(h));
goto done; goto done;
} }
@ -92,7 +87,7 @@ void do_file(char *filepath) {
done: done:
ufree(buf); ufree(buf);
ioctl(ioh, IOCTL_CLOSEF, 0, 0, 0); fs_closef(h);
} }
void do_mode_interactive(void) { void do_mode_interactive(void) {
@ -149,13 +144,11 @@ void do_mode_interactive(void) {
} }
void main(void) { void main(void) {
PID = processctl(-1, PCTL_GETPID, 0, 0, 0); PID = proc_getpid();
set_config(); set_config();
if (CONFIG.preloadpath != NULL) { do_file("base:/scripts/rc.tb");
do_file(CONFIG.preloadpath);
}
if (CONFIG.mode == MODE_INTERACTIVE) { if (CONFIG.mode == MODE_INTERACTIVE) {
devctl(&ps2kbdev, DEVCTL_GET_HANDLE, (uint8_t *)"ps2kbdev", 0, 0); devctl(&ps2kbdev, DEVCTL_GET_HANDLE, (uint8_t *)"ps2kbdev", 0, 0);

View File

@ -86,7 +86,7 @@ bool rt_PID(Token *tks) {
bool rt_do(Token *tks) { bool rt_do(Token *tks) {
bool ok = true; bool ok = true;
char *prepended_args[] = { "-m", "runstring", "-preload", "base:/scripts/rc.tb", "-rs" }; char *prepended_args[] = { "-m", "runstring", "-rs" };
#define SUBSH_MAX_STRING PROC_ARG_MAX #define SUBSH_MAX_STRING PROC_ARG_MAX
char *s = umalloc(SUBSH_MAX_STRING); char *s = umalloc(SUBSH_MAX_STRING);
@ -111,7 +111,7 @@ bool rt_do(Token *tks) {
args1[ARRLEN(prepended_args)] = umalloc(PROC_ARG_MAX); args1[ARRLEN(prepended_args)] = umalloc(PROC_ARG_MAX);
string_strcpy(args1[ARRLEN(prepended_args)], s); string_strcpy(args1[ARRLEN(prepended_args)], s);
int32_t app = processctl(-1, PCTL_SPAWN, (uint64_t)"base:/bin/tb", (uint64_t)args1, ARRLEN(prepended_args)+1); int32_t app = proc_spawn("base:/bin/tb", args1, ARRLEN(prepended_args)+1);
if (app < 0) { if (app < 0) {
ok = false; ok = false;
goto done; goto done;
@ -120,23 +120,23 @@ bool rt_do(Token *tks) {
StringBuffer outbuf; StringBuffer outbuf;
stringbuffer_init(&outbuf); stringbuffer_init(&outbuf);
ipcpipe(PID, 10, IPCPIPE_MAKE, NULL, 0); ipc_pipemake(10);
ipcpipe(app, IPCPIPE_OUT, IPCPIPE_REPLACE, (uint8_t *)PID, 10); ipc_pipeconnect(app, 0, PID, 10);
processctl(app, PCTL_RUN, 0, 0, 0); proc_run(app);
while (processctl(app, PCTL_POLLSTATE, 0, 0, 0) != 4) { while (proc_pollstate(app) != 4) {
int32_t r; int32_t r;
char buf[100]; char buf[100];
string_memset(buf, 0, sizeof(buf)); string_memset(buf, 0, sizeof(buf));
r = ipcpipe(app, IPCPIPE_OUT, IPCPIPE_READ, (uint8_t *)buf, sizeof(buf)-1); r = ipc_piperead(app, 0, (uint8_t *const)buf, sizeof(buf)-1);
if (r > 0) { if (r > 0) {
stringbuffer_appendcstr(&outbuf, buf); stringbuffer_appendcstr(&outbuf, buf);
} }
} }
ipcpipe(PID, 10, IPCPIPE_DELETE, NULL, 0); ipc_pipedelete(10);
rtstringv_stackpushcopy(outbuf.data, outbuf.count); rtstringv_stackpushcopy(outbuf.data, outbuf.count);