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;
}
