limine-install: Overhaul
This commit is contained in:
parent
9fc15b377a
commit
55166fda2f
|
@ -33,3 +33,4 @@ stage23-uefi32
|
||||||
stage23-uefi64
|
stage23-uefi64
|
||||||
decompressor-build
|
decompressor-build
|
||||||
stage1.stamp
|
stage1.stamp
|
||||||
|
incbin
|
||||||
|
|
|
@ -196,15 +196,30 @@ override STAGE1_FILES := $(shell find '$(call SHESCAPE,$(SRCDIR))/stage1' -type
|
||||||
.PHONY: all
|
.PHONY: all
|
||||||
all: limine-uefi limine-bios
|
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
|
.PHONY: limine-install
|
||||||
limine-install:
|
limine-install:
|
||||||
mkdir -p '$(call SHESCAPE,$(BINDIR))'
|
mkdir -p '$(call SHESCAPE,$(BINDIR))'
|
||||||
cp '$(call SHESCAPE,$(SRCDIR))/limine-install/'* '$(call SHESCAPE,$(SRCDIR))/limine-install/.gitignore' '$(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))'
|
$(MAKE) -C '$(call SHESCAPE,$(BINDIR))'
|
||||||
|
|
||||||
.PHONY: clean
|
.PHONY: clean
|
||||||
clean: limine-bios-clean limine-uefi32-clean limine-uefi64-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
|
.PHONY: install-data
|
||||||
install-data:
|
install-data:
|
||||||
|
|
|
@ -11,6 +11,11 @@ cd "$srcdir"
|
||||||
|
|
||||||
[ -d stivale ] || git clone https://github.com/stivale/stivale.git
|
[ -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 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
|
automake --add-missing --copy || true
|
||||||
autoconf
|
autoconf
|
||||||
|
|
|
@ -9,10 +9,8 @@ CFLAGS ?= -O2 -pipe -Wall -Wextra
|
||||||
.PHONY: all
|
.PHONY: all
|
||||||
all: limine-install
|
all: limine-install
|
||||||
|
|
||||||
.PHONY: install
|
.PHONY: install-data
|
||||||
install: all
|
install-data: all
|
||||||
$(INSTALL) -d '$(DESTDIR)$(PREFIX)/bin'
|
|
||||||
$(INSTALL) -s limine-install '$(DESTDIR)$(PREFIX)/bin/'
|
|
||||||
$(INSTALL) -d '$(DESTDIR)$(PREFIX)/share'
|
$(INSTALL) -d '$(DESTDIR)$(PREFIX)/share'
|
||||||
$(INSTALL) -d '$(DESTDIR)$(PREFIX)/share/limine'
|
$(INSTALL) -d '$(DESTDIR)$(PREFIX)/share/limine'
|
||||||
$(INSTALL) -m 644 limine.sys '$(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 BOOTX64.EFI '$(DESTDIR)$(PREFIX)/share/limine/'
|
||||||
$(INSTALL) -m 644 BOOTIA32.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
|
.PHONY: clean
|
||||||
clean:
|
clean:
|
||||||
rm -f limine-install limine-install.exe
|
rm -f limine-install limine-install.exe
|
||||||
|
|
||||||
limine-install: limine-install.c inc.S limine-hdd.bin
|
limine-install: limine-install.c
|
||||||
$(CC) $(CFLAGS) -std=c11 limine-install.c inc.S -o $@
|
$(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
|
#define _FILE_OFFSET_BITS 64
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
@ -7,12 +15,14 @@
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
#include <fcntl.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
|
|
||||||
#ifndef O_BINARY
|
static inline int seek_(FILE *stream, int64_t offset, int whence) {
|
||||||
#define O_BINARY 0
|
#ifdef IS_WINDOWS
|
||||||
|
return _fseeki64(stream, offset, whence);
|
||||||
|
#else
|
||||||
|
return fseeko(stream, offset, whence);
|
||||||
#endif
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
#define DIV_ROUNDUP(a, b) (((a) + ((b) - 1)) / (b))
|
#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 number_of_partition_entries;
|
||||||
uint32_t size_of_partition_entry;
|
uint32_t size_of_partition_entry;
|
||||||
uint32_t partition_entry_array_crc32;
|
uint32_t partition_entry_array_crc32;
|
||||||
} __attribute__((packed));
|
};
|
||||||
|
|
||||||
struct gpt_entry {
|
struct gpt_entry {
|
||||||
uint64_t partition_type_guid[2];
|
uint64_t partition_type_guid[2];
|
||||||
|
@ -51,7 +61,7 @@ struct gpt_entry {
|
||||||
uint64_t attributes;
|
uint64_t attributes;
|
||||||
|
|
||||||
uint16_t partition_name[36];
|
uint16_t partition_name[36];
|
||||||
} __attribute__((packed));
|
};
|
||||||
|
|
||||||
// This table from https://web.mit.edu/freebsd/head/sys/libkern/crc32.c
|
// This table from https://web.mit.edu/freebsd/head/sys/libkern/crc32.c
|
||||||
static const uint32_t crc32_table[] = {
|
static const uint32_t crc32_table[] = {
|
||||||
|
@ -118,7 +128,7 @@ static enum {
|
||||||
} cache_state;
|
} cache_state;
|
||||||
static uint64_t cached_block;
|
static uint64_t cached_block;
|
||||||
static uint8_t *cache = NULL;
|
static uint8_t *cache = NULL;
|
||||||
static int device = -1;
|
static FILE *device = NULL;
|
||||||
static size_t block_size;
|
static size_t block_size;
|
||||||
|
|
||||||
static bool device_init(void) {
|
static bool device_init(void) {
|
||||||
|
@ -132,25 +142,23 @@ static bool device_init(void) {
|
||||||
}
|
}
|
||||||
cache = tmp;
|
cache = tmp;
|
||||||
|
|
||||||
if (lseek(device, 0, SEEK_SET) == (off_t)-1) {
|
if (seek_(device, 0, SEEK_SET) == -1) {
|
||||||
perror("ERROR");
|
perror("ERROR");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
ssize_t ret = read(device, cache, guesses[i]);
|
size_t ret = fread(cache, guesses[i], 1, device);
|
||||||
if (ret == -1) {
|
if (ret != 1) {
|
||||||
perror("ERROR");
|
continue;
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
block_size = ret;
|
|
||||||
|
|
||||||
if (block_size == guesses[i]) {
|
block_size = guesses[i];
|
||||||
|
|
||||||
fprintf(stderr, "Physical block size of %zu bytes.\n", block_size);
|
fprintf(stderr, "Physical block size of %zu bytes.\n", block_size);
|
||||||
|
|
||||||
cache_state = CACHE_CLEAN;
|
cache_state = CACHE_CLEAN;
|
||||||
cached_block = 0;
|
cached_block = 0;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
fprintf(stderr, "ERROR: Couldn't determine block size of device.\n");
|
fprintf(stderr, "ERROR: Couldn't determine block size of device.\n");
|
||||||
return false;
|
return false;
|
||||||
|
@ -160,20 +168,16 @@ static bool device_flush_cache(void) {
|
||||||
if (cache_state == CACHE_CLEAN)
|
if (cache_state == CACHE_CLEAN)
|
||||||
return true;
|
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");
|
perror("ERROR");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
ssize_t ret = write(device, cache, block_size);
|
size_t ret = fwrite(cache, block_size, 1, device);
|
||||||
if (ret == -1) {
|
if (ret != 1) {
|
||||||
perror("ERROR");
|
perror("ERROR");
|
||||||
return false;
|
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;
|
cache_state = CACHE_CLEAN;
|
||||||
return true;
|
return true;
|
||||||
|
@ -188,20 +192,16 @@ static bool device_cache_block(uint64_t block) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (lseek(device, block * block_size, SEEK_SET) == (off_t)-1) {
|
if (seek_(device, block * block_size, SEEK_SET) == -1) {
|
||||||
perror("ERROR");
|
perror("ERROR");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
ssize_t ret = read(device, cache, block_size);
|
size_t ret = fread(cache, block_size, 1, device);
|
||||||
if (ret == -1) {
|
if (ret != 1) {
|
||||||
perror("ERROR");
|
perror("ERROR");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if ((size_t)ret != block_size) {
|
|
||||||
fprintf(stderr, "ERROR: Read back less bytes than cache size.\n");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
cached_block = block;
|
cached_block = block;
|
||||||
|
|
||||||
|
@ -267,20 +267,25 @@ static bool _device_write(const void *_buffer, uint64_t loc, size_t count) {
|
||||||
goto cleanup; \
|
goto cleanup; \
|
||||||
} while (0)
|
} 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 main(int argc, char *argv[]) {
|
||||||
int ok = 1;
|
int ok = 1;
|
||||||
int force_mbr = 0;
|
int force_mbr = 0;
|
||||||
uint8_t *bootloader_img = _binary_limine_hdd_bin_start;
|
uint8_t *bootloader_img = (uint8_t *)_binary_limine_hdd_bin_data;
|
||||||
size_t bootloader_file_size =
|
size_t bootloader_file_size = (size_t)_binary_limine_hdd_bin_size;
|
||||||
(size_t)_binary_limine_hdd_bin_end - (size_t)_binary_limine_hdd_bin_start;
|
|
||||||
uint8_t orig_mbr[70], timestamp[6];
|
uint8_t orig_mbr[70], timestamp[6];
|
||||||
|
|
||||||
|
#ifndef IS_WINDOWS
|
||||||
if (sizeof(off_t) != 8) {
|
if (sizeof(off_t) != 8) {
|
||||||
fprintf(stderr, "ERROR: off_t type is not 64-bit.\n");
|
fprintf(stderr, "ERROR: off_t type is not 64-bit.\n");
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
if (argc < 2) {
|
if (argc < 2) {
|
||||||
printf("Usage: %s <device> [GPT partition index]\n", argv[0]);
|
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);
|
device = fopen(argv[1], "r+b");
|
||||||
if (device == -1) {
|
if (device == NULL) {
|
||||||
perror("ERROR");
|
perror("ERROR");
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
@ -491,8 +496,8 @@ int main(int argc, char *argv[]) {
|
||||||
} else {
|
} else {
|
||||||
fprintf(stderr, "GPT partition NOT specified. Attempting GPT embedding.\n");
|
fprintf(stderr, "GPT partition NOT specified. Attempting GPT embedding.\n");
|
||||||
|
|
||||||
ssize_t max_partition_entry_used = -1;
|
int64_t max_partition_entry_used = -1;
|
||||||
for (ssize_t i = 0; i < (ssize_t)gpt_header.number_of_partition_entries; i++) {
|
for (int64_t i = 0; i < (int64_t)gpt_header.number_of_partition_entries; i++) {
|
||||||
struct gpt_entry gpt_entry;
|
struct gpt_entry gpt_entry;
|
||||||
device_read(&gpt_entry,
|
device_read(&gpt_entry,
|
||||||
(gpt_header.partition_entry_lba * lb_size)
|
(gpt_header.partition_entry_lba * lb_size)
|
||||||
|
@ -520,7 +525,7 @@ int main(int argc, char *argv[]) {
|
||||||
size_t new_partition_entry_count =
|
size_t new_partition_entry_count =
|
||||||
new_partition_array_lba_size * partition_entries_per_lb;
|
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");
|
fprintf(stderr, "ERROR: Cannot embed because there are too many used partition entries.\n");
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
@ -623,8 +628,8 @@ int main(int argc, char *argv[]) {
|
||||||
cleanup:
|
cleanup:
|
||||||
if (cache)
|
if (cache)
|
||||||
free(cache);
|
free(cache);
|
||||||
if (device != -1)
|
if (device != NULL)
|
||||||
close(device);
|
fclose(device);
|
||||||
|
|
||||||
return ok;
|
return ok;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue