limine-install: Overhaul
This commit is contained in:
parent
9fc15b377a
commit
55166fda2f
1
.gitignore
vendored
1
.gitignore
vendored
@ -33,3 +33,4 @@ stage23-uefi32
|
||||
stage23-uefi64
|
||||
decompressor-build
|
||||
stage1.stamp
|
||||
incbin
|
||||
|
@ -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:
|
||||
|
@ -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
|
||||
|
@ -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 $@
|
||||
|
@ -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;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user