Compare commits
11 Commits
c0f91dcced
...
406434fed0
| Author | SHA1 | Date | |
|---|---|---|---|
| 406434fed0 | |||
| c34a253d11 | |||
| 8aec45316c | |||
| a67d80a2d1 | |||
| ddb31ac5f5 | |||
| 9108299c31 | |||
| c972b0fbd1 | |||
| c895c5db3e | |||
| 25cb309105 | |||
| cb9e15330e | |||
| 5aebc61c06 |
@ -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
2
base/scripts/mount.tb
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
print 'Mounting filesystems...\n'
|
||||||
|
$fs mount -mp system -fs LittleFS -dev atasd-mst -fmt no
|
||||||
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -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);
|
||||||
|
|||||||
@ -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"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|||||||
@ -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_
|
||||||
|
|||||||
@ -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)));
|
||||||
|
|||||||
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -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
223
kernel/storedev/atasd.c
Normal 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
30
kernel/storedev/atasd.h
Normal 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_
|
||||||
@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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);
|
||||||
|
|
||||||
|
|||||||
@ -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);
|
||||||
|
|||||||
@ -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
228
kernel/syscall/fs.c
Normal 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
16
kernel/syscall/fs.h
Normal 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_
|
||||||
@ -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;
|
|
||||||
}
|
|
||||||
@ -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_
|
|
||||||
@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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
237
kernel/syscall/proc.c
Normal 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
18
kernel/syscall/proc.h
Normal 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_
|
||||||
@ -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;
|
|
||||||
}
|
|
||||||
@ -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_
|
|
||||||
@ -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
63
kernel/syscall/vfs.c
Normal 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
11
kernel/syscall/vfs.h
Normal 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_
|
||||||
@ -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;
|
||||||
|
}
|
||||||
|
|||||||
@ -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_
|
||||||
|
|||||||
@ -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);
|
||||||
|
|||||||
@ -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_
|
||||||
|
|||||||
@ -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
24
share/sysdefs/fs.h
Normal 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_
|
||||||
@ -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_
|
|
||||||
@ -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
15
share/sysdefs/proc.h
Normal 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_
|
||||||
@ -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_
|
|
||||||
@ -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_
|
||||||
|
|||||||
@ -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());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -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
|
|
||||||
|
|||||||
@ -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);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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);
|
||||||
|
}
|
||||||
|
|||||||
@ -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_
|
||||||
|
|||||||
@ -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>
|
||||||
|
|
||||||
|
|||||||
@ -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());
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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) {
|
||||||
|
|||||||
@ -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);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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
56
user/fs/mount.c
Normal 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -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;
|
||||||
|
|||||||
@ -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);
|
||||||
|
|
||||||
|
|||||||
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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) {
|
||||||
|
|||||||
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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);
|
||||||
|
|||||||
@ -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);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user