Support xz compression on yeeloong.
* Makefile.util.def (grub-mkimage): Add $(LIBLZMA). * configure.ac: Check for LZMA. * grub-core/Makefile.core.def (xz_decompress): New target. (none_decompress): Likewise. * grub-core/boot/decompressor/minilib.c: New file. * grub-core/boot/decompressor/none.c: Likewise. * grub-core/boot/decompressor/xz.c: Likewise. * grub-core/kern/mips/cache.S: Change to noreorder nomacro. * grub-core/kern/mips/cache_flush.S: Likewise. * grub-core/kern/i386/pc/lzma_decode.S: Remove dead code. * grub-core/kern/mips/startup.S: Move first stage to ... * grub-core/boot/mips/startup_raw.S: ...here. Change to noreorder nomacro. * grub-core/kern/mips/startup.S: Change to noreorder nomacro. * grub-core/lib/mips/relocator_asm.S: Change to noreorder nomacro. * grub-core/lib/xzembed/xz_dec_bcj.c [GRUB_EMBED_DECOMPRESSOR]: Allocate statically. * grub-core/lib/xzembed/xz_dec_lzma2.c [GRUB_EMBED_DECOMPRESSOR]: Allocate statically or use scratch. Don't check CRC32. * grub-core/lib/xzembed/xz_dec_stream.c [GRUB_EMBED_DECOMPRESSOR]: Allocate statically. Don't check CRC32. * include/grub/decompressor.h: New file. * include/grub/offsets.h (GRUB_KERNEL_MIPS_YEELOONG_RAW_SIZE): Removed. (GRUB_KERNEL_MIPS_YEELOONG_UNCOMPRESSED_SIZE): New field. (GRUB_KERNEL_MIPS_YEELOONG_TOTAL_MODULE_SIZE): Adjusted. (GRUB_KERNEL_MIPS_YEELOONG_PREFIX): Likewise. (GRUB_KERNEL_MIPS_YEELOONG_PREFIX_END): Likewise. (GRUB_KERNEL_MACHINE_UNCOMPRESSED_SIZE): New define. * util/grub-mkimage.c (grub_compression_t): New type. (PLATFORM_FLAGS_DECOMPRESSORS): New flag. (image_target_desc): New field default_compression. (image_targets): Adjust yeeloong targets. (compress_kernel_xz) [HAVE_LIBLZMA]: New function. (compress_kernel): New parameter comp. (generate_image): Likewise. Handle new compression case. (options): New option --compression (help): Likewise. (main): Handle new option.
This commit is contained in:
commit
6d0fa83c79
19 changed files with 812 additions and 233 deletions
|
@ -45,7 +45,16 @@
|
|||
|
||||
#define ALIGN_ADDR(x) (ALIGN_UP((x), image_target->voidp_sizeof))
|
||||
|
||||
#ifdef HAVE_LIBLZMA
|
||||
#include <lzma.h>
|
||||
#endif
|
||||
|
||||
#define TARGET_NO_FIELD 0xffffffff
|
||||
|
||||
typedef enum {
|
||||
COMPRESSION_AUTO, COMPRESSION_NONE, COMPRESSION_XZ
|
||||
} grub_compression_t;
|
||||
|
||||
struct image_target_desc
|
||||
{
|
||||
const char *name;
|
||||
|
@ -60,7 +69,8 @@ struct image_target_desc
|
|||
enum
|
||||
{
|
||||
PLATFORM_FLAGS_NONE = 0,
|
||||
PLATFORM_FLAGS_LZMA = 1
|
||||
PLATFORM_FLAGS_LZMA = 1,
|
||||
PLATFORM_FLAGS_DECOMPRESSORS = 2
|
||||
} flags;
|
||||
unsigned prefix;
|
||||
unsigned prefix_end;
|
||||
|
@ -75,6 +85,7 @@ struct image_target_desc
|
|||
unsigned install_dos_part, install_bsd_part;
|
||||
grub_uint64_t link_addr;
|
||||
unsigned mod_gap, mod_align;
|
||||
grub_compression_t default_compression;
|
||||
};
|
||||
|
||||
struct image_target_desc image_targets[] =
|
||||
|
@ -248,40 +259,42 @@ struct image_target_desc image_targets[] =
|
|||
.voidp_sizeof = 4,
|
||||
.bigendian = 0,
|
||||
.id = IMAGE_YEELOONG_FLASH,
|
||||
.flags = PLATFORM_FLAGS_NONE,
|
||||
.flags = PLATFORM_FLAGS_DECOMPRESSORS,
|
||||
.prefix = GRUB_KERNEL_MIPS_YEELOONG_PREFIX,
|
||||
.prefix_end = GRUB_KERNEL_MIPS_YEELOONG_PREFIX_END,
|
||||
.raw_size = GRUB_KERNEL_MIPS_YEELOONG_RAW_SIZE,
|
||||
.raw_size = 0,
|
||||
.total_module_size = GRUB_KERNEL_MIPS_YEELOONG_TOTAL_MODULE_SIZE,
|
||||
.compressed_size = GRUB_KERNEL_MIPS_YEELOONG_COMPRESSED_SIZE,
|
||||
.kernel_image_size = GRUB_KERNEL_MIPS_YEELOONG_KERNEL_IMAGE_SIZE,
|
||||
.compressed_size = TARGET_NO_FIELD,
|
||||
.kernel_image_size = TARGET_NO_FIELD,
|
||||
.section_align = 1,
|
||||
.vaddr_offset = 0,
|
||||
.install_dos_part = TARGET_NO_FIELD,
|
||||
.install_bsd_part = TARGET_NO_FIELD,
|
||||
.link_addr = GRUB_KERNEL_MIPS_YEELOONG_LINK_ADDR,
|
||||
.elf_target = EM_MIPS,
|
||||
.link_align = GRUB_KERNEL_MIPS_YEELOONG_LINK_ALIGN
|
||||
.link_align = GRUB_KERNEL_MIPS_YEELOONG_LINK_ALIGN,
|
||||
.default_compression = COMPRESSION_NONE
|
||||
},
|
||||
{
|
||||
.name = "mipsel-yeeloong-elf",
|
||||
.voidp_sizeof = 4,
|
||||
.bigendian = 0,
|
||||
.id = IMAGE_YEELOONG_ELF,
|
||||
.flags = PLATFORM_FLAGS_NONE,
|
||||
.flags = PLATFORM_FLAGS_DECOMPRESSORS,
|
||||
.prefix = GRUB_KERNEL_MIPS_YEELOONG_PREFIX,
|
||||
.prefix_end = GRUB_KERNEL_MIPS_YEELOONG_PREFIX_END,
|
||||
.raw_size = GRUB_KERNEL_MIPS_YEELOONG_RAW_SIZE,
|
||||
.raw_size = 0,
|
||||
.total_module_size = GRUB_KERNEL_MIPS_YEELOONG_TOTAL_MODULE_SIZE,
|
||||
.compressed_size = GRUB_KERNEL_MIPS_YEELOONG_COMPRESSED_SIZE,
|
||||
.kernel_image_size = GRUB_KERNEL_MIPS_YEELOONG_KERNEL_IMAGE_SIZE,
|
||||
.compressed_size = TARGET_NO_FIELD,
|
||||
.kernel_image_size = TARGET_NO_FIELD,
|
||||
.section_align = 1,
|
||||
.vaddr_offset = 0,
|
||||
.install_dos_part = TARGET_NO_FIELD,
|
||||
.install_bsd_part = TARGET_NO_FIELD,
|
||||
.link_addr = GRUB_KERNEL_MIPS_YEELOONG_LINK_ADDR,
|
||||
.elf_target = EM_MIPS,
|
||||
.link_align = GRUB_KERNEL_MIPS_YEELOONG_LINK_ALIGN
|
||||
.link_align = GRUB_KERNEL_MIPS_YEELOONG_LINK_ALIGN,
|
||||
.default_compression = COMPRESSION_NONE
|
||||
},
|
||||
{
|
||||
.name = "powerpc-ieee1275",
|
||||
|
@ -493,9 +506,66 @@ compress_kernel_lzma (char *kernel_img, size_t kernel_size,
|
|||
*core_size += raw_size;
|
||||
}
|
||||
|
||||
#ifdef HAVE_LIBLZMA
|
||||
static void
|
||||
compress_kernel_xz (char *kernel_img, size_t kernel_size,
|
||||
char **core_img, size_t *core_size, size_t raw_size)
|
||||
{
|
||||
lzma_stream strm = LZMA_STREAM_INIT;
|
||||
lzma_ret xzret;
|
||||
lzma_options_lzma lzopts = {
|
||||
.dict_size = 1 << 16,
|
||||
.preset_dict = NULL,
|
||||
.preset_dict_size = 0,
|
||||
.lc = 3,
|
||||
.lp = 0,
|
||||
.pb = 2,
|
||||
.mode = LZMA_MODE_NORMAL,
|
||||
.nice_len = 64,
|
||||
.mf = LZMA_MF_BT4,
|
||||
.depth = 0,
|
||||
};
|
||||
lzma_filter fltrs[] = {
|
||||
{ .id = LZMA_FILTER_LZMA2, .options = &lzopts},
|
||||
{ .id = LZMA_VLI_UNKNOWN, .options = NULL}
|
||||
};
|
||||
|
||||
if (kernel_size < raw_size)
|
||||
grub_util_error (_("the core image is too small"));
|
||||
|
||||
xzret = lzma_stream_encoder (&strm, fltrs, LZMA_CHECK_NONE);
|
||||
if (xzret != LZMA_OK)
|
||||
grub_util_error (_("cannot compress the kernel image"));
|
||||
|
||||
*core_img = xmalloc (kernel_size);
|
||||
memcpy (*core_img, kernel_img, raw_size);
|
||||
|
||||
*core_size = kernel_size - raw_size;
|
||||
strm.next_in = (unsigned char *) kernel_img + raw_size;
|
||||
strm.avail_in = kernel_size - raw_size;
|
||||
strm.next_out = (unsigned char *) *core_img + raw_size;
|
||||
strm.avail_out = *core_size;
|
||||
|
||||
while (1)
|
||||
{
|
||||
xzret = lzma_code (&strm, LZMA_FINISH);
|
||||
if (xzret == LZMA_OK)
|
||||
continue;
|
||||
if (xzret == LZMA_STREAM_END)
|
||||
break;
|
||||
grub_util_error (_("cannot compress the kernel image"));
|
||||
}
|
||||
|
||||
*core_size -= strm.avail_out;
|
||||
|
||||
*core_size += raw_size;
|
||||
}
|
||||
#endif
|
||||
|
||||
static void
|
||||
compress_kernel (struct image_target_desc *image_target, char *kernel_img,
|
||||
size_t kernel_size, char **core_img, size_t *core_size)
|
||||
size_t kernel_size, char **core_img, size_t *core_size,
|
||||
grub_compression_t comp)
|
||||
{
|
||||
if (image_target->flags & PLATFORM_FLAGS_LZMA)
|
||||
{
|
||||
|
@ -504,6 +574,20 @@ compress_kernel (struct image_target_desc *image_target, char *kernel_img,
|
|||
return;
|
||||
}
|
||||
|
||||
#ifdef HAVE_LIBLZMA
|
||||
if (image_target->flags & PLATFORM_FLAGS_DECOMPRESSORS
|
||||
&& (comp == COMPRESSION_XZ))
|
||||
{
|
||||
compress_kernel_xz (kernel_img, kernel_size, core_img,
|
||||
core_size, image_target->raw_size);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (image_target->flags & PLATFORM_FLAGS_DECOMPRESSORS
|
||||
&& (comp != COMPRESSION_NONE))
|
||||
grub_util_error ("unknown compression %d\n", comp);
|
||||
|
||||
*core_img = xmalloc (kernel_size);
|
||||
memcpy (*core_img, kernel_img, kernel_size);
|
||||
*core_size = kernel_size;
|
||||
|
@ -527,7 +611,8 @@ struct fixup_block_list
|
|||
static void
|
||||
generate_image (const char *dir, char *prefix, FILE *out, char *mods[],
|
||||
char *memdisk_path, char *config_path,
|
||||
struct image_target_desc *image_target, int note)
|
||||
struct image_target_desc *image_target, int note,
|
||||
grub_compression_t comp)
|
||||
{
|
||||
char *kernel_img, *core_img;
|
||||
size_t kernel_size, total_module_size, core_size, exec_size;
|
||||
|
@ -539,6 +624,10 @@ generate_image (const char *dir, char *prefix, FILE *out, char *mods[],
|
|||
grub_uint64_t start_address;
|
||||
void *rel_section;
|
||||
grub_size_t reloc_size, align;
|
||||
|
||||
if (comp == COMPRESSION_AUTO)
|
||||
comp = image_target->default_compression;
|
||||
|
||||
path_list = grub_util_resolve_dependencies (dir, "moddep.lst", mods);
|
||||
|
||||
kernel_path = grub_util_get_path (dir, "kernel.img");
|
||||
|
@ -653,13 +742,19 @@ generate_image (const char *dir, char *prefix, FILE *out, char *mods[],
|
|||
offset += config_size;
|
||||
}
|
||||
|
||||
if ((image_target->flags & PLATFORM_FLAGS_DECOMPRESSORS)
|
||||
&& (image_target->total_module_size != TARGET_NO_FIELD))
|
||||
*((grub_uint32_t *) (kernel_img + image_target->total_module_size))
|
||||
= grub_host_to_target32 (total_module_size);
|
||||
|
||||
grub_util_info ("kernel_img=%p, kernel_size=0x%x", kernel_img, kernel_size);
|
||||
compress_kernel (image_target, kernel_img, kernel_size + total_module_size,
|
||||
&core_img, &core_size);
|
||||
&core_img, &core_size, comp);
|
||||
|
||||
grub_util_info ("the core size is 0x%x", core_size);
|
||||
|
||||
if (image_target->total_module_size != TARGET_NO_FIELD)
|
||||
if (!(image_target->flags & PLATFORM_FLAGS_DECOMPRESSORS)
|
||||
&& image_target->total_module_size != TARGET_NO_FIELD)
|
||||
*((grub_uint32_t *) (core_img + image_target->total_module_size))
|
||||
= grub_host_to_target32 (total_module_size);
|
||||
if (image_target->kernel_image_size != TARGET_NO_FIELD)
|
||||
|
@ -680,6 +775,53 @@ generate_image (const char *dir, char *prefix, FILE *out, char *mods[],
|
|||
= grub_host_to_target32 (-2);
|
||||
}
|
||||
|
||||
if (image_target->flags & PLATFORM_FLAGS_DECOMPRESSORS)
|
||||
{
|
||||
char *full_img;
|
||||
size_t full_size;
|
||||
char *decompress_path, *decompress_img;
|
||||
size_t decompress_size;
|
||||
const char *name;
|
||||
|
||||
switch (comp)
|
||||
{
|
||||
case COMPRESSION_XZ:
|
||||
name = "xz_decompress.img";
|
||||
break;
|
||||
case COMPRESSION_NONE:
|
||||
name = "none_decompress.img";
|
||||
break;
|
||||
default:
|
||||
grub_util_error ("unknown compression %d\n", comp);
|
||||
}
|
||||
|
||||
decompress_path = grub_util_get_path (dir, name);
|
||||
decompress_size = grub_util_get_image_size (decompress_path);
|
||||
decompress_img = grub_util_read_image (decompress_path);
|
||||
|
||||
*((grub_uint32_t *) (decompress_img + GRUB_KERNEL_MIPS_YEELOONG_COMPRESSED_SIZE))
|
||||
= grub_host_to_target32 (core_size);
|
||||
|
||||
*((grub_uint32_t *) (decompress_img + GRUB_KERNEL_MIPS_YEELOONG_UNCOMPRESSED_SIZE))
|
||||
= grub_host_to_target32 (kernel_size + total_module_size);
|
||||
|
||||
full_size = core_size + decompress_size;
|
||||
|
||||
full_img = xmalloc (full_size);
|
||||
memset (full_img, 0, full_size);
|
||||
|
||||
memcpy (full_img, decompress_img, decompress_size);
|
||||
|
||||
memcpy (full_img + decompress_size, core_img, core_size);
|
||||
|
||||
memset (full_img + decompress_size + core_size, 0,
|
||||
full_size - (decompress_size + core_size));
|
||||
|
||||
free (core_img);
|
||||
core_img = full_img;
|
||||
core_size = full_size;
|
||||
}
|
||||
|
||||
switch (image_target->id)
|
||||
{
|
||||
case IMAGE_I386_PC:
|
||||
|
@ -1218,6 +1360,7 @@ static struct option options[] =
|
|||
{"output", required_argument, 0, 'o'},
|
||||
{"note", no_argument, 0, 'n'},
|
||||
{"format", required_argument, 0, 'O'},
|
||||
{"compression", required_argument, 0, 'C'},
|
||||
{"help", no_argument, 0, 'h'},
|
||||
{"version", no_argument, 0, 'V'},
|
||||
{"verbose", no_argument, 0, 'v'},
|
||||
|
@ -1260,6 +1403,7 @@ Make a bootable image of GRUB.\n\
|
|||
-o, --output=FILE output a generated image to FILE [default=stdout]\n\
|
||||
-O, --format=FORMAT generate an image in format\n\
|
||||
available formats: %s\n\
|
||||
-C, --compression=(xz|none|auto) choose the compression to use\n\
|
||||
-h, --help display this message and exit\n\
|
||||
-V, --version print version information and exit\n\
|
||||
-v, --verbose print verbose messages\n\
|
||||
|
@ -1286,6 +1430,7 @@ main (int argc, char *argv[])
|
|||
FILE *fp = stdout;
|
||||
int note = 0;
|
||||
struct image_target_desc *image_target = NULL;
|
||||
grub_compression_t comp = COMPRESSION_AUTO;
|
||||
|
||||
set_program_name (argv[0]);
|
||||
|
||||
|
@ -1293,7 +1438,7 @@ main (int argc, char *argv[])
|
|||
|
||||
while (1)
|
||||
{
|
||||
int c = getopt_long (argc, argv, "d:p:m:c:o:O:f:hVvn", options, 0);
|
||||
int c = getopt_long (argc, argv, "d:p:m:c:o:O:f:C:hVvn", options, 0);
|
||||
|
||||
if (c == -1)
|
||||
break;
|
||||
|
@ -1350,6 +1495,22 @@ main (int argc, char *argv[])
|
|||
config = xstrdup (optarg);
|
||||
break;
|
||||
|
||||
case 'C':
|
||||
if (grub_strcmp (optarg, "xz") == 0)
|
||||
{
|
||||
#ifdef HAVE_LIBLZMA
|
||||
comp = COMPRESSION_XZ;
|
||||
#else
|
||||
grub_util_error ("grub-mkimage is compiled without XZ support",
|
||||
optarg);
|
||||
#endif
|
||||
}
|
||||
else if (grub_strcmp (optarg, "none") == 0)
|
||||
comp = COMPRESSION_NONE;
|
||||
else
|
||||
grub_util_error ("Unknown compression format %s", optarg);
|
||||
break;
|
||||
|
||||
case 'h':
|
||||
usage (0);
|
||||
break;
|
||||
|
@ -1408,7 +1569,7 @@ main (int argc, char *argv[])
|
|||
|
||||
generate_image (dir, prefix ? : DEFAULT_DIRECTORY, fp,
|
||||
argv + optind, memdisk, config,
|
||||
image_target, note);
|
||||
image_target, note, comp);
|
||||
|
||||
fclose (fp);
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue