<p>Michał Żygowski has uploaded this change for <strong>review</strong>.</p><p><a href="https://review.coreboot.org/27957">View Change</a></p><pre style="font-family: monospace,monospace; white-space: pre-wrap;">Added multiboot support to cbfstool and made changes to behaviour for cbfs add-payload<br><br>* modified messaging and logic with respect to different payload types:<br>- tries multiboot if neither ELF nor UEFI<br>- then tries bzImage<br><br>* added check for Linux header in bzImage<br>* change ERROR level message if stage file not in ELF format (reduced to INFO)<br><br>Note: multiboot support limited to obtaining load location and entry point<br><br>Change-Id: Iaeb808e8750ad81bdf8c4daedb0d91e961eebb70<br>Signed-off-by: Paul Roberts <paul.c.roberts@ntlworld.com><br>---<br>M util/cbfstool/cbfs-mkpayload.c<br>M util/cbfstool/cbfs-payload-linux.c<br>M util/cbfstool/cbfstool.c<br>M util/cbfstool/common.h<br>4 files changed, 123 insertions(+), 2 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;">git pull ssh://review.coreboot.org:29418/coreboot refs/changes/57/27957/1</pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/util/cbfstool/cbfs-mkpayload.c b/util/cbfstool/cbfs-mkpayload.c</span><br><span>index d6c10ad..8df52d9 100644</span><br><span>--- a/util/cbfstool/cbfs-mkpayload.c</span><br><span>+++ b/util/cbfstool/cbfs-mkpayload.c</span><br><span>@@ -454,3 +454,104 @@</span><br><span> </span><br><span>     return 0;</span><br><span> }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#define MULTIBOOT_MAGIC 0x1BADB002</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+struct multiboot_header {</span><br><span style="color: hsl(120, 100%, 40%);">+     uint32_t magic;</span><br><span style="color: hsl(120, 100%, 40%);">+       uint32_t flags;</span><br><span style="color: hsl(120, 100%, 40%);">+       uint32_t checksum;</span><br><span style="color: hsl(120, 100%, 40%);">+    uint32_t header_addr;</span><br><span style="color: hsl(120, 100%, 40%);">+ uint32_t load_addr;</span><br><span style="color: hsl(120, 100%, 40%);">+   uint32_t load_end_addr;</span><br><span style="color: hsl(120, 100%, 40%);">+       uint32_t bss_end_addr;</span><br><span style="color: hsl(120, 100%, 40%);">+        uint32_t entry_addr;</span><br><span style="color: hsl(120, 100%, 40%);">+};</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static int find_multiboot_header(const struct buffer *input,</span><br><span style="color: hsl(120, 100%, 40%);">+                                      struct multiboot_header *mboot_hdr)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+        int i;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      for (i = 0; i < 8192; i += sizeof(uint32_t)) {</span><br><span style="color: hsl(120, 100%, 40%);">+             uint32_t sum;</span><br><span style="color: hsl(120, 100%, 40%);">+         struct buffer in;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+           buffer_clone(&in, input);</span><br><span style="color: hsl(120, 100%, 40%);">+         buffer_seek(&in, i);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+            mboot_hdr->magic = xdr_le.get32(&in);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+                if (mboot_hdr->magic != MULTIBOOT_MAGIC)</span><br><span style="color: hsl(120, 100%, 40%);">+                   continue;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+           mboot_hdr->flags = xdr_le.get32(&in);</span><br><span style="color: hsl(120, 100%, 40%);">+          mboot_hdr->checksum = xdr_le.get32(&in);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+             sum = mboot_hdr->magic + mboot_hdr->flags + mboot_hdr->checksum;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+           if (sum != 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+                       WARN("Multiboot header found @ %d. Checksum invalid\n",</span><br><span style="color: hsl(120, 100%, 40%);">+                             i);</span><br><span style="color: hsl(120, 100%, 40%);">+                   continue;</span><br><span style="color: hsl(120, 100%, 40%);">+             }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+           mboot_hdr->header_addr = xdr_le.get32(&in);</span><br><span style="color: hsl(120, 100%, 40%);">+            mboot_hdr->load_addr = xdr_le.get32(&in);</span><br><span style="color: hsl(120, 100%, 40%);">+              mboot_hdr->load_end_addr = xdr_le.get32(&in);</span><br><span style="color: hsl(120, 100%, 40%);">+          mboot_hdr->bss_end_addr = xdr_le.get32(&in);</span><br><span style="color: hsl(120, 100%, 40%);">+           mboot_hdr->entry_addr = xdr_le.get32(&in);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+           return i;</span><br><span style="color: hsl(120, 100%, 40%);">+     }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   return -1;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+int parse_multiboot_to_payload(const struct buffer *input,</span><br><span style="color: hsl(120, 100%, 40%);">+                           struct buffer *output, enum comp_algo algo)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+        int header_offset;</span><br><span style="color: hsl(120, 100%, 40%);">+    struct multiboot_header mboot_hdr;</span><br><span style="color: hsl(120, 100%, 40%);">+    uint32_t end_addr;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        header_offset = find_multiboot_header(input, &mboot_hdr);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+       if (header_offset < 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+           WARN("No valid multiboot header found.\n");</span><br><span style="color: hsl(120, 100%, 40%);">+         return -1;</span><br><span style="color: hsl(120, 100%, 40%);">+    }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   /* No runtime boot information supported. */</span><br><span style="color: hsl(120, 100%, 40%);">+  if (mboot_hdr.flags & ((1 << 2) | (1 << 1))) {</span><br><span style="color: hsl(120, 100%, 40%);">+                WARN("No multiboot runtime boot information supported: %x.\n",</span><br><span style="color: hsl(120, 100%, 40%);">+                      mboot_hdr.flags);</span><br><span style="color: hsl(120, 100%, 40%);">+             return -1;</span><br><span style="color: hsl(120, 100%, 40%);">+    }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   if (!(mboot_hdr.flags & (1 << 16))) {</span><br><span style="color: hsl(120, 100%, 40%);">+               WARN("No multiboot load information available: %x.\n",</span><br><span style="color: hsl(120, 100%, 40%);">+                      mboot_hdr.flags);</span><br><span style="color: hsl(120, 100%, 40%);">+             return -1;</span><br><span style="color: hsl(120, 100%, 40%);">+    }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   end_addr = mboot_hdr.load_end_addr;</span><br><span style="color: hsl(120, 100%, 40%);">+   if (!end_addr)</span><br><span style="color: hsl(120, 100%, 40%);">+                end_addr = mboot_hdr.load_addr + input->size;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    /* Support full file load only. */</span><br><span style="color: hsl(120, 100%, 40%);">+    if (header_offset + mboot_hdr.load_addr != mboot_hdr.header_addr ||</span><br><span style="color: hsl(120, 100%, 40%);">+           end_addr - mboot_hdr.load_addr != input->size) {</span><br><span style="color: hsl(120, 100%, 40%);">+           WARN("Multiboot payload loading only supports full file.\n");</span><br><span style="color: hsl(120, 100%, 40%);">+               return -1;</span><br><span style="color: hsl(120, 100%, 40%);">+    }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   INFO("Compatible Multiboot payload found. load address:"</span><br><span style="color: hsl(120, 100%, 40%);">+            " 0x%x entry: 0x%x\n",mboot_hdr.load_addr,mboot_hdr.entry_addr);</span><br><span style="color: hsl(120, 100%, 40%);">+    return parse_flat_binary_to_payload(input,</span><br><span style="color: hsl(120, 100%, 40%);">+                            output,</span><br><span style="color: hsl(120, 100%, 40%);">+                               mboot_hdr.load_addr,</span><br><span style="color: hsl(120, 100%, 40%);">+                          mboot_hdr.entry_addr,</span><br><span style="color: hsl(120, 100%, 40%);">+                         algo);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span>diff --git a/util/cbfstool/cbfs-payload-linux.c b/util/cbfstool/cbfs-payload-linux.c</span><br><span>index 6b4bf27..8183925 100644</span><br><span>--- a/util/cbfstool/cbfs-payload-linux.c</span><br><span>+++ b/util/cbfstool/cbfs-payload-linux.c</span><br><span>@@ -242,6 +242,19 @@</span><br><span> </span><br><span>    params.loader_type = 0xff; /* Unregistered Linux loader */</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+        /* Check for signatures and determine version */</span><br><span style="color: hsl(120, 100%, 40%);">+      if ( hdr->boot_sector_magic != 0xAA55 ) {</span><br><span style="color: hsl(120, 100%, 40%);">+          WARN("bzImage missing 55AA signature\n");</span><br><span style="color: hsl(120, 100%, 40%);">+           return -1;</span><br><span style="color: hsl(120, 100%, 40%);">+    }</span><br><span style="color: hsl(120, 100%, 40%);">+     if ( (hdr->header_magic[0] != 'H')||</span><br><span style="color: hsl(120, 100%, 40%);">+               (hdr->header_magic[1] != 'd')||</span><br><span style="color: hsl(120, 100%, 40%);">+            (hdr->header_magic[2] != 'r')||</span><br><span style="color: hsl(120, 100%, 40%);">+            (hdr->header_magic[3] != 'S')){</span><br><span style="color: hsl(120, 100%, 40%);">+            WARN("bzImage missing HdrS signature\n");</span><br><span style="color: hsl(120, 100%, 40%);">+           return -1;</span><br><span style="color: hsl(120, 100%, 40%);">+    }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>  if (cmdline != NULL) {</span><br><span>               if (hdr->protocol_version < 0x202) {</span><br><span>                   params.cl_magic = CL_MAGIC_VALUE;</span><br><span>diff --git a/util/cbfstool/cbfstool.c b/util/cbfstool/cbfstool.c</span><br><span>index f8b1f65..6fbe2fc 100644</span><br><span>--- a/util/cbfstool/cbfstool.c</span><br><span>+++ b/util/cbfstool/cbfstool.c</span><br><span>@@ -752,14 +752,19 @@</span><br><span>       if (ret != 0)</span><br><span>                ret = parse_fv_to_payload(buffer, &output, param.compression);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-  /* If it's neither ELF nor UEFI Fv, try bzImage */</span><br><span style="color: hsl(120, 100%, 40%);">+        /* If it's neither ELF nor UEFI Fv, try multiboot */</span><br><span style="color: hsl(120, 100%, 40%);">+      if (ret != 0)</span><br><span style="color: hsl(120, 100%, 40%);">+         ret = parse_multiboot_to_payload(buffer, &output,</span><br><span style="color: hsl(120, 100%, 40%);">+                         param.compression);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* If it's neither ELF, UEFI Fv, nor multiboot try bzImage*/</span><br><span>     if (ret != 0)</span><br><span>                ret = parse_bzImage_to_payload(buffer, &output,</span><br><span>                          param.initrd, param.cmdline, param.compression);</span><br><span> </span><br><span>         /* Not a supported payload type */</span><br><span>   if (ret != 0) {</span><br><span style="color: hsl(0, 100%, 40%);">-         ERROR("Not a supported payload type (ELF / FV).\n");</span><br><span style="color: hsl(120, 100%, 40%);">+                ERROR("Not a supported payload type (ELF / FV / bzImage / Multiboot).\n");</span><br><span>                 buffer_delete(buffer);</span><br><span>               return -1;</span><br><span>   }</span><br><span>diff --git a/util/cbfstool/common.h b/util/cbfstool/common.h</span><br><span>index baefc1c..ab2e441 100644</span><br><span>--- a/util/cbfstool/common.h</span><br><span>+++ b/util/cbfstool/common.h</span><br><span>@@ -198,6 +198,8 @@</span><br><span>                                  uint32_t loadaddress,</span><br><span>                                uint32_t entrypoint,</span><br><span>                                 enum comp_algo algo);</span><br><span style="color: hsl(120, 100%, 40%);">+int parse_multiboot_to_payload(const struct buffer *input,</span><br><span style="color: hsl(120, 100%, 40%);">+                            struct buffer *output, enum comp_algo algo);</span><br><span> /* cbfs-mkstage.c */</span><br><span> int parse_elf_to_stage(const struct buffer *input, struct buffer *output,</span><br><span>                   enum comp_algo algo, uint32_t *location,</span><br><span></span><br></pre><p>To view, visit <a href="https://review.coreboot.org/27957">change 27957</a>. To unsubscribe, or for help writing mail filters, visit <a href="https://review.coreboot.org/settings">settings</a>.</p><div itemscope itemtype="http://schema.org/EmailMessage"><div itemscope itemprop="action" itemtype="http://schema.org/ViewAction"><link itemprop="url" href="https://review.coreboot.org/27957"/><meta itemprop="name" content="View Change"/></div></div>

<div style="display:none"> Gerrit-Project: coreboot </div>
<div style="display:none"> Gerrit-Branch: master </div>
<div style="display:none"> Gerrit-MessageType: newchange </div>
<div style="display:none"> Gerrit-Change-Id: Iaeb808e8750ad81bdf8c4daedb0d91e961eebb70 </div>
<div style="display:none"> Gerrit-Change-Number: 27957 </div>
<div style="display:none"> Gerrit-PatchSet: 1 </div>
<div style="display:none"> Gerrit-Owner: Michał Żygowski <michal.zygowski@3mdeb.com> </div>