build: rework the whole build system

Still WIP & messy
This commit is contained in:
d0p1 🏳️‍⚧️ 2025-10-08 15:01:16 +02:00
parent 30b8a36bc0
commit 262020773c
65 changed files with 1873 additions and 363 deletions

2
.gitignore vendored
View file

@ -1,4 +1,5 @@
*.o
*.lo
*.img
*.bin
*.iso
@ -40,3 +41,4 @@ webring.json
webring.txt
kernel/const.inc
boot/common/const.inc
.build

168
Makefile
View file

@ -1,36 +1,36 @@
.DEFAULT_GOAL:=all
export MAKEFLAGS += --no-print-directory
export LIB =
export TOPDIR := $(dir $(realpath $(lastword $(MAKEFILE_LIST))))
export SYSROOTDIR := $(TOPDIR)/sysroot
export TOOLSDIR := $(TOPDIR)/tools
export BUILDDIR := $(TOPDIR)/.build
export SYSROOTDIR := $(BUILDDIR)/sysroot
export TOOLSDIR := $(BUILDDIR)/tools
export SYMSDIR := $(BUILDDIR)/syms
export BINDIR = /bin
export LIBDIR = /usr/lib
export INCDIR = /usr/include
export ASMDIR = /usr/asm
export MAKEFLAGS += -I $(TOPDIR)/share/mk -Orecurse --no-print-directory
export AS = fasm
export CC ?= gcc
export LD = $(TOOLSDIR)/ld
export RM = rm -f
export TOOL_CC ?= gcc
export TOOL_LD ?= ld
define subdir-rule
export MK_BUGREPORT := \"https://git.cute.engineering/d0p1/StupidOS/issues\"
export MK_COMMIT := \"$(shell git rev-parse --short HEAD)\"
export MK_PACKAGE := \"StupidOS\"
.PHONY: $1-$2
$1-$2:
@echo "📁 $2"
@DESTDIR=$(SYSROOTDIR) $$(MAKE) -C $2 $1
export CFLAGS = -DMK_COMMIT="$(MK_COMMIT)" \
-DMK_BUGREPORT="$(MK_BUGREPORT)" \
-DMK_PACKAGE="$(MK_PACKAGE)" \
-I$(TOPDIR)include
export LDFLAGS =
endef
SUBDIRS := external tools include lib bin sbin boot kernel modules tests
BUILD_RULES := build-tools .WAIT
BUILD_RULES += includes-kernel includes-include includes-lib .WAIT
BUILD_RULES += build-user build-kernel
USER_RULES := install-bin install-sbin
KERNEL_RULES := install-boot install-kernel install-modules
IMAGES = stupid.iso stupid.hdd floppy1440.img floppy2880.img
BUILD_START := $(shell date)
QEMU = qemu-system-i386
QEMU_COMMON = \
-rtc base=localtime \
-vga cirrus \
@ -39,97 +39,113 @@ QEMU_COMMON = \
-net nic,model=ne2k_isa \
-machine isapc
SUBDIRS := external tools include boot kernel modules lib bin
TARGET = stupid.tar.gz floppy1440.img floppy2880.img
ifneq ($(OS),Windows_NT)
EXEXT =
TARGET += stupid.iso stupid.hdd
else
EXEXT = .exe
endif
export EXEXT
.PHONY: all
all: $(TARGET)
all: $(IMAGES)
@echo "build start: $(BUILD_START)"
@printf "build end: " & date
GOAL:=install
clean: GOAL:=clean
.PHONY: build-tools
build-tools:
@echo "📁 tools"
@$(MAKE) -C tools install
.PHONY: $(SUBDIRS)
$(SUBDIRS):
@echo "📁 $@"
@DESTDIR=$(SYSROOTDIR) $(MAKE) -C $@ $(GOAL)
.PHONY: build-user
build-user: $(USER_RULES)
.PHONY: stupid.iso
stupid.iso: $(SUBDIRS)
$(TOPDIR)/tools/create-iso $@ sysroot
.PHONY: build-kernel
build-kernel: $(KERNEL_RULES)
.PHONY: stupid.hdd
stupid.hdd: $(SUBDIRS)
dd if=/dev/zero of=$@ bs=1M count=0 seek=64
mformat -L 12 -i $@
mcopy -i $@ boot/loader/stpdldr.sys ::/STPDLDR.SYS
mcopy -i $@ kernel/vmstupid.sys ::/VMSTUPID.SYS
$(eval $(foreach X,kernel include lib,$(call subdir-rule,includes,$X)))
$(eval $(foreach X,bin sbin,$(call subdir-rule,install,$X)))
$(eval $(foreach X,boot kernel modules,$(call subdir-rule,install,$X)))
.PHONY: stupid.tar.gz
stupid.tar.gz: $(SUBDIRS)
tar -czvf $@ sysroot
stupid.tar.gz: $(BUILD_RULES)
tar -czvf $@ $(SYSROOTDIR)
# +------------------------------------------------------------------+
# | Disk images |
# +------------------------------------------------------------------+
.PHONY: stupid.iso
stupid.iso: $(BUILD_RULES)
@echo "TODO"
.PHONY: stupid.hdd
stupid.hdd: $(BUILD_RULES)
dd if=/dev/zero of=$@ bs=1M count=0 seek=64
mformat -L 12 -i $@
mcopy -i $@ boot/loader/stpdldr.sys "::/STPDLDR.SYS"
mcopy -i $@ kernel/vmstupid.sys "::/VMSTUPID.SYS"
.PHONY: floppy1440.img
floppy1440.img: $(SUBDIRS)
floppy1440.img: $(BUILD_RULES)
dd if=/dev/zero of=$@ bs=512 count=1440
mformat -C -f 1440 -i $@
dd if=boot/bootsect/boot_floppy1440.bin of=$@ conv=notrunc
mcopy -i $@ boot/loader/stpdldr.sys ::/STPDLDR.SYS
mcopy -i $@ kernel/vmstupid.sys ::/VMSTUPID.SYS
mcopy -i $@ boot/loader/stpdldr.sys "::/STPDLDR.SYS"
mcopy -i $@ kernel/vmstupid.sys "::/VMSTUPID.SYS"
.PHONY: floppy2880.img
floppy2880.img: $(SUBDIRS)
floppy2880.img: $(BUILD_RULES)
dd if=/dev/zero of=$@ bs=512 count=2880
mformat -C -f 2880 -i $@
dd if=boot/bootsect/boot_floppy2880.bin of=$@ conv=notrunc
mcopy -i $@ boot/loader/stpdldr.sys ::/STPDLDR.SYS
mcopy -i $@ kernel/vmstupid.sys ::/VMSTUPID.SYS
mcopy -i $@ boot/loader/stpdldr.sys "::/STPDLDR.SYS"
mcopy -i $@ kernel/vmstupid.sys "::/VMSTUPID.SYS"
# +------------------------------------------------------------------+
# | QEMU / bochs |
# +------------------------------------------------------------------+
OVMF32.fd:
wget 'https://retrage.github.io/edk2-nightly/bin/DEBUGIa32_OVMF.fd' -O $@
.PHONY: run
run: all
qemu-system-i386 \
$(QEMU_COMMON) \
run: floppy1440.img
$(QEMU) $(QEMU_COMMON) \
-drive file=floppy1440.img,if=none,format=raw,id=boot \
-drive file=fat:rw:./sysroot,if=none,id=hdd \
-drive file=flat:rw:$(SYSROOTDIR),if=none,id=hdd \
-device floppy,drive=boot \
-global isa-fdc.bootindexA=0
.PHONY: run-iso
run-iso: all
qemu-system-i386 \
$(QEMU_COMMON) \
run-iso: $(BUILD_RULES)
$(QEMU) $(QEMU_COMMON) \
-cdrom stupid.iso
.PHONY: run-efi
run-efi: all OVMF32.fd
qemu-system-i386 \
-bios OVMF32.fd \
-drive file=fat:rw:./sysroot,if=none,id=hdd \
run-efi: OVMF32.fd $(BUILD_RULES)
$(QEMU) -bios OVMF32.fd \
-drive file=fat:rw:$(SYSROOTDIR),if=none,id=hdd \
-device ide-hd,drive=hdd
.PHONY: bochs
bochs:
bochs: $(BUILD_RULES)
bochs -f .bochsrc
# +------------------------------------------------------------------+
# | Website / docs |
# +------------------------------------------------------------------+
.PHONY: docs
docs:
@mkdir -p docs/html
wget -O docs/webring.json https://webring.devse.wiki/webring.json
wget -O docs/webring.json "https://webring.devse.wiki/webring.json"
python3 docs/devsewebring.py docs/webring.json docs/webring.txt
naturaldocs -p docs/config -img docs/img -xi sysroot -i . -ro -o HTML docs/html
cp docs/img/favicon.ico docs/html/
naturaldocs -p docs/config -img docs/img -xi .build -i . -ro -o HTML docs/html
cp docs/img/favicon.ico docs/html
# +------------------------------------------------------------------+
# | clean |
# +------------------------------------------------------------------+
$(eval $(foreach X,$(SUBDIRS),$(call subdir-rule,clean,$X)))
.PHONY: clean
clean: $(SUBDIRS)
$(RM) $(TARGET)
clean: $(foreach X,$(SUBDIRS),clean-$X)
rm -f $(IMAGES)
.PHONY: cleandir
cleandir: clean
rm -rf $(BUILDDIR)

View file

@ -1,3 +1,3 @@
SUBDIRS = cmd
include $(TOPDIR)/rules.mk
include stpd.subdirs.mk

View file

@ -1,6 +1,10 @@
all:
fasm cmd.asm
all: cmd.o
clean:
install: all
CLEANFILES = cmd.o
include stpd.base.mk
include stpd.clean.mk

View file

@ -281,6 +281,8 @@ process_file(char *file)
print_symbols();
}
fas_cleanup();
return (EXIT_SUCCESS);
}

View file

@ -1,16 +1,36 @@
#include <stdlib.h>
#include <stdio.h>
#include <stdint.h>
#include <stdarg.h>
#include <inttypes.h>
#include <time.h>
#include <unistd.h>
#include <libgen.h>
#include <string.h>
#include <assert.h>
#ifndef __stupidos__
# include <libgen.h>
#endif
#include <errno.h>
#include <coff.h>
static const char *prg_name = NULL;
static FILHDR filhdr;
static AOUTHDR aouthdr;
static SCNHDR *scnhdrs = NULL;
static SYMENT *symtab = NULL;
static char *strtab = NULL;
static size_t sym_cnt = 0;
static size_t sec_cnt = 0;
static const char *machine = NULL;
static const char *aoutmag = NULL;
static RELOC **relocs = NULL;
static uint8_t **secdata = NULL;
static int display_file_header = 0;
static int display_optional_header = 0;
static int display_sections = 0;
static const struct {
int magic;
char *machine;
uint16_t magic;
const char *machine;
} MACHINES[] = {
{F_MACH_AM33, "Matsushita AM33"},
{F_MACH_AMD64, "Intel amd64"},
@ -52,24 +72,312 @@ static const struct {
{0, NULL}
};
/* */
static const char *prg_name;
static const char *mach = NULL;
static const char *aoutmag = NULL;
static void
msg_err_common(const char *fmt, va_list ap)
{
fprintf(stderr, "%s: ", prg_name);
if (fmt)
{
vfprintf(stderr, fmt, ap);
}
}
/* */
static int display_header = 0;
static int display_optional_header = 0;
static int display_sections = 0;
static int display_symbol_table = 0;
static int display_relocs = 0;
static void
msg_errx(const char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
msg_err_common(fmt, ap);
fprintf(stderr, "\n");
va_end(ap);
}
static void
msg_err(const char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
msg_err_common(fmt, ap);
if (fmt)
{
fprintf(stderr, ": ");
}
fprintf(stderr, "%s\n", strerror(errno));
va_end(ap);
}
static void
coff_cleanup(void)
{
size_t idx;
if (relocs != NULL)
{
for (idx = 0; idx < filhdr.f_nscns; idx++)
{
free(relocs[idx]);
}
free(relocs);
relocs = NULL;
}
if (secdata != NULL)
{
for (idx = 0; idx < filhdr.f_nscns; idx++)
{
free(secdata[idx]);
}
free(secdata);
secdata = NULL;
}
free(scnhdrs);
scnhdrs = NULL;
free(symtab);
symtab = NULL;
free(strtab);
strtab = NULL;
sym_cnt = 0;
sec_cnt = 0;
machine = NULL;
aoutmag = NULL;
}
static int
coff_load_headers(const char *file, FILE *fp)
{
size_t idx;
if (fread(&filhdr, FILHSZ, 1, fp) != 1)
{
msg_errx("%s: An unexpected error/eof occured while reading " \
"COFF header", file);
return (-1);
}
for (idx = 0; MACHINES[idx].magic != F_MACH_UNKNOWN; idx++)
{
if (filhdr.f_magic == MACHINES[idx].magic)
{
machine = MACHINES[idx].machine;
break;
}
}
if (machine == NULL)
{
msg_errx("%s: Unknown magic '0x%04" PRIX16 "'",
file, filhdr.f_magic);
return (-1);
}
if (filhdr.f_opthdr == 0)
{
return (0);
}
if (filhdr.f_opthdr != AOUTHSZ)
{
msg_errx("%s: Invalid optional header size", file);
return (-1);
}
if (fread(&aouthdr, AOUTHSZ, 1, fp) != 1)
{
msg_errx("%s: An unexpected error/eof occured while reading " \
"optional header", file);
return (-1);
}
for (idx = 0; AOUTMAG[idx].str != NULL; idx++)
{
if (aouthdr.magic == AOUTMAG[idx].mag)
{
aoutmag = AOUTMAG[idx].str;
break;
}
}
if (aoutmag == NULL)
{
msg_errx("%s: Invalid optional header magic", file);
return (-1);
}
return (0);
}
static int
coff_load_sections(const char *file, FILE *fp)
{
uint16_t idx;
relocs = (RELOC **)malloc(sizeof(RELOC *) * filhdr.f_nscns);
if (relocs == NULL)
{
msg_err("%s", file);
return (-1);
}
memset(relocs, 0, sizeof(RELOC *) * filhdr.f_nscns);
secdata = (uint8_t **)malloc(sizeof(uint8_t *) * filhdr.f_nscns);
if (secdata == NULL)
{
msg_err("%s", file);
return (-1);
}
memset(secdata, 0, sizeof(uint8_t *) * filhdr.f_nscns);
scnhdrs = (SCNHDR *)malloc(SCNHSZ * filhdr.f_nscns);
if (scnhdrs == NULL)
{
msg_err("%s", file);
return (-1);
}
if (fread(scnhdrs, SCNHSZ * filhdr.f_nscns, 1, fp) != 1)
{
msg_errx("%s: An unexpected error/eof occured while reading " \
"section headers", file);
return (-1);
}
return (0);
}
static int
coff_load_file(const char *file)
{
FILE *fp;
fp = fopen(file, "rb");
if (fp == NULL)
{
return (-1);
}
if (coff_load_headers(file, fp) != 0)
{
goto err;
}
if (coff_load_sections(file, fp) != 0)
{
goto err_cleanup;
}
fclose(fp);
return (0);
err_cleanup:
coff_cleanup();
err:
fclose(fp);
return (-1);
}
static void
print_file_header(void)
{
size_t idx;
time_t timdat;
printf("COFF Header:\n");
printf(" Machine: %s\n", machine);
printf(" Number of section headers: %" PRIu16 "\n", filhdr.f_nscns);
timdat = filhdr.f_timdat;
printf(" Created at: %s", ctime(&timdat));
printf(" Start of Symbol Table: %" PRId32 " (bytes into file)\n",
filhdr.f_symptr);
printf(" Number of Symbols: %" PRId32 "\n", filhdr.f_nsyms);
printf(" Size of optional header: %" PRIu16 " (bytes)\n",
filhdr.f_opthdr);
printf(" Flags: ");
for (idx = 0; FLAGS[idx].str != NULL; idx++)
{
if (filhdr.f_flags & FLAGS[idx].flag)
{
printf("%s ", FLAGS[idx].str);
}
}
printf("\n\n");
}
static void
print_optional_header(void)
{
if (filhdr.f_opthdr)
{
printf("A.out Header:\n");
printf(" Magic: %s\n", aoutmag);
printf(" Version stamp: %" PRId16 "\n", aouthdr.vstamp);
printf(" Text size: %" PRId32 " (bytes)\n", aouthdr.tsize);
printf(" Data size: %" PRId32 " (bytes)\n", aouthdr.dsize);
printf(" BSS size: %" PRId32 " (bytes)\n", aouthdr.bsize);
printf(" Entry point: 0x%08" PRIX32 "\n", aouthdr.entry);
printf(" Text start: 0x%08" PRIX32 "\n", aouthdr.text_start);
printf(" Data start: 0x%08" PRIX32 "\n", aouthdr.data_start);
printf("\n");
}
else
{
printf("There is no optional header.\n\n");
}
}
static void
print_section_type(uint16_t idx)
{
if (scnhdrs[idx].s_flags & STYP_TEXT)
{
printf("TEXT ");
}
else if (scnhdrs[idx].s_flags & STYP_DATA)
{
printf("DATA ");
}
else if (scnhdrs[idx].s_flags & STYP_BSS)
{
printf("BSS ");
}
else
{
printf("??? ");
}
}
static void
print_sections(void)
{
uint16_t idx;
char name[9];
printf("Section Headers:\n");
printf(" [Nr] Name Type Paddr Vaddr Offset Size\n");
for (idx = 0; idx < filhdr.f_nscns; idx++)
{
printf(" [%2" PRIu16 "] ", idx);
memset(name, 0, 9);
memcpy(name, scnhdrs[idx].s_name, 8);
printf("%-8s ", name);
print_section_type(idx);
printf("%08" PRIX32 " %08" PRIX32 " ",
scnhdrs[idx].s_paddr, scnhdrs[idx].s_vaddr);
printf("%08" PRIX32 " %08" PRIX32 "\n",
scnhdrs[idx].s_scnptr, scnhdrs[idx].s_size);
}
printf("\n");
}
static void
usage(int retval)
{
if (retval == EXIT_FAILURE)
{
fprintf(stderr, "Try '%s -h' for more informations.", prg_name);
fprintf(stderr, "Try '%s -h' for more informations.\n",
prg_name);
}
else
{
@ -85,10 +393,100 @@ usage(int retval)
static void
version(void)
{
printf("%s (%s) %s", prg_name, MK_PACKAGE, MK_COMMIT);
printf("%s (%s) %s\n", prg_name, MK_PACKAGE, MK_COMMIT);
exit(EXIT_SUCCESS);
}
int
main(int argc, char **argv)
{
int c;
prg_name = basename(argv[0]);
while ((c = getopt(argc, argv, "hVHlS")) != -1)
{
switch (c)
{
case 'h':
usage(EXIT_SUCCESS);
break;
case 'V':
version();
break;
case 'H':
display_file_header = 1;
break;
case 'l':
display_optional_header = 1;
break;
case 'S':
display_sections = 1;
break;
default:
usage(EXIT_FAILURE);
break;
}
}
if (optind >= argc)
{
usage(EXIT_FAILURE);
}
if (coff_load_file(argv[optind]) != 0)
{
return (EXIT_FAILURE);
}
if (display_file_header)
{
print_file_header();
}
if (display_optional_header)
{
print_optional_header();
}
if (display_sections)
{
print_sections();
}
coff_cleanup();
return (EXIT_SUCCESS);
}
#if 0
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
#include <string.h>
#include <assert.h>
#ifndef __stupidos__
# include <libgen.h>
#endif
#include <coff.h>
/* */
static const char *prg_name;
static const char *mach = NULL;
static const char *aoutmag = NULL;
/* */
static int display_header = 0;
static int display_optional_header = 0;
static int display_sections = 0;
static int display_symbol_table = 0;
static int display_relocs = 0;
int
main(int argc, char **argv)
{
@ -308,3 +706,4 @@ main(int argc, char **argv)
return (EXIT_SUCCESS);
}
#endif

View file

@ -1,3 +1,3 @@
SUBDIRS = bootsect loader efi
SUBDIRS = bootsect efi loader
include $(TOPDIR)/rules.mk
include stpd.subdirs.mk

View file

@ -1,4 +1,6 @@
TARGET = boot_floppy1440.bin \
include stpd.base.mk
BINS = boot_floppy1440.bin \
boot_floppy2880.bin \
boot_mbr.bin \
boot_hdd.bin
@ -18,26 +20,30 @@ MBR_SRCS = mbr.asm \
$(addprefix $(COMMON_DIR)/, $(COMMON_SRCS))
.PHONY: all
all: $(TARGET)
all: $(BINS)
%.inc: %.inc.in
sh $(TOOLSDIR)/version.sh $< $@
@$(VERSION_SH)
boot_floppy1440.bin: $(FLOPPY_SRCS)
$(AS) floppy.asm $@
$(MSG_BUILD)
@$(FASM) floppy.asm $@ >/dev/null
boot_floppy2880.bin: $(FLOPPY_SRCS)
$(AS) -DFLOPPY_SIZE=FLOPPY_2880 floppy.asm $@
$(MSG_BUILD)
@$(FASM) -DFLOPPY_SIZE=FLOPPY_2880 floppy.asm $@ >/dev/null
boot_mbr.bin: $(MBR_SRCS)
$(AS) mbr.asm $@
$(MSG_BUILD)
@$(FASM) mbr.asm $@ >/dev/null
boot_hdd.bin: $(HDD_SRCS)
$(AS) hdd.asm $@
.PHONY: clean
clean:
$(RM) $(TARGET)
$(MSG_BUILD)
@$(FASM) hdd.asm $@ >/dev/null
.PHONY: install
install: $(TARGET)
install: $(BINS)
CLEANFILES = $(BINS) $(COMMON_DIR)/const.inc
include stpd.clean.mk

View file

@ -22,6 +22,9 @@
jmp 0x0:start
start:
sti
mov [uBootDrive], dl
; set LBA
mov ah, 0x41
mov bx, 0x55AA
@ -61,6 +64,8 @@ start:
hlt
jmp $
uBootDrive db 0
disk_packet:
db 0x10
db 0

View file

@ -1,5 +1,4 @@
TARGET = BOOTIA32.EFI
include stpd.base.mk
COMMON_DIR = ../common
@ -15,19 +14,22 @@ BOOTIA32_EFI_SRCS = bootia32.asm \
$(addprefix $(COMMON_DIR)/, $(COMMON_SRCS))
.PHONY: all
all: $(TARGET)
all: BOOTIA32.EFI
%.inc: %.inc.in
sh $(TOOLSDIR)/version.sh $< $@
@$(VERSION_SH)
BOOTIA32.EFI: $(BOOTIA32_EFI_SRCS)
$(AS) bootia32.asm $@
.PHONY: clean
clean:
$(RM) $(TARGET)
$(MSG_BUILD)
@$(FASM) bootia32.asm $@ >/dev/null
.PHONY: install
install: $(TARGET)
@ mkdir -p $(DESTDIR)/EFI/BOOT
install $(TARGET) $(DESTDIR)/EFI/BOOT
install: $(DESTDIR)/EFI/BOOT/BOOTIA32.EFI
$(DESTDIR)/EFI/BOOT/BOOTIA32.EFI: BOOTIA32.EFI
$(MSG_INSTALL)
@install -D $< $@
CLEANFILES = BOOTIA32.EFI $(COMMON_DIR)/const.inc
include stpd.clean.mk

View file

@ -1,4 +1,4 @@
TARGET = stpdldr.sys
include stpd.base.mk
COMMON_DIR = ../common
SYS_DIR = ../../kernel/sys
@ -22,19 +22,22 @@ LOADER_SRCS = loader.asm \
disk.inc
.PHONY: all
all: $(TARGET)
%.inc: %.inc.in
sh $(TOOLSDIR)/version.sh $< $@
all: stpdldr.sys
stpdldr.sys: $(LOADER_SRCS)
$(AS) loader.asm $@
$(MSG_BUILD)
@$(FASM) loader.asm $@ >/dev/null
.PHONY: clean
clean:
$(RM) $(TARGET)
%.inc: %.inc.in
@$(VERSION_SH)
.PHONY: install
install: $(TARGET)
@ mkdir -p $(DESTDIR)
install $(TARGET) $(DESTDIR)
install: $(DESTDIR)/stpdldr.sys
$(DESTDIR)/stpdldr.sys: stpdldr.sys
$(MSG_INSTALL)
@install -D $< $@
CLEANFILES = stpdldr.sys $(COMMON_DIR)/const.inc
include stpd.clean.mk

4
compile_flags.txt Normal file
View file

@ -0,0 +1,4 @@
-Iinclude
-DMK_COMMIT="\"XXXX\""
-DMK_BUGREPORT="\"XXXX\""
-DMK_PACKAGE="\"build\""

12
external/Makefile vendored
View file

@ -1,11 +1 @@
TOPGOALS = all clean install
SUBDIRS =
.PHONY: $(TOPGOALS)
$(TOPGOALS): $(SUBDIRS)
.PHONY: $(SUBDIRS)
$(SUBDIRS):
@echo "📁 external/$@"
@DESTDIR=$(DESTDIR) $(MAKE) -C $@ $(MAKECMDGOALS)
include stpd.subdirs.mk

View file

@ -1,4 +1,4 @@
SYSINCS = errno.h
INCS = coff.h elf.h ar.h ranlib.h $(addprefix sys/, $(SYSINCS))
INCS = ar.h coff.h elf.h fas.h ranlib.h stupidc.h $(addprefix sys/, $(SYSINCS))
include $(TOPDIR)/rules.mk
include stpd.inc.mk

View file

@ -51,7 +51,6 @@ enum fas_symbol_type
FAS_PLT_R_32
};
typedef struct fas_symbol
{
uint64_t value;
@ -66,14 +65,14 @@ typedef struct fas_symbol
uint32_t psrc_line_off;
} FAS_Sym;
struct fas_psrc_line
typedef struct fas_psrc_line
{
uint32_t from;
uint32_t lineno;
uint32_t src_off;
uint32_t macro_off;
uint8_t tokens[];
};
} FAS_Psrc_Line;
enum fas_code
{
@ -82,7 +81,7 @@ enum fas_code
FAS_CODE_64 = 64
};
struct fas_asmdmp
typedef struct fas_asmdmp
{
uint32_t of_off;
uint32_t psrc_line_off;
@ -93,7 +92,7 @@ struct fas_asmdmp
uint8_t code;
uint8_t virt;
uint8_t high;
};
} FAS_Asmdmp;
enum fas_register
{

62
include/stupidc.h Normal file
View file

@ -0,0 +1,62 @@
#ifndef STUPIDC_H
# define STUPIDC_H 1
# include <stddef.h>
# define ARR_BASE_CAP 8
# define ARR(type) \
struct { size_t cap; size_t cnt; type *elems; }
# define ARR_INIT { 0, 0, NULL }
# define ARR_GROW(arr) \
do { \
if ((arr)->cap < ((arr)->cnt + 1)) \
{ \
(arr)->cap = ((arr)->cap > ARR_BASE_CAP \
? (arr)->cap * 2 : ARR_BASE_CAP); \
(arr)->elems = realloc((arr)->elems, \
(arr)->cap * sizeof(*(arr)->elems)); \
} \
} while(0)
# define ARR_APPEND(arr, elem) \
do { \
ARR_GROW((arr)); \
(arr)->elems[(arr)->cnt++] = (elem); \
} while (0)
# define ARR_RESET(arr) \
do { \
(arr)->cnt = 0; \
} while (0)
# define ARR_FREE(arr) \
do { \
(arr)->cap = 0; \
(arr)->cnt = 0; \
free((arr)->elems); \
(arr)->elems = NULL; \
} while(0)
# define ARR_COUNT(arr) ((arr)->cnt)
# define ARR_EMPTY(arr) ((arr)->cnt == 0)
# define ARR_INDEX(arr, elem) ((elem) - (arr)->elems)
# define ARR_FIRST(arr) ((arr)->elems[0])
# define ARR_LAST(arr) ((arr)->elems[(arr)->cnt])
# define ARR_FOREACH(var, arr) \
for ((var) = (arr)->elems; \
(var) < ((arr)->elems + (arr)->cnt); \
(var)++)
# define LIST(type) \
struct { struct type *next; struct type **prev }
void set_progname(const char *name);
const char *get_progname(void);
void print_version(void);
#endif /* !STUPIDC_H */

View file

@ -1,6 +1,4 @@
AS = fasm
RM = rm -f
INSTALL = install
include stpd.base.mk
ASMINCS = sys/bootinfo.inc \
sys/coff.inc \
@ -11,7 +9,7 @@ ASMINCS = sys/bootinfo.inc \
sys/process.inc \
sys/register.inc
KERNEL = vmstupid.sys
KERNEL = vmstupid
MM_SRCS = bootstrap.inc \
mm.inc \
@ -47,24 +45,32 @@ SRCS = kernel.asm \
$(ASMINCS)
.PHONY: all
all: $(KERNEL)
all: $(KERNEL).sys $(KERNEL).sym
.PHONY: const.inc
const.inc: const.inc.in
sh $(TOOLSDIR)/version.sh $< $@
@$(VERSION_SH)
$(KERNEL): $(SRCS)
$(AS) kernel.asm $@
$(KERNEL).sys $(KERNEL).fas &: $(SRCS)
$(MSG_BUILD)
@$(FASM) -s $(KERNEL).fas kernel.asm $(KERNEL).sys >/dev/null
.PHONY: clean
clean:
$(RM) $(KERNEL)
$(KERNEL).sym: $(KERNEL).fas
$(MSG_CREATE)
@$(FAS2SYM) -o $@ $<
.PHONY: install
install: $(KERNEL)
@ mkdir -p $(DESTDIR)
install $(KERNEL) $(DESTDIR)
@ mkdir -p $(DESTDIR)$(ASMDIR)/sys
install $(ASMINCS) $(DESTDIR)$(ASMDIR)/sys
install: $(DESTDIR)/$(KERNEL).sys $(SYMSDIR)/$(KERNEL).sym
.PHONY: all clean install
$(DESTDIR)/$(KERNEL).sys: $(KERNEL).sys
$(MSG_INSTALL)
@install -D $< $@
$(SYMSDIR)/$(KERNEL).sym: $(KERNEL).sym
$(MSG_INSTALL)
@install -D $< $@
CLEANFILES = $(KERNEL).sys $(KERNEL).fas $(KERNEL).sys const.inc
include stpd.clean.mk
include stpd.inc.mk

View file

@ -1,3 +1,3 @@
SUBDIRS = csu crypto lzp c
include $(TOPDIR)/rules.mk
include stpd.subdirs.mk

View file

@ -14,9 +14,6 @@ $(LIBS): $(OBJS)
%.o: %.asm
$(AS) $< $@
$(DESTDIR)$(INCDIR)/%.h: %.h
install -D $< $@
$(DESTDIR)$(LIBDIR)/%.a: %.a
install -D $< $@
@ -26,3 +23,5 @@ clean:
.PHONY: install
install: $(INST)
include stpd.inc.mk

View file

@ -8,13 +8,11 @@ INCS = sha2/sha2.h \
dilithium/dilithium.h \
falcon/falcon.h \
keccak/keccak.h
ASMS = sha2/sha2.inc \
ASMINCS = sha2/sha2.inc \
chacha/chacha.inc \
hchacha/hchacha.inc
INST = $(addprefix $(DESTDIR)$(INCDIR)/, $(INCS)) \
$(addprefix $(DESTDIR)$(ASMDIR)/, $(ASMS)) \
$(addprefix $(DESTDIR)$(LIBDIR)/, $(LIBS))
INST = $(addprefix $(DESTDIR)$(LIBDIR)/, $(LIBS))
.PHONY: all
all: $(LIBS)
@ -25,11 +23,6 @@ $(LIBS): $(OBJS)
%.o: %.asm
$(AS) $< $@
$(DESTDIR)$(INCDIR)/%.h: %.h
install -D $< $@
$(DESTDIR)$(ASMDIR)/%.inc: %.inc
install -D $< $@
$(DESTDIR)$(LIBDIR)/%.a: %.a
install -D $< $@
@ -41,4 +34,4 @@ clean:
.PHONY: install
install: $(INST)
include stpd.inc.mk

View file

@ -14,3 +14,5 @@ clean:
$(RM) $(LIBS)
install: $(INST)
include stpd.base.mk

View file

@ -17,12 +17,6 @@ $(LIBS): $(OBJS)
%.o: %.asm
$(AS) $< $@
$(DESTDIR)$(INCDIR)/%.h: %.h
install -D $< $@
$(DESTDIR)$(ASMDIR)/%.inc: %.inc
install -D $< $@
$(DESTDIR)$(LIBDIR)/%.a: %.a
install -D $< $@
@ -33,3 +27,4 @@ clean:
.PHONY: install
install: $(INST)
include stpd.inc.mk

30
lib/stupidc/progname.c Normal file
View file

@ -0,0 +1,30 @@
#include <string.h>
#include <stupidc.h>
#ifdef _WIN32
# define PATH_SEP '\\'
#else
# define PATH_SEP '/'
#endif /* _WIN32 */
static const char *__progname;
void
set_progname(const char *progname)
{
__progname = strrchr(progname, PATH_SEP);
if (__progname == NULL)
{
__progname = progname;
}
else
{
__progname++;
}
}
const char *
get_progname(void)
{
return (__progname);
}

20
lib/stupidc/version.c Normal file
View file

@ -0,0 +1,20 @@
#include <stdio.h>
#include <stupidc.h>
#ifndef MK_PACKAGE
# define MK_PACKAGE "StupidOS"
#endif /* !MK_PACKAGE */
#ifndef MK_COMMIT
# define MK_COMMIT "???????"
#endif /* !MK_COMMIT */
void
print_version(void)
{
printf("%s (%s) %s\n", get_progname(), MK_PACKAGE, MK_COMMIT);
printf("Copyright (C) 2025, d0p1\n"
"License BSD-3-Clause: <https://directory.fsf.org/wiki/License:BSD-3-Clause>\n"
"This is free software: you are free to change and redistribute it.\n"
"There is NO WARRANTY, to the extent permitterd by law.\n");
}

View file

@ -1,3 +1,3 @@
SUBDIRS = dummy
include $(TOPDIR)/rules.mk
include stpd.subdirs.mk

View file

@ -1,16 +1,20 @@
include stpd.base.mk
MODULE = dummy.mod
INST = $(addprefix $(DESTDIR)/, $(MODULE))
all:
clean:
all: $(MODULE)
$(MODULE): $(MODULE:.mod=.asm)
fasm $^ $@
$(MSG_BUILD)
@fasm $^ $@
$(DESTDIR)/%.mod: %.mod
install -D $< $@
$(DESTDIR)/$(MODULE): $(MODULE)
$(MSG_INSTALL)
@install -D $< $@
.PHONY: install
install: $(INST)
install: $(DESTDIR)/$(MODULE)
CLEANFILES = $(MODULE)
include stpd.clean.mk

View file

@ -1,87 +0,0 @@
TARGETS = all install clean
.PHONY: $(TARGETS)
$(TARGETS): ;
_INST = $(addprefix $(DESTDIR)$(INCDIR)/, $(INCS)) \
$(addprefix $(DESTDIR)$(ASMDIR)/, $(ASMINCS)) \
$(addprefix $(DESTDIR)$(LIBDIR)/, $(LIB))
# ----------------- Subdirs -----------------------
ifdef SUBDIRS
_SUBDIRS:=$(filter-out .WAIT,$(SUBDIRS))
_CURDIR=$(subst $(TOPDIR),,$(CURDIR))
ifneq ($(_CURDIR),)
_CURDIR:=$(_CURDIR)/
endif
.PHONY: $(_SUBDIRS)
$(_SUBDIRS):
@echo "📁 $(_CURDIR)$@"
@DESTDIR=$(DESTDIR) $(MAKE) -C $@ $(MAKECMDGOALS)
$(TARGETS): $(SUBDIRS)
endif
# --------------- Build rules ------------------
%.o: %.asm
$(AS) $< $@
# --------------- Lib rules --------------------
ifneq ($(LIB),)
all: $(LIB)
_cleanlib:
$(RM) $(LIB)
clean: _cleanlib
endif
# --------------- Progs rules -------------------
ifneq ($(PROG),)
all: $(PROG)
endif
# --------------- Install rules -----------------
ifneq ($(_INST),)
install: $(_INST)
endif
# headers
$(DESTDIR)$(INCDIR)/%.h: %.h
install -D $< $@
$(DESTDIR)$(ASMDIR)/%.inc: %.inc
install -D $< $@
# libs
$(DESTDIR)$(LIBDIR)/%.a: %.a
install -D $< $@
$(DESTDIR)$(LIBDIR)/%.o: %.o
install -D $< $@
# bins
$(DESTDIR)$(BINDIR)/%: %
install -D $< $@
# kernel & mods
$(DESTDIR)/%.sys: %.sys
install -D $< $@
$(DESTDIR)/%.mod: %.mod
install -D $< $@

1
sbin/Makefile Normal file
View file

@ -0,0 +1 @@
include stpd.subdirs.mk

77
sbin/mtree/main.c Normal file
View file

@ -0,0 +1,77 @@
#include <stdlib.h>
#include <stdio.h>
#include <limits.h>
#include <unistd.h>
#include <libgen.h>
#ifndef PATH_MAX
# define PATH_MAX 1024
#endif /* !PATH_MAX */
static char curdir[PATH_MAX] = { 0 };
static const char *prg_name = NULL;
static const char *specfile = NULL;
static const char *basepath = NULL;
static FILE *specfp = NULL;
static void
usage(int retval)
{
if (retval == EXIT_FAILURE)
{
fprintf(stderr, "Try '%s -h' for more informations.\n",
prg_name);
}
else
{
printf("Usage: %s [-ce] [-p path] [-f spec]\n", prg_name);
printf(" -c \tXXX.\n");
printf(" -e \tXXXX\n");
printf(" -f spec\tXXXX\n");
printf(" -p path\tXXXX\n");
}
exit(retval);
}
int
main(int argc, char **argv)
{
int c;
prg_name = basename(argv[0]);
while ((c = getopt(argc, argv, "hf:")) != -1)
{
switch (c)
{
case 'h':
usage(EXIT_SUCCESS);
break;
case 'f':
specfile = optarg;
break;
case 'p':
basepath = optarg;
break;
default:
usage(EXIT_FAILURE);
break;
}
}
if (basepath == NULL)
{
basepath = getcwd(curdir, PATH_MAX);
if (basepath == NULL)
{
return (EXIT_FAILURE);
}
}
printf("basepath: %s\n", basepath);
return (EXIT_SUCCESS);
}

47
sbin/mtree/mtree.h Normal file
View file

@ -0,0 +1,47 @@
#ifndef MTREE_H
# define MTREE_H 1
# include <sys/types.h>
# include <stdint.h>
# define NODE_PARENT(n) ((n)->tree.parent)
# define NODE_CHILD_FIRST(n) ((n)->tree.child)
# define NODE_CHILD_ADD(p, c) do { \
(c)->tree.parent = p; \
if (((c)->list.next = (p)->tree.child) != NULL) { \
(p)->tree.child->list.prev = &(c)->list.next; \
} \
(p)->tree.child = (c); \
(c)->list.prev = (p)->tree.child; \
} while(0);
enum flags {
FL_TYPE = (1<<0),
FL_MODE = (1<<1),
FL_UID = (1<<2),
FL_GID = (1<<3),
};
struct node {
struct {
struct node *parent;
struct node *child;
} tree;
struct {
struct node *next;
struct node **prev;
} list;
uint32_t flags;
mode_t mode;
uid_t uid;
gid_t gid;
char *name;
};
/* node.c */
struct node *node_new(void);
void node_free(struct *node);
void node_dump(struct *node);
#endif /* !MTREE_H */

120
sbin/parted/cmd.c Normal file
View file

@ -0,0 +1,120 @@
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <fdisk/cmd.h>
#include <fdisk/version.h>
static inline void
cmd_help_print_idx(size_t idx)
{
printf("\e[1m%s\e[0m", cmds[idx].cmd);
if (cmds[idx].args != NULL)
{
printf(" \e[3m%s\e[0m", cmds[idx].args);
}
printf("\n\t%s\n", cmds[idx].desc);
}
static int
cmd_help(struct context *ctx, int argc, char **argv)
{
size_t idx;
(void)ctx;
(void)argc;
(void)argv;
for (idx = 0; cmds[idx].cmd != NULL; idx++)
{
if (argc >= 2)
{
if (strcmp(argv[1], cmds[idx].cmd) == 0)
{
cmd_help_print_idx(idx);
return (0);
}
}
else
{
cmd_help_print_idx(idx);
}
}
if (argc >= 2)
{
printf("\e[31mError:\e[0m Unknown command \"%s\"\n", argv[1]);
return (-1);
}
return (0);
}
static int
cmd_version(struct context *ctx, int argc, char **argv)
{
(void)ctx;
(void)argc;
(void)argv;
print_version();
return (0);
}
static int
cmd_print(struct context *ctx, int argc, char **argv)
{
long disk_sz;
(void)argc;
(void)argv;
fseek(ctx->dsk_fp, 0, SEEK_END);
disk_sz = ftell(ctx->dsk_fp);
rewind(ctx->dsk_fp);
printf("Disk %s: %ldB\n", ctx->dsk_fname, disk_sz);
return (0);
}
static int
cmd_quit(struct context *ctx, int argc, char **argv)
{
(void)argc;
(void)argv;
if (ctx->dsk_fp != NULL)
{
fclose(ctx->dsk_fp);
}
exit(EXIT_SUCCESS);
return (0);
}
static int
cmd_set(struct context *ctx, int argc, char **argv)
{
return (0);
}
static int
cmd_rm(struct context *ctx, int argc, char **argv)
{
return (0);
}
static int
cmd_mklabel(struct context *ctx, int argc, char **argv)
{
return (0);
}
const struct cmd cmds[] = {
DEF_CMD(help, "[command]", "Display general help or 'command' help"),
DEF_CMD(version, NULL, "Display version information and copyright message"),
DEF_CMD(print, NULL, "Display partition table"),
DEF_CMD(mklabel, "label-type", "Create a new partition table of 'label-type'. 'label-type' should be one of \"msdos\" or \"gpt\"."),
DEF_CMD(rm, "partition", "Delete 'partition'"),
DEF_CMD(set, "partition flag [state]", "XXX"),
DEF_CMD(quit, NULL, "Exit from fdisk"),
{ NULL, NULL, NULL, NULL }
};

13
sbin/parted/disk.c Normal file
View file

@ -0,0 +1,13 @@
#include <fdisk/disk.h>
int
disk_init(struct disk *dsk, struct device *dev)
{
if (dsk == NULL || dev == NULL)
{
return (-1);
}
memset(dsk, 0, sizeof(struct disk));
disk->dev = dev;
}

4
sbin/parted/disk.h Normal file
View file

@ -0,0 +1,4 @@
#ifndef PARTED_DISK_H
# define PARTED_DISK_H 1
#endif

29
sbin/parted/fdisk/cmd.h Normal file
View file

@ -0,0 +1,29 @@
#ifndef FDISK_CMD_H
# define FDISK_CMD_H 1
# define FDISK_LINE_MAX 1024
struct context {
const char *dsk_fname;
FILE *dsk_fp;
int script;
};
struct cmd {
const char *cmd;
const char *args;
const char *desc;
int (*cb)(struct context *, int, char **);
};
# define DEF_CMD(name, args, desc) \
{ #name, args, desc, cmd_##name }
/* cmd.c */
extern const struct cmd cmds[];
/* repl.c */
int repl(struct context *ctx);
#endif /* :FDISK_CMD_H */

View file

@ -0,0 +1,33 @@
#ifndef FDISK_DEVICE_H
# define FDISK_DEVICE_H 1
# include <stdint.h>
# define DEVICE_IS_OPEN(dev) ((dev)->status & (DEV_OPEN))
enum device_status {
DEV_OPEN = 1 << 0,
DEV_RDONLY = 1 << 1,
};
struct device {
const char *path;
uint8_t status;
uint16_t ph_secsz;
uint16_t lg_secsz;
uint64_t size;
uint64_t ph_secnt;
uint64_t lg_secnt;
};
int device_open(struct device *dev, const char *path);
int device_close(struct device *dev);
int device_read(struct device *dev, uint8_t *buff, uint64_t lba,
int count);
int device_write(struct device *dev, const uint8_t *buff, uint64_t lba,
int count);
#endif /* !FDISK_DEVICE_H */

37
sbin/parted/fdisk/disk.h Normal file
View file

@ -0,0 +1,37 @@
#ifndef FDISK_DISK_H
# define FDISK_DISK_H 1
struct disk;
struct device;
struct partition;
struct disk_ops {
int (*probe)(struct disk *dsk);
};
# define DEF_DISK_OPS(name) \
static const struct disk_ops ##name_ops = { ##name_probe }
struct disk_label {
const char *name;
const struct disk_ops *ops;
/* */
struct disk_label *next;
struct disk_label **prev;
};
# define DEF_DISK_LABEL(name) \
static const struct disk_label ##name_label = { \
#name, &##name_ops, 0, 0}
struct disk {
struct device *dev;
struct disk_label *label;
struct partition *parts;
};
int disk_init(struct disk *dsk);
int disk_cleanup(struct disk *dsk);
#endif /* !FDISK_DISK_H */

View file

@ -0,0 +1,12 @@
#ifndef FDISK_PARTITION_H
# define FDISK_PARTITION_H 1
enum partition_flags {
PARTITION_BOOTABLE,
};
struct partition {
int dummy;
};
#endif /* !FDISK_PARTITION_H */

View file

@ -0,0 +1,6 @@
#ifndef FDISK_VERSION_H
# define FDISK_VERSION_H 1
void print_version(void);
#endif /* !FDISK_VERSION_H */

119
sbin/parted/fildev.c Normal file
View file

@ -0,0 +1,119 @@
#include <stdio.h>
#include <fdisk/device.h>
#define DEFAULT_SECSZ 512
static FILE *fildev_fp = NULL;
int
device_open(struct device *dev, const char *path)
{
long sz;
if (dev == NULL || path == NULL)
{
return (-1);
}
dev->path = path;
fildev_fp = fopen(dev->path, "r+b");
if (fildev_fp == NULL)
{
/* XXX: error msg */
return (-1);
}
if (fseek(fildev_fp, 0, SEEK_END) != 0)
{
goto err;
}
sz = ftell(fildev_fp);
if (sz < 0)
{
goto err;
}
dev->size = (uint64_t)sz;
dev->ph_secsz = DEFAULT_SECSZ;
dev->ph_secnt = dev->size / dev->ph_secsz;
dev->status = DEV_OPEN;
return (0);
err:
fclose(fildev_fp);
return (-1);
}
int
device_close(struct device *dev)
{
if (dev == NULL || fildev_fp == NULL)
{
return (-1);
}
if (DEVICE_IS_OPEN(dev))
{
fclose(fildev_fp);
fildev_fp = NULL;
dev->status &= ~(DEV_OPEN);
}
return (0);
}
int
device_read(struct device *dev, uint8_t *buff, uint64_t lba,
int count)
{
if (dev == NULL || buff == NULL || count == 0)
{
return (-1);
}
if (!DEVICE_IS_OPEN(dev))
{
return (-1);
}
if (fseek(fildev_fp, dev->ph_secsz * lba, SEEK_SET) != 0)
{
return (-1);
}
if (fread(buff, dev->ph_secsz, count, fildev_fp) != count)
{
return (-1);
}
return (0);
}
int
device_write(struct device *dev, const uint8_t *buff, uint64_t lba,
int count)
{
if (dev == NULL || fildev_fp == NULL || buff == NULL || count == 0)
{
return (-1);
}
if (!DEVICE_IS_OPEN(dev))
{
return (-1);
}
if (fseek(fildev_fp, dev->ph_secsz * lba, SEEK_SET) != 0)
{
return (-1);
}
if (fwrite(buff, dev->ph_secsz, count, fildev_fp) != count)
{
return (-1);
}
return (0);
}

28
sbin/parted/gpt.h Normal file
View file

@ -0,0 +1,28 @@
#ifndef GPT_H
# define GPT_H 1
# define GPT_MAGIC "EFI PART"
# define GPT_UNUSED_ENTRY { 0x00000000, 0x0000, 0x0000, \
{ 0x00, 0x00, 0x00, 0x00, \
0x00, 0x00, 0x00, 0x00 }}
struct gpt_header {
uint8_t magic[8];
uint32_t revision;
uint32_t hsize;
uint32_t hcrc32;
uint32_t reserved;
uint64_t curr_LBA;
uint64_t alt_LBA;
uint64_t fuse_LBA;
uint64_t luse_LBA;
uint8_t guid[16];
uint64_t start_LBA;
uint32_t pentnum;
uint32_t pentsize;
uint32_t pentcrc32;
};
#endif /* !GPT_H */

16
sbin/parted/guid.h Normal file
View file

@ -0,0 +1,16 @@
#ifndef GUID_H
# define GUID_H 1
# include <stdint.h>
typedef struct {
uint32_t d1;
uint16_t d2;
uint16_t d3;
uint16_t d4;
uint8_t d5[6];
} GUID;
int guid_equal(GUID *g1, GUID *g2);
#endif /* !GUID_H */

11
sbin/parted/label/msdos.c Normal file
View file

@ -0,0 +1,11 @@
#include <fdisk/disk.h>
static int
msdos_probe(struct disk *dsk)
{
(void)dsk;
return (0);
}
DEF_DISK_OPS(msdos);
DEF_DISK_LABEL(msdos);

View file

@ -2,10 +2,130 @@
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <inttypes.h>
#include <errno.h>
#include <libgen.h>
#include <unistd.h>
#include <fdisk/device.h>
#include <fdisk/disk.h>
#include <fdisk/cmd.h>
#include <fdisk/version.h>
#include "mbr.h"
const char *prg_name = NULL;
static struct device dev;
static struct disk disk;
static const char *partfile[4] = { NULL, NULL, NULL, NULL };
static int do_list = 0;
static int do_script = 0;
static int do_import = 0;
static int do_export = 0;
static void
usage(int retcode)
{
if (retcode == EXIT_FAILURE)
{
fprintf(stderr, "Try '%s -h' for more information.\n", prg_name);
}
else
{
printf("Usage: %s [-hVlsei] [-p0-3 img] disk\n", prg_name);
printf(" Options:\n");
printf(" -l\tdump disk information\n");
printf(" -s\tscript mode\n");
printf(" -h\tdisplay this help and exit\n");
printf(" -p0-3 img\tXXX\n");
printf(" -i\timport\n");
printf(" -e\textract\n");
printf(" -V\toutput version information.\n");
printf("\nReport bugs to <%s>\n", MK_BUGREPORT);
}
exit(retcode);
}
static void
version(void)
{
print_version();
exit(EXIT_SUCCESS);
}
static int
parted(const char *disk_path)
{
struct device dev;
struct disk dsk;
struct context ctx;
if (device_open(&dev, disk_path) != 0)
{
return (EXIT_FAILURE);
}
repl(&ctx);
device_close(&dev);
return (EXIT_SUCCESS);
}
int
main(int argc, char **argv)
{
int c;
prg_name = basename(argv[0]);
while ((c = getopt(argc, argv, "hVlsp:ei")) != -1)
{
switch (c)
{
case 'h':
usage(EXIT_SUCCESS);
break;
case 'V':
version();
break;
case 'l':
do_list = 1;
break;
case 's':
do_script = 1;
break;
case 'p':
/* XXX: maybe there is a better way to do this */
if (optind >= argc || (optarg[0] < '0' && optarg[0] > '3'))
{
usage(EXIT_FAILURE);
}
partfile[optarg[0] - '0'] = argv[optind];
optind++;
break;
case 'e':
do_export = 0;
break;
case 'i':
do_import = 0;
break;
default:
usage(EXIT_FAILURE);
break;
}
}
if (optind >= argc)
{
usage(EXIT_FAILURE);
}
return (parted(argv[optind]));
}
#if 0
static char *prg_name = NULL;
static int dump_info = 0;
static const char *diskpath = NULL;
@ -54,28 +174,7 @@ dump_disk(void)
}
}
static void
usage(int retcode)
{
if (retcode == EXIT_FAILURE)
{
fprintf(stderr, "Try '%s -h' for more information.\n", prg_name);
}
else
{
printf("Usage: %s [-hVd] disk\n", prg_name);
printf("\t-h\tdisplay this help and exit\n");
printf("\t-V\toutput version information.\n");
printf("\t-d\tdump disk information\n");
printf("\t-p0-3\t\n");
printf("\t-o out\twrite to file 'out'\n");
printf("\t-e\textract\n");
printf("\t-i img\t\n");
printf("\nReport bugs to <%s>\n", MK_BUGREPORT);
}
exit(retcode);
}
static void
version(void)
@ -156,3 +255,4 @@ main(int argc, char **argv)
return (EXIT_SUCCESS);
}
#endif

13
sbin/parted/parted.8 Normal file
View file

@ -0,0 +1,13 @@
.Dd $Mdocdate$
.Dt PARTED 8
.Os
.Sh NAME
.Nm parted
.Nd a partition utility
.Sh SYNOPSIS
.Nm parted
.Op Fl d
.Op Fl p Ar 0-3
.Op Fl o Ar file
.Op Ar
.Sh DESCRIPTION

26
sbin/parted/parted.h Normal file
View file

@ -0,0 +1,26 @@
#ifndef PARTED_H
# define PARTED_H 1
# include <stdio.h>
# define PARTED_LINE_MAX 1024
# define PARTED_DEFAULT_SECSZ 512
enum parted_unit {
PARTED_KiB = 1024,
PARTED_MiB = 1024 * 1024,
PARTED_GiB = 1024 * 1024 * 1024,
PARTED_KB = 1000,
PARTED_MB = 1000 * 1000,
PARTED_GB = 1000 * 1000 * 1000,
};
/* copyright.c */
extern const char *copyright;
/* main.c */
extern const char *prg_name;
#endif /* !PARTED_H */

123
sbin/parted/repl.c Normal file
View file

@ -0,0 +1,123 @@
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <fdisk/cmd.h>
#define BUFFSZ 128
#define MAXARGS 6
static char *
readline(const char *prompt)
{
size_t linsz = 0;
size_t buffsz;
char *line = NULL;
char buffer[BUFFSZ];
printf(prompt);
while (fgets(buffer, BUFFSZ, stdin) != NULL)
{
buffsz = strlen(buffer);
line = realloc(line, linsz + buffsz + 1);
if (line == NULL)
{
return (NULL);
}
memcpy(line + linsz, buffer, buffsz);
linsz += buffsz;
line[linsz] = '\0';
if (line[linsz - 1] == '\n')
{
line[linsz - 1] = '\0';
return (line);
}
}
free(line);
return (NULL);
}
static int
parse_cmd(struct context *ctx, char *line)
{
char *argv[MAXARGS] = { NULL };
int argc;
size_t idx;
char *tmp;
argc = 0;
tmp = strtok(line, " \t");
while (tmp != NULL && argc < MAXARGS)
{
argv[argc++] = tmp;
tmp = strtok(NULL, " \t");
}
for (idx = 0; cmds[idx].cmd != NULL; idx++)
{
if (strcmp(argv[0], cmds[idx].cmd) == 0)
{
if (cmds[idx].cb != NULL)
{
return (cmds[idx].cb(ctx, argc, argv));
}
printf("not implemented\n");
return (-1);
}
}
fprintf(stderr, "\e[31mError:\e[0m unknown command '%s'\n", argv[0]);
return (-1);
}
int
repl_ask(const char *str)
{
int c = '\n';
do
{
if (c == '\n')
{
printf("%s [y/n] ", str);
}
c = fgetc(stdin);
if (c == 'Y' || c == 'y')
{
putchar('\n');
return (1);
}
else if (c == 'N' || c == 'n')
{
putchar('\n');
return (0);
}
}
while (c != EOF);
return (-1);
}
int
repl(struct context *ctx)
{
char *line;
while ((line = readline("(fdisk) ")) != NULL)
{
if (line[0] == '\0')
{
free(line);
continue;
}
parse_cmd(ctx, line);
free(line);
}
return (0);
}

24
sbin/parted/version.c Normal file
View file

@ -0,0 +1,24 @@
#include <stdio.h>
#ifndef MK_PACKAGE
# define MK_PACKAGE "ext"
#endif /* !MK_PACKAGE */
#ifndef MK_COMMIT
# define MK_COMMIT "????"
#endif /* !MK_COMMIT */
extern const char *prg_name;
static const char *copyright = \
"Copyright (c) 2025, d0p1\n" \
"License BSD-3-Clause: " \
"<https://directory.fsf.org/wiki/License:BSD-3-Clause>\n" \
"This is free software: you are free to change and redistribute it.\n" \
"There is NO WARRANTY, to the extent permitterd by law.\n";
void
print_version(void)
{
printf("%s (%s) %s\n", prg_name, MK_PACKAGE, MK_COMMIT);
printf(copyright);
}

79
share/mk/stpd.base.mk Normal file
View file

@ -0,0 +1,79 @@
ifndef _STPD_BASE_MK_
_STPD_BASE_MK_:=1
ifndef TOPDIR
$(error "TOPDIR is undefined")
endif
MK_BUGREPORT := \"https://git.cute.engineering/d0p1/StupidOS/issues\"
MK_COMMIT := \"$(shell git rev-parse --short HEAD)\"
MK_PACKAGE := \"StupidOS\"
BASE_CPPFLAGS = -DMK_COMMIT="$(MK_COMMIT)" \
-DMK_BUGREPORT="$(MK_BUGREPORT)" \
-DMK_PACKAGE="$(MK_PACKAGE)"
TARGETS = all clean includes install
BINDIR ?= /bin
LIBDIR ?= /usr/lib
INCDIR ?= /usr/include
ASMDIR ?= /usr/asm
MANDIR ?= /usr/share/man
DOCDIR ?= /usr/share/doc
# +------------------------------------------------------------------+
# | Tools |
# +------------------------------------------------------------------+
ifndef TOOLSDIR
$(error "TOOLSDIR is undefined")
endif
FASM = fasm
CC = $(TOOLSDIR)/bin/tcc
AR = ar
FAS2SYM = $(TOOLSDIR)/bin/fas2sym
define VERSION_SH =
$(MSG_CREATE)
@sh $(TOPDIR)/tools/version.sh $< $@
endef
# +------------------------------------------------------------------+
# | Host |
# +------------------------------------------------------------------+
HOST_CC = gcc
HOST_AR = ar
HOST_LDFLAGS += -L$(TOOLSDIR)/lib
HOST_CFLAGS +=
HOST_CPPFLAGS += $(BASE_CPPFLAGS) -I $(TOPDIR)/include
# +------------------------------------------------------------------+
# | Verbose |
# +------------------------------------------------------------------+
MSG ?= @echo ' '
MSG_BUILD ?= $(MSG) '👷‍♂️ build ' $@
MSG_CREATE ?= $(MSG) '🪄 create ' $@
MSG_COMPILE ?= $(MSG) '⚙️ compile ' $@
MSG_LINK ?= $(MSG) '🔗 link ' $@
MSG_EXECUTE ?= $(MSG) '▶️ execute ' $@
MSG_FORMAT ?= $(MSG) '✏️ format ' $@
MSG_INSTALL ?= $(MSG) '📦 install ' $(subst $(TOPDIR)/,,$@)
MSG_REMOVE ?= $(MSG) '🗑️ remove ' $@
# +------------------------------------------------------------------+
# | rules |
# +------------------------------------------------------------------+
%.o: %.asm
$(MSG_COMPILE)
@$(FASM) $< $@ >/dev/null
%.lo: %.c
$(MSG_COMPILE)
@$(HOST_CC) -c -o $@ $< $(HOST_CPPFLAGS) $(HOST_CFLAGS)
$(TARGETS):
endif

12
share/mk/stpd.clean.mk Normal file
View file

@ -0,0 +1,12 @@
ifndef _STPD_CLEAN_MK_
_STPD_CLEAN_MK_=1
.PHONY: clean
clean:
ifeq ($(strip $(CLEANFILES)),)
@true
else
rm -f $(CLEANFILES)
endif
endif

27
share/mk/stpd.hostlib.mk Normal file
View file

@ -0,0 +1,27 @@
include stpd.base.mk
ifdef HOSTLIB
ifndef OBJS
OBJS=$(SRCS:.c=.lo)
endif
_HOSTLIBINST = $(addprefix $(TOOLSDIR)/lib/,$(HOSTLIB))
$(HOSTLIB): $(OBJS)
$(MSG_BUILD)
@$(HOST_AR) rcs $@ $<
all: $(HOSTLIB)
install: $(_HOSTLIBINST)
$(_HOSTLIBINST): $(HOSTLIB)
$(MSG_INSTALL)
@install -D $< $@
CLEANFILES += $(OBJS) $(HOSTLIB)
include stpd.clean.mk
endif

31
share/mk/stpd.hostprog.mk Normal file
View file

@ -0,0 +1,31 @@
include stpd.base.mk
ifdef HOSTPROG
ifndef SRCS
SRCS=$(HOSTPROG).c
endif
ifndef OBJS
OBJS=$(SRCS:.c=.lo)
endif
_HOSTPROGINST = $(addprefix $(TOOLSDIR)/bin/,$(HOSTPROG))
$(HOSTPROG): $(OBJS)
$(MSG_LINK)
@$(HOST_CC) -o $@ $^ $(HOST_LDFLAGS) $(LDADD)
all: $(HOSTPROG)
install: $(_HOSTPROGINST)
$(_HOSTPROGINST): $(HOSTPROG)
$(MSG_INSTALL)
@install -D $< $@
CLEANFILES += $(OBJS) $(HOSTPROG)
include stpd.clean.mk
endif

17
share/mk/stpd.inc.mk Normal file
View file

@ -0,0 +1,17 @@
include stpd.base.mk
define includes-rule
$1/$2: $2
$$(MSG_INSTALL)
@install -D $2 $1/$2
endef
_INCLUDES:=$(addprefix $(DESTDIR)$(INCDIR)/, $(INCS)) \
$(addprefix $(DESTDIR)$(ASMDIR)/, $(ASMINCS))
includes: $(_INCLUDES)
$(eval $(foreach X,$(INCS),$(call includes-rule,$(DESTDIR)$(INCDIR),$X)))
$(eval $(foreach X,$(ASMINCS),$(call includes-rule,$(DESTDIR)$(ASMDIR),$X)))

33
share/mk/stpd.subdirs.mk Normal file
View file

@ -0,0 +1,33 @@
include stpd.base.mk
ifdef SUBDIRS
_SUBDIRS=$(filter-out .WAIT,$(SUBDIRS))
_CURDIR=$(subst $(TOPDIR),,$(CURDIR))
ifneq ($(_CURDIR),)
_CURDIR:=$(_CURDIR)/
endif
define subdir-rule
.PHONY: $1-$2
$1-$2:
@echo "📁 $(_CURDIR)$2"
@DESTDIR=$(DESTDIR) $$(MAKE) -C $2 $1
endef
define subdir-target
.PHONY: subdir-$1
subdir-$1: $(foreach X,$(SUBDIRS),$(if $(filter-out $(X),.WAIT),$1-$X,.WAIT))
$1: subdir-$1
endef
$(eval $(foreach T,$(TARGETS),$(foreach X,$(_SUBDIRS),$(call subdir-rule,$T,$X))))
$(eval $(foreach T,$(TARGETS),$(call subdir-target,$T)))
endif

View file

@ -1,4 +1,4 @@
TOPGOALS = all clean install
include stpd.base.mk
.PHONY: $(TOPGOALS)
$(TOPGOALS):
all:
@echo TODO

View file

@ -1,40 +1,4 @@
TARGET = ld$(EXEXT) parted$(EXEXT) readcoff$(EXEXT) \
elf2coff$(EXEXT) ar$(EXEXT) ranlib$(EXEXT) \
fasdump$(EXEXT) fas2sym$(EXEXT)
SUBDIRS = libstupidc .WAIT ar elf2coff fas2sym fasdump
SUBDIRS += fdisk ld mtree ranlib readcoff
FAS2SYM_SRCS = main.c fas.c elf.c buffer.c
FAS2SYM_OBJS = $(addprefix ../bin/fas2sym/, $(FAS2SYM_SRCS:.c=.o))
.PHONY: all
all: $(TARGET)
ld$(EXEXT): ../bin/ld/main.c
$(TOOL_CC) -o $@ $^ $(CFLAGS) $(LDFLAGS)
readcoff$(EXEXT): ../bin/readcoff/main.c
$(TOOL_CC) -o $@ $^ $(CFLAGS) $(LDFLAGS)
elf2coff$(EXEXT): ../bin/elf2coff/main.c
$(TOOL_CC) -o $@ $^ $(CFLAGS) $(LDFLAGS)
parted$(EXEXT): ../sbin/parted/main.c
$(TOOL_CC) -o $@ $^ $(CFLAGS) $(LDFLAGS)
ranlib$(EXEXT): ../bin/ranlib/main.c ../bin/ar/archive.c
$(TOOL_CC) -o $@ $^ $(CFLAGS) $(LDFLAGS)
ar$(EXEXT): ../bin/ar/main.c
$(TOOL_CC) -o $@ $^ $(CFLAGS) $(LDFLAGS)
fasdump$(EXEXT): ../bin/fasdump/main.c
$(TOOL_CC) -o $@ $^ $(CFLAGS) $(LDFLAGS)
fas2sym$(EXEXT): $(FAS2SYM_OBJS)
$(TOOL_CC) -o $@ $^ $(CFLAGS) $(LDFLAGS)
.PHONY: install
install: $(TARGET)
.PHONY: clean
clean:
$(RM) $(TARGET)
include stpd.subdirs.mk

5
tools/ar/Makefile Normal file
View file

@ -0,0 +1,5 @@
VPATH = $(TOPDIR)/bin/ar
HOSTPROG = ar
SRCS = main.c
include stpd.hostprog.mk

5
tools/elf2coff/Makefile Normal file
View file

@ -0,0 +1,5 @@
VPATH = $(TOPDIR)/bin/elf2coff
HOSTPROG = elf2coff
SRCS = main.c
include stpd.hostprog.mk

5
tools/fas2sym/Makefile Normal file
View file

@ -0,0 +1,5 @@
VPATH = $(TOPDIR)/bin/fas2sym
HOSTPROG = fas2sym
SRCS = main.c fas.c elf.c buffer.c
include stpd.hostprog.mk

5
tools/fasdump/Makefile Normal file
View file

@ -0,0 +1,5 @@
VPATH = $(TOPDIR)/bin/fasdump
HOSTPROG = fasdump
SRCS = main.c
include stpd.hostprog.mk

6
tools/fdisk/Makefile Normal file
View file

@ -0,0 +1,6 @@
VPATH = $(TOPDIR)/sbin/parted
HOSTPROG = fdisk
HOST_CPPFLAGS += -I$(TOPDIR)/sbin/parted
SRCS = main.c repl.c cmd.c version.c fildev.c
include stpd.hostprog.mk

5
tools/ld/Makefile Normal file
View file

@ -0,0 +1,5 @@
VPATH = $(TOPDIR)/bin/ld
HOSTPROG = ld
SRCS = main.c
include stpd.hostprog.mk

View file

@ -0,0 +1,6 @@
VPATH = $(TOPDIR)/lib/stupidc
HOSTLIB = libstupidc.a
SRCS = progname.c version.c
include stpd.hostlib.mk

5
tools/mtree/Makefile Normal file
View file

@ -0,0 +1,5 @@
VPATH = $(TOPDIR)/sbin/mtree
HOSTPROG = mtree
SRCS = main.c
include stpd.hostprog.mk

5
tools/ranlib/Makefile Normal file
View file

@ -0,0 +1,5 @@
VPATH = $(TOPDIR)/bin/ranlib $(TOPDIR)/bin/ar
HOSTPROG = ranlib
SRCS = main.c archive.c
include stpd.hostprog.mk

5
tools/readcoff/Makefile Normal file
View file

@ -0,0 +1,5 @@
VPATH = $(TOPDIR)/bin/readcoff
HOSTPROG = readcoff
SRCS = main.c
include stpd.hostprog.mk