limine-install: Overhaul

This commit is contained in:
mintsuki 2022-01-27 12:53:40 +01:00
parent 9fc15b377a
commit 55166fda2f
5 changed files with 85 additions and 51 deletions

1
.gitignore vendored
View File

@ -33,3 +33,4 @@ stage23-uefi32
stage23-uefi64
decompressor-build
stage1.stamp
incbin

View File

@ -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:

View File

@ -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

View File

@ -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 $@

View File

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