From 4f97daf67e0baaf64251b5643af5c9552c522156 Mon Sep 17 00:00:00 2001 From: "Ian M." Date: Fri, 11 Sep 2026 03:45:03 +0000 Subject: initial commit Signed-off-by: Ian M. --- .gitignore | 9 ++++++++ Makefile | 67 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ README | 4 ++++ config.def.h | 50 ++++++++++++++++++++++++++++++++++++++++ core/sboot.c | 35 ++++++++++++++++++++++++++++ head/sboot/sboot.h | 19 ++++++++++++++++ test/Makefile | 36 +++++++++++++++++++++++++++++ test/link.ld | 27 ++++++++++++++++++++++ test/test.c | 5 ++++ 9 files changed, 252 insertions(+) create mode 100644 .gitignore create mode 100644 Makefile create mode 100644 README create mode 100644 config.def.h create mode 100644 core/sboot.c create mode 100644 head/sboot/sboot.h create mode 100644 test/Makefile create mode 100644 test/link.ld create mode 100644 test/test.c diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..5a56358 --- /dev/null +++ b/.gitignore @@ -0,0 +1,9 @@ +*.o +*.d +*.so +*.sys +*.bin +*.img +*.EFI +/gnu-efi +/head/sboot/config.h diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..2eb84ed --- /dev/null +++ b/Makefile @@ -0,0 +1,67 @@ +# +# Copyright (c) 2026, Apollo Telephone Laboratories. +# Provided under the BSD-3 clause. +# + +CFILES = $(shell find core/ -name "*.c") +OFILES = $(CFILES:.c=.o) +DFILES = $(CFILES:.c=.d) + +CC = gcc +LD = ld + +CFLAGS = \ + -Wall \ + -MMD \ + -pedantic \ + -fpic \ + -ffreestanding \ + -fno-stack-protector \ + -fno-stack-check \ + -fshort-wchar \ + -mno-red-zone \ + -maccumulate-outgoing-args \ + -Ihead \ + -Ignu-efi/inc + +LDFLAGS = \ + -shared \ + -Bsymbolic \ + -Lgnu-efi/x86_64/lib \ + -Lgnu-efi/x86_64/gnuefi \ + -Tgnu-efi/gnuefi/elf_x86_64_efi.lds \ + gnu-efi/x86_64/gnuefi/crt0-efi-x86_64.o + +OBJCOPY_FLAGS = \ + -j .text \ + -j .sdata \ + -j .data \ + -j .rodata \ + -j .dynamic \ + -j .dynsym \ + -j .rel \ + -j .rela \ + -j .rel.* \ + -j .rela.* \ + -j .reloc \ + --output-target efi-app-x86_64 \ + --subsystem=10 + +.PHONY: all +all: prebuild gnu-efi $(OFILES) + ld $(LDFLAGS) $(OFILES) -lgnuefi -lefi -o main.so + objcopy $(OBJCOPY_FLAGS) main.so BOOTX64.EFI + rm -f *.so + +.PHONY: prebuild +prebuild: + echo -e "/* Generated by build; DO NOT edit */\n" >head/sboot/config.h + cat config.def.h >>head/sboot/config.h + +gnu-efi: + git clone https://github.com/ncroxon/gnu-efi.git + cd gnu-efi; make + +-include $(DFILES) +%.o: %.c + $(CC) -c $(CFLAGS) $< -o $@ diff --git a/README b/README new file mode 100644 index 0000000..4360041 --- /dev/null +++ b/README @@ -0,0 +1,4 @@ +<== Simple boot ==> + +Simple boot is a bootloader aiming to be as simple as possible while having a readable codebase and loading +only flat binaries. diff --git a/config.def.h b/config.def.h new file mode 100644 index 0000000..9a577d4 --- /dev/null +++ b/config.def.h @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2026, Apollo Telephone Laboratories. + * Provided under the BSD-3 clause. + */ + +#ifndef _CONFIG_DEF_H_ +#define _CONFIG_DEF_H_ 1 + +#include +#include + +/* + * Valid boot protocols + * + * @PROTOCOL_END: Menu terminator + * @PROTOCOL_SBOOT: Simple boot + */ +typedef enum { + PROTOCOL_END, + PROTOCOL_SBOOT +} BOOT_PROTOCOL; + +/* + * Boot menu entry + * + * @Protocol: Boot protocol + * @Name: Name of boot entry + * @BootPath: File to boot + */ +typedef struct { + BOOT_PROTOCOL Protocol; + CHAR16 *Name; + CHAR16 *BootPath; +} BOOT_ENTRY; + +static BOOT_ENTRY ConfigBootEntries[] = { + { + PROTOCOL_SBOOT, + L"BOOT", + L"kernel.bin" + }, + + { + PROTOCOL_END, + NULL, + NULL + } +}; + +#endif /* !_CONFIG_DEF_H_ */ diff --git a/core/sboot.c b/core/sboot.c new file mode 100644 index 0000000..e0b2387 --- /dev/null +++ b/core/sboot.c @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2026, Apollo Telephone Laboratories. + * Provided under the BSD-3 clause. + */ + +#include +#include +#include +#include + +EFI_STATUS +EFIAPI +efi_main(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable) +{ + UINTN NrBootEntries; + BOOT_PROTOCOL LastProtocol; + + InitializeLib(ImageHandle, SystemTable); + NrBootEntries = NELEM(ConfigBootEntries); + + /* Ensure the list is terminated */ + LastProtocol = ConfigBootEntries[NrBootEntries - 1].Protocol; + if (LastProtocol != PROTOCOL_END) { + Print(L"fatal: boot entry list not terminated\n"); + Hcf(); + } + + Print( + L"SBOOT %s - %d boot entrie(s)\n", + SBOOT_VERSION, + NELEM(ConfigBootEntries) - 1 + ); + + for (;;); +} diff --git a/head/sboot/sboot.h b/head/sboot/sboot.h new file mode 100644 index 0000000..749fbc7 --- /dev/null +++ b/head/sboot/sboot.h @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2026, Apollo Telephone Laboratories. + * Provided under the BSD-3 clause. + */ + +#ifndef _COMMON_SBOOT_H_ +#define _COMMON_SBOOT_H_ 1 + +/* Bootloader version */ +#define SBOOT_VERSION L"v0.0.1" + +/* Helper macros */ +#define NELEM(a) (sizeof(a) / sizeof(a[0])) + +/* TODO: Move this and make it less of an infinite loop */ +#define Hcf() \ + for (;;); + +#endif /* !_COMMON_SBOOT_H_ */ diff --git a/test/Makefile b/test/Makefile new file mode 100644 index 0000000..2cfdf95 --- /dev/null +++ b/test/Makefile @@ -0,0 +1,36 @@ +# +# Copyright (c) 2026, Apollo Telephone Laboratories. +# Provided under the BSD-3 clause. +# + +IMG_PATH = sboot.img + +CC = clang +LD = ld.lld +OBJCOPY = llvm-objcopy + +CFLAGS = \ + -Wall \ + -pedantic \ + -ffreestanding \ + -mno-red-zone \ + -mno-avx \ + -mno-avx2 \ + -mno-sse2 \ + -nostdlib \ + -nostdinc + +.PHONY: all +all: test + rm -f $(IMG_PATH) + mkfs.fat -C $(IMG_PATH) 4096 + mmd -i $(IMG_PATH) ::/EFI + mmd -i $(IMG_PATH) ::/EFI/BOOT + mcopy -i $(IMG_PATH) kernel.bin :: + mcopy -i $(IMG_PATH) ../BOOTX64.EFI ::EFI/BOOT + +.PHONY: test +test: + $(CC) -c $(CFLAGS) test.c -o test.o + $(LD) -Tlink.ld test.o -o kernel.sys + $(OBJCOPY) -O binary kernel.sys kernel.bin diff --git a/test/link.ld b/test/link.ld new file mode 100644 index 0000000..2899d94 --- /dev/null +++ b/test/link.ld @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2026, Apollo Telephone Laboratories. + * Provided under the BSD-3 clause. + */ + +ENTRY(main) + +SECTIONS { + . = 0xFFFFFFFF80000000; + + .text : { + *(.text .text.*) + } + + .data : { + *(.data .data.*) + } + + .rodata :{ + *(.rodata .rodata.*) + } + + .bss : { + *(COMMON) + *(.bss .bss.*) + } +} diff --git a/test/test.c b/test/test.c new file mode 100644 index 0000000..66b8c19 --- /dev/null +++ b/test/test.c @@ -0,0 +1,5 @@ +void +main(void) +{ + for (;;); +} -- cgit v1.2.3