diff --git a/font/font.c b/font/font.c index a81291916..a6cdf3c93 100644 --- a/font/font.c +++ b/font/font.c @@ -17,7 +17,6 @@ * along with GRUB. If not, see . */ -#include #include #include #include @@ -374,25 +373,12 @@ read_section_as_short (struct font_file_section *section, grub_int16_t *value) /* Load a font and add it to the beginning of the global font list. Returns 0 upon success, nonzero upon failure. */ int -grub_font_load (const char *filename) +grub_font_load (grub_file_t file) { - grub_file_t file = 0; struct font_file_section section; char magic[4]; grub_font_t font = 0; -#if FONT_DEBUG >= 1 - grub_printf("add_font(%s)\n", filename); -#endif - - file = grub_buffile_open (filename, 1024); - if (!file) - goto fail; - -#if FONT_DEBUG >= 3 - grub_printf("file opened\n"); -#endif - /* Read the FILE section. It indicates the file format. */ if (open_section (file, §ion) != 0) goto fail; diff --git a/font/font_cmd.c b/font/font_cmd.c index 0402b8d77..8b9817409 100644 --- a/font/font_cmd.c +++ b/font/font_cmd.c @@ -17,10 +17,13 @@ * along with GRUB. If not, see . */ +#include #include #include #include #include +#include +#include static grub_err_t loadfont_command (grub_command_t cmd __attribute__ ((unused)), @@ -31,8 +34,16 @@ loadfont_command (grub_command_t cmd __attribute__ ((unused)), return grub_error (GRUB_ERR_BAD_ARGUMENT, "no font specified"); while (argc--) - if (grub_font_load (*args++) != 0) - return GRUB_ERR_BAD_FONT; + { + grub_file_t file = 0; + + file = grub_buffile_open (*args++, 1024); + if (!file) + return grub_errno; + + if (grub_font_load (file) != 0) + return GRUB_ERR_BAD_FONT; + } return GRUB_ERR_NONE; } @@ -54,12 +65,67 @@ lsfonts_command (grub_command_t cmd __attribute__ ((unused)), return GRUB_ERR_NONE; } +static grub_ssize_t +pseudo_file_read (struct grub_file *file, char *buf, grub_size_t len) +{ + grub_memcpy (buf, (char *) file->data + file->offset, len); + return len; +} + +static grub_err_t +pseudo_file_close (struct grub_file *file) +{ + grub_free (file->data); + file->data = 0; + return GRUB_ERR_NONE; +} + + +/* Filesystem descriptor. */ +static struct grub_fs pseudo_fs = +{ + .name = "Font Loader", + .read = pseudo_file_read, + .close = pseudo_file_close +}; + + +static int +load_font_module (struct grub_module_header *header) +{ + grub_file_t file; + if (header->type != OBJ_TYPE_FONT) + return 0; + + file = grub_malloc (sizeof (*file)); + + file->read_hook = 0; + + file->offset = 0; + file->size = header->size - sizeof (struct grub_module_header); + file->data = grub_malloc (header->size - sizeof (struct grub_module_header)); + if (!file->data) + return 0; + grub_memcpy (file->data, (char *) header + sizeof (struct grub_module_header), + file->size); + + file->device = 0; + file->fs = &pseudo_fs; + + grub_font_load (file); + + return 0; +} + + static grub_command_t cmd_loadfont, cmd_lsfonts; GRUB_MOD_INIT(font_manager) { grub_font_loader_init (); + grub_module_iterate (load_font_module); + cmd_loadfont = grub_register_command ("loadfont", loadfont_command, "loadfont FILE...", diff --git a/include/grub/font.h b/include/grub/font.h index 8a5f3ac7d..2129c30b3 100644 --- a/include/grub/font.h +++ b/include/grub/font.h @@ -21,6 +21,7 @@ #include #include +#include /* Forward declaration of opaque structure grub_font. Users only pass struct grub_font pointers to the font module functions, @@ -74,7 +75,7 @@ void grub_font_loader_init (void); /* Load a font and add it to the beginning of the global font list. Returns: 0 upon success; nonzero upon failure. */ -int grub_font_load (const char *filename); +int grub_font_load (grub_file_t file); /* Get the font that has the specified name. Font names are in the form "Family Name Bold Italic 14", where Bold and Italic are optional. diff --git a/include/grub/kernel.h b/include/grub/kernel.h index 75ec77c2a..9586a90b9 100644 --- a/include/grub/kernel.h +++ b/include/grub/kernel.h @@ -26,7 +26,8 @@ enum { OBJ_TYPE_ELF, OBJ_TYPE_MEMDISK, - OBJ_TYPE_CONFIG + OBJ_TYPE_CONFIG, + OBJ_TYPE_FONT }; /* The module header. */ diff --git a/util/grub-mkrawimage.c b/util/grub-mkrawimage.c index 2097cefeb..5005afd1f 100644 --- a/util/grub-mkrawimage.c +++ b/util/grub-mkrawimage.c @@ -93,7 +93,7 @@ compress_kernel (char *kernel_img, size_t kernel_size, static void generate_image (const char *dir, char *prefix, FILE *out, char *mods[], - char *memdisk_path, char *config_path, + char *memdisk_path, char *font_path, char *config_path, #ifdef GRUB_PLATFORM_IMAGE_DEFAULT grub_platform_image_format_t format #else @@ -104,7 +104,7 @@ generate_image (const char *dir, char *prefix, FILE *out, char *mods[], { char *kernel_img, *core_img; size_t kernel_size, total_module_size, core_size; - size_t memdisk_size = 0, config_size = 0; + size_t memdisk_size = 0, font_size = 0, config_size = 0; char *kernel_path; size_t offset; struct grub_util_path_list *path_list, *p, *next; @@ -124,6 +124,12 @@ generate_image (const char *dir, char *prefix, FILE *out, char *mods[], total_module_size += memdisk_size + sizeof (struct grub_module_header); } + if (font_path) + { + font_size = ALIGN_UP(grub_util_get_image_size (font_path), 4); + total_module_size += font_size + sizeof (struct grub_module_header); + } + if (config_path) { config_size = grub_util_get_image_size (config_path) + 1; @@ -183,6 +189,20 @@ generate_image (const char *dir, char *prefix, FILE *out, char *mods[], offset += memdisk_size; } + if (font_path) + { + struct grub_module_header *header; + + header = (struct grub_module_header *) (kernel_img + offset); + memset (header, 0, sizeof (struct grub_module_header)); + header->type = OBJ_TYPE_FONT; + header->size = grub_host_to_target32 (font_size + sizeof (*header)); + offset += sizeof (*header); + + grub_util_load_image (font_path, kernel_img + offset); + offset += font_size; + } + if (config_path) { struct grub_module_header *header; @@ -339,7 +359,10 @@ generate_image (const char *dir, char *prefix, FILE *out, char *mods[], phdr->p_flags = grub_host_to_target32 (PF_R | PF_W | PF_X); target_addr = ALIGN_UP (GRUB_KERNEL_MACHINE_LINK_ADDR - + kernel_size + total_module_size, 32); + + kernel_size + total_module_size + + 0x100000 + // + BSS_SIZE + , 32); ehdr->e_entry = grub_host_to_target32 (target_addr); phdr->p_vaddr = grub_host_to_target32 (target_addr); phdr->p_paddr = grub_host_to_target32 (target_addr); @@ -376,10 +399,11 @@ static struct option options[] = {"directory", required_argument, 0, 'd'}, {"prefix", required_argument, 0, 'p'}, {"memdisk", required_argument, 0, 'm'}, + {"font", required_argument, 0, 'f'}, {"config", required_argument, 0, 'c'}, {"output", required_argument, 0, 'o'}, #ifdef GRUB_PLATFORM_IMAGE_DEFAULT - {"format", required_argument, 0, 'f'}, + {"format", required_argument, 0, 'O'}, #endif {"help", no_argument, 0, 'h'}, {"version", no_argument, 0, 'V'}, @@ -401,11 +425,12 @@ Make a bootable image of GRUB.\n\ -d, --directory=DIR use images and modules under DIR [default=%s]\n\ -p, --prefix=DIR set grub_prefix directory [default=%s]\n\ -m, --memdisk=FILE embed FILE as a memdisk image\n\ + -f, --font=FILE embed FILE as a boot font\n\ -c, --config=FILE embed FILE as boot config\n\ -o, --output=FILE output a generated image to FILE [default=stdout]\n" #ifdef GRUB_PLATFORM_IMAGE_DEFAULT "\ - -f, --format=FORMAT generate an image in format [default=" + -O, --format=FORMAT generate an image in format [default=" GRUB_PLATFORM_IMAGE_DEFAULT_FORMAT "]\n \ available formats: " GRUB_PLATFORM_IMAGE_FORMATS "\n" @@ -428,6 +453,7 @@ main (int argc, char *argv[]) char *dir = NULL; char *prefix = NULL; char *memdisk = NULL; + char *font = NULL; char *config = NULL; FILE *fp = stdout; #ifdef GRUB_PLATFORM_IMAGE_DEFAULT @@ -438,7 +464,7 @@ main (int argc, char *argv[]) while (1) { - int c = getopt_long (argc, argv, "d:p:m:c:o:f:hVv", options, 0); + int c = getopt_long (argc, argv, "d:p:m:c:o:O:f:hVv", options, 0); if (c == -1) break; @@ -453,7 +479,7 @@ main (int argc, char *argv[]) break; #ifdef GRUB_PLATFORM_IMAGE_DEFAULT - case 'f': + case 'O': #ifdef GRUB_PLATFORM_IMAGE_RAW if (strcmp (optarg, "raw") == 0) format = GRUB_PLATFORM_IMAGE_RAW; @@ -487,6 +513,13 @@ main (int argc, char *argv[]) prefix = xstrdup ("(memdisk)/boot/grub"); break; + case 'f': + if (font) + free (font); + + font = xstrdup (optarg); + break; + case 'c': if (config) free (config); @@ -528,7 +561,7 @@ main (int argc, char *argv[]) } generate_image (dir ? : GRUB_LIBDIR, prefix ? : DEFAULT_DIRECTORY, fp, - argv + optind, memdisk, config, + argv + optind, memdisk, font, config, #ifdef GRUB_PLATFORM_IMAGE_DEFAULT format #else