iPXE
Macros | Functions | Variables
multiboot.c File Reference

Multiboot image format. More...

#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <assert.h>
#include <realmode.h>
#include <multiboot.h>
#include <ipxe/image.h>
#include <ipxe/segment.h>
#include <ipxe/memmap.h>
#include <ipxe/elf.h>
#include <ipxe/init.h>
#include <ipxe/features.h>
#include <ipxe/uri.h>
#include <ipxe/version.h>

Go to the source code of this file.

Macros

#define MAX_MODULES   8
 Maximum number of modules we will allow for. More...
 
#define MAX_MEMMAP   8
 Maximum number of memory map entries. More...
 
#define MB_MAX_CMDLINE   512
 Maximum combined length of command lines. More...
 
#define MB_SUPPORTED_FLAGS
 Multiboot flags that we support. More...
 
#define MB_COMPULSORY_FLAGS   0x0000ffff
 Compulsory feature multiboot flags. More...
 
#define MB_OPTIONAL_FLAGS   0xffff0000
 Optional feature multiboot flags. More...
 
#define MB_UNSUPPORTED_FLAGS   ( MB_COMPULSORY_FLAGS & ~MB_SUPPORTED_FLAGS )
 Multiboot flags that we don't support. More...
 
#define mb_cmdlines   __use_data16 ( mb_cmdlines )
 
#define mbinfo   __use_data16 ( mbinfo )
 
#define mb_bootloader_name   __use_data16 ( mb_bootloader_name )
 
#define mbmemmap   __use_data16 ( mbmemmap )
 
#define mbmodules   __use_data16 ( mbmodules )
 

Functions

 FILE_LICENCE (GPL2_OR_LATER_OR_UBDL)
 
 FEATURE (FEATURE_IMAGE, "MBOOT", DHCP_EB_FEATURE_MULTIBOOT, 1)
 
static char __bss16_array (mb_cmdlines, [MB_MAX_CMDLINE])
 Multiboot module command lines. More...
 
static void multiboot_build_memmap (struct image *image, struct multiboot_info *mbinfo, struct multiboot_memory_map *mbmemmap, unsigned int limit)
 Build multiboot memory map. More...
 
static physaddr_t multiboot_add_cmdline (struct image *image)
 Add command line in base memory. More...
 
static int multiboot_add_modules (struct image *image, physaddr_t start, struct multiboot_info *mbinfo, struct multiboot_module *modules, unsigned int limit)
 Add multiboot modules. More...
 
static struct multiboot_info __bss16 (mbinfo)
 The multiboot information structure. More...
 
static char __bss16_array (mb_bootloader_name, [32])
 The multiboot bootloader name. More...
 
static struct multiboot_memory_map __bss16_array (mbmemmap, [MAX_MEMMAP])
 The multiboot memory map. More...
 
static struct multiboot_module __bss16_array (mbmodules, [MAX_MODULES])
 The multiboot module list. More...
 
static int multiboot_find_header (struct image *image)
 Find multiboot header. More...
 
static int multiboot_load_raw (struct image *image, size_t offset, physaddr_t *entry, physaddr_t *max)
 Load raw multiboot image into memory. More...
 
static int multiboot_load_elf (struct image *image, physaddr_t *entry, physaddr_t *max)
 Load ELF multiboot image into memory. More...
 
static int multiboot_exec (struct image *image)
 Execute multiboot image. More...
 
static int multiboot_probe (struct image *image)
 Probe multiboot image. More...
 
struct image_type multiboot_image_type __image_type (PROBE_MULTIBOOT)
 Multiboot image type. More...
 

Variables

static unsigned int mb_cmdline_offset
 Offset within module command lines. More...
 

Detailed Description

Multiboot image format.

Definition in file multiboot.c.

Macro Definition Documentation

◆ MAX_MODULES

#define MAX_MODULES   8

Maximum number of modules we will allow for.

If this has bitten you: sorry. I did have a perfect scheme with a dynamically allocated list of modules on the protected-mode stack, but it was incompatible with some broken OSes that can only access low memory at boot time (even though we kindly set up 4GB flat physical addressing as per the multiboot specification.

Definition at line 60 of file multiboot.c.

◆ MAX_MEMMAP

#define MAX_MEMMAP   8

Maximum number of memory map entries.

Definition at line 63 of file multiboot.c.

◆ MB_MAX_CMDLINE

#define MB_MAX_CMDLINE   512

Maximum combined length of command lines.

Again; sorry. Some broken OSes zero out any non-base memory that isn't part of the loaded module set, so we can't just use virt_to_phys(cmdline) to point to the command lines, even though this would comply with the Multiboot spec.

Definition at line 73 of file multiboot.c.

◆ MB_SUPPORTED_FLAGS

#define MB_SUPPORTED_FLAGS
Value:
MB_FLAG_VIDMODE | MB_FLAG_RAW )
#define MB_FLAG_PGALIGN
Boot modules must be page aligned.
Definition: multiboot.h:19
#define MB_FLAG_MEMMAP
Memory map must be provided.
Definition: multiboot.h:22
#define MB_FLAG_RAW
Image is a raw multiboot image (not ELF)
Definition: multiboot.h:28

Multiboot flags that we support.

Definition at line 76 of file multiboot.c.

◆ MB_COMPULSORY_FLAGS

#define MB_COMPULSORY_FLAGS   0x0000ffff

Compulsory feature multiboot flags.

Definition at line 80 of file multiboot.c.

◆ MB_OPTIONAL_FLAGS

#define MB_OPTIONAL_FLAGS   0xffff0000

Optional feature multiboot flags.

Definition at line 83 of file multiboot.c.

◆ MB_UNSUPPORTED_FLAGS

#define MB_UNSUPPORTED_FLAGS   ( MB_COMPULSORY_FLAGS & ~MB_SUPPORTED_FLAGS )

Multiboot flags that we don't support.

We only care about the compulsory feature flags (bits 0-15); we are allowed to ignore the optional feature flags.

Definition at line 91 of file multiboot.c.

◆ mb_cmdlines

#define mb_cmdlines   __use_data16 ( mb_cmdlines )

Definition at line 95 of file multiboot.c.

◆ mbinfo

#define mbinfo   __use_data16 ( mbinfo )

Definition at line 257 of file multiboot.c.

◆ mb_bootloader_name

#define mb_bootloader_name   __use_data16 ( mb_bootloader_name )

Definition at line 261 of file multiboot.c.

◆ mbmemmap

#define mbmemmap   __use_data16 ( mbmemmap )

Definition at line 265 of file multiboot.c.

◆ mbmodules

#define mbmodules   __use_data16 ( mbmodules )

Definition at line 269 of file multiboot.c.

Function Documentation

◆ FILE_LICENCE()

FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL  )

◆ FEATURE()

FEATURE ( FEATURE_IMAGE  ,
"MBOOT"  ,
DHCP_EB_FEATURE_MULTIBOOT  ,
 
)

◆ __bss16_array() [1/4]

static char __bss16_array ( mb_cmdlines  )
static

Multiboot module command lines.

◆ multiboot_build_memmap()

static void multiboot_build_memmap ( struct image image,
struct multiboot_info mbinfo,
struct multiboot_memory_map mbmemmap,
unsigned int  limit 
)
static

Build multiboot memory map.

Parameters
imageMultiboot image
mbinfoMultiboot information structure
mbmemmapMultiboot memory map
limitMaxmimum number of memory map entries

Definition at line 108 of file multiboot.c.

111  {
112  struct memmap_region region;
113  unsigned int remaining;
114 
115  /* Translate into multiboot format */
116  memset ( mbmemmap, 0, sizeof ( *mbmemmap ) );
117  remaining = limit;
118  for_each_memmap ( &region, 0 ) {
119 
120  /* Ignore any non-memory regions */
121  if ( ! ( region.flags & MEMMAP_FL_MEMORY ) )
122  continue;
123  DBGC_MEMMAP ( image, &region );
124 
125  /* Check Multiboot memory map limit */
126  if ( ! remaining ) {
127  DBGC ( image, "MULTIBOOT %s limit of %d memmap "
128  "entries reached\n", image->name, limit );
129  break;
130  }
131 
132  /* Populate Multiboot memory map entry */
133  mbmemmap->size = ( sizeof ( *mbmemmap ) -
134  sizeof ( mbmemmap->size ) );
135  mbmemmap->base_addr = region.min;
136  mbmemmap->length = memmap_size ( &region );
137  mbmemmap->type = MBMEM_RAM;
138 
139  /* Update Multiboot information */
140  mbinfo->mmap_length += sizeof ( *mbmemmap );
141  if ( mbmemmap->base_addr == 0 )
142  mbinfo->mem_lower = ( mbmemmap->length / 1024 );
143  if ( mbmemmap->base_addr == 0x100000 )
144  mbinfo->mem_upper = ( mbmemmap->length / 1024 );
145 
146  /* Move to next Multiboot memory map entry */
147  mbmemmap++;
148  remaining--;
149  }
150 }
#define DBGC(...)
Definition: compiler.h:505
An executable image.
Definition: image.h:23
#define mbinfo
Definition: multiboot.c:257
#define DBGC_MEMMAP(...)
Definition: memmap.h:206
#define for_each_memmap(region, hide)
Iterate over memory regions.
Definition: memmap.h:183
uint16_t limit
Limit.
Definition: librm.h:136
static uint64_t memmap_size(const struct memmap_region *region)
Get remaining size of memory region (from the described address upwards)
Definition: memmap.h:98
#define MEMMAP_FL_MEMORY
Contains memory.
Definition: memmap.h:59
#define MBMEM_RAM
Usable RAM.
Definition: multiboot.h:147
#define mbmemmap
Definition: multiboot.c:265
A memory region descriptor.
Definition: memmap.h:48
char * name
Name.
Definition: image.h:37
void * memset(void *dest, int character, size_t len) __nonnull

References DBGC, DBGC_MEMMAP, memmap_region::flags, for_each_memmap, limit, mbinfo, MBMEM_RAM, mbmemmap, MEMMAP_FL_MEMORY, memmap_size(), memset(), memmap_region::min, and image::name.

Referenced by multiboot_exec().

◆ multiboot_add_cmdline()

static physaddr_t multiboot_add_cmdline ( struct image image)
static

Add command line in base memory.

Parameters
imageImage
Return values
physaddrPhysical address of command line

Definition at line 158 of file multiboot.c.

158  {
159  char *mb_cmdline = ( mb_cmdlines + mb_cmdline_offset );
160  size_t remaining = ( sizeof ( mb_cmdlines ) - mb_cmdline_offset );
161  char *buf = mb_cmdline;
162  size_t len;
163 
164  /* Copy image URI to base memory buffer as start of command line */
165  len = ( format_uri ( image->uri, buf, remaining ) + 1 /* NUL */ );
166  if ( len > remaining )
167  len = remaining;
169  buf += len;
170  remaining -= len;
171 
172  /* Copy command line to base memory buffer, if present */
173  if ( image->cmdline ) {
174  mb_cmdline_offset--; /* Strip NUL */
175  buf--;
176  remaining++;
177  len = ( snprintf ( buf, remaining, " %s",
178  image->cmdline ) + 1 /* NUL */ );
179  if ( len > remaining )
180  len = remaining;
182  }
183 
184  return virt_to_phys ( mb_cmdline );
185 }
An executable image.
Definition: image.h:23
#define mb_cmdlines
Definition: multiboot.c:95
char * cmdline
Command line to pass to image.
Definition: image.h:42
ring len
Length.
Definition: dwmac.h:231
size_t format_uri(const struct uri *uri, char *buf, size_t len)
Format URI.
Definition: uri.c:471
static unsigned int mb_cmdline_offset
Offset within module command lines.
Definition: multiboot.c:98
struct uri * uri
URI of image.
Definition: image.h:31
int snprintf(char *buf, size_t size, const char *fmt,...)
Write a formatted string to a buffer.
Definition: vsprintf.c:382

References image::cmdline, format_uri(), len, mb_cmdline_offset, mb_cmdlines, snprintf(), and image::uri.

Referenced by multiboot_add_modules(), and multiboot_exec().

◆ multiboot_add_modules()

static int multiboot_add_modules ( struct image image,
physaddr_t  start,
struct multiboot_info mbinfo,
struct multiboot_module modules,
unsigned int  limit 
)
static

Add multiboot modules.

Parameters
imageMultiboot image
startStart address for modules
mbinfoMultiboot information structure
modulesMultiboot module list
Return values
rcReturn status code

Definition at line 196 of file multiboot.c.

199  {
200  struct image *module_image;
201  struct multiboot_module *module;
202  int rc;
203 
204  /* Add each image as a multiboot module */
205  for_each_image ( module_image ) {
206 
207  if ( mbinfo->mods_count >= limit ) {
208  DBGC ( image, "MULTIBOOT %s limit of %d modules "
209  "reached\n", image->name, limit );
210  break;
211  }
212 
213  /* Skip hidden images */
214  if ( module_image->flags & IMAGE_HIDDEN )
215  continue;
216 
217  /* Page-align the module */
218  start = ( ( start + 0xfff ) & ~0xfff );
219 
220  /* Prepare segment */
221  if ( ( rc = prep_segment ( phys_to_virt ( start ),
222  module_image->len,
223  module_image->len ) ) != 0 ) {
224  DBGC ( image, "MULTIBOOT %s could not prepare module "
225  "%s: %s\n", image->name, module_image->name,
226  strerror ( rc ) );
227  return rc;
228  }
229 
230  /* Copy module */
231  memcpy ( phys_to_virt ( start ), module_image->data,
232  module_image->len );
233 
234  /* Add module to list */
235  module = &modules[mbinfo->mods_count++];
236  module->mod_start = start;
237  module->mod_end = ( start + module_image->len );
238  module->string = multiboot_add_cmdline ( module_image );
239  module->reserved = 0;
240  DBGC ( image, "MULTIBOOT %s module %s is [%x,%x)\n",
241  image->name, module_image->name, module->mod_start,
242  module->mod_end );
243  start += module_image->len;
244  }
245 
246  return 0;
247 }
unsigned int flags
Flags.
Definition: image.h:39
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
const void * data
Read-only data.
Definition: image.h:50
static physaddr_t multiboot_add_cmdline(struct image *image)
Add command line in base memory.
Definition: multiboot.c:158
#define DBGC(...)
Definition: compiler.h:505
An executable image.
Definition: image.h:23
#define mbinfo
Definition: multiboot.c:257
A multiboot module structure.
Definition: multiboot.h:131
uint32_t start
Starting offset.
Definition: netvsc.h:12
uint32_t mod_end
Definition: multiboot.h:133
void * memcpy(void *dest, const void *src, size_t len) __nonnull
#define for_each_image(image)
Iterate over all registered images.
Definition: image.h:190
uint16_t limit
Limit.
Definition: librm.h:136
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
size_t len
Length of raw file image.
Definition: image.h:55
#define IMAGE_HIDDEN
Image will be hidden from enumeration.
Definition: image.h:85
uint32_t reserved
Definition: multiboot.h:135
uint32_t mod_start
Definition: multiboot.h:132
uint32_t string
Definition: multiboot.h:134
int prep_segment(void *segment, size_t filesz, size_t memsz)
Prepare segment for loading.
Definition: segment.c:61
char * name
Name.
Definition: image.h:37

References image::data, DBGC, image::flags, for_each_image, IMAGE_HIDDEN, image::len, limit, mbinfo, memcpy(), multiboot_module::mod_end, multiboot_module::mod_start, multiboot_add_cmdline(), image::name, prep_segment(), rc, multiboot_module::reserved, start, strerror(), and multiboot_module::string.

Referenced by multiboot_exec().

◆ __bss16()

static struct multiboot_info __bss16 ( mbinfo  )
static

The multiboot information structure.

Kept in base memory because some OSes won't find it elsewhere, along with the other structures belonging to the Multiboot information table.

◆ __bss16_array() [2/4]

static char __bss16_array ( mb_bootloader_name  )
static

The multiboot bootloader name.

◆ __bss16_array() [3/4]

static struct multiboot_memory_map __bss16_array ( mbmemmap  )
static

The multiboot memory map.

◆ __bss16_array() [4/4]

static struct multiboot_module __bss16_array ( mbmodules  )
static

The multiboot module list.

◆ multiboot_find_header()

static int multiboot_find_header ( struct image image)
static

Find multiboot header.

Parameters
imageMultiboot file
Return values
offsetOffset to Multiboot header, or negative error

Definition at line 277 of file multiboot.c.

277  {
278  const struct multiboot_header *mb;
279  size_t offset;
281 
282  /* Scan through first 8kB of image file */
283  for ( offset = 0 ; offset < 8192 ; offset += 4 ) {
284  /* Check for end of image */
285  if ( ( offset + sizeof ( *mb ) ) > image->len )
286  break;
287  mb = ( image->data + offset );
288  /* Check signature */
289  if ( mb->magic != MULTIBOOT_HEADER_MAGIC )
290  continue;
291  /* Copy header and verify checksum */
292  checksum = ( mb->magic + mb->flags + mb->checksum );
293  if ( checksum != 0 )
294  continue;
295  /* Return header */
296  return offset;
297  }
298 
299  /* No multiboot header found */
300  DBGC ( image, "MULTIBOOT %s has no multiboot header\n",
301  image->name );
302  return -ENOEXEC;
303 }
uint8_t checksum
Checksum.
Definition: pnpbios.c:37
const void * data
Read-only data.
Definition: image.h:50
#define ENOEXEC
Exec format error.
Definition: errno.h:519
#define DBGC(...)
Definition: compiler.h:505
An executable image.
Definition: image.h:23
#define MULTIBOOT_HEADER_MAGIC
The magic number for the Multiboot header.
Definition: multiboot.h:16
size_t len
Length of raw file image.
Definition: image.h:55
unsigned int uint32_t
Definition: stdint.h:12
void mb(void)
Memory barrier.
uint16_t offset
Offset to command line.
Definition: bzimage.h:8
A multiboot header.
Definition: multiboot.h:75
char * name
Name.
Definition: image.h:37

References checksum, image::data, DBGC, ENOEXEC, image::len, mb(), MULTIBOOT_HEADER_MAGIC, image::name, and offset.

Referenced by multiboot_exec(), and multiboot_probe().

◆ multiboot_load_raw()

static int multiboot_load_raw ( struct image image,
size_t  offset,
physaddr_t entry,
physaddr_t max 
)
static

Load raw multiboot image into memory.

Parameters
imageMultiboot image
offsetOffset to Multiboot header
Return values
entryEntry point
maxMaximum used address
rcReturn status code

Definition at line 314 of file multiboot.c.

315  {
316  const struct multiboot_header *mb = ( image->data + offset );
317  size_t filesz;
318  size_t memsz;
319  void *buffer;
320  int rc;
321 
322  /* Sanity check */
323  if ( ! ( mb->flags & MB_FLAG_RAW ) ) {
324  DBGC ( image, "MULTIBOOT %s is not flagged as a raw image\n",
325  image->name );
326  return -EINVAL;
327  }
328 
329  /* Calculate starting offset within file */
330  if ( ( mb->load_addr > mb->header_addr ) ||
331  ( ( mb->header_addr - mb->load_addr ) > offset ) ) {
332  DBGC ( image, "MULTIBOOT %s has misplaced header\n",
333  image->name );
334  return -EINVAL;
335  }
336  offset -= ( mb->header_addr - mb->load_addr );
337  assert ( offset < image->len );
338 
339  /* Calculate length of initialized data */
340  filesz = ( mb->load_end_addr ?
341  ( mb->load_end_addr - mb->load_addr ) :
342  ( image->len - offset ) );
343  if ( filesz > image->len ) {
344  DBGC ( image, "MULTIBOOT %s has overlength data\n",
345  image->name );
346  return -EINVAL;
347  }
348 
349  /* Calculate length of uninitialised data */
350  memsz = ( mb->bss_end_addr ?
351  ( mb->bss_end_addr - mb->load_addr ) : filesz );
352  DBGC ( image, "MULTIBOOT %s loading [%zx,%zx) to [%x,%zx,%zx)\n",
353  image->name, offset, ( offset + filesz ), mb->load_addr,
354  ( mb->load_addr + filesz ), ( mb->load_addr + memsz ) );
355 
356  /* Verify and prepare segment */
357  buffer = phys_to_virt ( mb->load_addr );
358  if ( ( rc = prep_segment ( buffer, filesz, memsz ) ) != 0 ) {
359  DBGC ( image, "MULTIBOOT %s could not prepare segment: %s\n",
360  image->name, strerror ( rc ) );
361  return rc;
362  }
363 
364  /* Copy image to segment */
365  memcpy ( buffer, ( image->data + offset ), filesz );
366 
367  /* Record execution entry point and maximum used address */
368  *entry = mb->entry_addr;
369  *max = ( mb->load_addr + memsz );
370 
371  return 0;
372 }
#define EINVAL
Invalid argument.
Definition: errno.h:428
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
#define max(x, y)
Definition: ath.h:40
const void * data
Read-only data.
Definition: image.h:50
#define DBGC(...)
Definition: compiler.h:505
uint32_t buffer
Buffer index (or NETVSC_RNDIS_NO_BUFFER)
Definition: netvsc.h:16
An executable image.
Definition: image.h:23
void * memcpy(void *dest, const void *src, size_t len) __nonnull
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
ring len
Length.
Definition: dwmac.h:231
#define MB_FLAG_RAW
Image is a raw multiboot image (not ELF)
Definition: multiboot.h:28
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
size_t len
Length of raw file image.
Definition: image.h:55
static size_t memsz
Definition: fdtmem.c:51
void mb(void)
Memory barrier.
int prep_segment(void *segment, size_t filesz, size_t memsz)
Prepare segment for loading.
Definition: segment.c:61
uint16_t offset
Offset to command line.
Definition: bzimage.h:8
A multiboot header.
Definition: multiboot.h:75
char * name
Name.
Definition: image.h:37

References assert(), buffer, image::data, DBGC, EINVAL, image::len, len, max, mb(), MB_FLAG_RAW, memcpy(), memsz, image::name, offset, prep_segment(), rc, and strerror().

Referenced by multiboot_exec().

◆ multiboot_load_elf()

static int multiboot_load_elf ( struct image image,
physaddr_t entry,
physaddr_t max 
)
static

Load ELF multiboot image into memory.

Parameters
imageMultiboot file
Return values
entryEntry point
maxMaximum used address
rcReturn status code

Definition at line 382 of file multiboot.c.

383  {
384  int rc;
385 
386  /* Load ELF image*/
387  if ( ( rc = elf_load ( image, entry, max ) ) != 0 ) {
388  DBGC ( image, "MULTIBOOT %s ELF image failed to load: %s\n",
389  image->name, strerror ( rc ) );
390  return rc;
391  }
392 
393  return 0;
394 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
#define max(x, y)
Definition: ath.h:40
#define DBGC(...)
Definition: compiler.h:505
An executable image.
Definition: image.h:23
int elf_load(struct image *image, physaddr_t *entry, physaddr_t *max)
Load ELF image into memory.
Definition: elf.c:206
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
char * name
Name.
Definition: image.h:37

References DBGC, elf_load(), max, image::name, rc, and strerror().

Referenced by multiboot_exec().

◆ multiboot_exec()

static int multiboot_exec ( struct image image)
static

Execute multiboot image.

Parameters
imageMultiboot image
Return values
rcReturn status code

Definition at line 402 of file multiboot.c.

402  {
403  const struct multiboot_header *mb;
404  physaddr_t entry;
405  physaddr_t max;
406  int offset;
407  int rc;
408 
409  /* Locate multiboot header, if present */
411  if ( offset < 0 ) {
412  rc = offset;
413  return rc;
414  }
415  mb = ( image->data + offset );
416 
417  /* Abort if we detect flags that we cannot support */
418  if ( mb->flags & MB_UNSUPPORTED_FLAGS ) {
419  DBGC ( image, "MULTIBOOT %s flags %#08x not supported\n",
420  image->name, ( mb->flags & MB_UNSUPPORTED_FLAGS ) );
421  return -ENOTSUP;
422  }
423 
424  /* There is technically a bit MB_FLAG_RAW to indicate whether
425  * this is an ELF or a raw image. In practice, grub will use
426  * the ELF header if present, and Solaris relies on this
427  * behaviour.
428  */
429  if ( ( ( rc = multiboot_load_elf ( image, &entry, &max ) ) != 0 ) &&
430  ( ( rc = multiboot_load_raw ( image, offset, &entry,
431  &max ) ) != 0 ) ) {
432  return rc;
433  }
434 
435  /* Populate multiboot information structure */
436  memset ( &mbinfo, 0, sizeof ( mbinfo ) );
439  mb_cmdline_offset = 0;
440  mbinfo.cmdline = multiboot_add_cmdline ( image );
441  mbinfo.mods_addr = virt_to_phys ( mbmodules );
442  mbinfo.mmap_addr = virt_to_phys ( mbmemmap );
444  "iPXE %s", product_version );
445  mbinfo.boot_loader_name = virt_to_phys ( mb_bootloader_name );
447  ( sizeof ( mbmodules ) /
448  sizeof ( mbmodules[0] ) ) ) ) !=0)
449  return rc;
450 
451  /* Multiboot images may not return and have no callback
452  * interface, so shut everything down prior to booting the OS.
453  */
454  shutdown_boot();
455 
456  /* Build memory map after unhiding bootloader memory regions as part of
457  * shutting everything down.
458  */
460  ( sizeof(mbmemmap) / sizeof(mbmemmap[0]) ) );
461 
462  /* Jump to OS with flat physical addressing */
463  DBGC ( image, "MULTIBOOT %s starting execution at %lx\n",
464  image->name, entry );
465  __asm__ __volatile__ ( PHYS_CODE ( "pushl %%ebp\n\t"
466  "call *%%edi\n\t"
467  "popl %%ebp\n\t" )
468  : : "a" ( MULTIBOOT_BOOTLOADER_MAGIC ),
469  "b" ( virt_to_phys ( &mbinfo ) ),
470  "D" ( entry )
471  : "ecx", "edx", "esi", "memory" );
472 
473  DBGC ( image, "MULTIBOOT %s returned\n", image->name );
474 
475  /* It isn't safe to continue after calling shutdown() */
476  while ( 1 ) {}
477 
478  return -ECANCELED; /* -EIMPOSSIBLE, anyone? */
479 }
#define PHYS_CODE(asm_code_str)
Definition: librm.h:167
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
#define MBI_FLAG_CMDLINE
Multiboot information structure cmdline field is valid.
Definition: multiboot.h:45
#define max(x, y)
Definition: ath.h:40
static int multiboot_load_raw(struct image *image, size_t offset, physaddr_t *entry, physaddr_t *max)
Load raw multiboot image into memory.
Definition: multiboot.c:314
static int multiboot_add_modules(struct image *image, physaddr_t start, struct multiboot_info *mbinfo, struct multiboot_module *modules, unsigned int limit)
Add multiboot modules.
Definition: multiboot.c:196
const void * data
Read-only data.
Definition: image.h:50
static physaddr_t multiboot_add_cmdline(struct image *image)
Add command line in base memory.
Definition: multiboot.c:158
#define DBGC(...)
Definition: compiler.h:505
An executable image.
Definition: image.h:23
#define mbinfo
Definition: multiboot.c:257
#define MBI_FLAG_MMAP
Multiboot information structure memory map is valid.
Definition: multiboot.h:57
#define ECANCELED
Operation canceled.
Definition: errno.h:343
#define ENOTSUP
Operation not supported.
Definition: errno.h:589
static void multiboot_build_memmap(struct image *image, struct multiboot_info *mbinfo, struct multiboot_memory_map *mbmemmap, unsigned int limit)
Build multiboot memory map.
Definition: multiboot.c:108
static unsigned int mb_cmdline_offset
Offset within module command lines.
Definition: multiboot.c:98
static int multiboot_find_header(struct image *image)
Find multiboot header.
Definition: multiboot.c:277
__asm__ __volatile__("call *%9" :"=a"(result), "=c"(discard_ecx), "=d"(discard_edx) :"d"(0), "a"(code), "b"(0), "c"(in_phys), "D"(0), "S"(out_phys), "m"(hypercall))
const char product_version[]
Product version string.
Definition: version.c:70
#define mb_bootloader_name
Definition: multiboot.c:261
static int multiboot_load_elf(struct image *image, physaddr_t *entry, physaddr_t *max)
Load ELF multiboot image into memory.
Definition: multiboot.c:382
unsigned long physaddr_t
Definition: stdint.h:20
__asm__(".section \".rodata\", \"a\", " PROGBITS "\n\t" "\nprivate_key_data:\n\t" ".size private_key_data, ( . - private_key_data )\n\t" ".equ private_key_len, ( . - private_key_data )\n\t" ".previous\n\t")
#define MULTIBOOT_BOOTLOADER_MAGIC
The magic number passed by a Multiboot-compliant boot loader.
Definition: multiboot.h:36
#define MBI_FLAG_MODS
Multiboot information structure module fields are valid.
Definition: multiboot.h:48
#define MBI_FLAG_MEM
Multiboot information structure mem_* fields are valid.
Definition: multiboot.h:39
#define mbmemmap
Definition: multiboot.c:265
int snprintf(char *buf, size_t size, const char *fmt,...)
Write a formatted string to a buffer.
Definition: vsprintf.c:382
void mb(void)
Memory barrier.
uint16_t offset
Offset to command line.
Definition: bzimage.h:8
#define MB_UNSUPPORTED_FLAGS
Multiboot flags that we don't support.
Definition: multiboot.c:91
#define mbmodules
Definition: multiboot.c:269
#define MBI_FLAG_LOADER
Multiboot information structure boot loader name field is valid.
Definition: multiboot.h:66
A multiboot header.
Definition: multiboot.h:75
static void shutdown_boot(void)
Shut down system for OS boot.
Definition: init.h:77
char * name
Name.
Definition: image.h:37
void * memset(void *dest, int character, size_t len) __nonnull

References __asm__(), __volatile__(), image::data, DBGC, ECANCELED, ENOTSUP, max, mb(), mb_bootloader_name, mb_cmdline_offset, MB_UNSUPPORTED_FLAGS, MBI_FLAG_CMDLINE, MBI_FLAG_LOADER, MBI_FLAG_MEM, MBI_FLAG_MMAP, MBI_FLAG_MODS, mbinfo, mbmemmap, mbmodules, memset(), multiboot_add_cmdline(), multiboot_add_modules(), MULTIBOOT_BOOTLOADER_MAGIC, multiboot_build_memmap(), multiboot_find_header(), multiboot_load_elf(), multiboot_load_raw(), image::name, offset, PHYS_CODE, product_version, rc, shutdown_boot(), and snprintf().

◆ multiboot_probe()

static int multiboot_probe ( struct image image)
static

Probe multiboot image.

Parameters
imageMultiboot file
Return values
rcReturn status code

Definition at line 487 of file multiboot.c.

487  {
488  const struct multiboot_header *mb;
489  int offset;
490  int rc;
491 
492  /* Locate multiboot header, if present */
494  if ( offset < 0 ) {
495  rc = offset;
496  return rc;
497  }
498  mb = ( image->data + offset );
499  DBGC ( image, "MULTIBOOT %s found header at +%#x with flags %#08x\n",
500  image->name, offset, mb->flags );
501 
502  return 0;
503 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
const void * data
Read-only data.
Definition: image.h:50
#define DBGC(...)
Definition: compiler.h:505
An executable image.
Definition: image.h:23
static int multiboot_find_header(struct image *image)
Find multiboot header.
Definition: multiboot.c:277
void mb(void)
Memory barrier.
uint16_t offset
Offset to command line.
Definition: bzimage.h:8
A multiboot header.
Definition: multiboot.h:75
char * name
Name.
Definition: image.h:37

References image::data, DBGC, mb(), multiboot_find_header(), image::name, offset, and rc.

◆ __image_type()

struct image_type multiboot_image_type __image_type ( PROBE_MULTIBOOT  )

Multiboot image type.

Variable Documentation

◆ mb_cmdline_offset

unsigned int mb_cmdline_offset
static

Offset within module command lines.

Definition at line 98 of file multiboot.c.

Referenced by multiboot_add_cmdline(), and multiboot_exec().