From 55166fda2f6d9970014c41ba979befe1cbc12976 Mon Sep 17 00:00:00 2001 From: mintsuki Date: Thu, 27 Jan 2022 12:53:40 +0100 Subject: [PATCH] limine-install: Overhaul --- .gitignore | 1 + GNUmakefile.in | 17 +++++- autogen.sh | 5 ++ limine-install/Makefile | 20 ++++--- limine-install/limine-install.c | 93 +++++++++++++++++---------------- 5 files changed, 85 insertions(+), 51 deletions(-) diff --git a/.gitignore b/.gitignore index 3d1916be..44c11eac 100644 --- a/.gitignore +++ b/.gitignore @@ -33,3 +33,4 @@ stage23-uefi32 stage23-uefi64 decompressor-build stage1.stamp +incbin diff --git a/GNUmakefile.in b/GNUmakefile.in index 105b153e..9785af08 100644 --- a/GNUmakefile.in +++ b/GNUmakefile.in @@ -196,15 +196,30 @@ override STAGE1_FILES := $(shell find '$(call SHESCAPE,$(SRCDIR))/stage1' -type .PHONY: all all: limine-uefi limine-bios +$(call MKESCAPE,$(BUILDDIR))/incbin/incbin: $(call MKESCAPE,$(SRCDIR))/incbin/incbin.c + mkdir -p '$(call SHESCAPE,$(BUILDDIR))/incbin' + $(CC) $(CFLAGS) '$(call SHESCAPE,$(SRCDIR))/incbin/incbin.c' -o '$(call SHESCAPE,$(BUILDDIR))/incbin/incbin' + +.PHONY: limine-hdd.h +limine-hdd.h: $(call MKESCAPE,$(BINDIR))/limine-hdd.h + +$(call MKESCAPE,$(BINDIR))/incbin.h: $(call MKESCAPE,$(SRCDIR))/incbin/incbin.h + cp '$(call SHESCAPE,$(SRCDIR))/incbin/incbin.h' '$(call SHESCAPE,$(BINDIR))/incbin.h' + +$(call MKESCAPE,$(BINDIR))/limine-hdd.h: $(call MKESCAPE,$(BINDIR))/incbin.h $(call MKESCAPE,$(BUILDDIR))/incbin/incbin $(call MKESCAPE,$(BINDIR))/limine-hdd.bin + cd '$(call SHESCAPE,$(BINDIR))' && \ + '$(call SHESCAPE,$(BUILDDIR))/incbin/incbin' -p _binary_ -Ssnake limine-install.c -o limine-hdd.h + .PHONY: limine-install limine-install: mkdir -p '$(call SHESCAPE,$(BINDIR))' cp '$(call SHESCAPE,$(SRCDIR))/limine-install/'* '$(call SHESCAPE,$(SRCDIR))/limine-install/.gitignore' '$(call SHESCAPE,$(BINDIR))/' + $(MAKE) limine-hdd.h $(MAKE) -C '$(call SHESCAPE,$(BINDIR))' .PHONY: clean clean: limine-bios-clean limine-uefi32-clean limine-uefi64-clean - rm -rf '$(call SHESCAPE,$(BINDIR))' '$(call SHESCAPE,$(BUILDDIR))/stage1.stamp' + rm -rf '$(call SHESCAPE,$(BINDIR))' '$(call SHESCAPE,$(BUILDDIR))/stage1.stamp' '$(call SHESCAPE,$(BUILDDIR))/incbin' .PHONY: install-data install-data: diff --git a/autogen.sh b/autogen.sh index 5cafff59..ed8db0d1 100755 --- a/autogen.sh +++ b/autogen.sh @@ -11,6 +11,11 @@ cd "$srcdir" [ -d stivale ] || git clone https://github.com/stivale/stivale.git [ -d reduced-gnu-efi ] || git clone https://github.com/limine-bootloader/reduced-gnu-efi.git +[ -d incbin ] || ( + git clone https://github.com/graphitemaster/incbin.git + cd incbin + git checkout 6e576cae5ab5810f25e2631f2e0b80cbe7dc8cbf +) automake --add-missing --copy || true autoconf diff --git a/limine-install/Makefile b/limine-install/Makefile index f0d89577..a17f2fc4 100644 --- a/limine-install/Makefile +++ b/limine-install/Makefile @@ -9,10 +9,8 @@ CFLAGS ?= -O2 -pipe -Wall -Wextra .PHONY: all all: limine-install -.PHONY: install -install: all - $(INSTALL) -d '$(DESTDIR)$(PREFIX)/bin' - $(INSTALL) -s limine-install '$(DESTDIR)$(PREFIX)/bin/' +.PHONY: install-data +install-data: all $(INSTALL) -d '$(DESTDIR)$(PREFIX)/share' $(INSTALL) -d '$(DESTDIR)$(PREFIX)/share/limine' $(INSTALL) -m 644 limine.sys '$(DESTDIR)$(PREFIX)/share/limine/' @@ -22,9 +20,19 @@ install: all $(INSTALL) -m 644 BOOTX64.EFI '$(DESTDIR)$(PREFIX)/share/limine/' $(INSTALL) -m 644 BOOTIA32.EFI '$(DESTDIR)$(PREFIX)/share/limine/' +.PHONY: install +install: install-data + $(INSTALL) -d '$(DESTDIR)$(PREFIX)/bin' + $(INSTALL) limine-install '$(DESTDIR)$(PREFIX)/bin/' + +.PHONY: install-strip +install-strip: install-data + $(INSTALL) -d '$(DESTDIR)$(PREFIX)/bin' + $(INSTALL) -s limine-install '$(DESTDIR)$(PREFIX)/bin/' + .PHONY: clean clean: rm -f limine-install limine-install.exe -limine-install: limine-install.c inc.S limine-hdd.bin - $(CC) $(CFLAGS) -std=c11 limine-install.c inc.S -o $@ +limine-install: limine-install.c + $(CC) $(CFLAGS) -std=c11 limine-install.c -o $@ diff --git a/limine-install/limine-install.c b/limine-install/limine-install.c index de25aabb..4d67a59c 100644 --- a/limine-install/limine-install.c +++ b/limine-install/limine-install.c @@ -1,4 +1,12 @@ +#undef IS_WINDOWS +#if defined(WIN32) || defined(_WIN32) || defined(__WIN32) && !defined(__CYGWIN__) +#define IS_WINDOWS 1 +#endif + +#ifndef IS_WINDOWS +#define _POSIX_C_SOURCE 200112L #define _FILE_OFFSET_BITS 64 +#endif #include #include @@ -7,12 +15,14 @@ #include #include #include -#include -#include -#ifndef O_BINARY -#define O_BINARY 0 +static inline int seek_(FILE *stream, int64_t offset, int whence) { +#ifdef IS_WINDOWS + return _fseeki64(stream, offset, whence); +#else + return fseeko(stream, offset, whence); #endif +} #define DIV_ROUNDUP(a, b) (((a) + ((b) - 1)) / (b)) @@ -38,7 +48,7 @@ struct gpt_table_header { uint32_t number_of_partition_entries; uint32_t size_of_partition_entry; uint32_t partition_entry_array_crc32; -} __attribute__((packed)); +}; struct gpt_entry { uint64_t partition_type_guid[2]; @@ -51,7 +61,7 @@ struct gpt_entry { uint64_t attributes; uint16_t partition_name[36]; -} __attribute__((packed)); +}; // This table from https://web.mit.edu/freebsd/head/sys/libkern/crc32.c static const uint32_t crc32_table[] = { @@ -118,7 +128,7 @@ static enum { } cache_state; static uint64_t cached_block; static uint8_t *cache = NULL; -static int device = -1; +static FILE *device = NULL; static size_t block_size; static bool device_init(void) { @@ -132,24 +142,22 @@ static bool device_init(void) { } cache = tmp; - if (lseek(device, 0, SEEK_SET) == (off_t)-1) { + if (seek_(device, 0, SEEK_SET) == -1) { perror("ERROR"); return false; } - ssize_t ret = read(device, cache, guesses[i]); - if (ret == -1) { - perror("ERROR"); - return false; + size_t ret = fread(cache, guesses[i], 1, device); + if (ret != 1) { + continue; } - block_size = ret; - if (block_size == guesses[i]) { - fprintf(stderr, "Physical block size of %zu bytes.\n", block_size); + block_size = guesses[i]; - cache_state = CACHE_CLEAN; - cached_block = 0; - return true; - } + fprintf(stderr, "Physical block size of %zu bytes.\n", block_size); + + cache_state = CACHE_CLEAN; + cached_block = 0; + return true; } fprintf(stderr, "ERROR: Couldn't determine block size of device.\n"); @@ -160,20 +168,16 @@ static bool device_flush_cache(void) { if (cache_state == CACHE_CLEAN) return true; - if (lseek(device, cached_block * block_size, SEEK_SET) == (off_t)-1) { + if (seek_(device, cached_block * block_size, SEEK_SET) == -1) { perror("ERROR"); return false; } - ssize_t ret = write(device, cache, block_size); - if (ret == -1) { + size_t ret = fwrite(cache, block_size, 1, device); + if (ret != 1) { perror("ERROR"); return false; } - if ((size_t)ret != block_size) { - fprintf(stderr, "ERROR: Wrote back less bytes than cache size.\n"); - return false; - } cache_state = CACHE_CLEAN; return true; @@ -188,20 +192,16 @@ static bool device_cache_block(uint64_t block) { return false; } - if (lseek(device, block * block_size, SEEK_SET) == (off_t)-1) { + if (seek_(device, block * block_size, SEEK_SET) == -1) { perror("ERROR"); return false; } - ssize_t ret = read(device, cache, block_size); - if (ret == -1) { + size_t ret = fread(cache, block_size, 1, device); + if (ret != 1) { perror("ERROR"); return false; } - if ((size_t)ret != block_size) { - fprintf(stderr, "ERROR: Read back less bytes than cache size.\n"); - return false; - } cached_block = block; @@ -267,20 +267,25 @@ static bool _device_write(const void *_buffer, uint64_t loc, size_t count) { goto cleanup; \ } while (0) -extern uint8_t _binary_limine_hdd_bin_start[], _binary_limine_hdd_bin_end[]; +/* dummy incbin call so incbin generates the header +INCBIN(limine_hdd_bin, "limine-hdd.bin"); +*/ + +#include "limine-hdd.h" int main(int argc, char *argv[]) { int ok = 1; int force_mbr = 0; - uint8_t *bootloader_img = _binary_limine_hdd_bin_start; - size_t bootloader_file_size = - (size_t)_binary_limine_hdd_bin_end - (size_t)_binary_limine_hdd_bin_start; + uint8_t *bootloader_img = (uint8_t *)_binary_limine_hdd_bin_data; + size_t bootloader_file_size = (size_t)_binary_limine_hdd_bin_size; uint8_t orig_mbr[70], timestamp[6]; +#ifndef IS_WINDOWS if (sizeof(off_t) != 8) { fprintf(stderr, "ERROR: off_t type is not 64-bit.\n"); goto cleanup; } +#endif if (argc < 2) { printf("Usage: %s [GPT partition index]\n", argv[0]); @@ -293,8 +298,8 @@ int main(int argc, char *argv[]) { } } - device = open(argv[1], O_RDWR | O_BINARY); - if (device == -1) { + device = fopen(argv[1], "r+b"); + if (device == NULL) { perror("ERROR"); goto cleanup; } @@ -491,8 +496,8 @@ int main(int argc, char *argv[]) { } else { fprintf(stderr, "GPT partition NOT specified. Attempting GPT embedding.\n"); - ssize_t max_partition_entry_used = -1; - for (ssize_t i = 0; i < (ssize_t)gpt_header.number_of_partition_entries; i++) { + int64_t max_partition_entry_used = -1; + for (int64_t i = 0; i < (int64_t)gpt_header.number_of_partition_entries; i++) { struct gpt_entry gpt_entry; device_read(&gpt_entry, (gpt_header.partition_entry_lba * lb_size) @@ -520,7 +525,7 @@ int main(int argc, char *argv[]) { size_t new_partition_entry_count = new_partition_array_lba_size * partition_entries_per_lb; - if ((ssize_t)new_partition_entry_count <= max_partition_entry_used) { + if ((int64_t)new_partition_entry_count <= max_partition_entry_used) { fprintf(stderr, "ERROR: Cannot embed because there are too many used partition entries.\n"); goto cleanup; } @@ -623,8 +628,8 @@ int main(int argc, char *argv[]) { cleanup: if (cache) free(cache); - if (device != -1) - close(device); + if (device != NULL) + fclose(device); return ok; }