Compare commits

..

4 Commits

Author SHA1 Message Date
ff33afbb2a fs Clean up dummy mount point post-formatting 2025-10-19 23:03:13 +02:00
1e0eca3076 fs Disk formatting subcommand 2025-10-19 23:01:02 +02:00
a96ea5edb6 tb Command-like scripts 2025-10-19 23:00:46 +02:00
01da863b8b Handle disk partitioning 2025-10-19 22:29:19 +02:00
26 changed files with 387 additions and 107 deletions

1
.gitignore vendored
View File

@ -2,3 +2,4 @@
/iso_root /iso_root
*.iso *.iso
*.img *.img
*.hdd

View File

@ -1,4 +1,4 @@
.PHONY: clean prepare cleanall iso base system kernel user test .PHONY: clean prepare cleanall iso hdd base kernel user test
ARCH ?= x86_64 ARCH ?= x86_64
@ -38,13 +38,13 @@ clean:
make -C kernel ARCH=$(ARCH) ROOT=$(PWD) clean make -C kernel ARCH=$(ARCH) ROOT=$(PWD) clean
make -C user ARCH=$(ARCH) ROOT=$(PWD) clean make -C user ARCH=$(ARCH) ROOT=$(PWD) clean
make -C ulib ARCH=$(ARCH) ROOT=$(PWD) clean make -C ulib ARCH=$(ARCH) ROOT=$(PWD) clean
rm -f mop2.iso base.img system.img rm -f mop2.iso base.img disk.hdd
base: base:
./scripts/mkbaseimg.sh ./scripts/mkbaseimg.sh
system:
./scripts/mksystemimg.sh
iso: iso:
./scripts/mkiso.sh ./scripts/mkiso.sh
hdd:
./scripts/mkhdd.sh

1
base/scripts/fmtdisk.tb Normal file
View File

@ -0,0 +1 @@
$fs fmt -dev $0 -fs $1

View File

@ -1,3 +1,3 @@
print 'Mounting filesystems...\n' print 'Mounting filesystems...\n'
setlogcmds yes setlogcmds yes
$fs mount -mp system -fs LittleFS -dev atasd-ch0-M -fmt no $fs mount -mp uhome -fs LittleFS -dev atasd-ch0-M-part2 -fmt no

View File

@ -61,6 +61,7 @@ SRCFILES += $(call GRABSRC, \
dev \ dev \
randcrypto \ randcrypto \
time \ time \
diskpart \
) )
CFILES := $(call GET_CFILES, $(SRCFILES)) CFILES := $(call GET_CFILES, $(SRCFILES))

View File

@ -0,0 +1,15 @@
#include <stdint.h>
#include <stddef.h>
#include "storedev/storedev.h"
#include "mbr.h"
#include "util/util.h"
#include "kprintf.h"
void diskpart_init(void) {
LOG("diskpart", "probing for disks with partitions\n");
StoreDev *sd, *sdtmp;
LL_FOREACH_SAFE(STOREDEV_LIST.head, sd, sdtmp) {
diskpart_mbr_probe(sd);
}
}

View File

@ -0,0 +1,6 @@
#ifndef DISKPART_DISKPART_H_
#define DISKPART_DISKPART_H_
void diskpart_init(void);
#endif // DISKPART_DISKPART_H_

77
kernel/diskpart/mbr.c Normal file
View File

@ -0,0 +1,77 @@
#include <stdbool.h>
#include <stdint.h>
#include <stddef.h>
#include "storedev/storedev.h"
#include "mbr.h"
#include "diskpart.h"
#include "compiler/attr.h"
#include "errors.h"
#include "kprintf.h"
#include "hal/hal.h"
#include "util/util.h"
#include "dev/dev.h"
typedef struct {
uint8_t driveattrs;
uint8_t chs_start_addr[3];
uint8_t parttype;
uint8_t chs_last_sect_addr[3];
uint32_t startlba;
uint32_t sectorcount;
} PACKED PTE;
typedef struct {
uint8_t bootcode[440];
uint8_t signature[4];
uint8_t resv[2];
PTE pte1;
PTE pte2;
PTE pte3;
PTE pte4;
uint8_t validsign[2];
} PACKED MBR;
void diskpart_mbr_expose_partitions(StoreDev *sd, MBR *mbr) {
PTE *parts[4] = { &mbr->pte1, &mbr->pte2, &mbr->pte3, &mbr->pte4 };
for (size_t i = 0; i < 4; i++) {
char *name = NULL;
spinlock_acquire(&DEVTABLE.spinlock);
for (size_t i = 0; i < LEN(DEVTABLE.devs); i++) {
Dev *dev = &DEVTABLE.devs[i];
if (dev->extra == sd) {
name = (char *)dev->ident;
}
}
spinlock_release(&DEVTABLE.spinlock);
PartSdInitExtra extra = {
.parent = sd,
.sectorcount = parts[i]->sectorcount,
.startsector = parts[i]->startlba,
};
char name1[100];
ksprintf(name1, "%s-part%zu", name, i+1);
kprintf("%s\n", name1);
storedev_create(STOREDEV_PARTSD, name1, &extra);
}
}
bool diskpart_mbr_probe(StoreDev *sd) {
LOG("diskpart", "probing for MBR\n");
MBR mbr;
hal_memset(&mbr, 0, sizeof(mbr));
sd->read(sd, (uint8_t *const)&mbr, 0, 0, sizeof(mbr));
if (!(mbr.validsign[0] == 0x55 && mbr.validsign[1] == 0xAA)) {
return false;
}
LOG("diskpart", "got valid MBR on %s\n", storedev_strings[sd->sdtype]);
diskpart_mbr_expose_partitions(sd, &mbr);
return true;
}

9
kernel/diskpart/mbr.h Normal file
View File

@ -0,0 +1,9 @@
#ifndef DISKPART_MBR_H_
#define DISKPART_MBR_H_
#include <stdbool.h>
#include "storedev/storedev.h"
bool diskpart_mbr_probe(StoreDev *sd);
#endif // DISKPART_MBR_H_

View File

@ -14,6 +14,7 @@
#include "dev/dev.h" #include "dev/dev.h"
#include "randcrypto/randcrypto.h" #include "randcrypto/randcrypto.h"
#include "time/time.h" #include "time/time.h"
#include "diskpart/diskpart.h"
void log_bootinfo(void) { void log_bootinfo(void) {
char buf[100]; char buf[100];
@ -46,6 +47,7 @@ void kmain(void) {
randcrypto_init(); randcrypto_init();
dev_init(); dev_init();
storedev_init(); storedev_init();
diskpart_init();
baseimg_init(); baseimg_init();
vfs_init(); vfs_init();
proc_init(); proc_init();

View File

@ -121,7 +121,7 @@ void ata_probe(void) {
.iobase = 0x1F0, .iobase = 0x1F0,
.ctrlbase = 0x3F6, .ctrlbase = 0x3F6,
}; };
storedev_create(STOREDEV_ATASD, (void *)&extra); storedev_create(STOREDEV_ATASD, "atasd-ch0-M", (void *)&extra);
} }
probesize = ata_probesize_bytes(0x1F0, 0x3F6, ATA_SLAVE); probesize = ata_probesize_bytes(0x1F0, 0x3F6, ATA_SLAVE);
@ -135,7 +135,7 @@ void ata_probe(void) {
.iobase = 0x1F0, .iobase = 0x1F0,
.ctrlbase = 0x3F6, .ctrlbase = 0x3F6,
}; };
storedev_create(STOREDEV_ATASD, (void *)&extra); storedev_create(STOREDEV_ATASD, "atasd-ch0-S", (void *)&extra);
} }
probesize = ata_probesize_bytes(0x170, 0x376, ATA_MASTER); probesize = ata_probesize_bytes(0x170, 0x376, ATA_MASTER);
@ -149,7 +149,7 @@ void ata_probe(void) {
.iobase = 0x170, .iobase = 0x170,
.ctrlbase = 0x376, .ctrlbase = 0x376,
}; };
storedev_create(STOREDEV_ATASD, (void *)&extra); storedev_create(STOREDEV_ATASD, "atasd-ch1-M", (void *)&extra);
} }
probesize = ata_probesize_bytes(0x170, 0x376, ATA_SLAVE); probesize = ata_probesize_bytes(0x170, 0x376, ATA_SLAVE);
@ -163,7 +163,7 @@ void ata_probe(void) {
.iobase = 0x170, .iobase = 0x170,
.ctrlbase = 0x376, .ctrlbase = 0x376,
}; };
storedev_create(STOREDEV_ATASD, (void *)&extra); storedev_create(STOREDEV_ATASD, "atasd-ch1-S", (void *)&extra);
} }
} }
@ -185,6 +185,51 @@ void ata_setup(uint16_t iobase, uint16_t ctrlbase, int devno, uint16_t sectors,
} }
int32_t ata_read(uint16_t iobase, uint16_t ctrlbase, int devno,
uint64_t sectorsize, uint8_t *const buffer,
ptrdiff_t sector, ptrdiff_t off, size_t size) {
int32_t ret = E_OK;
uint64_t lba = (uint64_t)(sector * (ptrdiff_t)sectorsize + off) / sectorsize;
size_t sectors = size / sectorsize;
if (size % sectorsize) sectors++;
ata_setup(iobase, ctrlbase, devno, sectors, lba);
io_out8(iobase + ATA_REG_COMMAND, ATA_CMD_READ_PIO_EXT);
for (size_t s = 0; s < sectors; s++) {
if (ata_wait(iobase, 100000, true, 1) < 0) { ret = E_BADIO; goto done; }
io_ins16(iobase + ATA_REG_DATA, (uint16_t *)(buffer + s * sectorsize), sectorsize / 2);
}
done:
return ret;
}
int32_t ata_write(uint16_t iobase, uint16_t ctrlbase, int devno,
uint64_t sectorsize, const uint8_t *const buffer,
ptrdiff_t sector, ptrdiff_t off, size_t size) {
int32_t ret = E_OK;
uint64_t lba = (uint64_t)(sector * (ptrdiff_t)sectorsize + off) / sectorsize;
size_t sectors = size / sectorsize;
if (size % sectorsize) sectors++;
ata_setup(iobase, ctrlbase, devno, sectors, lba);
io_out8(iobase + ATA_REG_COMMAND, ATA_CMD_WRITE_PIO_EXT);
for (size_t s = 0; s < sectors; s++) {
if (ata_wait(iobase, 100000, true, 1) < 0) { ret = E_BADIO; goto done; }
io_outs16(iobase + ATA_REG_DATA, (uint16_t *)(buffer + s * sectorsize), sectorsize / 2);
}
io_out8(iobase + ATA_REG_COMMAND, ATA_CMD_CACHE_FLUSH_EXT);
if (ata_wait(iobase, 100000, false, 1) < 0) { ret = E_BADIO; goto done; }
done:
return ret;
}
int32_t atasd_init(struct StoreDev *sd, void *extra) { int32_t atasd_init(struct StoreDev *sd, void *extra) {
AtaSdInitExtra *e = (AtaSdInitExtra *)extra; AtaSdInitExtra *e = (AtaSdInitExtra *)extra;
sd->sd.atasd.devno = e->devno; sd->sd.atasd.devno = e->devno;
@ -200,21 +245,9 @@ int32_t atasd_read(struct StoreDev *sd, uint8_t *const buffer, ptrdiff_t sector,
AtaSd *ata = &sd->sd.atasd; AtaSd *ata = &sd->sd.atasd;
uint64_t lba = (uint64_t)(sector * (ptrdiff_t)sd->sectorsize + off) / (uint64_t)STOREDEV_ATASD_SECTORSIZE; ret = ata_read(ata->iobase, ata->ctrlbase, ata->devno,
size_t sectors = size / STOREDEV_ATASD_SECTORSIZE; sd->sectorsize, buffer, sector, off, size);
if (size % STOREDEV_ATASD_SECTORSIZE) sectors++;
ata_setup(ata->iobase, ata->ctrlbase, ata->devno, sectors, lba);
io_out8(ata->iobase + ATA_REG_COMMAND, ATA_CMD_READ_PIO_EXT);
for (size_t s = 0; s < sectors; s++) {
if (ata_wait(ata->iobase, 100000, true, 1) < 0) { ret = E_BADIO; goto done; }
io_ins16(ata->iobase + ATA_REG_DATA, (uint16_t *)(buffer + s * STOREDEV_ATASD_SECTORSIZE), STOREDEV_ATASD_SECTORSIZE/2);
}
ret = E_OK;
done:
spinlock_release(&sd->spinlock); spinlock_release(&sd->spinlock);
return ret; return ret;
} }
@ -225,24 +258,9 @@ int32_t atasd_write(struct StoreDev *sd, const uint8_t *const buffer, ptrdiff_t
AtaSd *ata = &sd->sd.atasd; AtaSd *ata = &sd->sd.atasd;
uint64_t lba = (uint64_t)(sector * (ptrdiff_t)sd->sectorsize + off) / (uint64_t)STOREDEV_ATASD_SECTORSIZE; ret = ata_write(ata->iobase, ata->ctrlbase, ata->devno,
size_t sectors = size / STOREDEV_ATASD_SECTORSIZE; sd->sectorsize, buffer, sector, off, size);
if (size % STOREDEV_ATASD_SECTORSIZE) sectors++;
ata_setup(ata->iobase, ata->ctrlbase, ata->devno, sectors, lba);
io_out8(ata->iobase + ATA_REG_COMMAND, ATA_CMD_WRITE_PIO_EXT);
for (size_t s = 0; s < sectors; s++) {
if (ata_wait(ata->iobase, 100000, true, 1) < 0) { ret = E_BADIO; goto done; }
io_outs16(ata->iobase + ATA_REG_DATA, (uint16_t *)(buffer + s * STOREDEV_ATASD_SECTORSIZE), STOREDEV_ATASD_SECTORSIZE/2);
}
io_out8(ata->iobase + ATA_REG_COMMAND, ATA_CMD_CACHE_FLUSH_EXT);
if (ata_wait(ata->iobase, 100000, false, 1) < 0) { ret = E_BADIO; goto done; }
ret = E_OK;
done:
spinlock_release(&sd->spinlock); spinlock_release(&sd->spinlock);
return ret; return ret;
} }

33
kernel/storedev/partsd.c Normal file
View File

@ -0,0 +1,33 @@
#include <stdint.h>
#include <stddef.h>
#include "partsd.h"
#include "storedev.h"
#include "errors.h"
#include "kprintf.h"
int32_t partsd_init(struct StoreDev *sd, void *extra) {
PartSdInitExtra *e = (PartSdInitExtra *)extra;
sd->sd.partsd.sectorcount = e->sectorcount;
sd->sd.partsd.startsector = e->startsector;
sd->sd.partsd.parent = e->parent;
sd->sectorsize = e->parent->sectorsize;
return E_OK;
}
int32_t partsd_read(struct StoreDev *sd, uint8_t *const buffer, ptrdiff_t sector, ptrdiff_t off, size_t size) {
PartSd *part = &sd->sd.partsd;
return part->parent->read(part->parent, buffer, part->startsector + sector, off, size);
}
int32_t partsd_write(struct StoreDev *sd, const uint8_t *const buffer, ptrdiff_t sector, ptrdiff_t off, size_t size) {
PartSd *part = &sd->sd.partsd;
return part->parent->write(part->parent, buffer, part->startsector + sector, off, size);
}
int32_t partsd_cleanup(struct StoreDev *sd) {
return E_OK;
}
size_t partsd_capacity(struct StoreDev *sd) {
return sd->sd.partsd.parent->sectorsize * sd->sd.partsd.sectorcount;
}

27
kernel/storedev/partsd.h Normal file
View File

@ -0,0 +1,27 @@
#ifndef STOREDEV_PARTSD_H_
#define STOREDEV_PARTSD_H_
#include <stdint.h>
#include <stddef.h>
struct StoreDev;
typedef struct {
struct StoreDev *parent;
size_t sectorcount;
size_t startsector;
} PartSd;
typedef struct {
struct StoreDev *parent;
size_t sectorcount;
size_t startsector;
} PartSdInitExtra;
int32_t partsd_init(struct StoreDev *sd, void *extra);
int32_t partsd_read(struct StoreDev *sd, uint8_t *const buffer, ptrdiff_t sector, ptrdiff_t off, size_t size);
int32_t partsd_write(struct StoreDev *sd, const uint8_t *const buffer, ptrdiff_t sector, ptrdiff_t off, size_t size);
int32_t partsd_cleanup(struct StoreDev *sd);
size_t partsd_capacity(struct StoreDev *sd);
#endif // STOREDEV_PARTSD_H_

View File

@ -24,23 +24,10 @@ void storedev_init(void) {
ata_probe(); ata_probe();
} }
size_t ramsd_counter = 0; void storedev_register_dev_entry(StoreDev *sd, char *name, int32_t sdtype) {
void storedev_register_dev_entry(StoreDev *sd, int32_t sdtype) {
char key[20];
if (sdtype == STOREDEV_RAMSD) {
ksprintf(key, "ramsd-%zu", ramsd_counter++);
} else if (sdtype == STOREDEV_ATASD) {
ksprintf(key, "atasd-ch%d-%c",
sd->sd.atasd.iobase == 0x1F0 ? 0 : 1,
sd->sd.atasd.devno == 0x00 ? 'M' : 'S'
);
}
spinlock_acquire(&DEVTABLE.spinlock); spinlock_acquire(&DEVTABLE.spinlock);
Dev *dev = NULL; Dev *dev = NULL;
HSHTB_ALLOC(DEVTABLE.devs, ident, key, dev); HSHTB_ALLOC(DEVTABLE.devs, ident, name, dev);
spinlock_release(&DEVTABLE.spinlock); spinlock_release(&DEVTABLE.spinlock);
if (dev == NULL) { if (dev == NULL) {
@ -58,7 +45,7 @@ void storedev_unregister_dev_entry(Dev *dev) {
spinlock_release(&DEVTABLE.spinlock); spinlock_release(&DEVTABLE.spinlock);
} }
StoreDev *storedev_create(int32_t sdtype, void *extra) { StoreDev *storedev_create(int32_t sdtype, char *name, void *extra) {
StoreDev *sd = dlmalloc(sizeof(*sd)); StoreDev *sd = dlmalloc(sizeof(*sd));
if (sd == NULL) { if (sd == NULL) {
return NULL; return NULL;
@ -67,10 +54,10 @@ StoreDev *storedev_create(int32_t sdtype, void *extra) {
spinlock_acquire(&STOREDEV_LIST.spinlock); spinlock_acquire(&STOREDEV_LIST.spinlock);
sd->_magic = STOREDEV_MAGIC; sd->_magic = STOREDEV_MAGIC;
spinlock_init(&sd->spinlock);
switch (sdtype) { switch (sdtype) {
case STOREDEV_RAMSD: { case STOREDEV_RAMSD: {
spinlock_init(&sd->spinlock);
sd->sdtype = STOREDEV_RAMSD; sd->sdtype = STOREDEV_RAMSD;
sd->init = &ramsd_init; sd->init = &ramsd_init;
sd->cleanup = &ramsd_cleanup; sd->cleanup = &ramsd_cleanup;
@ -80,7 +67,6 @@ StoreDev *storedev_create(int32_t sdtype, void *extra) {
sd->sectorsize = STOREDEV_RAMSD_SECTORSIZE; sd->sectorsize = STOREDEV_RAMSD_SECTORSIZE;
} break; } break;
case STOREDEV_ATASD: { case STOREDEV_ATASD: {
spinlock_init(&sd->spinlock);
sd->sdtype = STOREDEV_ATASD; sd->sdtype = STOREDEV_ATASD;
sd->init = &atasd_init; sd->init = &atasd_init;
sd->cleanup = &atasd_cleanup; sd->cleanup = &atasd_cleanup;
@ -89,6 +75,15 @@ StoreDev *storedev_create(int32_t sdtype, void *extra) {
sd->capacity = &atasd_capacity; sd->capacity = &atasd_capacity;
sd->sectorsize = STOREDEV_ATASD_SECTORSIZE; sd->sectorsize = STOREDEV_ATASD_SECTORSIZE;
} break; } break;
case STOREDEV_PARTSD: {
sd->sdtype = STOREDEV_PARTSD;
sd->init = &partsd_init;
sd->cleanup = &partsd_cleanup;
sd->read = &partsd_read;
sd->write = &partsd_write;
sd->capacity = &partsd_capacity;
sd->sectorsize = 0; // lazy
} break;
default: default:
spinlock_release(&STOREDEV_LIST.spinlock); spinlock_release(&STOREDEV_LIST.spinlock);
return NULL; return NULL;
@ -102,7 +97,7 @@ StoreDev *storedev_create(int32_t sdtype, void *extra) {
LL_APPEND(STOREDEV_LIST.head, sd); 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, name, sdtype);
return sd; return sd;
} }

View File

@ -6,6 +6,7 @@
#include "spinlock/spinlock.h" #include "spinlock/spinlock.h"
#include "ramsd.h" #include "ramsd.h"
#include "atasd.h" #include "atasd.h"
#include "partsd.h"
#include "compiler/attr.h" #include "compiler/attr.h"
#include "dev/dev.h" #include "dev/dev.h"
@ -14,10 +15,11 @@
enum { enum {
STOREDEV_RAMSD, STOREDEV_RAMSD,
STOREDEV_ATASD, STOREDEV_ATASD,
STOREDEV_PARTSD,
}; };
UNUSED static const char *storedev_strings[] = { UNUSED static const char *storedev_strings[] = {
"RAMSD", "ATASD" "RAMSD", "ATASD", "PARTSD",
}; };
typedef struct StoreDev { typedef struct StoreDev {
@ -35,6 +37,7 @@ typedef struct StoreDev {
union { union {
RamSd ramsd; RamSd ramsd;
AtaSd atasd; AtaSd atasd;
PartSd partsd;
} sd; } sd;
SpinLock spinlock; SpinLock spinlock;
} StoreDev; } StoreDev;
@ -48,10 +51,10 @@ extern StoreDevList STOREDEV_LIST;
void storedev_init(void); void storedev_init(void);
StoreDev *storedev_create(int32_t sdtype, void *extra); StoreDev *storedev_create(int32_t sdtype, char *name, void *extra);
int32_t storedev_delete(StoreDev *sd); int32_t storedev_delete(StoreDev *sd);
void storedev_register_dev_entry(StoreDev *sd, int32_t sdtype); void storedev_register_dev_entry(StoreDev *sd, char *name, int32_t sdtype);
void storedev_unregister_dev_entry(Dev *dev); void storedev_unregister_dev_entry(Dev *dev);
#endif // STOREDEV_STOREDEV_H_ #endif // STOREDEV_STOREDEV_H_

View File

@ -179,7 +179,7 @@ void vfs_init(void) {
{ {
RamSdInitExtra extra = { .capacity = baseimg_getsize(), .preallocbuffer = (uint8_t *)baseimg_getaddr() }; RamSdInitExtra extra = { .capacity = baseimg_getsize(), .preallocbuffer = (uint8_t *)baseimg_getaddr() };
StoreDev *backingsd = storedev_create(STOREDEV_RAMSD, &extra); StoreDev *backingsd = storedev_create(STOREDEV_RAMSD, "ramsd-0", &extra);
if (backingsd == NULL) { if (backingsd == NULL) {
return; return;
} }
@ -188,7 +188,7 @@ void vfs_init(void) {
{ {
RamSdInitExtra extra = { .capacity = (1024*1024*10) }; RamSdInitExtra extra = { .capacity = (1024*1024*10) };
StoreDev *backingsd = storedev_create(STOREDEV_RAMSD, &extra); StoreDev *backingsd = storedev_create(STOREDEV_RAMSD, "ramsd-1", &extra);
if (backingsd == NULL) { if (backingsd == NULL) {
return; return;
} }

11
run/qemu-x86_64-hdd.sh Executable file
View File

@ -0,0 +1,11 @@
#!/bin/sh
set -x
qemu-system-x86_64 \
-cpu IvyBridge \
-m 4G \
-boot d \
-serial stdio \
-drive file=disk.hdd,format=raw,if=ide \
$@

View File

@ -8,5 +8,4 @@ qemu-system-x86_64 \
-cdrom mop2.iso \ -cdrom mop2.iso \
-boot d \ -boot d \
-serial stdio \ -serial stdio \
-drive file=system.img,format=raw,if=ide \
$@ $@

View File

@ -4,5 +4,5 @@ make -B kernel && \
make -B ulib && \ make -B ulib && \
make -B user && \ make -B user && \
make base && \ make base && \
make system && \ make iso && \
make iso make hdd

23
scripts/mkhdd.sh Executable file
View File

@ -0,0 +1,23 @@
#!/bin/sh
rm -f disk.hdd
dd if=/dev/zero of=disk.hdd bs=1M count=128
parted disk.hdd --script mklabel msdos
parted disk.hdd --script mkpart primary fat32 1MiB 63MiB
parted disk.hdd --script set 1 boot on
parted disk.hdd --script mkpart primary 64MiB 127MiB
LOOP=$(sudo losetup --find --show --partscan disk.hdd)
sudo mkfs.fat -F32 ${LOOP}p1
mkdir mnt
sudo mount ${LOOP}p1 mnt
sudo cp -r iso_root/* mnt/
sudo ./limine/limine bios-install ${LOOP}
sudo umount mnt
sudo losetup -d ${LOOP}
rm -rf mnt

View File

@ -1,5 +0,0 @@
#!/bin/sh
if [ ! -e system.img ]; then
mklittlefs -c system -b 512 -s $((1<<20)) system.img
fi

View File

36
user/fs/fmt.c Normal file
View File

@ -0,0 +1,36 @@
#include <stdint.h>
#include <stddef.h>
#include <ulib.h>
struct {
char *devname;
char *fstype;
} FS_FMT_CONFIG = {0};
static Arg ARGS[] = {
ARG("-dev", ARG_STRING, &FS_FMT_CONFIG.devname),
ARG("-fs", ARG_STRING, &FS_FMT_CONFIG.fstype),
ARG_END(),
};
void fs_fmt(void) {
int32_t ret;
if ((ret = parse_args(args()+1, argslen()-1, ARGS)) < 0) {
uprintf("fs fmt: Could not parse args: %d\n", ret);
}
Dev_t dev;
ret = dev_gethandle(&dev, FS_FMT_CONFIG.devname);
if (ret != E_OK) {
uprintf("fs: device %s not found\n", FS_FMT_CONFIG.devname);
return;
}
ret = vfsmount("fmt-dummy", FS_FMT_CONFIG.fstype, &dev, true);
if (ret != E_OK) {
uprintf("fs: mount error %s\n", ERRSTRING(ret));
return;
}
vfsunmount("fmt-dummy");
}

View File

@ -4,7 +4,8 @@
#define CMDS(X) \ #define CMDS(X) \
X(fetch) X(mkf) X(mkd) \ X(fetch) X(mkf) X(mkd) \
X(tree) X(mount) X(del) X(tree) X(mount) X(del) \
X(fmt)
void main(void) { void main(void) {
if (argslen() == 0) { if (argslen() == 0) {

View File

@ -136,6 +136,22 @@ void tz_expandspecial(Tokenizer *tz) {
Token *tk, *tktmp; Token *tk, *tktmp;
LL_FOREACH_SAFE(tz->tokens, tk, tktmp) { LL_FOREACH_SAFE(tz->tokens, tk, tktmp) {
if (tk->str[0] == '$' && string_len(tk->str) > 1) { if (tk->str[0] == '$' && string_len(tk->str) > 1) {
bool isnum;
STRING_CHECK_ALL(tk->str + 1, string_chr_isdigit, isnum);
if (isnum) {
// this is a special case for command-like scripts
char *endp;
unsigned long idx = string_conv_strtoul(tk->str + 1, &endp, 10);
idx += 2; // skip command itself and indicator / '.'
ufree(tk->str);
char *s = idx < argslen() ? args()[idx] : "";
size_t len = string_len(s);
char *copy = umalloc(len+1);
string_memcpy(copy, s, len);
copy[len] = '\0';
tk->str = copy;
} else {
if (string_strcmp(tk->str, "$stack") == 0) { if (string_strcmp(tk->str, "$stack") == 0) {
char *s = rtstringv_stackpeek(); char *s = rtstringv_stackpeek();
ufree(tk->str); ufree(tk->str);
@ -165,6 +181,7 @@ void tz_expandspecial(Tokenizer *tz) {
} }
} }
} }
}
#define LINE_MAX 1024 #define LINE_MAX 1024

View File

@ -134,6 +134,16 @@ void do_mode_interactive(void) {
void main(void) { void main(void) {
PID = proc_getpid(); PID = proc_getpid();
// short command-like script was supplied
if (argslen() > 0 && args()[0][0] == '.') {
do_file("base:/scripts/rc.tb");
char *path = umalloc(4096);
usprintf(path, "base:/scripts/%s.tb", args()[1]);
do_file(path);
ufree(path);
return;
}
set_config(); set_config();
do_file("base:/scripts/rc.tb"); do_file("base:/scripts/rc.tb");