diff options
author | Bill Richardson <wfrichar@chromium.org> | 2011-08-22 16:03:59 -0700 |
---|---|---|
committer | Bill Richardson <wfrichar@chromium.org> | 2011-08-24 09:27:12 -0700 |
commit | 0a9977e161ce6ad6b11935dfb05ae840bf758078 (patch) | |
tree | b3ec3bf4e7b17dad7b9c0a6ec9f8b2d1aec75fd7 | |
parent | efea801390caff45c2ef6083fde5f253f03bc395 (diff) | |
download | vboot-0a9977e161ce6ad6b11935dfb05ae840bf758078.tar.gz |
bmpblock v1.2 - render HWID inside vboot_reference
The vboot_api.h doesn't require the BIOS display the ASCII HWID in
a graphical form (ARM U-Boot doesn't know how), so we have to do it
ourselves. This change makes that possible.
Summary of changes:
* bmpblk_font.h defines a structure to map ASCII chars to BMPs
* bmpblk_font utility generates that font structure
* bmpblock format is bumped to version 1.2
- YAML file specifies font to use for $HWID
- make_default_yaml updated to emit the new format
- README updated to describe the difference
BUG=chromium-os:18631
TEST=manual
I've tested this on ARM, like so:
Inside the chroot, build a U-Boot that uses it:
emerge-tegra2_kaen vboot_reference vboot_reference-firmware
emerge-tegra2_kaen tegra-bct tegra2-public-firmware-fdts \
chromeos-u-boot chromeos-bootimage
Outside chroot, but in src/platform/vboot_reference:
make
<copy ./build/utility/bmpblk_font and ./build/utility/bmpblk_utility to
somewhere in your $PATH>
make clean
cd scripts/newbitmaps/fonts
bmpblk_font --outfile ../images/hwid_fonts.bin outdir/*
cd scripts/newbitmaps/images
make arm
cd out_arm
<edit DEFAULT.yaml>
bmpblk_utility -z 2 -c DEFAULT.yaml arm_bmpblock.bin
<use gbb_utility to replace the bitmaps in the U-Boot image, boot it>
The HWID string is displayed.
Change-Id: I782004a0f30c57fa1f3bb246e8c59a02c5e9f561
Reviewed-on: http://gerrit.chromium.org/gerrit/6544
Reviewed-by: Bill Richardson <wfrichar@chromium.org>
Tested-by: Bill Richardson <wfrichar@chromium.org>
-rw-r--r-- | firmware/include/bmpblk_header.h | 3 | ||||
-rw-r--r-- | firmware/lib/include/bmpblk_font.h | 65 | ||||
-rw-r--r-- | firmware/lib/vboot_display.c | 215 | ||||
-rw-r--r-- | scripts/newbitmaps/README | 25 | ||||
-rwxr-xr-x | scripts/newbitmaps/fonts/make_ascii_bmps.py | 87 | ||||
-rw-r--r-- | scripts/newbitmaps/images/DEFAULT.yaml | 6 | ||||
-rw-r--r-- | scripts/newbitmaps/images/Makefile | 32 | ||||
-rw-r--r-- | scripts/newbitmaps/images/hwid_fonts.bin | bin | 0 -> 66136 bytes | |||
-rwxr-xr-x | scripts/newbitmaps/images/make_default_yaml | 8 | ||||
-rwxr-xr-x | scripts/newbitmaps/lib/bmpblock.py | 11 | ||||
-rw-r--r-- | utility/Makefile | 13 | ||||
-rw-r--r-- | utility/bmpblk_font.c | 227 | ||||
-rw-r--r-- | utility/bmpblk_util.c | 33 | ||||
-rw-r--r-- | utility/bmpblk_utility.cc | 105 | ||||
-rw-r--r-- | utility/image_types.c | 71 | ||||
-rw-r--r-- | utility/include/bmpblk_utility.h | 8 | ||||
-rw-r--r-- | utility/include/image_types.h | 25 |
17 files changed, 798 insertions, 136 deletions
diff --git a/firmware/include/bmpblk_header.h b/firmware/include/bmpblk_header.h index 9d42123a..c99f0fe3 100644 --- a/firmware/include/bmpblk_header.h +++ b/firmware/include/bmpblk_header.h @@ -54,7 +54,7 @@ __pragma(pack(push, 1)) /* Support packing for MSVC. */ #define BMPBLOCK_SIGNATURE_SIZE (4) #define BMPBLOCK_MAJOR_VERSION (0x0001) -#define BMPBLOCK_MINOR_VERSION (0x0001) +#define BMPBLOCK_MINOR_VERSION (0x0002) #define MAX_IMAGE_IN_LAYOUT (8) @@ -118,6 +118,7 @@ typedef enum ImageTag { typedef enum ImageFormat { FORMAT_INVALID = 0, FORMAT_BMP, + FORMAT_FONT, } ImageFormat; /* Constants for ImageInfo.compression */ diff --git a/firmware/lib/include/bmpblk_font.h b/firmware/lib/include/bmpblk_font.h new file mode 100644 index 00000000..1ffaefda --- /dev/null +++ b/firmware/lib/include/bmpblk_font.h @@ -0,0 +1,65 @@ +/* Copyright (c) 2011 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + * + * This describes the internal format used to pack a set of character glpyhs so + * we can render strings by drawing one character at a time. + * + * The format is this: + * + * +-------------------------+ + * | FontArrayHeader | + * +-------------------------+ + * | FontArrayEntryHeader[0] | + * +-------------------------+ + * | raw image data[0] | + * +-------------------------+ + * | FontArrayEntryHeader[1] | + * +-------------------------+ + * | raw image data[1] | + * +-------------------------+ + * | FontArrayEntryHeader[2] | + * +-------------------------+ + * | raw image data[2] | + * +-------------------------+ + * ... + * +-------------------------+ + * | FontArrayEntryHeader[n] | + * +-------------------------+ + * | raw image data[n] | + * +-------------------------+ + * + * The FontArrayHeader describes how many characters will be encoded. + * Each character encoding consists of a FontArrayEntryHeader followed + * immediately by the raw image data for that character. + */ + +#ifndef VBOOT_REFERENCE_BMPBLK_FONT_H_ +#define VBOOT_REFERENCE_BMPBLK_FONT_H_ + +#include "bmpblk_header.h" + +__pragma(pack(push, 1)) /* Support packing for MSVC. */ + +#define FONT_SIGNATURE "FONT" +#define FONT_SIGNATURE_SIZE 4 + +typedef struct FontArrayHeader { + uint8_t signature[FONT_SIGNATURE_SIZE]; + uint32_t num_entries; /* Number of chars encoded here. */ +} __attribute__((packed)) FontArrayHeader; + +typedef struct FontArrayEntryHeader { + uint32_t ascii; /* What to show. Could even be UTF? */ + ImageInfo info; /* Describes the bitmap. */ + /* The image to use follows immediately, NOT compressed. It's uncompressed + * because each glyph is only a few hundred bytes, but they have much in + * common (colormaps, for example). When we add the whole font blob to the + * bmpblk, it will be compressed as a single item there. + */ +} __attribute__((packed)) FontArrayEntryHeader; + + +__pragma(pack(pop)) /* Support packing for MSVC. */ + +#endif /* VBOOT_REFERENCE_BMPBLK_FONT_H_ */ diff --git a/firmware/lib/vboot_display.c b/firmware/lib/vboot_display.c index 179bf7ba..9ee9419e 100644 --- a/firmware/lib/vboot_display.c +++ b/firmware/lib/vboot_display.c @@ -5,6 +5,7 @@ * Display functions used in kernel selection. */ +#include "bmpblk_font.h" #include "gbb_header.h" #include "utility.h" #include "vboot_api.h" @@ -48,21 +49,131 @@ static VbError_t VbGetLocalizationCount(VbCommonParams* cparams, +/* Return a fixed string representing the HWID */ +static char *VbHWID(VbCommonParams* cparams) { + GoogleBinaryBlockHeader* gbb = (GoogleBinaryBlockHeader*)cparams->gbb_data; + if (0 == gbb->hwid_size || + gbb->hwid_offset > cparams->gbb_size || + gbb->hwid_offset + gbb->hwid_size > cparams->gbb_size) { + VBDEBUG(("VbHWID(): invalid hwid offset/size\n")); + return "{INVALID}"; + } + return (char*)((uint8_t*)gbb + gbb->hwid_offset); +} + + +/* TODO: We could cache the font info to speed things up, by making the + * in-memory font structure distinct from the in-flash version. We'll do that + * Real Soon Now. Until then, we just repeat the same linear search every time. + */ +typedef FontArrayHeader VbFont_t; + +static VbFont_t *VbInternalizeFontData(FontArrayHeader *fonthdr) { + /* Just return the raw data pointer for now. */ + return (VbFont_t *)fonthdr; +} + +static void VbDoneWithFontForNow(VbFont_t *ptr) { + /* Nothing. */ +} + +static ImageInfo *VbFindFontGlyph(VbFont_t *font, uint32_t ascii, + void **bufferptr, uint32_t *buffersize) { + uint8_t *ptr, *firstptr; + uint32_t max; + uint32_t i; + FontArrayEntryHeader *entry; + + ptr = (uint8_t *)font; + max = ((FontArrayHeader *)ptr)->num_entries; + ptr += sizeof(FontArrayHeader); + firstptr = ptr; + + /* Simple linear search. */ + for(i=0; i<max; i++) + { + entry = (FontArrayEntryHeader *)ptr; + if (entry->ascii == ascii) { + /* Note: We're assuming the glpyh is uncompressed. That's true + * because the bmpblk_font tool doesn't compress anything. The + * bmpblk_utility does, but it compresses the entire font blob at once, + * and we've already uncompressed that before we got here. + */ + *bufferptr = ptr + sizeof(FontArrayEntryHeader); + *buffersize = entry->info.original_size; + return &(entry->info); + } + ptr += sizeof(FontArrayEntryHeader)+entry->info.compressed_size; + } + + /* NOTE: We must return something valid. We'll just use the first glyph in the + * font structure (so it should be something distinct). + */ + entry = (FontArrayEntryHeader *)firstptr; + *bufferptr = firstptr + sizeof(FontArrayEntryHeader); + *buffersize = entry->info.original_size; + return &(entry->info); +} + +/* Try to display the specified text at a particular position. */ +static void VbRenderTextAtPos(char *text, int right_to_left, + uint32_t x, uint32_t y, VbFont_t *font) { + int i; + ImageInfo *image_info = 0; + void *buffer; + uint32_t buffersize; + uint32_t cur_x = x, cur_y = y; + + if (!text || !font) { + VBDEBUG((" VbRenderTextAtPos: invalid args\n")); + return; + } + + for (i=0; text[i]; i++) { + + if (text[i] == '\n') { + if (!image_info) + image_info = VbFindFontGlyph(font, text[i], &buffer, &buffersize); + cur_x = x; + cur_y += image_info->height; + continue; + } + + image_info = VbFindFontGlyph(font, text[i], &buffer, &buffersize); + + if (right_to_left) { + cur_x -= image_info->width; + } + + if (VBERROR_SUCCESS != VbExDisplayImage(cur_x, cur_y, buffer, buffersize)) { + VBDEBUG((" VbRenderTextAtPos: can't display ascii 0x%x\n", text[i])); + } + + if (!right_to_left) { + cur_x += image_info->width; + } + } +} + + /* Display a screen from the GBB. */ VbError_t VbDisplayScreenFromGBB(VbCommonParams* cparams, uint32_t screen, VbNvContext *vncptr) { GoogleBinaryBlockHeader* gbb = (GoogleBinaryBlockHeader*)cparams->gbb_data; uint8_t* bmpfv = NULL; - uint8_t* fullimage = NULL; + void* fullimage = NULL; BmpBlockHeader* hdr; ScreenLayout* layout; ImageInfo* image_info; uint32_t screen_index; uint32_t localization = 0; - VbError_t retval = VBERROR_UNKNOWN; /* Assume error until proven ok */ + VbError_t retval = VBERROR_UNKNOWN; /* Assume error until proven ok */ uint32_t inoutsize; uint32_t offset; uint32_t i; + VbFont_t *font; + char *text_to_show; + int rtol = 0; /* Make sure the bitmap data is inside the GBB and is non-zero in size */ if (0 == gbb->bmpfv_size || @@ -93,26 +204,26 @@ VbError_t VbDisplayScreenFromGBB(VbCommonParams* cparams, uint32_t screen, /* TODO: ensure screen IDs match indices? Having this translation * here is awful. */ switch (screen) { - case VB_SCREEN_DEVELOPER_WARNING: - screen_index = 0; - break; - case VB_SCREEN_RECOVERY_REMOVE: - screen_index = 1; - break; - case VB_SCREEN_RECOVERY_NO_GOOD: - screen_index = 2; - break; - case VB_SCREEN_RECOVERY_INSERT: - screen_index = 3; - break; - case VB_SCREEN_BLANK: - case VB_SCREEN_DEVELOPER_EGG: - default: - /* Screens which aren't in the GBB */ - VBDEBUG(("VbDisplayScreenFromGBB(): screen %d not in the GBB\n", - (int)screen)); - retval = VBERROR_INVALID_SCREEN_INDEX; - goto VbDisplayScreenFromGBB_exit; + case VB_SCREEN_DEVELOPER_WARNING: + screen_index = 0; + break; + case VB_SCREEN_RECOVERY_REMOVE: + screen_index = 1; + break; + case VB_SCREEN_RECOVERY_NO_GOOD: + screen_index = 2; + break; + case VB_SCREEN_RECOVERY_INSERT: + screen_index = 3; + break; + case VB_SCREEN_BLANK: + case VB_SCREEN_DEVELOPER_EGG: + default: + /* Screens which aren't in the GBB */ + VBDEBUG(("VbDisplayScreenFromGBB(): screen %d not in the GBB\n", + (int)screen)); + retval = VBERROR_INVALID_SCREEN_INDEX; + goto VbDisplayScreenFromGBB_exit; } if (screen_index >= hdr->number_of_screenlayouts) { VBDEBUG(("VbDisplayScreenFromGBB(): screen %d index %d not in the GBB\n", @@ -131,10 +242,8 @@ VbError_t VbDisplayScreenFromGBB(VbCommonParams* cparams, uint32_t screen, /* Calculate offset of screen layout = start of screen stuff + * correct locale + correct screen. */ offset = sizeof(BmpBlockHeader) + - localization * hdr->number_of_screenlayouts * sizeof(ScreenLayout) + - screen_index * sizeof(ScreenLayout); - VBDEBUG(("VbDisplayScreenFromGBB(): scr_%d_%d at offset 0x%x\n", - localization, screen_index, offset)); + localization * hdr->number_of_screenlayouts * sizeof(ScreenLayout) + + screen_index * sizeof(ScreenLayout); layout = (ScreenLayout*)(bmpfv + offset); /* Display all bitmaps for the image */ @@ -142,15 +251,10 @@ VbError_t VbDisplayScreenFromGBB(VbCommonParams* cparams, uint32_t screen, if (layout->images[i].image_info_offset) { offset = layout->images[i].image_info_offset; image_info = (ImageInfo*)(bmpfv + offset); - VBDEBUG(("VbDisplayScreenFromGBB: image %d: %dx%d+%d+%d %d/%d" - "tag %d at 0x%x\n", - i, image_info->width, image_info->height, - layout->images[i].x, layout->images[i].y, - image_info->compressed_size, image_info->original_size, - image_info->tag, offset)); - if (COMPRESS_NONE != image_info->compression) { - inoutsize = image_info->original_size; - fullimage = (uint8_t*)VbExMalloc(inoutsize); + fullimage = bmpfv + offset + sizeof(ImageInfo); + inoutsize = image_info->original_size; + if (inoutsize && image_info->compression != COMPRESS_NONE) { + fullimage = VbExMalloc(inoutsize); retval = VbExDecompress(bmpfv + offset + sizeof(ImageInfo), image_info->compressed_size, image_info->compression, @@ -159,16 +263,45 @@ VbError_t VbDisplayScreenFromGBB(VbCommonParams* cparams, uint32_t screen, VbExFree(fullimage); goto VbDisplayScreenFromGBB_exit; } + } + + switch(image_info->format) { + case FORMAT_BMP: retval = VbExDisplayImage(layout->images[i].x, layout->images[i].y, fullimage, inoutsize); - VbExFree(fullimage); - } else { - retval = VbExDisplayImage(layout->images[i].x, layout->images[i].y, - bmpfv + offset + sizeof(ImageInfo), - image_info->original_size); + break; + + case FORMAT_FONT: + /* The uncompressed blob is our font structure. Cache it as needed. */ + font = VbInternalizeFontData(fullimage); + + /* TODO: handle text in general here */ + if (TAG_HWID == image_info->tag || TAG_HWID_RTOL == image_info->tag) { + text_to_show = VbHWID(cparams); + rtol = (TAG_HWID_RTOL == image_info->tag); + } else { + text_to_show = ""; + rtol = 0; + } + + VbRenderTextAtPos(text_to_show, rtol, + layout->images[i].x, layout->images[i].y, font); + + VbDoneWithFontForNow(font); + break; + + default: + VBDEBUG(("VbDisplayScreenFromGBB(): unsupported ImageFormat %d\n", + image_info->format)); + retval = VBERROR_INVALID_GBB; } + + if (COMPRESS_NONE != image_info->compression) + VbExFree(fullimage); + if (VBERROR_SUCCESS != retval) goto VbDisplayScreenFromGBB_exit; + } } @@ -189,8 +322,6 @@ VbError_t VbDisplayScreen(VbCommonParams* cparams, uint32_t screen, int force, VbNvContext *vncptr) { VbError_t retval; - VBDEBUG(("VbDisplayScreen(%d, %d)\n", (int)screen, force)); - /* Initialize display if necessary */ if (!disp_width) { retval = VbExDisplayInit(&disp_width, &disp_height); diff --git a/scripts/newbitmaps/README b/scripts/newbitmaps/README index 5a23eaf6..728d42f2 100644 --- a/scripts/newbitmaps/README +++ b/scripts/newbitmaps/README @@ -49,6 +49,31 @@ last-displayed locale is stored in nvram, so it's sticky across reboots. The factory process sets the default locale to the appropriate region. +Version 1.2. Used by any BIOS that uses "vboot_api.h" + +The "vboot wrapper" is a refactoring of the vboot_reference library to +isolate our verified boot stuff from the underlying BIOS. Among other +things, it places the burden of displaying the ASCII HWID value on the +vboot_reference library, which means the bmpblock must contain a "font" to +translate the ASCII characters in the HWID into graphical images. The yaml +file must now specify a font file for the $HWID (and $HWID.rtol, if used) +image name. For example: + + bmpblock: 1.2 + images: + $HWID: font.bin # THIS IS NOW REQUIRED WHEN USING $HWID + screens: + scr_0_0: + - [ 0, 0, $HWID] + localizations: + - [ scr_0_0, scr_0_0, scr_0_0, scr_0_0 ] + locale_index: + en + +The old v1.1 bmpblock will be accepted by the vboot wrapper, but a $HWID +screen without a corresponding font will be silently ignored. + + Instructions: diff --git a/scripts/newbitmaps/fonts/make_ascii_bmps.py b/scripts/newbitmaps/fonts/make_ascii_bmps.py new file mode 100755 index 00000000..df6083e1 --- /dev/null +++ b/scripts/newbitmaps/fonts/make_ascii_bmps.py @@ -0,0 +1,87 @@ +#!/usr/bin/python -tt +# Copyright (c) 2011 The Chromium OS Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +import optparse +import os +import subprocess +import sys +import tempfile + +chars = '* 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ{}-_' + +def main(): + """Convert a set of text chars into individual BMPs. + + This uses ImageMagick, so don't run it inside the build chroot. + Not all characters in the world are supported. + """ + + parser = optparse.OptionParser() + parser.description = ' '.join(main.__doc__.split()) + parser.add_option("--foreground", default='#9ccaec', + dest="fg", action="store", metavar="COLOR", + help="foreground color (%default)") + parser.add_option("--background", default='#607c91', + dest="bg", action="store", metavar="COLOR", + help="background color (%default)") + parser.add_option("--font", default='Helvetica', + dest="font", action="store", + help="font to use (%default)") + parser.add_option("--size", default='22', metavar="POINTSIZE", + dest="size", action="store", + help="font size (%default)") + parser.add_option('--dir', default='./outdir', + dest="outdir", action="store", + help="output directory (%default)") + (options, args) = parser.parse_args() + + + if not os.path.isdir(options.outdir): + os.mkdir(options.outdir) + + # ARM U-Boot is very picky about its BMPs. They have to have exactly 256 + # colors in their colormap. Imagemagick generally tries to reduce the + # colormap when it can, so we have to play some games to force it not to. + # We'll create a gradient file with 256 colors, and then make sure that all + # our rendered characters use the same colormap. This makes the resulting + # images larger, but it also means they'll work on x86 too. Sigh. + (handle, gradient_file) = tempfile.mkstemp(".png") + os.close(handle) + + cmd = ('convert', '-size', '256x1', + 'gradient:%s-%s' % (options.fg, options.bg), + gradient_file) + print ' '.join(cmd) + subprocess.call(cmd) + + + count=0 + for ascii in chars: + outfile = os.path.join(options.outdir, + "idx%03d_%x.bmp" % (count,ord(ascii))) + print outfile + cmd = ('convert', + '-font', options.font, + '-background', options.bg, + '-fill', options.fg, + '-bordercolor', options.bg, + '-border', '0x3', + '-gravity', 'Center', + '-pointsize', options.size, + 'label:%s' % ascii, + '-remap', gradient_file, + '-compress', 'none', + '-alpha', 'off', + outfile) + print ' '.join(cmd) + count += 1 + subprocess.call(cmd) + + os.unlink(gradient_file) + + +# Start it all off +if __name__ == '__main__': + main() diff --git a/scripts/newbitmaps/images/DEFAULT.yaml b/scripts/newbitmaps/images/DEFAULT.yaml index 3aa9677c..fa5269ea 100644 --- a/scripts/newbitmaps/images/DEFAULT.yaml +++ b/scripts/newbitmaps/images/DEFAULT.yaml @@ -1,11 +1,11 @@ -bmpblock: 1.1 +bmpblock: 1.2 compression: 1 images: - # The HWID must change for every BOM - # $HWID: hwid_unknown.bmp + # We must specify a font blob to use to render the HWID + $HWID: hwid_fonts.bin # This URL never changes url: Url.bmp diff --git a/scripts/newbitmaps/images/Makefile b/scripts/newbitmaps/images/Makefile index b026ef56..fe2be482 100644 --- a/scripts/newbitmaps/images/Makefile +++ b/scripts/newbitmaps/images/Makefile @@ -14,6 +14,7 @@ TARGETS=x86 arm BASE_IMAGES=Devmode.bmp Insert.bmp Remove.bmp Yuck.bmp OTHER_IMAGES=Url.bmp hwid_unknown.bmp +FONTS=hwid_fonts.bin default: outside_chroot @echo "Specify a target to build for:" @@ -36,6 +37,8 @@ ${TARGETS}:: outside_chroot # those, so let's just assume 16:9 for future platforms to make things simpler. _x86_max="800x600!" _x86_scale="59%x78%" +_arm_max="800x600!" +_arm_scale="59%x78%" x86:: # create output directories @@ -43,6 +46,8 @@ x86:: for i in localized_images/*; do \ mkdir -p "out_$@/$$i"; \ done + # copy stuff we need + cp "${FONTS}" "out_$@" # scale the background pictures exactly for i in ${BASE_IMAGES}; do \ convert $$i -scale "${_x86_max}" "out_$@/$$i"; \ @@ -58,7 +63,32 @@ x86:: arm:: - echo "Not sure what to do here. Please fix me." + # create output directories + mkdir -p "out_$@" + for i in localized_images/*; do \ + mkdir -p "out_$@/$$i"; \ + done + # copy stuff we need + cp "${FONTS}" "out_$@" + convert ${BASE_IMAGES} -append \ + -colors 256 -unique-colors "out_$@/base_cmap.png" + convert localized_images/*/*.bmp -append \ + -colors 256 -unique-colors "out_$@/loc_cmap.png" + # scale the background pictures exactly + for i in ${BASE_IMAGES}; do \ + convert $$i -scale "${_arm_max}" \ + -remap "out_$@/base_cmap.png" "out_$@/$$i"; \ + done + # scale the localized string images using percentages + for i in ${OTHER_IMAGES} localized_images/*/*.bmp; do \ + convert $$i -scale "${_arm_scale}" \ + -remap "out_$@/loc_cmap.png" "out_$@/$$i"; \ + done + # produce the new yaml + cd "out_$@" && ../make_default_yaml + # Note: hand-edit the new DEFAULT.yaml to select the shipping locales, + # then use bmpblk_utility to create the binary. + clean: diff --git a/scripts/newbitmaps/images/hwid_fonts.bin b/scripts/newbitmaps/images/hwid_fonts.bin Binary files differnew file mode 100644 index 00000000..ecdfaef6 --- /dev/null +++ b/scripts/newbitmaps/images/hwid_fonts.bin diff --git a/scripts/newbitmaps/images/make_default_yaml b/scripts/newbitmaps/images/make_default_yaml index 93178f51..88c540e8 100755 --- a/scripts/newbitmaps/images/make_default_yaml +++ b/scripts/newbitmaps/images/make_default_yaml @@ -117,15 +117,15 @@ for hwid_bmp in hwid_unknown.bmp; do echo "$yaml_file" # List the images. The major difference is the HWID. - cat >"$yaml_file" <<EOF1 -bmpblock: 1.1 + cat >"$yaml_file" <<'EOF1' +bmpblock: 1.2 compression: 1 images: - # The HWID must change for every BOM - # hwid: $hwid_bmp + # We must specify a font blob to use to render the HWID + $HWID: hwid_fonts.bin # This URL never changes url: Url.bmp diff --git a/scripts/newbitmaps/lib/bmpblock.py b/scripts/newbitmaps/lib/bmpblock.py index 4d588d76..539159bc 100755 --- a/scripts/newbitmaps/lib/bmpblock.py +++ b/scripts/newbitmaps/lib/bmpblock.py @@ -57,10 +57,13 @@ class BmpBlock(object): # image values should all be filenames (ie, strings) for val in images.values(): assert val and isinstance(val, types.StringTypes) - if not "$HWID" in images: - images["$HWID"] = os.path.join(self.libdir,'current_hwid.bmp') - if not "$HWID.rtol" in images: - images["$HWID.rtol"] = os.path.join(self.libdir, 'current_hwid.bmp') + # don't worry about fonts. eventually we'll have graphical mocks on host. + if "$HWID" in images: + print "WARNING: ignoring $HWID font blob" + if "$HWID.rtol" in images: + print "WARNING: ignoring $HWID.rtol font blob" + images["$HWID"] = os.path.join(self.libdir,'current_hwid.bmp') + images["$HWID.rtol"] = os.path.join(self.libdir, 'current_hwid.bmp') screens = thing["screens"] assert isinstance(screens, dict) diff --git a/utility/Makefile b/utility/Makefile index 88c8a5b4..b53ee572 100644 --- a/utility/Makefile +++ b/utility/Makefile @@ -39,7 +39,7 @@ TARGET_NAMES = crossystem \ vbutil_what_keys ifeq ($(MINIMAL),) -TARGET_NAMES += bmpblk_utility eficompress efidecompress +TARGET_NAMES += bmpblk_font bmpblk_utility eficompress efidecompress endif TARGET_BINS = $(addprefix ${BUILD_ROOT}/,$(TARGET_NAMES)) @@ -65,6 +65,12 @@ ${BUILD_ROOT}/bmpblk_utility.o: bmpblk_utility.cc ${BUILD_ROOT}/bmpblk_util.o: bmpblk_util.c $(CC) $(CFLAGS) -c $< -o $@ +${BUILD_ROOT}/bmpblk_font.o: bmpblk_font.c + $(CC) $(CFLAGS) -c $< -o $@ + +${BUILD_ROOT}/image_types.o: image_types.c + $(CC) $(CFLAGS) -c $< -o $@ + ${BUILD_ROOT}/eficompress.o: eficompress.c $(CC) $(CFLAGS) -c $< -o $@ @@ -79,10 +85,15 @@ ${BUILD_ROOT}/efidecompress: efidecompress.c ${BUILD_ROOT}/bmpblk_utility: ${BUILD_ROOT}/bmpblk_utility.o \ ${BUILD_ROOT}/bmpblk_util.o \ + ${BUILD_ROOT}/image_types.o \ ${BUILD_ROOT}/eficompress.o \ ${BUILD_ROOT}/efidecompress.o $(CXX) -llzma -lyaml $(CFLAGS) $^ -o $@ +${BUILD_ROOT}/bmpblk_font: ${BUILD_ROOT}/bmpblk_font.o \ + ${BUILD_ROOT}/image_types.o + $(CC) $(CFLAGS) $^ -o $@ + # TODO: rewrite load_firmware_test to support new wrapper API #${BUILD_ROOT}/load_firmware_test: load_firmware_test.c $(LIBS) # $(CC) $(CFLAGS) $< -o $@ $(LIBS) -lcrypto diff --git a/utility/bmpblk_font.c b/utility/bmpblk_font.c new file mode 100644 index 00000000..493e87f0 --- /dev/null +++ b/utility/bmpblk_font.c @@ -0,0 +1,227 @@ +// Copyright (c) 2011 The Chromium OS Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include <errno.h> +#include <fcntl.h> +#include <getopt.h> +#include <limits.h> +#include <stdarg.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <sys/mman.h> +#include <sys/stat.h> +#include <sys/types.h> +#include <unistd.h> + +#include "bmpblk_font.h" +#include "image_types.h" + +static char *progname; + +static void error(const char *fmt, ...) +{ + va_list args; + va_start( args, fmt ); + fprintf(stderr, "%s: ", progname); + vfprintf( stderr, fmt, args ); + va_end( args ); +} +#define fatal(args...) do { error(args); exit(1); } while(0) + + +/* Command line options */ +enum { + OPT_OUTFILE = 1000, +}; + +#define DEFAULT_OUTFILE "font.bin" + + +static struct option long_opts[] = { + {"outfile", 1, 0, OPT_OUTFILE }, + {NULL, 0, 0, 0} +}; + + +/* Print help and return error */ +static void HelpAndDie(void) { + fprintf(stderr, + "\n" + "%s - Create a vboot fontfile from a set of BMP files.\n" + "\n" + "Usage: %s [OPTIONS] BMPFILE [BMPFILE...]\n" + "\n" + "Each BMP file must match *_HEX.bmp, where HEX is the hexadecimal\n" + "representation of the character that the file displays. The images\n" + "will be encoded in the given order. Typically the first image is\n" + "reused to represent any missing characters.\n" + "\n" + "OPTIONS are:\n" + " --outfile <filename> Output file (default is %s)\n" + "\n", progname, progname, DEFAULT_OUTFILE); + exit(1); +} + +////////////////////////////////////////////////////////////////////////////// + +// Returns pointer to buffer containing entire file, sets length. +static void *read_entire_file(const char *filename, size_t *length) { + int fd; + struct stat sbuf; + void *ptr; + + *length = 0; // just in case + + if (0 != stat(filename, &sbuf)) { + error("Unable to stat %s: %s\n", filename, strerror(errno)); + return 0; + } + + if (!sbuf.st_size) { + error("File %s is empty\n", filename); + return 0; + } + + fd = open(filename, O_RDONLY); + if (fd < 0) { + error("Unable to open %s: %s\n", filename, strerror(errno)); + return 0; + } + + ptr = mmap(0, sbuf.st_size, PROT_READ, MAP_PRIVATE, fd, 0); + if (MAP_FAILED == ptr) { + error("Unable to mmap %s: %s\n", filename, strerror(errno)); + close(fd); + return 0; + } + + *length = sbuf.st_size; + + close(fd); + + return ptr; +} + + +// Reclaims buffer from read_entire_file(). +static void discard_file(void *ptr, size_t length) { + munmap(ptr, length); +} + +////////////////////////////////////////////////////////////////////////////// + + + +int main(int argc, char* argv[]) { + char* outfile = DEFAULT_OUTFILE; + int numimages = 0; + int parse_error = 0; + int i; + FILE *ofp; + FontArrayHeader header; + FontArrayEntryHeader entry; + + progname = strrchr(argv[0], '/'); + if (progname) + progname++; + else + progname = argv[0]; + + while ((i = getopt_long(argc, argv, "", long_opts, NULL)) != -1) { + switch (i) { + case OPT_OUTFILE: + outfile = optarg; + break; + + default: + /* Unhandled option */ + printf("Unknown option\n"); + parse_error = 1; + break; + } + } + + numimages = argc - optind; + + if (parse_error || numimages < 1) + HelpAndDie(); + + printf("outfile is %s\n", outfile); + printf("numimages is %d\n", numimages); + + ofp = fopen(outfile, "wb"); + if (!ofp) + fatal("Unable to open %s: %s\n", outfile, strerror(errno)); + + memcpy(&header.signature, FONT_SIGNATURE, FONT_SIGNATURE_SIZE); + header.num_entries = numimages; + if (1 != fwrite(&header, sizeof(header), 1, ofp)) { + error("Can't write header to %s: %s\n", outfile, strerror(errno)); + goto bad1; + } + + for(i=0; i<numimages; i++) { + char *imgfile = argv[optind+i]; + char *s; + uint32_t ascii; + void *imgdata = 0; + size_t imgsize, filesize, diff; + + s = strrchr(imgfile, '_'); + if (!s || 1 != sscanf(s, "_%x.bmp", &ascii)) { // This is not foolproof. + error("Unable to parse the character from filename %s\n", imgfile); + goto bad1; + } + + imgdata = read_entire_file(imgfile, &imgsize); + if (!imgdata) + goto bad1; + + if (FORMAT_BMP != identify_image_type(imgdata, imgsize, &entry.info)) { + error("%s does not contain a valid BMP image\n", imgfile); + goto bad1; + } + + // Pad the image to align it on a 4-byte boundary. + filesize = imgsize; + if (imgsize % 4) + filesize = ((imgsize + 4) / 4) * 4; + diff = filesize - imgsize; + + entry.ascii = ascii; + entry.info.tag = TAG_NONE; + entry.info.compression = COMPRESS_NONE; // we'll compress it all later + entry.info.original_size = filesize; + entry.info.compressed_size = filesize; + + printf("%s => 0x%x %dx%d\n", imgfile, entry.ascii, + entry.info.width, entry.info.height); + + if (1 != fwrite(&entry, sizeof(entry), 1, ofp)) { + error("Can't write entry to %s: %s\n", outfile, strerror(errno)); + goto bad1; + } + if (1 != fwrite(imgdata, imgsize, 1, ofp)) { + error("Can't write image to %s: %s\n", outfile, strerror(errno)); + goto bad1; + } + if (diff && 1 != fwrite("\0\0\0\0\0\0\0\0", diff, 1, ofp)) { + error("Can't write padding to %s: %s\n", outfile, strerror(errno)); + goto bad1; + } + + + discard_file(imgdata, imgsize); + } + + fclose(ofp); + return 0; + +bad1: + fclose(ofp); + error("Aborting\n"); + (void) unlink(outfile); + exit(1); +} diff --git a/utility/bmpblk_util.c b/utility/bmpblk_util.c index 84a48fb1..49573af9 100644 --- a/utility/bmpblk_util.c +++ b/utility/bmpblk_util.c @@ -285,20 +285,23 @@ int dump_bmpblock(const char *infile, int show_as_yaml, if (img->compressed_size) { sprintf(image_name, "img_%08x.bmp", offset); if (img->tag == TAG_HWID) { - fprintf(yfp, " %s: %s # %dx%d %d/%d tag=%d\n", + fprintf(yfp, " %s: %s # %dx%d %d/%d tag=%d fmt=%d\n", RENDER_HWID, image_name, img->width, img->height, - img->compressed_size, img->original_size, img->tag); + img->compressed_size, img->original_size, + img->tag, img->format); } else if (img->tag == TAG_HWID_RTOL) { - fprintf(yfp, " %s: %s # %dx%d %d/%d tag=%d\n", + fprintf(yfp, " %s: %s # %dx%d %d/%d tag=%d fmt=%d\n", RENDER_HWID_RTOL, image_name, img->width, img->height, - img->compressed_size, img->original_size, img->tag); + img->compressed_size, img->original_size, + img->tag, img->format); } else { - fprintf(yfp, " img_%08x: %s # %dx%d %d/%d tag=%d\n", + fprintf(yfp, " img_%08x: %s # %dx%d %d/%d tag=%d fmt=%d\n", offset, image_name, img->width, img->height, - img->compressed_size, img->original_size, img->tag); + img->compressed_size, img->original_size, + img->tag, img->format); } if (todir) { sprintf(full_path_name, "%s/%s", todir, image_name); @@ -388,17 +391,23 @@ int dump_bmpblock(const char *infile, int show_as_yaml, ImageInfo *iptr = (ImageInfo *)(ptr + scr->images[i].image_info_offset); if (iptr->tag == TAG_HWID) { - fprintf(yfp, " - [%d, %d, %s]\n", + fprintf(yfp, " - [%d, %d, %s] # tag=%d fmt=%d c=%d %d/%d\n", scr->images[i].x, scr->images[i].y, - RENDER_HWID); + RENDER_HWID, iptr->tag, iptr->format, iptr->compression, + iptr->compressed_size, iptr->original_size); } else if (iptr->tag == TAG_HWID_RTOL) { - fprintf(yfp, " - [%d, %d, %s]\n", + fprintf(yfp, " - [%d, %d, %s] # tag=%d fmt=%d c=%d %d/%d\n", scr->images[i].x, scr->images[i].y, - RENDER_HWID_RTOL); + RENDER_HWID_RTOL, iptr->tag, + iptr->format, iptr->compression, + iptr->compressed_size, iptr->original_size); } else { - fprintf(yfp, " - [%d, %d, img_%08x]\n", + fprintf(yfp, " - [%d, %d, img_%08x]" + " # tag=%d fmt=%d c=%d %d/%d\n", scr->images[i].x, scr->images[i].y, - scr->images[i].image_info_offset); + scr->images[i].image_info_offset, + iptr->tag, iptr->format, iptr->compression, + iptr->compressed_size, iptr->original_size); } } } diff --git a/utility/bmpblk_utility.cc b/utility/bmpblk_utility.cc index f4bde7c7..2846746f 100644 --- a/utility/bmpblk_utility.cc +++ b/utility/bmpblk_utility.cc @@ -6,6 +6,7 @@ // #include "bmpblk_utility.h" +#include "image_types.h" #include <assert.h> #include <errno.h> @@ -22,29 +23,6 @@ extern "C" { } -/* BMP header, used to validate image requirements - * See http://en.wikipedia.org/wiki/BMP_file_format - */ -typedef struct { - uint8_t CharB; // must be 'B' - uint8_t CharM; // must be 'M' - uint32_t Size; - uint16_t Reserved[2]; - uint32_t ImageOffset; - uint32_t HeaderSize; - uint32_t PixelWidth; - uint32_t PixelHeight; - uint16_t Planes; // Must be 1 for x86 - uint16_t BitPerPixel; // 1, 4, 8, or 24 for x86 - uint32_t CompressionType; // 0 (none) for x86, 1 (RLE) for arm - uint32_t ImageSize; - uint32_t XPixelsPerMeter; - uint32_t YPixelsPerMeter; - uint32_t NumberOfColors; - uint32_t ImportantColors; -} __attribute__((packed)) BMP_IMAGE_HEADER; - - static void error(const char *format, ...) { va_list ap; va_start(ap, format); @@ -71,6 +49,10 @@ namespace vboot_reference { set_compression_ = false; compression_ = COMPRESS_NONE; debug_ = debug; + render_hwid_ = true; + support_font_ = true; + got_font_ = false; + got_rtol_font_ = false; } BmpBlockUtil::~BmpBlockUtil() { @@ -125,11 +107,12 @@ namespace vboot_reference { for (StrImageConfigMap::iterator it = config_.images_map.begin(); it != config_.images_map.end(); ++it) { - printf(" \"%s\": filename=\"%s\" offset=0x%x tag=%d\n", + printf(" \"%s\": filename=\"%s\" offset=0x%x tag=%d fmt=%d\n", it->first.c_str(), it->second.filename.c_str(), it->second.offset, - it->second.data.tag); + it->second.data.tag, + it->second.data.format); } printf("%ld screens_map\n", config_.screens_map.size()); for (StrScreenConfigMap::iterator it = config_.screens_map.begin(); @@ -206,11 +189,19 @@ namespace vboot_reference { error("Syntax error in parsing bmpblock.\n"); } string gotversion = (char*)event.data.scalar.value; - if (gotversion == "1.1") { + if (gotversion == "1.2") { render_hwid_ = true; + support_font_ = true; + } else if (gotversion == "1.1") { + minor_version_ = 1; + render_hwid_ = true; + support_font_ = false; + fprintf(stderr, "WARNING: using old format: %s\n", gotversion.c_str()); } else if (gotversion == "1.0") { minor_version_ = 0; render_hwid_ = false; + support_font_ = false; + fprintf(stderr, "WARNING: using old format: %s\n", gotversion.c_str()); } else { error("Unsupported version specified in config file (%s)\n", gotversion.c_str()); @@ -254,6 +245,12 @@ namespace vboot_reference { config_.image_names.push_back(image_name); config_.images_map[image_name] = ImageConfig(); config_.images_map[image_name].filename = image_filename; + if (image_name == RENDER_HWID) { + got_font_ = true; + } + if (image_name == RENDER_HWID_RTOL) { + got_rtol_font_ = true; + } break; case YAML_MAPPING_END_EVENT: yaml_event_delete(&event); @@ -286,17 +283,22 @@ namespace vboot_reference { case 2: screen.image_names[index1] = (char*)event.data.scalar.value; // Detect the special case where we're rendering the HWID string - // instead of displaying a bitmap. The image name shouldn't - // exist in the list of images, but we will still need an + // instead of displaying a bitmap. The image name may not + // exist in the list of images (v1.1), but we will still need an // ImageInfo struct to remember where to draw the text. - // Note that if the image name DOES exist, we still will won't - // display it (yet). Future versions may use that image to hold the - // font glpyhs, which is why we pass it around now. + // Note that v1.2 requires that the image name DOES exist, because + // the corresponding file is used to hold the font glpyhs. if (render_hwid_) { if (screen.image_names[index1] == RENDER_HWID) { config_.images_map[RENDER_HWID].data.tag = TAG_HWID; + if (support_font_ && !got_font_) + error("Font required in 'image:' section for %s\n", + RENDER_HWID); } else if (screen.image_names[index1] == RENDER_HWID_RTOL) { config_.images_map[RENDER_HWID_RTOL].data.tag = TAG_HWID_RTOL; + if (support_font_ && !got_rtol_font_) + error("Font required in 'image:' section for %s\n", + RENDER_HWID_RTOL); } } break; @@ -406,13 +408,10 @@ namespace vboot_reference { const string &content = read_image_file(it->second.filename.c_str()); it->second.raw_content = content; it->second.data.original_size = content.size(); - it->second.data.format = get_image_format(content); - switch (it->second.data.format) { - case FORMAT_BMP: - it->second.data.width = get_bmp_image_width(it->second.raw_content); - it->second.data.height = get_bmp_image_height(it->second.raw_content); - break; - default: + it->second.data.format = + identify_image_type(content.c_str(), + (uint32_t)content.size(), &it->second.data); + if (FORMAT_INVALID == it->second.data.format) { error("Unsupported image format in %s\n", it->second.filename.c_str()); } switch(compression_) { @@ -503,31 +502,6 @@ namespace vboot_reference { return content; } - ImageFormat BmpBlockUtil::get_image_format(const string content) { - if (content.size() < sizeof(BMP_IMAGE_HEADER)) - return FORMAT_INVALID; - const BMP_IMAGE_HEADER *hdr = (const BMP_IMAGE_HEADER *)content.c_str(); - - if (hdr->CharB != 'B' || hdr->CharM != 'M' || - hdr->Planes != 1 || - (hdr->CompressionType != 0 && hdr->CompressionType != 1) || - (hdr->BitPerPixel != 1 && hdr->BitPerPixel != 4 && - hdr->BitPerPixel != 8 && hdr->BitPerPixel != 24)) - return FORMAT_INVALID; - - return FORMAT_BMP; - } - - uint32_t BmpBlockUtil::get_bmp_image_width(const string content) { - const BMP_IMAGE_HEADER *hdr = (const BMP_IMAGE_HEADER *)content.c_str(); - return hdr->PixelWidth; - } - - uint32_t BmpBlockUtil::get_bmp_image_height(const string content) { - const BMP_IMAGE_HEADER *hdr = (const BMP_IMAGE_HEADER *)content.c_str(); - return hdr->PixelHeight; - } - void BmpBlockUtil::fill_bmpblock_header() { memset(&config_.header, '\0', sizeof(config_.header)); memcpy(&config_.header.signature, BMPBLOCK_SIGNATURE, @@ -557,11 +531,12 @@ namespace vboot_reference { ++it) { it->second.offset = current_offset; if (debug_) - printf(" \"%s\": filename=\"%s\" offset=0x%x tag=%d\n", + printf(" \"%s\": filename=\"%s\" offset=0x%x tag=%d fmt=%d\n", it->first.c_str(), it->second.filename.c_str(), it->second.offset, - it->second.data.tag); + it->second.data.tag, + it->second.data.format); current_offset += sizeof(ImageInfo) + it->second.data.compressed_size; /* Make it 4-byte aligned. */ diff --git a/utility/image_types.c b/utility/image_types.c new file mode 100644 index 00000000..2cc27b32 --- /dev/null +++ b/utility/image_types.c @@ -0,0 +1,71 @@ +// Copyright (c) 2010 The Chromium OS Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include <stdint.h> +#include <string.h> + +#include "bmpblk_header.h" +#include "bmpblk_font.h" +#include "image_types.h" + +/* BMP header, used to validate image requirements + * See http://en.wikipedia.org/wiki/BMP_file_format + */ +typedef struct { + uint8_t CharB; // must be 'B' + uint8_t CharM; // must be 'M' + uint32_t Size; + uint16_t Reserved[2]; + uint32_t ImageOffset; + uint32_t HeaderSize; + uint32_t PixelWidth; + uint32_t PixelHeight; + uint16_t Planes; // Must be 1 for x86 + uint16_t BitPerPixel; // 1, 4, 8, or 24 for x86 + uint32_t CompressionType; // 0 (none) for x86, 1 (RLE) for arm + uint32_t ImageSize; + uint32_t XPixelsPerMeter; + uint32_t YPixelsPerMeter; + uint32_t NumberOfColors; + uint32_t ImportantColors; +} __attribute__((packed)) BMP_IMAGE_HEADER; + + +ImageFormat identify_image_type(const void *buf, uint32_t bufsize, + ImageInfo *info) { + + if (info) + info->format = FORMAT_INVALID; + + if (bufsize < sizeof(BMP_IMAGE_HEADER) && + bufsize < sizeof(FontArrayHeader)) { + return FORMAT_INVALID; + } + + const BMP_IMAGE_HEADER *bhdr = buf; + if (bhdr->CharB == 'B' && bhdr->CharM == 'M' && + bhdr->Planes == 1 && + (bhdr->CompressionType == 0 || bhdr->CompressionType == 1) && + (bhdr->BitPerPixel == 1 || bhdr->BitPerPixel == 4 || + bhdr->BitPerPixel == 8 || bhdr->BitPerPixel == 24)) { + if (info) { + info->format = FORMAT_BMP; + info->width = bhdr->PixelWidth; + info->height = bhdr->PixelHeight; + } + return FORMAT_BMP; + } + + const FontArrayHeader *fhdr = buf; + if (0 == memcmp(&fhdr->signature, FONT_SIGNATURE, FONT_SIGNATURE_SIZE) && + fhdr->num_entries > 0) { + if (info) + info->format = FORMAT_FONT; + return FORMAT_FONT; + } + + return FORMAT_BMP; +} + + diff --git a/utility/include/bmpblk_utility.h b/utility/include/bmpblk_utility.h index 5b70ce2d..fec2b02f 100644 --- a/utility/include/bmpblk_utility.h +++ b/utility/include/bmpblk_utility.h @@ -7,6 +7,8 @@ #define VBOOT_REFERENCE_BMPBLK_UTILITY_H_ #include "bmpblk_header.h" +#include "bmpblk_font.h" +#include "image_types.h" #include <yaml.h> @@ -93,9 +95,6 @@ class BmpBlockUtil { /* Useful functions */ const string read_image_file(const char *filename); - ImageFormat get_image_format(const string content); - uint32_t get_bmp_image_width(const string content); - uint32_t get_bmp_image_height(const string content); /* Verbosity flags */ bool debug_; @@ -106,6 +105,9 @@ class BmpBlockUtil { /* Flags for version-specific features */ bool render_hwid_; + bool support_font_; + bool got_font_; + bool got_rtol_font_; /* Internal variable for storing the config of BmpBlock. */ BmpBlockConfig config_; diff --git a/utility/include/image_types.h b/utility/include/image_types.h new file mode 100644 index 00000000..f85a9a98 --- /dev/null +++ b/utility/include/image_types.h @@ -0,0 +1,25 @@ +/* Copyright (c) 2011 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#ifndef VBOOT_REFERENCE_IMAGE_TYPES_H_ +#define VBOOT_REFERENCE_IMAGE_TYPES_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include <stdint.h> +#include "bmpblk_header.h" + +/* Identify the data. Fill in known values if info is not NULL */ +ImageFormat identify_image_type(const void *buf, uint32_t bufsize, + ImageInfo *info); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* VBOOT_REFERENCE_IMAGE_TYPES_H_ */ + |