uri: Add support for gzip-compressed files

This commit is contained in:
mintsuki 2020-12-27 00:27:47 +01:00
parent 9bff739de1
commit a9ff406d31
14 changed files with 58 additions and 17 deletions

View File

@ -105,3 +105,7 @@ A resource can be one of the following:
* `guid` - The `root` takes the form of a GUID/UUID, such as `guid://736b5698-5ae1-4dff-be2c-ef8f44a61c52/...`. The GUID is that of either a filesystem, when available, or a GPT partition GUID, when using GPT, in a unified namespace. * `guid` - The `root` takes the form of a GUID/UUID, such as `guid://736b5698-5ae1-4dff-be2c-ef8f44a61c52/...`. The GUID is that of either a filesystem, when available, or a GPT partition GUID, when using GPT, in a unified namespace.
* `uuid` - Alias of `guid`. * `uuid` - Alias of `guid`.
* `tftp` - The `root` is the IP address of the tftp server to load the file from. If the root is left empty (`tftp:///...`) the file will be loaded from the server Limine booted from. This resource is only available when booting off PXE. * `tftp` - The `root` is the IP address of the tftp server to load the file from. If the root is left empty (`tftp:///...`) the file will be loaded from the server Limine booted from. This resource is only available when booting off PXE.
A URI can optionally be prefixed by a `$` character to indicate that the file
pointed to be the URI is a gzip-compressed payload to be uncompressed on the
fly. E.g.: `$boot:///somemodule.gz`.

View File

@ -51,7 +51,7 @@ echfs-test: all limine-install test.hdd
rm -f limine.cfg.tmp part_guid rm -f limine.cfg.tmp part_guid
echfs-utils -g -p0 test.hdd import stage2.map boot/stage2.map echfs-utils -g -p0 test.hdd import stage2.map boot/stage2.map
echfs-utils -g -p0 test.hdd import test/test.elf boot/test.elf echfs-utils -g -p0 test.hdd import test/test.elf boot/test.elf
echfs-utils -g -p0 test.hdd import test/bg.bmp boot/bg.bmp echfs-utils -g -p0 test.hdd import test/bg.bmp.gz boot/bg.bmp.gz
echfs-utils -g -p0 test.hdd import test/font.bin boot/font.bin echfs-utils -g -p0 test.hdd import test/font.bin boot/font.bin
./limine-install limine.bin test.hdd ./limine-install limine.bin test.hdd
qemu-system-x86_64 -net none -smp 4 -enable-kvm -cpu host -hda test.hdd -debugcon stdio qemu-system-x86_64 -net none -smp 4 -enable-kvm -cpu host -hda test.hdd -debugcon stdio

View File

@ -12,12 +12,13 @@ void entry(uint8_t *compressed_stage2, size_t stage2_size, uint8_t boot_drive, i
asm volatile ( asm volatile (
"mov esp, 0x7c00\n\t" "mov esp, 0x7c00\n\t"
"xor ebp, ebp\n\t" "xor ebp, ebp\n\t"
"push %2\n\t"
"push %1\n\t" "push %1\n\t"
"push %0\n\t" "push %0\n\t"
"push 0\n\t" "push 0\n\t"
"jmp 0x8000\n\t" "jmp 0x8000\n\t"
: :
: "r" ((uint32_t)boot_drive), "r" (pxe) : "r" ((uint32_t)boot_drive), "r" (pxe), "r" (tinf_gzip_uncompress)
: "memory" : "memory"
); );

Binary file not shown.

Binary file not shown.

Binary file not shown.

4
stage2/lib/tinf.c Normal file
View File

@ -0,0 +1,4 @@
#include <lib/tinf.h>
int (*tinf_gzip_uncompress)(void *dest,
const void *source, unsigned int sourceLen);

7
stage2/lib/tinf.h Normal file
View File

@ -0,0 +1,7 @@
#ifndef __LIB__TINF_H__
#define __LIB__TINF_H__
extern int (*tinf_gzip_uncompress)(void *dest,
const void *source, unsigned int sourceLen);
#endif

View File

@ -8,6 +8,7 @@
#include <mm/pmm.h> #include <mm/pmm.h>
#include <lib/print.h> #include <lib/print.h>
#include <pxe/tftp.h> #include <pxe/tftp.h>
#include <lib/tinf.h>
// A URI takes the form of: resource://root/path // A URI takes the form of: resource://root/path
// The following function splits up a URI into its componenets // The following function splits up a URI into its componenets
@ -170,7 +171,14 @@ static bool uri_tftp_dispatch(struct file_handle *fd, char *root, char *path) {
return true; return true;
} }
static int mem_read(void *fd, void *buf, uint64_t loc, uint64_t count) {
memcpy(buf, fd + loc, count);
return 0;
}
bool uri_open(struct file_handle *fd, char *uri) { bool uri_open(struct file_handle *fd, char *uri) {
bool ret;
char *resource, *root, *path; char *resource, *root, *path;
uri_resolve(uri, &resource, &root, &path); uri_resolve(uri, &resource, &root, &path);
@ -178,17 +186,37 @@ bool uri_open(struct file_handle *fd, char *uri) {
panic("No resource specified for URI `%s`.", uri); panic("No resource specified for URI `%s`.", uri);
} }
bool compressed = false;
if (*resource == '$') {
compressed = true;
resource++;
}
if (!strcmp(resource, "bios")) { if (!strcmp(resource, "bios")) {
return uri_bios_dispatch(fd, root, path); ret = uri_bios_dispatch(fd, root, path);
} else if (!strcmp(resource, "boot")) { } else if (!strcmp(resource, "boot")) {
return uri_boot_dispatch(fd, root, path); ret = uri_boot_dispatch(fd, root, path);
} else if (!strcmp(resource, "guid")) { } else if (!strcmp(resource, "guid")) {
return uri_guid_dispatch(fd, root, path); ret = uri_guid_dispatch(fd, root, path);
} else if (!strcmp(resource, "uuid")) { } else if (!strcmp(resource, "uuid")) {
return uri_guid_dispatch(fd, root, path); ret = uri_guid_dispatch(fd, root, path);
} else if (!strcmp(resource, "tftp")) { } else if (!strcmp(resource, "tftp")) {
return uri_tftp_dispatch(fd, root, path); ret = uri_tftp_dispatch(fd, root, path);
} else { } else {
panic("Resource `%s` not valid.", resource); panic("Resource `%s` not valid.", resource);
} }
if (compressed && ret) {
struct file_handle compressed_fd = {0};
fread(fd, &compressed_fd.size, fd->size - 4, sizeof(uint32_t));
compressed_fd.fd = ext_mem_alloc(compressed_fd.size);
void *src = ext_mem_alloc(fd->size);
fread(fd, src, 0, fd->size);
if (tinf_gzip_uncompress(compressed_fd.fd, src, fd->size))
panic("tinf error");
compressed_fd.read = mem_read;
*fd = compressed_fd;
}
return ret;
} }

View File

@ -20,9 +20,11 @@
#include <menu.h> #include <menu.h>
#include <pxe/pxe.h> #include <pxe/pxe.h>
#include <pxe/tftp.h> #include <pxe/tftp.h>
#include <lib/tinf.h>
void entry(uint8_t _boot_drive, int pxe_boot) { void entry(uint8_t _boot_drive, int pxe_boot, void *_tinf_gzip_uncompress) {
boot_drive = _boot_drive; boot_drive = _boot_drive;
tinf_gzip_uncompress = _tinf_gzip_uncompress;
mtrr_save(); mtrr_save();

View File

@ -311,18 +311,13 @@ void memmap_alloc_range(uint64_t base, uint64_t length, uint32_t type) {
extern symbol bss_end; extern symbol bss_end;
static size_t bump_allocator_base = (size_t)bss_end; static size_t bump_allocator_base = (size_t)bss_end;
static size_t bump_allocator_limit = 0; static size_t bump_allocator_limit = 0x70000;
void *conv_mem_alloc(size_t count) { void *conv_mem_alloc(size_t count) {
return conv_mem_alloc_aligned(count, 4); return conv_mem_alloc_aligned(count, 4);
} }
void *conv_mem_alloc_aligned(size_t count, size_t alignment) { void *conv_mem_alloc_aligned(size_t count, size_t alignment) {
if (!bump_allocator_limit) {
// The balloc limit is the beginning of the EBDA
bump_allocator_limit = *((uint16_t *)0x40e) << 4;
}
size_t new_base = ALIGN_UP(bump_allocator_base, alignment); size_t new_base = ALIGN_UP(bump_allocator_base, alignment);
void *ret = (void *)new_base; void *ret = (void *)new_base;
new_base += count; new_base += count;

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.3 MiB

BIN
test/bg.bmp.gz Normal file

Binary file not shown.

View File

@ -10,7 +10,7 @@ STAGE2_MAP=bios://:1/boot/stage2.map
THEME_COLOURS=60000000;aa0000;00aaff;aa5500;0000aa;aa00aa;9076de;aaaaaa THEME_COLOURS=60000000;aa0000;00aaff;aa5500;0000aa;aa00aa;9076de;aaaaaa
THEME_MARGIN=64 THEME_MARGIN=64
BACKGROUND_PATH=bios://:1/boot/bg.bmp BACKGROUND_PATH=$bios://:1/boot/bg.bmp.gz
:+Legacy :+Legacy
@ -23,7 +23,7 @@ KERNEL_CMDLINE=Hi! This is an example!
MODULE_PATH=bios://:1/boot/test.elf MODULE_PATH=bios://:1/boot/test.elf
MODULE_STRING=yooooo MODULE_STRING=yooooo
MODULE_PATH=bios://:1/boot/bg.bmp MODULE_PATH=$bios://:1/boot/bg.bmp.gz
MODULE_STRING=yooooo MODULE_STRING=yooooo
:Stivale2 Test :Stivale2 Test
@ -33,5 +33,5 @@ RESOLUTION=640x480x16
KERNEL_PATH=bios://:1/boot/test.elf KERNEL_PATH=bios://:1/boot/test.elf
KERNEL_CMDLINE=Woah! Another example! KERNEL_CMDLINE=Woah! Another example!
MODULE_PATH=bios://:1/boot/bg.bmp MODULE_PATH=$bios://:1/boot/bg.bmp.gz
MODULE_STRING=yooooo MODULE_STRING=yooooo