diff --git a/.gitignore b/.gitignore index 244b48a..7674ef3 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,4 @@ /iso_root *.iso *.img +*.hdd diff --git a/Makefile b/Makefile index d4a0e53..9a01a5d 100644 --- a/Makefile +++ b/Makefile @@ -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 @@ -38,13 +38,13 @@ clean: make -C kernel ARCH=$(ARCH) ROOT=$(PWD) clean make -C user 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: ./scripts/mkbaseimg.sh -system: - ./scripts/mksystemimg.sh - iso: ./scripts/mkiso.sh + +hdd: + ./scripts/mkhdd.sh diff --git a/base/scripts/mount.tb b/base/scripts/mount.tb index f65dd1b..539d36e 100644 --- a/base/scripts/mount.tb +++ b/base/scripts/mount.tb @@ -1,3 +1,3 @@ print 'Mounting filesystems...\n' 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 diff --git a/kernel/Makefile b/kernel/Makefile index 4b35263..68d35cd 100644 --- a/kernel/Makefile +++ b/kernel/Makefile @@ -61,6 +61,7 @@ SRCFILES += $(call GRABSRC, \ dev \ randcrypto \ time \ + diskpart \ ) CFILES := $(call GET_CFILES, $(SRCFILES)) diff --git a/kernel/diskpart/diskpart.c b/kernel/diskpart/diskpart.c new file mode 100644 index 0000000..669697a --- /dev/null +++ b/kernel/diskpart/diskpart.c @@ -0,0 +1,15 @@ +#include +#include +#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); + } +} diff --git a/kernel/diskpart/diskpart.h b/kernel/diskpart/diskpart.h new file mode 100644 index 0000000..7f0b46e --- /dev/null +++ b/kernel/diskpart/diskpart.h @@ -0,0 +1,6 @@ +#ifndef DISKPART_DISKPART_H_ +#define DISKPART_DISKPART_H_ + +void diskpart_init(void); + +#endif // DISKPART_DISKPART_H_ diff --git a/kernel/diskpart/mbr.c b/kernel/diskpart/mbr.c new file mode 100644 index 0000000..7a75d8d --- /dev/null +++ b/kernel/diskpart/mbr.c @@ -0,0 +1,77 @@ +#include +#include +#include +#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; +} diff --git a/kernel/diskpart/mbr.h b/kernel/diskpart/mbr.h new file mode 100644 index 0000000..d23b5ce --- /dev/null +++ b/kernel/diskpart/mbr.h @@ -0,0 +1,9 @@ +#ifndef DISKPART_MBR_H_ +#define DISKPART_MBR_H_ + +#include +#include "storedev/storedev.h" + +bool diskpart_mbr_probe(StoreDev *sd); + +#endif // DISKPART_MBR_H_ diff --git a/kernel/kmain.c b/kernel/kmain.c index 3c54f48..b78fa20 100644 --- a/kernel/kmain.c +++ b/kernel/kmain.c @@ -14,6 +14,7 @@ #include "dev/dev.h" #include "randcrypto/randcrypto.h" #include "time/time.h" +#include "diskpart/diskpart.h" void log_bootinfo(void) { char buf[100]; @@ -46,6 +47,7 @@ void kmain(void) { randcrypto_init(); dev_init(); storedev_init(); + diskpart_init(); baseimg_init(); vfs_init(); proc_init(); diff --git a/kernel/storedev/atasd.c b/kernel/storedev/atasd.c index 7f3d1ac..7a4690f 100644 --- a/kernel/storedev/atasd.c +++ b/kernel/storedev/atasd.c @@ -121,7 +121,7 @@ void ata_probe(void) { .iobase = 0x1F0, .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); @@ -135,7 +135,7 @@ void ata_probe(void) { .iobase = 0x1F0, .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); @@ -149,7 +149,7 @@ void ata_probe(void) { .iobase = 0x170, .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); @@ -163,7 +163,7 @@ void ata_probe(void) { .iobase = 0x170, .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) { AtaSdInitExtra *e = (AtaSdInitExtra *)extra; 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; - 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++; + ret = ata_read(ata->iobase, ata->ctrlbase, ata->devno, + sd->sectorsize, buffer, sector, off, size); - 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); 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; - 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->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; + ret = ata_write(ata->iobase, ata->ctrlbase, ata->devno, + sd->sectorsize, buffer, sector, off, size); -done: spinlock_release(&sd->spinlock); return ret; } diff --git a/kernel/storedev/partsd.c b/kernel/storedev/partsd.c new file mode 100644 index 0000000..ac5b0c5 --- /dev/null +++ b/kernel/storedev/partsd.c @@ -0,0 +1,33 @@ +#include +#include +#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; +} diff --git a/kernel/storedev/partsd.h b/kernel/storedev/partsd.h new file mode 100644 index 0000000..be86e2a --- /dev/null +++ b/kernel/storedev/partsd.h @@ -0,0 +1,27 @@ +#ifndef STOREDEV_PARTSD_H_ +#define STOREDEV_PARTSD_H_ + +#include +#include + +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_ diff --git a/kernel/storedev/storedev.c b/kernel/storedev/storedev.c index a7cd339..2f2ddf6 100644 --- a/kernel/storedev/storedev.c +++ b/kernel/storedev/storedev.c @@ -24,23 +24,10 @@ void storedev_init(void) { ata_probe(); } -size_t ramsd_counter = 0; - -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' - ); - } - +void storedev_register_dev_entry(StoreDev *sd, char *name, int32_t sdtype) { spinlock_acquire(&DEVTABLE.spinlock); Dev *dev = NULL; - HSHTB_ALLOC(DEVTABLE.devs, ident, key, dev); + HSHTB_ALLOC(DEVTABLE.devs, ident, name, dev); spinlock_release(&DEVTABLE.spinlock); if (dev == NULL) { @@ -58,7 +45,7 @@ void storedev_unregister_dev_entry(Dev *dev) { 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)); if (sd == NULL) { return NULL; @@ -67,28 +54,36 @@ StoreDev *storedev_create(int32_t sdtype, void *extra) { spinlock_acquire(&STOREDEV_LIST.spinlock); sd->_magic = STOREDEV_MAGIC; + spinlock_init(&sd->spinlock); switch (sdtype) { case STOREDEV_RAMSD: { - spinlock_init(&sd->spinlock); - sd->sdtype = STOREDEV_RAMSD; - sd->init = &ramsd_init; - sd->cleanup = &ramsd_cleanup; - sd->read = &ramsd_read; - sd->write = &ramsd_write; - sd->capacity = &ramsd_capacity; + sd->sdtype = STOREDEV_RAMSD; + sd->init = &ramsd_init; + sd->cleanup = &ramsd_cleanup; + sd->read = &ramsd_read; + sd->write = &ramsd_write; + sd->capacity = &ramsd_capacity; sd->sectorsize = STOREDEV_RAMSD_SECTORSIZE; } break; case STOREDEV_ATASD: { - spinlock_init(&sd->spinlock); - sd->sdtype = STOREDEV_ATASD; - sd->init = &atasd_init; - sd->cleanup = &atasd_cleanup; - sd->read = &atasd_read; - sd->write = &atasd_write; - sd->capacity = &atasd_capacity; + sd->sdtype = STOREDEV_ATASD; + sd->init = &atasd_init; + sd->cleanup = &atasd_cleanup; + sd->read = &atasd_read; + sd->write = &atasd_write; + sd->capacity = &atasd_capacity; sd->sectorsize = STOREDEV_ATASD_SECTORSIZE; } 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: spinlock_release(&STOREDEV_LIST.spinlock); return NULL; @@ -102,7 +97,7 @@ StoreDev *storedev_create(int32_t sdtype, void *extra) { LL_APPEND(STOREDEV_LIST.head, sd); spinlock_release(&STOREDEV_LIST.spinlock); - storedev_register_dev_entry(sd, sdtype); + storedev_register_dev_entry(sd, name, sdtype); return sd; } diff --git a/kernel/storedev/storedev.h b/kernel/storedev/storedev.h index c98e73e..4b38352 100644 --- a/kernel/storedev/storedev.h +++ b/kernel/storedev/storedev.h @@ -6,6 +6,7 @@ #include "spinlock/spinlock.h" #include "ramsd.h" #include "atasd.h" +#include "partsd.h" #include "compiler/attr.h" #include "dev/dev.h" @@ -14,10 +15,11 @@ enum { STOREDEV_RAMSD, STOREDEV_ATASD, + STOREDEV_PARTSD, }; UNUSED static const char *storedev_strings[] = { - "RAMSD", "ATASD" + "RAMSD", "ATASD", "PARTSD", }; typedef struct StoreDev { @@ -35,6 +37,7 @@ typedef struct StoreDev { union { RamSd ramsd; AtaSd atasd; + PartSd partsd; } sd; SpinLock spinlock; } StoreDev; @@ -48,10 +51,10 @@ extern StoreDevList STOREDEV_LIST; 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); -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); #endif // STOREDEV_STOREDEV_H_ diff --git a/kernel/vfs/vfs.c b/kernel/vfs/vfs.c index 2ded261..ca8f261 100644 --- a/kernel/vfs/vfs.c +++ b/kernel/vfs/vfs.c @@ -179,7 +179,7 @@ void vfs_init(void) { { 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) { return; } @@ -188,7 +188,7 @@ void vfs_init(void) { { 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) { return; } diff --git a/run/qemu-x86_64-hdd.sh b/run/qemu-x86_64-hdd.sh new file mode 100755 index 0000000..8e10c5b --- /dev/null +++ b/run/qemu-x86_64-hdd.sh @@ -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 \ + $@ diff --git a/run/qemu-x86_64.sh b/run/qemu-x86_64-iso.sh similarity index 73% rename from run/qemu-x86_64.sh rename to run/qemu-x86_64-iso.sh index f9f3cfd..b1da2be 100755 --- a/run/qemu-x86_64.sh +++ b/run/qemu-x86_64-iso.sh @@ -8,5 +8,4 @@ qemu-system-x86_64 \ -cdrom mop2.iso \ -boot d \ -serial stdio \ - -drive file=system.img,format=raw,if=ide \ $@ diff --git a/scripts/devel.sh b/scripts/devel.sh index b6abeb7..d08657a 100755 --- a/scripts/devel.sh +++ b/scripts/devel.sh @@ -4,5 +4,5 @@ make -B kernel && \ make -B ulib && \ make -B user && \ make base && \ - make system && \ - make iso + make iso && \ + make hdd diff --git a/scripts/mkhdd.sh b/scripts/mkhdd.sh new file mode 100755 index 0000000..b8facb2 --- /dev/null +++ b/scripts/mkhdd.sh @@ -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 diff --git a/scripts/mksystemimg.sh b/scripts/mksystemimg.sh deleted file mode 100755 index a26c98b..0000000 --- a/scripts/mksystemimg.sh +++ /dev/null @@ -1,5 +0,0 @@ -#!/bin/sh - -if [ ! -e system.img ]; then - mklittlefs -c system -b 512 -s $((1<<20)) system.img -fi diff --git a/system/home/.gitkeep b/system/home/.gitkeep deleted file mode 100644 index e69de29..0000000