Compare commits
78 Commits
v3.1-binar
...
v3.2022092
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
95e78137b0 | ||
|
|
ec558edef4 | ||
|
|
d96dc79a42 | ||
|
|
27816688cf | ||
|
|
c5ceb70e60 | ||
|
|
032c49db72 | ||
|
|
5c8f3f2f99 | ||
|
|
6bfc97dd87 | ||
|
|
111ae25c86 | ||
|
|
e98107b7db | ||
|
|
0d3698d6d8 | ||
|
|
35132937f8 | ||
|
|
510a4389d5 | ||
|
|
bc318c8d5e | ||
|
|
d6d0e88689 | ||
|
|
daaf492656 | ||
|
|
fac3a4bc54 | ||
|
|
34f4e9c222 | ||
|
|
f635c7e2cd | ||
|
|
99ffad04dd | ||
|
|
0e682f6902 | ||
|
|
92a27afa82 | ||
|
|
9924b70ac8 | ||
|
|
ebda58a85e | ||
|
|
2317a4aaab | ||
|
|
d16ab69e7a | ||
|
|
b7012fb936 | ||
|
|
73e38a6b3d | ||
|
|
29a31c49c4 | ||
|
|
f7d59869a5 | ||
|
|
5641f35f82 | ||
|
|
881ae89ec2 | ||
|
|
d77aad942a | ||
|
|
704d61dec3 | ||
|
|
77610750bf | ||
|
|
eee5ab3b6c | ||
|
|
8bfc2ba07a | ||
|
|
2670a1a360 | ||
|
|
3df2f4c366 | ||
|
|
e0c2d0f087 | ||
|
|
e63dfea9dd | ||
|
|
99dd26dbd4 | ||
|
|
a723c2c844 | ||
|
|
89fd3d1fce | ||
|
|
666b979724 | ||
|
|
c2401e5dc5 | ||
|
|
0d998455fa | ||
|
|
b98647d3f2 | ||
|
|
d9aa07aef2 | ||
|
|
46fa56327e | ||
|
|
f58367e049 | ||
|
|
aeb241570d | ||
|
|
7d8e981f75 | ||
|
|
7ee08cdc09 | ||
|
|
ace1de816c | ||
|
|
d4092b0945 | ||
|
|
cfabdd7d0b | ||
|
|
35efd09542 | ||
|
|
3f6a330343 | ||
|
|
9761d387a7 | ||
|
|
1ddcbb1c3d | ||
|
|
45f84c7043 | ||
|
|
c53a4a92d5 | ||
|
|
deb1839dd8 | ||
|
|
13c5b4a819 | ||
|
|
9e89ed70e4 | ||
|
|
5facec7bb4 | ||
|
|
59fa094afa | ||
|
|
6cd7ad79d6 | ||
|
|
f43bef5d10 | ||
|
|
82f9163abd | ||
|
|
ca40946d3c | ||
|
|
0666714cc1 | ||
|
|
9ae19cae3b | ||
|
|
4aa412f24d | ||
|
|
77192cacd7 | ||
|
|
bf55897b46 | ||
|
|
9be80cb694 |
2
.gitignore
vendored
2
.gitignore
vendored
@@ -1,2 +1,4 @@
|
||||
limine-deploy
|
||||
limine-deploy.exe
|
||||
limine-version
|
||||
limine-version.exe
|
||||
|
||||
BIN
BOOTIA32.EFI
BIN
BOOTIA32.EFI
Binary file not shown.
BIN
BOOTX64.EFI
BIN
BOOTX64.EFI
Binary file not shown.
12
Makefile
12
Makefile
@@ -6,7 +6,7 @@ PREFIX ?= /usr/local
|
||||
CFLAGS ?= -g -O2 -pipe -Wall -Wextra
|
||||
|
||||
.PHONY: all
|
||||
all: limine-deploy
|
||||
all: limine-deploy limine-version
|
||||
|
||||
.PHONY: install-data
|
||||
install-data: all
|
||||
@@ -25,15 +25,21 @@ install-data: all
|
||||
install: install-data
|
||||
$(INSTALL) -d '$(DESTDIR)$(PREFIX)/bin'
|
||||
$(INSTALL) limine-deploy '$(DESTDIR)$(PREFIX)/bin/'
|
||||
$(INSTALL) limine-version '$(DESTDIR)$(PREFIX)/bin/'
|
||||
|
||||
.PHONY: install-strip
|
||||
install-strip: install-data
|
||||
$(INSTALL) -d '$(DESTDIR)$(PREFIX)/bin'
|
||||
$(INSTALL) -s limine-deploy '$(DESTDIR)$(PREFIX)/bin/'
|
||||
$(INSTALL) -s limine-version '$(DESTDIR)$(PREFIX)/bin/'
|
||||
|
||||
.PHONY: clean
|
||||
clean:
|
||||
rm -f limine-deploy limine-deploy.exe
|
||||
rm -f limine-version limine-version.exe
|
||||
|
||||
limine-deploy: limine-deploy.c
|
||||
$(CC) $(CFLAGS) $(LDFLAGS) -std=c99 limine-deploy.c -o $@
|
||||
limine-deploy: limine-deploy.c limine-hdd.h
|
||||
$(CC) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) -std=c99 -D__USE_MINGW_ANSI_STDIO limine-deploy.c $(LIBS) -o $@
|
||||
|
||||
limine-version: limine-version.c
|
||||
$(CC) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) -std=c99 -D__USE_MINGW_ANSI_STDIO limine-version.c $(LIBS) -o $@
|
||||
|
||||
157
install-sh
157
install-sh
@@ -1,7 +1,7 @@
|
||||
#!/bin/sh
|
||||
# install - install a program, script, or datafile
|
||||
|
||||
scriptversion=2018-03-11.20; # UTC
|
||||
scriptversion=2020-11-14.01; # UTC
|
||||
|
||||
# This originates from X11R5 (mit/util/scripts/install.sh), which was
|
||||
# later released in X11R6 (xc/config/util/install.sh) with the
|
||||
@@ -69,6 +69,11 @@ posix_mkdir=
|
||||
# Desired mode of installed file.
|
||||
mode=0755
|
||||
|
||||
# Create dirs (including intermediate dirs) using mode 755.
|
||||
# This is like GNU 'install' as of coreutils 8.32 (2020).
|
||||
mkdir_umask=22
|
||||
|
||||
backupsuffix=
|
||||
chgrpcmd=
|
||||
chmodcmd=$chmodprog
|
||||
chowncmd=
|
||||
@@ -99,18 +104,28 @@ Options:
|
||||
--version display version info and exit.
|
||||
|
||||
-c (ignored)
|
||||
-C install only if different (preserve the last data modification time)
|
||||
-C install only if different (preserve data modification time)
|
||||
-d create directories instead of installing files.
|
||||
-g GROUP $chgrpprog installed files to GROUP.
|
||||
-m MODE $chmodprog installed files to MODE.
|
||||
-o USER $chownprog installed files to USER.
|
||||
-p pass -p to $cpprog.
|
||||
-s $stripprog installed files.
|
||||
-S SUFFIX attempt to back up existing files, with suffix SUFFIX.
|
||||
-t DIRECTORY install into DIRECTORY.
|
||||
-T report an error if DSTFILE is a directory.
|
||||
|
||||
Environment variables override the default commands:
|
||||
CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG
|
||||
RMPROG STRIPPROG
|
||||
|
||||
By default, rm is invoked with -f; when overridden with RMPROG,
|
||||
it's up to you to specify -f if you want it.
|
||||
|
||||
If -S is not specified, no backups are attempted.
|
||||
|
||||
Email bug reports to bug-automake@gnu.org.
|
||||
Automake home page: https://www.gnu.org/software/automake/
|
||||
"
|
||||
|
||||
while test $# -ne 0; do
|
||||
@@ -137,8 +152,13 @@ while test $# -ne 0; do
|
||||
-o) chowncmd="$chownprog $2"
|
||||
shift;;
|
||||
|
||||
-p) cpprog="$cpprog -p";;
|
||||
|
||||
-s) stripcmd=$stripprog;;
|
||||
|
||||
-S) backupsuffix="$2"
|
||||
shift;;
|
||||
|
||||
-t)
|
||||
is_target_a_directory=always
|
||||
dst_arg=$2
|
||||
@@ -255,6 +275,10 @@ do
|
||||
dstdir=$dst
|
||||
test -d "$dstdir"
|
||||
dstdir_status=$?
|
||||
# Don't chown directories that already exist.
|
||||
if test $dstdir_status = 0; then
|
||||
chowncmd=""
|
||||
fi
|
||||
else
|
||||
|
||||
# Waiting for this to be detected by the "$cpprog $src $dsttmp" command
|
||||
@@ -301,22 +325,6 @@ do
|
||||
if test $dstdir_status != 0; then
|
||||
case $posix_mkdir in
|
||||
'')
|
||||
# Create intermediate dirs using mode 755 as modified by the umask.
|
||||
# This is like FreeBSD 'install' as of 1997-10-28.
|
||||
umask=`umask`
|
||||
case $stripcmd.$umask in
|
||||
# Optimize common cases.
|
||||
*[2367][2367]) mkdir_umask=$umask;;
|
||||
.*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;;
|
||||
|
||||
*[0-7])
|
||||
mkdir_umask=`expr $umask + 22 \
|
||||
- $umask % 100 % 40 + $umask % 20 \
|
||||
- $umask % 10 % 4 + $umask % 2
|
||||
`;;
|
||||
*) mkdir_umask=$umask,go-w;;
|
||||
esac
|
||||
|
||||
# With -d, create the new directory with the user-specified mode.
|
||||
# Otherwise, rely on $mkdir_umask.
|
||||
if test -n "$dir_arg"; then
|
||||
@@ -326,52 +334,49 @@ do
|
||||
fi
|
||||
|
||||
posix_mkdir=false
|
||||
case $umask in
|
||||
*[123567][0-7][0-7])
|
||||
# POSIX mkdir -p sets u+wx bits regardless of umask, which
|
||||
# is incompatible with FreeBSD 'install' when (umask & 300) != 0.
|
||||
;;
|
||||
*)
|
||||
# Note that $RANDOM variable is not portable (e.g. dash); Use it
|
||||
# here however when possible just to lower collision chance.
|
||||
tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$
|
||||
# The $RANDOM variable is not portable (e.g., dash). Use it
|
||||
# here however when possible just to lower collision chance.
|
||||
tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$
|
||||
|
||||
trap 'ret=$?; rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir" 2>/dev/null; exit $ret' 0
|
||||
trap '
|
||||
ret=$?
|
||||
rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir" 2>/dev/null
|
||||
exit $ret
|
||||
' 0
|
||||
|
||||
# Because "mkdir -p" follows existing symlinks and we likely work
|
||||
# directly in world-writeable /tmp, make sure that the '$tmpdir'
|
||||
# directory is successfully created first before we actually test
|
||||
# 'mkdir -p' feature.
|
||||
if (umask $mkdir_umask &&
|
||||
$mkdirprog $mkdir_mode "$tmpdir" &&
|
||||
exec $mkdirprog $mkdir_mode -p -- "$tmpdir/a/b") >/dev/null 2>&1
|
||||
then
|
||||
if test -z "$dir_arg" || {
|
||||
# Check for POSIX incompatibilities with -m.
|
||||
# HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or
|
||||
# other-writable bit of parent directory when it shouldn't.
|
||||
# FreeBSD 6.1 mkdir -m -p sets mode of existing directory.
|
||||
test_tmpdir="$tmpdir/a"
|
||||
ls_ld_tmpdir=`ls -ld "$test_tmpdir"`
|
||||
case $ls_ld_tmpdir in
|
||||
d????-?r-*) different_mode=700;;
|
||||
d????-?--*) different_mode=755;;
|
||||
*) false;;
|
||||
esac &&
|
||||
$mkdirprog -m$different_mode -p -- "$test_tmpdir" && {
|
||||
ls_ld_tmpdir_1=`ls -ld "$test_tmpdir"`
|
||||
test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1"
|
||||
}
|
||||
}
|
||||
then posix_mkdir=:
|
||||
fi
|
||||
rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir"
|
||||
else
|
||||
# Remove any dirs left behind by ancient mkdir implementations.
|
||||
rmdir ./$mkdir_mode ./-p ./-- "$tmpdir" 2>/dev/null
|
||||
fi
|
||||
trap '' 0;;
|
||||
esac;;
|
||||
# Because "mkdir -p" follows existing symlinks and we likely work
|
||||
# directly in world-writeable /tmp, make sure that the '$tmpdir'
|
||||
# directory is successfully created first before we actually test
|
||||
# 'mkdir -p'.
|
||||
if (umask $mkdir_umask &&
|
||||
$mkdirprog $mkdir_mode "$tmpdir" &&
|
||||
exec $mkdirprog $mkdir_mode -p -- "$tmpdir/a/b") >/dev/null 2>&1
|
||||
then
|
||||
if test -z "$dir_arg" || {
|
||||
# Check for POSIX incompatibilities with -m.
|
||||
# HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or
|
||||
# other-writable bit of parent directory when it shouldn't.
|
||||
# FreeBSD 6.1 mkdir -m -p sets mode of existing directory.
|
||||
test_tmpdir="$tmpdir/a"
|
||||
ls_ld_tmpdir=`ls -ld "$test_tmpdir"`
|
||||
case $ls_ld_tmpdir in
|
||||
d????-?r-*) different_mode=700;;
|
||||
d????-?--*) different_mode=755;;
|
||||
*) false;;
|
||||
esac &&
|
||||
$mkdirprog -m$different_mode -p -- "$test_tmpdir" && {
|
||||
ls_ld_tmpdir_1=`ls -ld "$test_tmpdir"`
|
||||
test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1"
|
||||
}
|
||||
}
|
||||
then posix_mkdir=:
|
||||
fi
|
||||
rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir"
|
||||
else
|
||||
# Remove any dirs left behind by ancient mkdir implementations.
|
||||
rmdir ./$mkdir_mode ./-p ./-- "$tmpdir" 2>/dev/null
|
||||
fi
|
||||
trap '' 0;;
|
||||
esac
|
||||
|
||||
if
|
||||
@@ -382,7 +387,7 @@ do
|
||||
then :
|
||||
else
|
||||
|
||||
# The umask is ridiculous, or mkdir does not conform to POSIX,
|
||||
# mkdir does not conform to POSIX,
|
||||
# or it failed possibly due to a race condition. Create the
|
||||
# directory the slow way, step by step, checking for races as we go.
|
||||
|
||||
@@ -411,7 +416,7 @@ do
|
||||
prefixes=
|
||||
else
|
||||
if $posix_mkdir; then
|
||||
(umask=$mkdir_umask &&
|
||||
(umask $mkdir_umask &&
|
||||
$doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break
|
||||
# Don't fail if two instances are running concurrently.
|
||||
test -d "$prefix" || exit 1
|
||||
@@ -451,7 +456,18 @@ do
|
||||
trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0
|
||||
|
||||
# Copy the file name to the temp name.
|
||||
(umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") &&
|
||||
(umask $cp_umask &&
|
||||
{ test -z "$stripcmd" || {
|
||||
# Create $dsttmp read-write so that cp doesn't create it read-only,
|
||||
# which would cause strip to fail.
|
||||
if test -z "$doit"; then
|
||||
: >"$dsttmp" # No need to fork-exec 'touch'.
|
||||
else
|
||||
$doit touch "$dsttmp"
|
||||
fi
|
||||
}
|
||||
} &&
|
||||
$doit_exec $cpprog "$src" "$dsttmp") &&
|
||||
|
||||
# and set any options; do chmod last to preserve setuid bits.
|
||||
#
|
||||
@@ -477,6 +493,13 @@ do
|
||||
then
|
||||
rm -f "$dsttmp"
|
||||
else
|
||||
# If $backupsuffix is set, and the file being installed
|
||||
# already exists, attempt a backup. Don't worry if it fails,
|
||||
# e.g., if mv doesn't support -f.
|
||||
if test -n "$backupsuffix" && test -f "$dst"; then
|
||||
$doit $mvcmd -f "$dst" "$dst$backupsuffix" 2>/dev/null
|
||||
fi
|
||||
|
||||
# Rename the file to the real destination.
|
||||
$doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null ||
|
||||
|
||||
@@ -491,9 +514,9 @@ do
|
||||
# file should still install successfully.
|
||||
{
|
||||
test ! -f "$dst" ||
|
||||
$doit $rmcmd -f "$dst" 2>/dev/null ||
|
||||
$doit $rmcmd "$dst" 2>/dev/null ||
|
||||
{ $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null &&
|
||||
{ $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; }
|
||||
{ $doit $rmcmd "$rmtmp" 2>/dev/null; :; }
|
||||
} ||
|
||||
{ echo "$0: cannot unlink or rename $dst" >&2
|
||||
(exit 1); exit 1
|
||||
|
||||
Binary file not shown.
BIN
limine-cd.bin
BIN
limine-cd.bin
Binary file not shown.
355
limine-deploy.c
355
limine-deploy.c
@@ -257,6 +257,108 @@ static bool device_cache_block(uint64_t block) {
|
||||
return true;
|
||||
}
|
||||
|
||||
struct undeploy_data {
|
||||
void *data;
|
||||
uint64_t loc;
|
||||
uint64_t count;
|
||||
};
|
||||
|
||||
#define UNDEPLOY_DATA_MAX 256
|
||||
|
||||
static bool undeploying = false;
|
||||
static struct undeploy_data undeploy_data[UNDEPLOY_DATA_MAX];
|
||||
static struct undeploy_data undeploy_data_rev[UNDEPLOY_DATA_MAX];
|
||||
static uint64_t undeploy_data_i = 0;
|
||||
static const char *undeploy_file = NULL;
|
||||
|
||||
static void reverse_undeploy_data(void) {
|
||||
for (size_t i = 0, j = undeploy_data_i - 1; i < undeploy_data_i; i++, j--) {
|
||||
undeploy_data_rev[j] = undeploy_data[i];
|
||||
}
|
||||
|
||||
memcpy(undeploy_data, undeploy_data_rev, undeploy_data_i * sizeof(struct undeploy_data));
|
||||
}
|
||||
|
||||
static void free_undeploy_data(void) {
|
||||
for (size_t i = 0; i < undeploy_data_i; i++) {
|
||||
free(undeploy_data[i].data);
|
||||
}
|
||||
}
|
||||
|
||||
static bool store_undeploy_data(const char *filename) {
|
||||
fprintf(stderr, "Storing undeploy data to file: `%s`...\n", filename);
|
||||
|
||||
FILE *udfile = fopen(filename, "wb");
|
||||
if (udfile == NULL) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (fwrite(&undeploy_data_i, sizeof(uint64_t), 1, udfile) != 1) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < undeploy_data_i; i++) {
|
||||
if (fwrite(&undeploy_data[i].loc, sizeof(uint64_t), 1, udfile) != 1) {
|
||||
goto error;
|
||||
}
|
||||
if (fwrite(&undeploy_data[i].count, sizeof(uint64_t), 1, udfile) != 1) {
|
||||
goto error;
|
||||
}
|
||||
if (fwrite(undeploy_data[i].data, undeploy_data[i].count, 1, udfile) != 1) {
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
|
||||
fclose(udfile);
|
||||
return true;
|
||||
|
||||
error:
|
||||
perror("ERROR");
|
||||
if (udfile != NULL) {
|
||||
fclose(udfile);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool load_undeploy_data(const char *filename) {
|
||||
fprintf(stderr, "Loading undeploy data from file: `%s`...\n", filename);
|
||||
|
||||
FILE *udfile = fopen(filename, "rb");
|
||||
if (udfile == NULL) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (fread(&undeploy_data_i, sizeof(uint64_t), 1, udfile) != 1) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < undeploy_data_i; i++) {
|
||||
if (fread(&undeploy_data[i].loc, sizeof(uint64_t), 1, udfile) != 1) {
|
||||
goto error;
|
||||
}
|
||||
if (fread(&undeploy_data[i].count, sizeof(uint64_t), 1, udfile) != 1) {
|
||||
goto error;
|
||||
}
|
||||
undeploy_data[i].data = malloc(undeploy_data[i].count);
|
||||
if (undeploy_data[i].data == NULL) {
|
||||
goto error;
|
||||
}
|
||||
if (fread(undeploy_data[i].data, undeploy_data[i].count, 1, udfile) != 1) {
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
|
||||
fclose(udfile);
|
||||
return true;
|
||||
|
||||
error:
|
||||
perror("ERROR");
|
||||
if (udfile != NULL) {
|
||||
fclose(udfile);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool _device_read(void *_buffer, uint64_t loc, size_t count) {
|
||||
uint8_t *buffer = _buffer;
|
||||
uint64_t progress = 0;
|
||||
@@ -281,6 +383,32 @@ static bool _device_read(void *_buffer, uint64_t loc, size_t count) {
|
||||
}
|
||||
|
||||
static bool _device_write(const void *_buffer, uint64_t loc, size_t count) {
|
||||
if (undeploying) {
|
||||
goto skip_save;
|
||||
}
|
||||
|
||||
if (undeploy_data_i >= UNDEPLOY_DATA_MAX) {
|
||||
fprintf(stderr, "Internal error: Too many undeploy data entries!\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
struct undeploy_data *ud = &undeploy_data[undeploy_data_i];
|
||||
|
||||
ud->data = malloc(count);
|
||||
if (ud->data == NULL) {
|
||||
fprintf(stderr, "ERROR: Memory allocation failure.\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!_device_read(ud->data, loc, count)) {
|
||||
fprintf(stderr, "ERROR: Device read failure.\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
ud->loc = loc;
|
||||
ud->count = count;
|
||||
|
||||
skip_save:;
|
||||
const uint8_t *buffer = _buffer;
|
||||
uint64_t progress = 0;
|
||||
while (progress < count) {
|
||||
@@ -301,9 +429,43 @@ static bool _device_write(const void *_buffer, uint64_t loc, size_t count) {
|
||||
progress += chunk;
|
||||
}
|
||||
|
||||
if (!undeploying) {
|
||||
undeploy_data_i++;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static void undeploy(void) {
|
||||
undeploying = true;
|
||||
|
||||
cache_state = CACHE_CLEAN;
|
||||
cached_block = (uint64_t)-1;
|
||||
|
||||
for (size_t i = 0; i < undeploy_data_i; i++) {
|
||||
struct undeploy_data *ud = &undeploy_data[i];
|
||||
bool retry = false;
|
||||
while (!_device_write(ud->data, ud->loc, ud->count)) {
|
||||
if (retry) {
|
||||
fprintf(stderr, "ERROR: Undeploy data index %zu failed to write. Undeploy may be incomplete!\n", i);
|
||||
break;
|
||||
}
|
||||
fprintf(stderr, "Warning: Undeploy data index %zu failed to write, retrying...\n", i);
|
||||
if (!device_flush_cache()) {
|
||||
fprintf(stderr, "ERROR: Device cache flush failure. Undeploy may be incomplete!\n");
|
||||
}
|
||||
cache_state = CACHE_CLEAN;
|
||||
cached_block = (uint64_t)-1;
|
||||
retry = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!device_flush_cache()) {
|
||||
fprintf(stderr, "ERROR: Device cache flush failure. Undeploy may be incomplete!\n");
|
||||
}
|
||||
|
||||
fprintf(stderr, "Undeploy data restored successfully. Limine undeployed!\n");
|
||||
}
|
||||
|
||||
#define device_read(BUFFER, LOC, COUNT) \
|
||||
do { \
|
||||
if (!_device_read(BUFFER, LOC, COUNT)) \
|
||||
@@ -316,39 +478,101 @@ static bool _device_write(const void *_buffer, uint64_t loc, size_t count) {
|
||||
goto cleanup; \
|
||||
} while (0)
|
||||
|
||||
static void usage(const char *name) {
|
||||
printf("Usage: %s <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");
|
||||
printf("\n");
|
||||
printf(" --undeploy Reverse the entire deployment procedure\n");
|
||||
printf("\n");
|
||||
printf(" --undeploy-data-file=<filename>\n");
|
||||
printf(" Set the input (for --undeploy) or output file\n");
|
||||
printf(" name of the file which contains undeploy data\n");
|
||||
printf("\n");
|
||||
printf(" --help | -h Display this help message\n");
|
||||
printf("\n");
|
||||
#ifdef IS_WINDOWS
|
||||
system("pause");
|
||||
#endif
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
int ok = 1;
|
||||
int ok = EXIT_FAILURE;
|
||||
int force_mbr = 0;
|
||||
const uint8_t *bootloader_img = _binary_limine_hdd_bin_data;
|
||||
size_t bootloader_file_size = sizeof(_binary_limine_hdd_bin_data);
|
||||
bool undeploy_mode = false;
|
||||
const uint8_t *bootloader_img = binary_limine_hdd_bin_data;
|
||||
size_t bootloader_file_size = sizeof(binary_limine_hdd_bin_data);
|
||||
uint8_t orig_mbr[70], timestamp[6];
|
||||
const char *part_ndx = NULL;
|
||||
|
||||
uint32_t endcheck = 0x12345678;
|
||||
uint8_t endbyte = *((uint8_t *)&endcheck);
|
||||
bigendian = endbyte == 0x12;
|
||||
|
||||
if (argc < 2) {
|
||||
printf("Usage: %s <device> [GPT partition index]\n", argv[0]);
|
||||
#ifdef IS_WINDOWS
|
||||
system("pause");
|
||||
#endif
|
||||
goto cleanup;
|
||||
usage(argv[0]);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
if (argc >= 3) {
|
||||
if (strcmp(argv[2], "--force-mbr") == 0) {
|
||||
for (int i = 1; i < argc; i++) {
|
||||
if (strcmp(argv[i], "--help") == 0 || strcmp(argv[i], "-h") == 0) {
|
||||
usage(argv[0]);
|
||||
return EXIT_SUCCESS;
|
||||
} else if (strcmp(argv[i], "--force-mbr") == 0) {
|
||||
if (force_mbr) {
|
||||
fprintf(stderr, "Warning: --force-mbr already set.\n");
|
||||
}
|
||||
force_mbr = 1;
|
||||
} else if (strcmp(argv[i], "--undeploy") == 0) {
|
||||
if (undeploy_mode) {
|
||||
fprintf(stderr, "Warning: --undeploy already set.\n");
|
||||
}
|
||||
undeploy_mode = true;
|
||||
} else if (memcmp(argv[i], "--undeploy-data-file=", 21) == 0) {
|
||||
if (undeploy_file != NULL) {
|
||||
fprintf(stderr, "Warning: --undeploy-data-file already set. Overriding...\n");
|
||||
}
|
||||
undeploy_file = argv[i] + 21;
|
||||
if (strlen(undeploy_file) == 0) {
|
||||
fprintf(stderr, "ERROR: Undeploy data file has a zero-length name!\n");
|
||||
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");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
device = fopen(argv[1], "r+b");
|
||||
if (device == NULL) {
|
||||
perror("ERROR");
|
||||
goto cleanup;
|
||||
fprintf(stderr, "ERROR: No device specified\n");
|
||||
usage(argv[0]);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
if (!device_init())
|
||||
goto cleanup;
|
||||
if (!device_init()) {
|
||||
goto undeploy_mode_cleanup;
|
||||
}
|
||||
|
||||
if (undeploy_mode) {
|
||||
if (undeploy_file == NULL) {
|
||||
fprintf(stderr, "ERROR: Undeploy mode set but no --undeploy-data-file=... passed.\n");
|
||||
goto undeploy_mode_cleanup;
|
||||
}
|
||||
|
||||
if (!load_undeploy_data(undeploy_file)) {
|
||||
goto undeploy_mode_cleanup;
|
||||
}
|
||||
|
||||
undeploy();
|
||||
|
||||
ok = EXIT_SUCCESS;
|
||||
goto undeploy_mode_cleanup;
|
||||
}
|
||||
|
||||
// Probe for GPT and logical block size
|
||||
int gpt = 0;
|
||||
@@ -364,8 +588,8 @@ int main(int argc, char *argv[]) {
|
||||
fprintf(stderr, "Deploying to GPT. Logical block size of %" PRIu64 " bytes.\n",
|
||||
lb_guesses[i]);
|
||||
} else {
|
||||
memset(&gpt_header, 0, sizeof(struct gpt_table_header));
|
||||
device_write(&gpt_header, lb_guesses[i], sizeof(struct gpt_table_header));
|
||||
fprintf(stderr, "Device has a valid GPT, refusing to force MBR.\n");
|
||||
goto cleanup;
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -392,41 +616,8 @@ int main(int argc, char *argv[]) {
|
||||
|
||||
uint8_t hint8 = 0;
|
||||
uint16_t hint16 = 0;
|
||||
device_read(&hint16, 218, sizeof(uint16_t));
|
||||
hint16 = ENDSWAP(hint16);
|
||||
if (hint16 != 0) {
|
||||
if (!force_mbr) {
|
||||
mbr = 0;
|
||||
} else {
|
||||
hint16 = 0;
|
||||
hint16 = ENDSWAP(hint16);
|
||||
device_write(&hint16, 218, sizeof(uint16_t));
|
||||
}
|
||||
}
|
||||
|
||||
device_read(&hint16, 444, sizeof(uint16_t));
|
||||
hint16 = ENDSWAP(hint16);
|
||||
if (hint16 != 0 && hint16 != 0x5a5a) {
|
||||
if (!force_mbr) {
|
||||
mbr = 0;
|
||||
} else {
|
||||
hint16 = 0;
|
||||
hint16 = ENDSWAP(hint16);
|
||||
device_write(&hint16, 444, sizeof(uint16_t));
|
||||
}
|
||||
}
|
||||
|
||||
device_read(&hint16, 510, sizeof(uint16_t));
|
||||
hint16 = ENDSWAP(hint16);
|
||||
if (hint16 != 0xaa55) {
|
||||
if (!force_mbr) {
|
||||
mbr = 0;
|
||||
} else {
|
||||
hint16 = 0xaa55;
|
||||
hint16 = ENDSWAP(hint16);
|
||||
device_write(&hint16, 510, sizeof(uint16_t));
|
||||
}
|
||||
}
|
||||
bool any_active = false;
|
||||
|
||||
device_read(&hint8, 446, sizeof(uint8_t));
|
||||
if (hint8 != 0x00 && hint8 != 0x80) {
|
||||
@@ -437,6 +628,7 @@ int main(int argc, char *argv[]) {
|
||||
device_write(&hint8, 446, sizeof(uint8_t));
|
||||
}
|
||||
}
|
||||
any_active = any_active ? any_active : (hint8 & 0x80) != 0;
|
||||
device_read(&hint8, 462, sizeof(uint8_t));
|
||||
if (hint8 != 0x00 && hint8 != 0x80) {
|
||||
if (!force_mbr) {
|
||||
@@ -446,6 +638,7 @@ int main(int argc, char *argv[]) {
|
||||
device_write(&hint8, 462, sizeof(uint8_t));
|
||||
}
|
||||
}
|
||||
any_active = any_active ? any_active : (hint8 & 0x80) != 0;
|
||||
device_read(&hint8, 478, sizeof(uint8_t));
|
||||
if (hint8 != 0x00 && hint8 != 0x80) {
|
||||
if (!force_mbr) {
|
||||
@@ -455,6 +648,7 @@ int main(int argc, char *argv[]) {
|
||||
device_write(&hint8, 478, sizeof(uint8_t));
|
||||
}
|
||||
}
|
||||
any_active = any_active ? any_active : (hint8 & 0x80) != 0;
|
||||
device_read(&hint8, 494, sizeof(uint8_t));
|
||||
if (hint8 != 0x00 && hint8 != 0x80) {
|
||||
if (!force_mbr) {
|
||||
@@ -464,6 +658,7 @@ int main(int argc, char *argv[]) {
|
||||
device_write(&hint8, 494, sizeof(uint8_t));
|
||||
}
|
||||
}
|
||||
any_active = any_active ? any_active : (hint8 & 0x80) != 0;
|
||||
|
||||
char hintc[64];
|
||||
device_read(hintc, 4, 8);
|
||||
@@ -475,6 +670,15 @@ int main(int argc, char *argv[]) {
|
||||
device_write(hintc, 4, 8);
|
||||
}
|
||||
}
|
||||
device_read(hintc, 3, 4);
|
||||
if (memcmp(hintc, "NTFS", 4) == 0) {
|
||||
if (!force_mbr) {
|
||||
mbr = 0;
|
||||
} else {
|
||||
memset(hintc, 0, 4);
|
||||
device_write(hintc, 3, 4);
|
||||
}
|
||||
}
|
||||
device_read(hintc, 54, 3);
|
||||
if (memcmp(hintc, "FAT", 3) == 0) {
|
||||
if (!force_mbr) {
|
||||
@@ -484,6 +688,24 @@ int main(int argc, char *argv[]) {
|
||||
device_write(hintc, 54, 5);
|
||||
}
|
||||
}
|
||||
device_read(hintc, 82, 3);
|
||||
if (memcmp(hintc, "FAT", 3) == 0) {
|
||||
if (!force_mbr) {
|
||||
mbr = 0;
|
||||
} else {
|
||||
memset(hintc, 0, 5);
|
||||
device_write(hintc, 82, 5);
|
||||
}
|
||||
}
|
||||
device_read(hintc, 3, 5);
|
||||
if (memcmp(hintc, "FAT32", 5) == 0) {
|
||||
if (!force_mbr) {
|
||||
mbr = 0;
|
||||
} else {
|
||||
memset(hintc, 0, 5);
|
||||
device_write(hintc, 3, 5);
|
||||
}
|
||||
}
|
||||
device_read(&hint16, 1080, sizeof(uint16_t));
|
||||
hint16 = ENDSWAP(hint16);
|
||||
if (hint16 == 0xef53) {
|
||||
@@ -495,14 +717,20 @@ int main(int argc, char *argv[]) {
|
||||
device_write(&hint16, 1080, sizeof(uint16_t));
|
||||
}
|
||||
}
|
||||
|
||||
if (mbr && !any_active) {
|
||||
fprintf(stderr, "No active partition found, some systems may not boot.\n");
|
||||
fprintf(stderr, "Setting partition 1 as active to work around the issue...\n");
|
||||
hint8 = 0x80;
|
||||
device_write(&hint8, 446, sizeof(uint8_t));
|
||||
}
|
||||
}
|
||||
|
||||
if (gpt == 0 && mbr == 0) {
|
||||
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` at the end of the command to\n");
|
||||
fprintf(stderr, " override these checks. ONLY DO THIS AT YOUR OWN RISK, DATA LOSS\n");
|
||||
fprintf(stderr, " MAY OCCUR!\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");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
@@ -518,9 +746,9 @@ int main(int argc, char *argv[]) {
|
||||
uint64_t stage2_loc_b = stage2_loc_a + stage2_size_a;
|
||||
|
||||
if (gpt) {
|
||||
if (argc >= 3) {
|
||||
if (part_ndx != NULL) {
|
||||
uint32_t partition_num;
|
||||
sscanf(argv[2], "%" SCNu32, &partition_num);
|
||||
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");
|
||||
@@ -530,7 +758,7 @@ int main(int argc, char *argv[]) {
|
||||
struct gpt_entry gpt_entry;
|
||||
device_read(&gpt_entry,
|
||||
(ENDSWAP(gpt_header.partition_entry_lba) * lb_size)
|
||||
+ (partition_num * sizeof(struct gpt_entry)),
|
||||
+ (partition_num * ENDSWAP(gpt_header.size_of_partition_entry)),
|
||||
sizeof(struct gpt_entry));
|
||||
|
||||
if (gpt_entry.unique_partition_guid[0] == 0 &&
|
||||
@@ -553,7 +781,7 @@ int main(int argc, char *argv[]) {
|
||||
struct gpt_entry gpt_entry;
|
||||
device_read(&gpt_entry,
|
||||
(ENDSWAP(gpt_header.partition_entry_lba) * lb_size)
|
||||
+ (i * sizeof(struct gpt_entry)),
|
||||
+ (i * ENDSWAP(gpt_header.size_of_partition_entry)),
|
||||
sizeof(struct gpt_entry));
|
||||
|
||||
if (gpt_entry.unique_partition_guid[0] != 0 ||
|
||||
@@ -680,9 +908,18 @@ int main(int argc, char *argv[]) {
|
||||
|
||||
fprintf(stderr, "Limine deployed successfully!\n");
|
||||
|
||||
ok = 0;
|
||||
ok = EXIT_SUCCESS;
|
||||
|
||||
cleanup:
|
||||
reverse_undeploy_data();
|
||||
if (ok != EXIT_SUCCESS) {
|
||||
// If we failed, attempt to reverse deploy process
|
||||
undeploy();
|
||||
} else if (undeploy_file != NULL) {
|
||||
store_undeploy_data(undeploy_file);
|
||||
}
|
||||
undeploy_mode_cleanup:
|
||||
free_undeploy_data();
|
||||
if (cache)
|
||||
free(cache);
|
||||
if (device != NULL)
|
||||
|
||||
Binary file not shown.
2946
limine-hdd.h
2946
limine-hdd.h
File diff suppressed because it is too large
Load Diff
BIN
limine-pxe.bin
BIN
limine-pxe.bin
Binary file not shown.
7
limine-version.c
Normal file
7
limine-version.c
Normal file
@@ -0,0 +1,7 @@
|
||||
#include <stdio.h>
|
||||
|
||||
#define LIMINE_VERSION "3.20220928.0"
|
||||
|
||||
int main(void) {
|
||||
puts(LIMINE_VERSION);
|
||||
}
|
||||
16
limine.h
16
limine.h
@@ -93,15 +93,15 @@ struct limine_hhdm_request {
|
||||
|
||||
/* Framebuffer */
|
||||
|
||||
#define LIMINE_FRAMEBUFFER_REQUEST { LIMINE_COMMON_MAGIC, 0xcbfe81d7dd2d1977, 0x063150319ebc9b71 }
|
||||
#define LIMINE_FRAMEBUFFER_REQUEST { LIMINE_COMMON_MAGIC, 0x9d5827dcd881dd75, 0xa3148604f6fab11b }
|
||||
|
||||
#define LIMINE_FRAMEBUFFER_RGB 1
|
||||
|
||||
struct limine_framebuffer {
|
||||
LIMINE_PTR(void *) address;
|
||||
uint16_t width;
|
||||
uint16_t height;
|
||||
uint16_t pitch;
|
||||
uint64_t width;
|
||||
uint64_t height;
|
||||
uint64_t pitch;
|
||||
uint16_t bpp;
|
||||
uint8_t memory_model;
|
||||
uint8_t red_mask_size;
|
||||
@@ -110,7 +110,7 @@ struct limine_framebuffer {
|
||||
uint8_t green_mask_shift;
|
||||
uint8_t blue_mask_size;
|
||||
uint8_t blue_mask_shift;
|
||||
uint8_t unused;
|
||||
uint8_t unused[7];
|
||||
uint64_t edid_size;
|
||||
LIMINE_PTR(void *) edid;
|
||||
};
|
||||
@@ -129,7 +129,7 @@ struct limine_framebuffer_request {
|
||||
|
||||
/* Terminal */
|
||||
|
||||
#define LIMINE_TERMINAL_REQUEST { LIMINE_COMMON_MAGIC, 0x0785a0aea5d0750f, 0x1c1936fee0d6cf6e }
|
||||
#define LIMINE_TERMINAL_REQUEST { LIMINE_COMMON_MAGIC, 0xc8ac59310c2b0844, 0xa68d0c7265d38878 }
|
||||
|
||||
#define LIMINE_TERMINAL_CB_DEC 10
|
||||
#define LIMINE_TERMINAL_CB_BELL 20
|
||||
@@ -151,8 +151,8 @@ typedef void (*limine_terminal_write)(struct limine_terminal *, const char *, ui
|
||||
typedef void (*limine_terminal_callback)(struct limine_terminal *, uint64_t, uint64_t, uint64_t, uint64_t);
|
||||
|
||||
struct limine_terminal {
|
||||
uint32_t columns;
|
||||
uint32_t rows;
|
||||
uint64_t columns;
|
||||
uint64_t rows;
|
||||
LIMINE_PTR(struct limine_framebuffer *) framebuffer;
|
||||
};
|
||||
|
||||
|
||||
BIN
limine.sys
BIN
limine.sys
Binary file not shown.
Reference in New Issue
Block a user