iPXE
multiboot.c
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2007 Michael Brown <mbrown@fensystems.co.uk>.
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License as
6  * published by the Free Software Foundation; either version 2 of the
7  * License, or any later version.
8  *
9  * This program is distributed in the hope that it will be useful, but
10  * WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12  * General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
17  * 02110-1301, USA.
18  *
19  * You can also choose to distribute this program under the terms of
20  * the Unmodified Binary Distribution Licence (as given in the file
21  * COPYING.UBDL), provided that you have satisfied its requirements.
22  */
23 
24 FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
25 
26 /**
27  * @file
28  *
29  * Multiboot image format
30  *
31  */
32 
33 #include <stdio.h>
34 #include <string.h>
35 #include <errno.h>
36 #include <assert.h>
37 #include <realmode.h>
38 #include <multiboot.h>
39 #include <ipxe/image.h>
40 #include <ipxe/segment.h>
41 #include <ipxe/memmap.h>
42 #include <ipxe/elf.h>
43 #include <ipxe/init.h>
44 #include <ipxe/features.h>
45 #include <ipxe/uri.h>
46 #include <ipxe/version.h>
47 
49 
50 /**
51  * Maximum number of modules we will allow for
52  *
53  * If this has bitten you: sorry. I did have a perfect scheme with a
54  * dynamically allocated list of modules on the protected-mode stack,
55  * but it was incompatible with some broken OSes that can only access
56  * low memory at boot time (even though we kindly set up 4GB flat
57  * physical addressing as per the multiboot specification.
58  *
59  */
60 #define MAX_MODULES 8
61 
62 /** Maximum number of memory map entries */
63 #define MAX_MEMMAP 8
64 
65 /**
66  * Maximum combined length of command lines
67  *
68  * Again; sorry. Some broken OSes zero out any non-base memory that
69  * isn't part of the loaded module set, so we can't just use
70  * virt_to_phys(cmdline) to point to the command lines, even though
71  * this would comply with the Multiboot spec.
72  */
73 #define MB_MAX_CMDLINE 512
74 
75 /** Multiboot flags that we support */
76 #define MB_SUPPORTED_FLAGS ( MB_FLAG_PGALIGN | MB_FLAG_MEMMAP | \
77  MB_FLAG_VIDMODE | MB_FLAG_RAW )
78 
79 /** Compulsory feature multiboot flags */
80 #define MB_COMPULSORY_FLAGS 0x0000ffff
81 
82 /** Optional feature multiboot flags */
83 #define MB_OPTIONAL_FLAGS 0xffff0000
84 
85 /**
86  * Multiboot flags that we don't support
87  *
88  * We only care about the compulsory feature flags (bits 0-15); we are
89  * allowed to ignore the optional feature flags.
90  */
91 #define MB_UNSUPPORTED_FLAGS ( MB_COMPULSORY_FLAGS & ~MB_SUPPORTED_FLAGS )
92 
93 /** Multiboot module command lines */
94 static char __bss16_array ( mb_cmdlines, [MB_MAX_CMDLINE] );
95 #define mb_cmdlines __use_data16 ( mb_cmdlines )
96 
97 /** Offset within module command lines */
98 static unsigned int mb_cmdline_offset;
99 
100 /**
101  * Build multiboot memory map
102  *
103  * @v image Multiboot image
104  * @v mbinfo Multiboot information structure
105  * @v mbmemmap Multiboot memory map
106  * @v limit Maxmimum number of memory map entries
107  */
108 static void multiboot_build_memmap ( struct image *image,
109  struct multiboot_info *mbinfo,
111  unsigned int limit ) {
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 }
151 
152 /**
153  * Add command line in base memory
154  *
155  * @v image Image
156  * @ret physaddr Physical address of command line
157  */
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 }
186 
187 /**
188  * Add multiboot modules
189  *
190  * @v image Multiboot image
191  * @v start Start address for modules
192  * @v mbinfo Multiboot information structure
193  * @v modules Multiboot module list
194  * @ret rc Return status code
195  */
197  struct multiboot_info *mbinfo,
198  struct multiboot_module *modules,
199  unsigned int limit ) {
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 }
248 
249 /**
250  * The multiboot information structure
251  *
252  * Kept in base memory because some OSes won't find it elsewhere,
253  * along with the other structures belonging to the Multiboot
254  * information table.
255  */
256 static struct multiboot_info __bss16 ( mbinfo );
257 #define mbinfo __use_data16 ( mbinfo )
258 
259 /** The multiboot bootloader name */
260 static char __bss16_array ( mb_bootloader_name, [32] );
261 #define mb_bootloader_name __use_data16 ( mb_bootloader_name )
262 
263 /** The multiboot memory map */
265 #define mbmemmap __use_data16 ( mbmemmap )
266 
267 /** The multiboot module list */
269 #define mbmodules __use_data16 ( mbmodules )
270 
271 /**
272  * Find multiboot header
273  *
274  * @v image Multiboot file
275  * @ret offset Offset to Multiboot header, or negative error
276  */
277 static int multiboot_find_header ( struct image *image ) {
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 }
304 
305 /**
306  * Load raw multiboot image into memory
307  *
308  * @v image Multiboot image
309  * @v offset Offset to Multiboot header
310  * @ret entry Entry point
311  * @ret max Maximum used address
312  * @ret rc Return status code
313  */
314 static int multiboot_load_raw ( struct image *image, size_t offset,
315  physaddr_t *entry, physaddr_t *max ) {
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 }
373 
374 /**
375  * Load ELF multiboot image into memory
376  *
377  * @v image Multiboot file
378  * @ret entry Entry point
379  * @ret max Maximum used address
380  * @ret rc Return status code
381  */
382 static int multiboot_load_elf ( struct image *image, physaddr_t *entry,
383  physaddr_t *max ) {
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 }
395 
396 /**
397  * Execute multiboot image
398  *
399  * @v image Multiboot image
400  * @ret rc Return status code
401  */
402 static int multiboot_exec ( struct image *image ) {
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 }
480 
481 /**
482  * Probe multiboot image
483  *
484  * @v image Multiboot file
485  * @ret rc Return status code
486  */
487 static int multiboot_probe ( struct image *image ) {
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 }
504 
505 /** Multiboot image type */
506 struct image_type multiboot_image_type __image_type ( PROBE_MULTIBOOT ) = {
507  .name = "Multiboot",
508  .probe = multiboot_probe,
509  .exec = multiboot_exec,
510 };
struct image_type multiboot_image_type __image_type(PROBE_MULTIBOOT)
Multiboot image type.
#define PHYS_CODE(asm_code_str)
Definition: librm.h:167
unsigned int flags
Flags.
Definition: image.h:39
#define EINVAL
Invalid argument.
Definition: errno.h:428
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
uint8_t checksum
Checksum.
Definition: pnpbios.c:37
static int multiboot_probe(struct image *image)
Probe multiboot image.
Definition: multiboot.c:487
#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
#define MB_MAX_CMDLINE
Maximum combined length of command lines.
Definition: multiboot.c:73
Error codes.
const void * data
Read-only data.
Definition: image.h:50
#define ENOEXEC
Exec format error.
Definition: errno.h:519
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 type.
Definition: image.h:94
static struct multiboot_info __bss16(mbinfo)
The multiboot information structure.
uint32_t buffer
Buffer index (or NETVSC_RNDIS_NO_BUFFER)
Definition: netvsc.h:16
An executable image.
Definition: image.h:23
#define FEATURE_IMAGE
Image formats.
Definition: features.h:22
Uniform Resource Identifiers.
A multiboot information structure.
Definition: multiboot.h:103
#define mbinfo
Definition: multiboot.c:257
A multiboot module structure.
Definition: multiboot.h:131
#define MULTIBOOT_HEADER_MAGIC
The magic number for the Multiboot header.
Definition: multiboot.h:16
#define DBGC_MEMMAP(...)
Definition: memmap.h:206
#define MBI_FLAG_MMAP
Multiboot information structure memory map is valid.
Definition: multiboot.h:57
#define mb_cmdlines
Definition: multiboot.c:95
#define ECANCELED
Operation canceled.
Definition: errno.h:343
char * name
Name of this image type.
Definition: image.h:96
#define ENOTSUP
Operation not supported.
Definition: errno.h:589
char * cmdline
Command line to pass to image.
Definition: image.h:42
ELF image format.
uint32_t start
Starting offset.
Definition: netvsc.h:12
A multiboot memory map entry.
Definition: multiboot.h:139
Executable image segments.
uint32_t mod_end
Definition: multiboot.h:133
void * memcpy(void *dest, const void *src, size_t len) __nonnull
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
Assertions.
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
int elf_load(struct image *image, physaddr_t *entry, physaddr_t *max)
Load ELF image into memory.
Definition: elf.c:206
Executable images.
#define for_each_memmap(region, hide)
Iterate over memory regions.
Definition: memmap.h:183
ring len
Length.
Definition: dwmac.h:231
Feature list.
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
FEATURE(FEATURE_IMAGE, "MBOOT", DHCP_EB_FEATURE_MULTIBOOT, 1)
#define MB_FLAG_RAW
Image is a raw multiboot image (not ELF)
Definition: multiboot.h:28
#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
unsigned int flags
Region flags.
Definition: memmap.h:54
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
static int multiboot_find_header(struct image *image)
Find multiboot header.
Definition: multiboot.c:277
struct uri * uri
URI of image.
Definition: image.h:31
__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
Multiboot operating systems.
FILE_LICENCE(GPL2_OR_LATER_OR_UBDL)
static int multiboot_load_elf(struct image *image, physaddr_t *entry, physaddr_t *max)
Load ELF multiboot image into memory.
Definition: multiboot.c:382
Version number.
unsigned int uint32_t
Definition: stdint.h:12
uint32_t reserved
Definition: multiboot.h:135
unsigned long physaddr_t
Definition: stdint.h:20
uint32_t mod_start
Definition: multiboot.h:132
#define MAX_MEMMAP
Maximum number of memory map entries.
Definition: multiboot.c:63
#define DHCP_EB_FEATURE_MULTIBOOT
Multiboot format.
Definition: features.h:45
__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
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
uint32_t string
Definition: multiboot.h:134
static size_t memsz
Definition: fdtmem.c:51
uint64_t min
Minimum address in region.
Definition: memmap.h:50
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.
int prep_segment(void *segment, size_t filesz, size_t memsz)
Prepare segment for loading.
Definition: segment.c:61
#define MAX_MODULES
Maximum number of modules we will allow for.
Definition: multiboot.c:60
A memory region descriptor.
Definition: memmap.h:48
uint16_t offset
Offset to command line.
Definition: bzimage.h:8
static int multiboot_exec(struct image *image)
Execute multiboot image.
Definition: multiboot.c:402
#define MB_UNSUPPORTED_FLAGS
Multiboot flags that we don't support.
Definition: multiboot.c:91
static char __bss16_array(mb_cmdlines, [MB_MAX_CMDLINE])
Multiboot module command lines.
#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
#define PROBE_MULTIBOOT
Multiboot image probe priority.
Definition: image.h:150
System memory map.
String functions.
void * memset(void *dest, int character, size_t len) __nonnull