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 <errno.h>
35 #include <assert.h>
36 #include <realmode.h>
37 #include <multiboot.h>
38 #include <ipxe/uaccess.h>
39 #include <ipxe/image.h>
40 #include <ipxe/segment.h>
41 #include <ipxe/io.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 /**
63  * Maximum combined length of command lines
64  *
65  * Again; sorry. Some broken OSes zero out any non-base memory that
66  * isn't part of the loaded module set, so we can't just use
67  * virt_to_phys(cmdline) to point to the command lines, even though
68  * this would comply with the Multiboot spec.
69  */
70 #define MB_MAX_CMDLINE 512
71 
72 /** Multiboot flags that we support */
73 #define MB_SUPPORTED_FLAGS ( MB_FLAG_PGALIGN | MB_FLAG_MEMMAP | \
74  MB_FLAG_VIDMODE | MB_FLAG_RAW )
75 
76 /** Compulsory feature multiboot flags */
77 #define MB_COMPULSORY_FLAGS 0x0000ffff
78 
79 /** Optional feature multiboot flags */
80 #define MB_OPTIONAL_FLAGS 0xffff0000
81 
82 /**
83  * Multiboot flags that we don't support
84  *
85  * We only care about the compulsory feature flags (bits 0-15); we are
86  * allowed to ignore the optional feature flags.
87  */
88 #define MB_UNSUPPORTED_FLAGS ( MB_COMPULSORY_FLAGS & ~MB_SUPPORTED_FLAGS )
89 
90 /** A multiboot header descriptor */
92  /** The actual multiboot header */
94  /** Offset of header within the multiboot image */
95  size_t offset;
96 };
97 
98 /** Multiboot module command lines */
99 static char __bss16_array ( mb_cmdlines, [MB_MAX_CMDLINE] );
100 #define mb_cmdlines __use_data16 ( mb_cmdlines )
101 
102 /** Offset within module command lines */
103 static unsigned int mb_cmdline_offset;
104 
105 /**
106  * Build multiboot memory map
107  *
108  * @v image Multiboot image
109  * @v mbinfo Multiboot information structure
110  * @v mbmemmap Multiboot memory map
111  * @v limit Maxmimum number of memory map entries
112  */
113 static void multiboot_build_memmap ( struct image *image,
114  struct multiboot_info *mbinfo,
116  unsigned int limit ) {
117  struct memory_map memmap;
118  unsigned int i;
119 
120  /* Get memory map */
121  get_memmap ( &memmap );
122 
123  /* Translate into multiboot format */
124  memset ( mbmemmap, 0, sizeof ( *mbmemmap ) );
125  for ( i = 0 ; i < memmap.count ; i++ ) {
126  if ( i >= limit ) {
127  DBGC ( image, "MULTIBOOT %p limit of %d memmap "
128  "entries reached\n", image, limit );
129  break;
130  }
131  mbmemmap[i].size = ( sizeof ( mbmemmap[i] ) -
132  sizeof ( mbmemmap[i].size ) );
133  mbmemmap[i].base_addr = memmap.regions[i].start;
134  mbmemmap[i].length = ( memmap.regions[i].end -
135  memmap.regions[i].start );
136  mbmemmap[i].type = MBMEM_RAM;
137  mbinfo->mmap_length += sizeof ( mbmemmap[i] );
138  if ( memmap.regions[i].start == 0 )
139  mbinfo->mem_lower = ( memmap.regions[i].end / 1024 );
140  if ( memmap.regions[i].start == 0x100000 )
141  mbinfo->mem_upper = ( ( memmap.regions[i].end -
142  0x100000 ) / 1024 );
143  }
144 }
145 
146 /**
147  * Add command line in base memory
148  *
149  * @v image Image
150  * @ret physaddr Physical address of command line
151  */
153  char *mb_cmdline = ( mb_cmdlines + mb_cmdline_offset );
154  size_t remaining = ( sizeof ( mb_cmdlines ) - mb_cmdline_offset );
155  char *buf = mb_cmdline;
156  size_t len;
157 
158  /* Copy image URI to base memory buffer as start of command line */
159  len = ( format_uri ( image->uri, buf, remaining ) + 1 /* NUL */ );
160  if ( len > remaining )
161  len = remaining;
163  buf += len;
164  remaining -= len;
165 
166  /* Copy command line to base memory buffer, if present */
167  if ( image->cmdline ) {
168  mb_cmdline_offset--; /* Strip NUL */
169  buf--;
170  remaining++;
171  len = ( snprintf ( buf, remaining, " %s",
172  image->cmdline ) + 1 /* NUL */ );
173  if ( len > remaining )
174  len = remaining;
176  }
177 
178  return virt_to_phys ( mb_cmdline );
179 }
180 
181 /**
182  * Add multiboot modules
183  *
184  * @v image Multiboot image
185  * @v start Start address for modules
186  * @v mbinfo Multiboot information structure
187  * @v modules Multiboot module list
188  * @ret rc Return status code
189  */
191  struct multiboot_info *mbinfo,
192  struct multiboot_module *modules,
193  unsigned int limit ) {
194  struct image *module_image;
195  struct multiboot_module *module;
196  int rc;
197 
198  /* Add each image as a multiboot module */
199  for_each_image ( module_image ) {
200 
201  if ( mbinfo->mods_count >= limit ) {
202  DBGC ( image, "MULTIBOOT %p limit of %d modules "
203  "reached\n", image, limit );
204  break;
205  }
206 
207  /* Do not include kernel image itself as a module */
208  if ( module_image == image )
209  continue;
210 
211  /* Page-align the module */
212  start = ( ( start + 0xfff ) & ~0xfff );
213 
214  /* Prepare segment */
215  if ( ( rc = prep_segment ( phys_to_user ( start ),
216  module_image->len,
217  module_image->len ) ) != 0 ) {
218  DBGC ( image, "MULTIBOOT %p could not prepare module "
219  "%s: %s\n", image, module_image->name,
220  strerror ( rc ) );
221  return rc;
222  }
223 
224  /* Copy module */
225  memcpy_user ( phys_to_user ( start ), 0,
226  module_image->data, 0, module_image->len );
227 
228  /* Add module to list */
229  module = &modules[mbinfo->mods_count++];
230  module->mod_start = start;
231  module->mod_end = ( start + module_image->len );
232  module->string = multiboot_add_cmdline ( module_image );
233  module->reserved = 0;
234  DBGC ( image, "MULTIBOOT %p module %s is [%x,%x)\n",
235  image, module_image->name, module->mod_start,
236  module->mod_end );
237  start += module_image->len;
238  }
239 
240  return 0;
241 }
242 
243 /**
244  * The multiboot information structure
245  *
246  * Kept in base memory because some OSes won't find it elsewhere,
247  * along with the other structures belonging to the Multiboot
248  * information table.
249  */
250 static struct multiboot_info __bss16 ( mbinfo );
251 #define mbinfo __use_data16 ( mbinfo )
252 
253 /** The multiboot bootloader name */
254 static char __bss16_array ( mb_bootloader_name, [32] );
255 #define mb_bootloader_name __use_data16 ( mb_bootloader_name )
256 
257 /** The multiboot memory map */
258 static struct multiboot_memory_map
260 #define mbmemmap __use_data16 ( mbmemmap )
261 
262 /** The multiboot module list */
264 #define mbmodules __use_data16 ( mbmodules )
265 
266 /**
267  * Find multiboot header
268  *
269  * @v image Multiboot file
270  * @v hdr Multiboot header descriptor to fill in
271  * @ret rc Return status code
272  */
273 static int multiboot_find_header ( struct image *image,
274  struct multiboot_header_info *hdr ) {
275  uint32_t buf[64];
276  size_t offset;
277  unsigned int buf_idx;
279 
280  /* Scan through first 8kB of image file 256 bytes at a time.
281  * (Use the buffering to avoid the overhead of a
282  * copy_from_user() for every dword.)
283  */
284  for ( offset = 0 ; offset < 8192 ; offset += sizeof ( buf[0] ) ) {
285  /* Check for end of image */
286  if ( offset > image->len )
287  break;
288  /* Refill buffer if applicable */
289  buf_idx = ( ( offset % sizeof ( buf ) ) / sizeof ( buf[0] ) );
290  if ( buf_idx == 0 ) {
291  copy_from_user ( buf, image->data, offset,
292  sizeof ( buf ) );
293  }
294  /* Check signature */
295  if ( buf[buf_idx] != MULTIBOOT_HEADER_MAGIC )
296  continue;
297  /* Copy header and verify checksum */
298  copy_from_user ( &hdr->mb, image->data, offset,
299  sizeof ( hdr->mb ) );
300  checksum = ( hdr->mb.magic + hdr->mb.flags +
301  hdr->mb.checksum );
302  if ( checksum != 0 )
303  continue;
304  /* Record offset of multiboot header and return */
305  hdr->offset = offset;
306  return 0;
307  }
308 
309  /* No multiboot header found */
310  return -ENOEXEC;
311 }
312 
313 /**
314  * Load raw multiboot image into memory
315  *
316  * @v image Multiboot file
317  * @v hdr Multiboot header descriptor
318  * @ret entry Entry point
319  * @ret max Maximum used address
320  * @ret rc Return status code
321  */
322 static int multiboot_load_raw ( struct image *image,
323  struct multiboot_header_info *hdr,
325  size_t offset;
326  size_t filesz;
327  size_t memsz;
329  int rc;
330 
331  /* Sanity check */
332  if ( ! ( hdr->mb.flags & MB_FLAG_RAW ) ) {
333  DBGC ( image, "MULTIBOOT %p is not flagged as a raw image\n",
334  image );
335  return -EINVAL;
336  }
337 
338  /* Verify and prepare segment */
339  offset = ( hdr->offset - hdr->mb.header_addr + hdr->mb.load_addr );
340  filesz = ( hdr->mb.load_end_addr ?
341  ( hdr->mb.load_end_addr - hdr->mb.load_addr ) :
342  ( image->len - offset ) );
343  memsz = ( hdr->mb.bss_end_addr ?
344  ( hdr->mb.bss_end_addr - hdr->mb.load_addr ) : filesz );
345  buffer = phys_to_user ( hdr->mb.load_addr );
346  if ( ( rc = prep_segment ( buffer, filesz, memsz ) ) != 0 ) {
347  DBGC ( image, "MULTIBOOT %p could not prepare segment: %s\n",
348  image, strerror ( rc ) );
349  return rc;
350  }
351 
352  /* Copy image to segment */
353  memcpy_user ( buffer, 0, image->data, offset, filesz );
354 
355  /* Record execution entry point and maximum used address */
356  *entry = hdr->mb.entry_addr;
357  *max = ( hdr->mb.load_addr + memsz );
358 
359  return 0;
360 }
361 
362 /**
363  * Load ELF multiboot image into memory
364  *
365  * @v image Multiboot file
366  * @ret entry Entry point
367  * @ret max Maximum used address
368  * @ret rc Return status code
369  */
371  physaddr_t *max ) {
372  int rc;
373 
374  /* Load ELF image*/
375  if ( ( rc = elf_load ( image, entry, max ) ) != 0 ) {
376  DBGC ( image, "MULTIBOOT %p ELF image failed to load: %s\n",
377  image, strerror ( rc ) );
378  return rc;
379  }
380 
381  return 0;
382 }
383 
384 /**
385  * Execute multiboot image
386  *
387  * @v image Multiboot image
388  * @ret rc Return status code
389  */
390 static int multiboot_exec ( struct image *image ) {
391  struct multiboot_header_info hdr;
393  physaddr_t max;
394  int rc;
395 
396  /* Locate multiboot header, if present */
397  if ( ( rc = multiboot_find_header ( image, &hdr ) ) != 0 ) {
398  DBGC ( image, "MULTIBOOT %p has no multiboot header\n",
399  image );
400  return rc;
401  }
402 
403  /* Abort if we detect flags that we cannot support */
404  if ( hdr.mb.flags & MB_UNSUPPORTED_FLAGS ) {
405  DBGC ( image, "MULTIBOOT %p flags %08x not supported\n",
406  image, ( hdr.mb.flags & MB_UNSUPPORTED_FLAGS ) );
407  return -ENOTSUP;
408  }
409 
410  /* There is technically a bit MB_FLAG_RAW to indicate whether
411  * this is an ELF or a raw image. In practice, grub will use
412  * the ELF header if present, and Solaris relies on this
413  * behaviour.
414  */
415  if ( ( ( rc = multiboot_load_elf ( image, &entry, &max ) ) != 0 ) &&
416  ( ( rc = multiboot_load_raw ( image, &hdr, &entry, &max ) ) != 0 ))
417  return rc;
418 
419  /* Populate multiboot information structure */
420  memset ( &mbinfo, 0, sizeof ( mbinfo ) );
423  mb_cmdline_offset = 0;
424  mbinfo.cmdline = multiboot_add_cmdline ( image );
425  mbinfo.mods_addr = virt_to_phys ( mbmodules );
426  mbinfo.mmap_addr = virt_to_phys ( mbmemmap );
428  "iPXE %s", product_version );
429  mbinfo.boot_loader_name = virt_to_phys ( mb_bootloader_name );
431  ( sizeof ( mbmodules ) /
432  sizeof ( mbmodules[0] ) ) ) ) !=0)
433  return rc;
434 
435  /* Multiboot images may not return and have no callback
436  * interface, so shut everything down prior to booting the OS.
437  */
438  shutdown_boot();
439 
440  /* Build memory map after unhiding bootloader memory regions as part of
441  * shutting everything down.
442  */
444  ( sizeof(mbmemmap) / sizeof(mbmemmap[0]) ) );
445 
446  /* Jump to OS with flat physical addressing */
447  DBGC ( image, "MULTIBOOT %p starting execution at %lx\n",
448  image, entry );
449  __asm__ __volatile__ ( PHYS_CODE ( "pushl %%ebp\n\t"
450  "call *%%edi\n\t"
451  "popl %%ebp\n\t" )
452  : : "a" ( MULTIBOOT_BOOTLOADER_MAGIC ),
453  "b" ( virt_to_phys ( &mbinfo ) ),
454  "D" ( entry )
455  : "ecx", "edx", "esi", "memory" );
456 
457  DBGC ( image, "MULTIBOOT %p returned\n", image );
458 
459  /* It isn't safe to continue after calling shutdown() */
460  while ( 1 ) {}
461 
462  return -ECANCELED; /* -EIMPOSSIBLE, anyone? */
463 }
464 
465 /**
466  * Probe multiboot image
467  *
468  * @v image Multiboot file
469  * @ret rc Return status code
470  */
471 static int multiboot_probe ( struct image *image ) {
472  struct multiboot_header_info hdr;
473  int rc;
474 
475  /* Locate multiboot header, if present */
476  if ( ( rc = multiboot_find_header ( image, &hdr ) ) != 0 ) {
477  DBGC ( image, "MULTIBOOT %p has no multiboot header\n",
478  image );
479  return rc;
480  }
481  DBGC ( image, "MULTIBOOT %p found header with flags %08x\n",
482  image, hdr.mb.flags );
483 
484  return 0;
485 }
486 
487 /** Multiboot image type */
488 struct image_type multiboot_image_type __image_type ( PROBE_MULTIBOOT ) = {
489  .name = "Multiboot",
490  .probe = multiboot_probe,
491  .exec = multiboot_exec,
492 };
struct image_type multiboot_image_type __image_type(PROBE_MULTIBOOT)
Multiboot image type.
#define PHYS_CODE(asm_code_str)
Definition: librm.h:279
#define EINVAL
Invalid argument.
Definition: errno.h:428
iPXE I/O API
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
void get_memmap(struct memory_map *memmap)
Get memory map.
uint8_t checksum
Checksum.
Definition: pnpbios.c:37
userptr_t data
Raw file image.
Definition: image.h:41
static int multiboot_probe(struct image *image)
Probe multiboot image.
Definition: multiboot.c:471
#define max(x, y)
Definition: ath.h:39
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:190
#define MB_MAX_CMDLINE
Maximum combined length of command lines.
Definition: multiboot.c:70
unsigned int count
Number of used regions.
Definition: io.h:503
Error codes.
#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:152
static __always_inline void copy_from_user(void *dest, userptr_t src, off_t src_off, size_t len)
Copy data from user buffer.
Definition: uaccess.h:337
#define DBGC(...)
Definition: compiler.h:505
An executable image type.
Definition: image.h:76
static struct multiboot_info __bss16(mbinfo)
The multiboot information structure.
userptr_t phys_to_user(unsigned long phys_addr)
Convert physical address to user pointer.
uint32_t buffer
Buffer index (or NETVSC_RNDIS_NO_BUFFER)
Definition: netvsc.h:16
An executable image.
Definition: image.h:24
#define FEATURE_IMAGE
Image formats.
Definition: features.h:22
Uniform Resource Identifiers.
A memory map.
Definition: io.h:499
A multiboot information structure.
Definition: multiboot.h:103
#define mbinfo
Definition: multiboot.c:251
A multiboot module structure.
Definition: multiboot.h:131
A multiboot header descriptor.
Definition: multiboot.c:91
#define MULTIBOOT_HEADER_MAGIC
The magic number for the Multiboot header.
Definition: multiboot.h:16
static __always_inline unsigned long virt_to_phys(volatile const void *addr)
Convert virtual address to a physical address.
Definition: uaccess.h:287
Access to external ("user") memory.
#define MBI_FLAG_MMAP
Multiboot information structure memory map is valid.
Definition: multiboot.h:57
#define mb_cmdlines
Definition: multiboot.c:100
struct multiboot_header mb
The actual multiboot header.
Definition: multiboot.c:93
#define ECANCELED
Operation canceled.
Definition: errno.h:343
char * name
Name of this image type.
Definition: image.h:78
#define ENOTSUP
Operation not supported.
Definition: errno.h:589
char * cmdline
Command line to pass to image.
Definition: image.h:39
ELF image format.
uint32_t start
Starting offset.
Definition: netvsc.h:12
#define MAX_MEMORY_REGIONS
Maximum number of memory regions we expect to encounter.
Definition: io.h:496
struct memory_region regions[MAX_MEMORY_REGIONS]
Memory regions.
Definition: io.h:501
A multiboot memory map entry.
Definition: multiboot.h:139
Executable image segments.
uint32_t mod_end
Definition: multiboot.h:133
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:113
Assertions.
int prep_segment(userptr_t segment, size_t filesz, size_t memsz)
Prepare segment for loading.
Definition: segment.c:60
int elf_load(struct image *image, physaddr_t *entry, physaddr_t *max)
Load ELF image into memory.
Definition: elf.c:201
Executable images.
static userptr_t size_t offset
Offset of the first segment within the content.
Definition: deflate.h:259
Feature list.
size_t format_uri(const struct uri *uri, char *buf, size_t len)
Format URI.
Definition: uri.c:457
static unsigned int mb_cmdline_offset
Offset within module command lines.
Definition: multiboot.c:103
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:149
uint16_t limit
Limit.
Definition: librm.h:250
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
union aes_table_entry entry[256]
Table entries, indexed by S(N)
Definition: aes.c:26
size_t len
Length of raw file image.
Definition: image.h:43
struct uri * uri
URI of image.
Definition: image.h:32
const char product_version[]
Product version string.
Definition: version.c:69
#define mb_bootloader_name
Definition: multiboot.c:255
Multiboot operating systems.
static int multiboot_find_header(struct image *image, struct multiboot_header_info *hdr)
Find multiboot header.
Definition: multiboot.c:273
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:370
Version number.
unsigned int uint32_t
Definition: stdint.h:12
__asm__ __volatile__("\n1:\n\t" "movb -1(%2,%1), %%al\n\t" "stosb\n\t" "loop 1b\n\t" "xorl %%eax, %%eax\n\t" "mov %3, %1\n\t" "rep stosb\n\t" :"=&D"(discard_D), "=&c"(discard_c) :"r"(data), "g"(pad_len), "0"(value0), "1"(len) :"eax")
uint32_t hdr
Message header.
Definition: intelvf.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 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
uint32_t len
Length.
Definition: ena.h:14
uint64_t start
Physical start address.
Definition: io.h:490
#define MBI_FLAG_MEM
Multiboot information structure mem_* fields are valid.
Definition: multiboot.h:39
#define MBMEM_RAM
Usable RAM.
Definition: multiboot.h:147
#define mbmemmap
Definition: multiboot.c:260
uint32_t string
Definition: multiboot.h:134
uint8_t size
Entry size (in 32-bit words)
Definition: ena.h:16
int snprintf(char *buf, size_t size, const char *fmt,...)
Write a formatted string to a buffer.
Definition: vsprintf.c:382
static int multiboot_load_raw(struct image *image, struct multiboot_header_info *hdr, physaddr_t *entry, physaddr_t *max)
Load raw multiboot image into memory.
Definition: multiboot.c:322
#define MAX_MODULES
Maximum number of modules we will allow for.
Definition: multiboot.c:60
static int multiboot_exec(struct image *image)
Execute multiboot image.
Definition: multiboot.c:390
#define MB_UNSUPPORTED_FLAGS
Multiboot flags that we don't support.
Definition: multiboot.c:88
static char __bss16_array(mb_cmdlines, [MB_MAX_CMDLINE])
Multiboot module command lines.
#define mbmodules
Definition: multiboot.c:264
uint64_t end
Physical end address.
Definition: io.h:492
size_t offset
Offset of header within the multiboot image.
Definition: multiboot.c:95
#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:76
char * name
Name.
Definition: image.h:34
#define PROBE_MULTIBOOT
Multiboot image probe priority.
Definition: image.h:124
void memcpy_user(userptr_t dest, off_t dest_off, userptr_t src, off_t src_off, size_t len)
Copy data between user buffers.
unsigned long userptr_t
A pointer to a user buffer.
Definition: uaccess.h:33
void * memset(void *dest, int character, size_t len) __nonnull