Compare commits

...

13 Commits

Author SHA1 Message Date
mintsuki
986c9a996a Binary release v5.20231207.1 2023-12-07 01:30:44 +00:00
mintsuki
b9152da995 Binary release v5.20231207.0 2023-12-06 23:44:34 +00:00
mintsuki
d0dffc6548 Binary release v5.20231124.0 2023-11-24 02:20:24 +00:00
mintsuki
30db67dab1 Binary release v5.20231121.0 2023-11-21 18:02:45 +00:00
mintsuki
2905758ed2 Binary release v5.20231114.1 2023-11-14 18:31:19 +00:00
mintsuki
f26075a694 Binary release v5.20231114.0 2023-11-14 07:38:53 +00:00
mintsuki
1976e46574 Binary release v5.20231103.0 2023-11-03 05:29:55 +00:00
mintsuki
8c2e4bb918 Binary release v5.20231029.0 2023-10-29 03:43:23 +00:00
mintsuki
dd33f1cafb Binary release v5.20231028.0 2023-10-28 03:22:26 +00:00
mintsuki
8e5b660e6f Binary release v5.20231024.0 2023-10-24 16:59:44 +00:00
mintsuki
ee753845b2 Binary release v5.20231006.0 2023-10-06 17:34:14 +00:00
mintsuki
9538b1431a Binary release v5.20230928.2 2023-09-28 23:04:14 +00:00
mintsuki
061c170fc7 Binary release v5.20230928.1 2023-09-28 21:39:58 +00:00
13 changed files with 1259 additions and 1196 deletions

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

21
LICENSE
View File

@@ -1,9 +1,22 @@
Copyright (C) 2019-2023 mintsuki and contributors.
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
1. Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

Binary file not shown.

File diff suppressed because it is too large Load Diff

Binary file not shown.

Binary file not shown.

Binary file not shown.

139
limine.c
View File

@@ -8,7 +8,9 @@
#include <stdint.h>
#include <stddef.h>
#include <stdbool.h>
#include <stdarg.h>
#include <string.h>
#include <errno.h>
#include <inttypes.h>
#include <limits.h>
@@ -16,6 +18,23 @@
#include "limine-bios-hdd.h"
#endif
static const char *program_name = NULL;
static void perror_wrap(const char *fmt, ...) {
int old_errno = errno;
fprintf(stderr, "%s: ", program_name);
va_list args;
va_start(args, fmt);
vfprintf(stderr, fmt, args);
va_end(args);
fprintf(stderr, ": %s\n", strerror(old_errno));
}
static void remove_arg(int *argc, char *argv[], int index) {
for (int i = index; i < *argc - 1; i++) {
argv[i] = argv[i + 1];
@@ -216,7 +235,7 @@ static bool device_init(void) {
for (size_t i = 0; i < sizeof(guesses) / sizeof(size_t); i++) {
void *tmp = realloc(cache, guesses[i]);
if (tmp == NULL) {
perror("ERROR");
perror_wrap("error: device_init(): realloc()");
return false;
}
cache = tmp;
@@ -239,7 +258,7 @@ static bool device_init(void) {
return true;
}
fprintf(stderr, "ERROR: Couldn't determine block size of device.\n");
fprintf(stderr, "%s: error: device_init(): Couldn't determine block size of device.\n", program_name);
return false;
}
@@ -248,14 +267,14 @@ static bool device_flush_cache(void) {
return true;
if (set_pos(device, cached_block * block_size) != 0) {
perror("ERROR");
perror_wrap("error: device_flush_cache(): set_pos()");
return false;
}
size_t ret = fwrite(cache, block_size, 1, device);
if (ret != 1) {
if (ferror(device)) {
perror("ERROR");
perror_wrap("error: device_flush_cache(): fwrite()");
}
return false;
}
@@ -274,14 +293,14 @@ static bool device_cache_block(uint64_t block) {
}
if (set_pos(device, block * block_size) != 0) {
perror("ERROR");
perror_wrap("error: device_cache_block(): set_pos()");
return false;
}
size_t ret = fread(cache, block_size, 1, device);
if (ret != 1) {
if (ferror(device)) {
perror("ERROR");
perror_wrap("error: device_cache_block(): fread()");
}
return false;
}
@@ -326,30 +345,33 @@ static bool store_uninstall_data(const char *filename) {
FILE *udfile = fopen(filename, "wb");
if (udfile == NULL) {
perror_wrap("error: `%s`", filename);
goto error;
}
if (fwrite(&uninstall_data_i, sizeof(uint64_t), 1, udfile) != 1) {
goto error;
goto fwrite_error;
}
for (size_t i = 0; i < uninstall_data_i; i++) {
if (fwrite(&uninstall_data[i].loc, sizeof(uint64_t), 1, udfile) != 1) {
goto error;
goto fwrite_error;
}
if (fwrite(&uninstall_data[i].count, sizeof(uint64_t), 1, udfile) != 1) {
goto error;
goto fwrite_error;
}
if (fwrite(uninstall_data[i].data, uninstall_data[i].count, 1, udfile) != 1) {
goto error;
goto fwrite_error;
}
}
fclose(udfile);
return true;
fwrite_error:
perror_wrap("error: store_uninstall_data(): fwrite()");
error:
perror("ERROR");
if (udfile != NULL) {
fclose(udfile);
}
@@ -363,34 +385,38 @@ static bool load_uninstall_data(const char *filename) {
FILE *udfile = fopen(filename, "rb");
if (udfile == NULL) {
perror_wrap("error: `%s`", filename);
goto error;
}
if (fread(&uninstall_data_i, sizeof(uint64_t), 1, udfile) != 1) {
goto error;
goto fread_error;
}
for (size_t i = 0; i < uninstall_data_i; i++) {
if (fread(&uninstall_data[i].loc, sizeof(uint64_t), 1, udfile) != 1) {
goto error;
goto fread_error;
}
if (fread(&uninstall_data[i].count, sizeof(uint64_t), 1, udfile) != 1) {
goto error;
goto fread_error;
}
uninstall_data[i].data = malloc(uninstall_data[i].count);
if (uninstall_data[i].data == NULL) {
perror_wrap("error: load_uninstall_data(): malloc()");
goto error;
}
if (fread(uninstall_data[i].data, uninstall_data[i].count, 1, udfile) != 1) {
goto error;
goto fread_error;
}
}
fclose(udfile);
return true;
fread_error:
perror_wrap("error: load_uninstall_data(): fread()");
error:
perror("ERROR");
if (udfile != NULL) {
fclose(udfile);
}
@@ -404,7 +430,6 @@ static bool _device_read(void *_buffer, uint64_t loc, size_t count) {
uint64_t block = (loc + progress) / block_size;
if (!device_cache_block(block)) {
fprintf(stderr, "ERROR: Read error.\n");
return false;
}
@@ -426,7 +451,7 @@ static bool _device_write(const void *_buffer, uint64_t loc, size_t count) {
}
if (uninstall_data_i >= UNINSTALL_DATA_MAX) {
fprintf(stderr, "Internal error: Too many uninstall data entries!\n");
fprintf(stderr, "%s: error: Too many uninstall data entries! Please report this bug upstream.\n", program_name);
return false;
}
@@ -434,12 +459,11 @@ static bool _device_write(const void *_buffer, uint64_t loc, size_t count) {
ud->data = malloc(count);
if (ud->data == NULL) {
fprintf(stderr, "ERROR: Memory allocation failure.\n");
perror_wrap("error: _device_write(): malloc()");
return false;
}
if (!_device_read(ud->data, loc, count)) {
fprintf(stderr, "ERROR: Device read failure.\n");
return false;
}
@@ -453,7 +477,6 @@ skip_save:;
uint64_t block = (loc + progress) / block_size;
if (!device_cache_block(block)) {
fprintf(stderr, "ERROR: Write error.\n");
return false;
}
@@ -484,14 +507,14 @@ static void uninstall(void) {
bool retry = false;
while (!_device_write(ud->data, ud->loc, ud->count)) {
if (retry) {
fprintf(stderr, "ERROR: Uninstall data index %zu failed to write. Uninstall may be incomplete!\n", i);
fprintf(stderr, "%s: error: Uninstall data index %zu failed to write. Uninstall may be incomplete!\n", program_name, i);
break;
}
if (!quiet) {
fprintf(stderr, "Warning: Uninstall data index %zu failed to write, retrying...\n", i);
fprintf(stderr, "%s: warning: Uninstall data index %zu failed to write, retrying...\n", program_name, i);
}
if (!device_flush_cache()) {
fprintf(stderr, "ERROR: Device cache flush failure. Uninstall may be incomplete!\n");
fprintf(stderr, "%s: error: Device cache flush failure. Uninstall may be incomplete!\n", program_name);
}
cache_state = CACHE_CLEAN;
cached_block = (uint64_t)-1;
@@ -500,7 +523,7 @@ static void uninstall(void) {
}
if (!device_flush_cache()) {
fprintf(stderr, "ERROR: Device cache flush failure. Uninstall may be incomplete!\n");
fprintf(stderr, "%s: error: Device cache flush failure. Uninstall may be incomplete!\n", program_name);
}
if (!quiet) {
@@ -521,7 +544,7 @@ static void uninstall(void) {
} while (0)
static void bios_install_usage(const char *name) {
printf("Usage: %s bios-install <device> [GPT partition index]\n", name);
printf("usage: %s bios-install <device> [GPT partition index]\n", name);
printf("\n");
printf(" --force-mbr Force MBR detection to work even if the\n");
printf(" safety checks fail (DANGEROUS!)\n");
@@ -569,35 +592,35 @@ static int bios_install(int argc, char *argv[]) {
quiet = true;
} else if (strcmp(argv[i], "--force-mbr") == 0) {
if (force_mbr && !quiet) {
fprintf(stderr, "Warning: --force-mbr already set.\n");
fprintf(stderr, "%s: warning: --force-mbr already set.\n", program_name);
}
force_mbr = 1;
} else if (strcmp(argv[i], "--uninstall") == 0) {
if (uninstall_mode && !quiet) {
fprintf(stderr, "Warning: --uninstall already set.\n");
fprintf(stderr, "%s: warning: --uninstall already set.\n", program_name);
}
uninstall_mode = true;
} else if (memcmp(argv[i], "--uninstall-data-file=", 21) == 0) {
if (uninstall_file != NULL && !quiet) {
fprintf(stderr, "Warning: --uninstall-data-file already set. Overriding...\n");
fprintf(stderr, "%s: warning: --uninstall-data-file already set. Overriding...\n", program_name);
}
uninstall_file = argv[i] + 21;
if (strlen(uninstall_file) == 0) {
fprintf(stderr, "ERROR: Uninstall data file has a zero-length name!\n");
fprintf(stderr, "%s: error: Uninstall data file has a zero-length name!\n", program_name);
return EXIT_FAILURE;
}
} else {
if (device != NULL) { // [GPT partition index]
part_ndx = argv[i]; // TODO: Make this non-positional?
} else if ((device = fopen(argv[i], "r+b")) == NULL) { // <device>
perror("ERROR");
perror_wrap("error: `%s`", argv[i]);
return EXIT_FAILURE;
}
}
}
if (device == NULL) {
fprintf(stderr, "ERROR: No device specified\n");
fprintf(stderr, "%s: error: No device specified\n", program_name);
bios_install_usage(argv[-1]);
return EXIT_FAILURE;
}
@@ -608,7 +631,7 @@ static int bios_install(int argc, char *argv[]) {
if (uninstall_mode) {
if (uninstall_file == NULL) {
fprintf(stderr, "ERROR: Uninstall mode set but no --uninstall-data-file=... passed.\n");
fprintf(stderr, "%s: error: Uninstall mode set but no --uninstall-data-file=... passed.\n", program_name);
goto uninstall_mode_cleanup;
}
@@ -638,7 +661,7 @@ static int bios_install(int argc, char *argv[]) {
lb_guesses[i]);
}
} else {
fprintf(stderr, "ERROR: Device has a valid GPT, refusing to force MBR.\n");
fprintf(stderr, "%s: error: Device has a valid GPT, refusing to force MBR.\n", program_name);
goto cleanup;
}
break;
@@ -658,7 +681,7 @@ static int bios_install(int argc, char *argv[]) {
fprintf(stderr, "Secondary header valid.\n");
}
} else {
fprintf(stderr, "ERROR: Secondary header not valid, aborting.\n");
fprintf(stderr, "%s: error: Secondary header not valid, aborting.\n", program_name);
goto cleanup;
}
}
@@ -783,7 +806,7 @@ static int bios_install(int argc, char *argv[]) {
}
if (gpt == 0 && mbr == 0) {
fprintf(stderr, "ERROR: Could not determine if the device has a valid partition table.\n");
fprintf(stderr, "error: Could not determine if the device has a valid partition table.\n");
fprintf(stderr, " Please ensure the device has a valid MBR or GPT.\n");
fprintf(stderr, " Alternatively, pass `--force-mbr` to override these checks.\n");
fprintf(stderr, " **ONLY DO THIS AT YOUR OWN RISK, DATA LOSS MAY OCCUR!**\n");
@@ -807,7 +830,7 @@ static int bios_install(int argc, char *argv[]) {
sscanf(part_ndx, "%" SCNu32, &partition_num);
partition_num--;
if (partition_num > ENDSWAP(gpt_header.number_of_partition_entries)) {
fprintf(stderr, "ERROR: Partition number is too large.\n");
fprintf(stderr, "%s: error: Partition number is too large.\n", program_name);
goto cleanup;
}
@@ -819,7 +842,7 @@ static int bios_install(int argc, char *argv[]) {
if (gpt_entry.unique_partition_guid[0] == 0 &&
gpt_entry.unique_partition_guid[1] == 0) {
fprintf(stderr, "ERROR: No such partition.\n");
fprintf(stderr, "%s: error: No such partition: `%s`.\n", program_name, part_ndx);
goto cleanup;
}
@@ -866,7 +889,7 @@ static int bios_install(int argc, char *argv[]) {
new_partition_array_lba_size * partition_entries_per_lb;
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, "%s: error: Cannot embed because there are too many used partition entries.\n", program_name);
goto cleanup;
}
@@ -891,7 +914,7 @@ static int bios_install(int argc, char *argv[]) {
uint8_t *partition_array =
malloc(new_partition_entry_count * ENDSWAP(gpt_header.size_of_partition_entry));
if (partition_array == NULL) {
perror("ERROR");
perror_wrap("error: bios_install(): malloc()");
goto cleanup;
}
@@ -1000,7 +1023,7 @@ uninstall_mode_cleanup:
#define CONFIG_B2SUM_SIGNATURE "++CONFIG_B2SUM_SIGNATURE++"
static void enroll_config_usage(const char *name) {
printf("Usage: %s enroll-config <Limine executable> <BLAKE2B of config file>\n", name);
printf("usage: %s enroll-config <Limine executable> <BLAKE2B of config file>\n", name);
printf("\n");
printf(" --reset Remove enrolled BLAKE2B, will not check config integrity\n");
printf("\n");
@@ -1040,18 +1063,18 @@ static int enroll_config(int argc, char *argv[]) {
}
if (!reset && strlen(argv[2]) != 128) {
fprintf(stderr, "ERROR: BLAKE2B specified is not 128 characters long\n");
fprintf(stderr, "%s: error: BLAKE2B specified is not 128 characters long.\n", program_name);
goto cleanup;
}
bootloader_file = fopen(argv[1], "r+b");
if (bootloader_file == NULL) {
perror("ERROR");
goto cleanup;;
perror_wrap("error: `%s`", argv[1]);
goto cleanup;
}
if (fseek(bootloader_file, 0, SEEK_END) != 0) {
perror("ERROR");
perror_wrap("error: enroll_config(): fseek()");
goto cleanup;
}
size_t bootloader_size = ftell(bootloader_file);
@@ -1059,12 +1082,12 @@ static int enroll_config(int argc, char *argv[]) {
bootloader = malloc(bootloader_size);
if (bootloader == NULL) {
perror("ERROR");
perror_wrap("error: enroll_config(): malloc()");
goto cleanup;
}
if (fread(bootloader, bootloader_size, 1, bootloader_file) != 1) {
perror("ERROR");
perror_wrap("error: enroll_config(): fread()");
goto cleanup;
}
@@ -1086,7 +1109,7 @@ static int enroll_config(int argc, char *argv[]) {
}
if (checksum_loc == NULL) {
fprintf(stderr, "ERROR: Checksum location not found in provided executable\n");
fprintf(stderr, "%s: error: Checksum location not found in provided executable.\n", program_name);
goto cleanup;
}
@@ -1097,11 +1120,11 @@ static int enroll_config(int argc, char *argv[]) {
}
if (fseek(bootloader_file, 0, SEEK_SET) != 0) {
perror("ERROR");
perror_wrap("error: enroll_config(): fseek()");
goto cleanup;
}
if (fwrite(bootloader, bootloader_size, 1, bootloader_file) != 1) {
perror("ERROR");
perror_wrap("error: enroll_config(): fwrite()");
goto cleanup;
}
@@ -1120,7 +1143,7 @@ cleanup:
return ret;
}
#define LIMINE_VERSION "5.20230928.0"
#define LIMINE_VERSION "5.20231207.1"
#define LIMINE_COPYRIGHT "Copyright (C) 2019-2023 mintsuki and contributors."
static int version(void) {
@@ -1131,28 +1154,30 @@ static int version(void) {
return EXIT_SUCCESS;
}
static void general_usage(const char *name) {
printf("Usage: %s <command> <args...>\n", name);
static void general_usage(void) {
printf("usage: %s <command> <args...>\n", program_name);
printf("\n");
printf("Valid commands: help, version, bios-install, enroll-config\n");
}
int main(int argc, char *argv[]) {
program_name = argv[0];
if (argc <= 1) {
general_usage(argv[0]);
general_usage();
return EXIT_FAILURE;
}
if (strcmp(argv[1], "help") == 0
|| strcmp(argv[1], "--help") == 0
|| strcmp(argv[1], "-h") == 0) {
general_usage(argv[0]);
general_usage();
return EXIT_SUCCESS;
} else if (strcmp(argv[1], "bios-install") == 0) {
#ifndef LIMINE_NO_BIOS
return bios_install(argc - 1, &argv[1]);
#else
fprintf(stderr, "ERROR: Limine has been compiled without BIOS support.\n");
fprintf(stderr, "%s: error: Limine has been compiled without BIOS support.\n", program_name);
return EXIT_FAILURE;
#endif
} else if (strcmp(argv[1], "enroll-config") == 0) {
@@ -1162,6 +1187,6 @@ int main(int argc, char *argv[]) {
return version();
}
general_usage(argv[0]);
general_usage();
return EXIT_FAILURE;
}

Binary file not shown.

View File

@@ -44,6 +44,11 @@ extern "C" {
# define LIMINE_DEPRECATED_IGNORE_END
#endif
#define LIMINE_BASE_REVISION(N) \
uint64_t limine_base_revision[3] = { 0xf9562b2d5c95a6c8, 0x6a7b384944536bdc, (N) };
#define LIMINE_BASE_REVISION_SUPPORTED (limine_base_revision[2] == 0)
#define LIMINE_COMMON_MAGIC 0xc7b1dd30df4c8b88, 0x0a82e883a194f07b
struct limine_uuid {
@@ -502,6 +507,24 @@ struct limine_efi_system_table_request {
LIMINE_PTR(struct limine_efi_system_table_response *) response;
};
/* EFI memory map */
#define LIMINE_EFI_MEMMAP_REQUEST { LIMINE_COMMON_MAGIC, 0x7df62a431d6872d5, 0xa4fcdfb3e57306c8 }
struct limine_efi_memmap_response {
uint64_t revision;
LIMINE_PTR(void *) memmap;
uint64_t memmap_size;
uint64_t desc_size;
uint64_t desc_version;
};
struct limine_efi_memmap_request {
uint64_t id[4];
uint64_t revision;
LIMINE_PTR(struct limine_efi_memmap_response *) response;
};
/* Boot time */
#define LIMINE_BOOT_TIME_REQUEST { LIMINE_COMMON_MAGIC, 0x502746e184c088aa, 0xfbc5ec83e6327893 }