:: commit d1b94b206f631499d7e6604bebe902feb1a8b878

mintsuki <mintsuki@protonmail.com> — 2022-01-27 11:53

parents: f382291499

limine-install: Overhaul

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 <stdio.h>
 #include <stdlib.h>
@@ -7,12 +15,14 @@
 #include <stdbool.h>
 #include <string.h>
 #include <inttypes.h>
-#include <fcntl.h>
-#include <unistd.h>
 
-#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 <device> [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;
 }
tab: 248 wrap: offon