#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <assert.h>
#include <realmode.h>
#include <bzimage.h>
#include <gpxe/uaccess.h>
#include <gpxe/image.h>
#include <gpxe/segment.h>
#include <gpxe/init.h>
#include <gpxe/cpio.h>
#include <gpxe/features.h>
Go to the source code of this file.
Data Structures | |
| struct | bzimage_context |
| bzImage context More... | |
Functions | |
| FILE_LICENCE (GPL2_OR_LATER) | |
| FEATURE (FEATURE_IMAGE,"bzImage", DHCP_EB_FEATURE_BZIMAGE, 1) | |
| struct image_type bzimage_image_type | __image_type (PROBE_NORMAL) |
| Linux bzImage image type. | |
| static int | bzimage_parse_header (struct image *image, struct bzimage_context *bzimg, userptr_t src) |
| Parse bzImage header. | |
| static void | bzimage_update_header (struct image *image, struct bzimage_context *bzimg, userptr_t dst) |
| Update bzImage header in loaded kernel. | |
| static int | bzimage_parse_cmdline (struct image *image, struct bzimage_context *bzimg, const char *cmdline) |
| Parse kernel command line for bootloader parameters. | |
| static int | bzimage_set_cmdline (struct image *image, struct bzimage_context *bzimg, const char *cmdline) |
| Set command line. | |
| static size_t | bzimage_load_initrd (struct image *image, struct image *initrd, userptr_t address) |
| Load initrd. | |
| static int | bzimage_load_initrds (struct image *image, struct bzimage_context *bzimg) |
| Load initrds, if any. | |
| static int | bzimage_exec (struct image *image) |
| Execute bzImage image. | |
| int | bzimage_load (struct image *image) |
| Load bzImage image into memory. | |
Definition in file bzimage.c.
| FILE_LICENCE | ( | GPL2_OR_LATER | ) |
| FEATURE | ( | FEATURE_IMAGE | , | |
| "bzImage" | , | |||
| DHCP_EB_FEATURE_BZIMAGE | , | |||
| 1 | ||||
| ) |
| struct image_type bzimage_image_type __image_type | ( | PROBE_NORMAL | ) | [read] |
Linux bzImage image type.
| static int bzimage_parse_header | ( | struct image * | image, | |
| struct bzimage_context * | bzimg, | |||
| userptr_t | src | |||
| ) | [static] |
Parse bzImage header.
| image | bzImage file | |
| bzimg | bzImage context | |
| src | bzImage to parse |
| rc | Return status code |
Definition at line 93 of file bzimage.c.
References bzimage_header::boot_flag, bzimage_context::bzhdr, BZI_ASSUMED_RM_SIZE, BZI_BOOT_FLAG, BZI_CMDLINE_OFFSET, BZI_CMDLINE_SIZE, BZI_HDR_OFFSET, BZI_INITRD_MAX, BZI_LOAD_HIGH, BZI_LOAD_HIGH_ADDR, BZI_LOAD_LOW_ADDR, BZI_SIGNATURE, BZI_STACK_SIZE, bzimage_context::cmdline_magic, bzimage_header::cmdline_size, bzimage_context::cmdline_size, copy_from_user(), DBGC, ENOEXEC, bzimage_header::header, bzimage_header::initrd_addr_max, image::len, bzimage_header::loadflags, bzimage_context::mem_limit, memset(), phys_to_user(), bzimage_context::pm_kernel, bzimage_context::pm_sz, real_to_user(), bzimage_context::rm_cmdline, bzimage_context::rm_filesz, bzimage_context::rm_heap, bzimage_context::rm_kernel, bzimage_context::rm_kernel_seg, bzimage_context::rm_memsz, bzimage_header::setup_sects, bzimage_header::syssize, user_to_phys(), bzimage_header::version, bzimage_context::version, bzimage_header::vid_mode, and bzimage_context::vid_mode.
Referenced by bzimage_exec(), and bzimage_load().
00095 { 00096 unsigned int syssize; 00097 int is_bzimage; 00098 00099 /* Sanity check */ 00100 if ( image->len < ( BZI_HDR_OFFSET + sizeof ( bzimg->bzhdr ) ) ) { 00101 DBGC ( image, "bzImage %p too short for kernel header\n", 00102 image ); 00103 return -ENOEXEC; 00104 } 00105 00106 /* Read in header structures */ 00107 memset ( bzimg, 0, sizeof ( *bzimg ) ); 00108 copy_from_user ( &bzimg->cmdline_magic, src, BZI_CMDLINE_OFFSET, 00109 sizeof ( bzimg->cmdline_magic ) ); 00110 copy_from_user ( &bzimg->bzhdr, src, BZI_HDR_OFFSET, 00111 sizeof ( bzimg->bzhdr ) ); 00112 00113 /* Calculate size of real-mode portion */ 00114 bzimg->rm_filesz = 00115 ( ( bzimg->bzhdr.setup_sects ? bzimg->bzhdr.setup_sects : 4 ) + 1 ) << 9; 00116 if ( bzimg->rm_filesz > image->len ) { 00117 DBGC ( image, "bzImage %p too short for %zd byte of setup\n", 00118 image, bzimg->rm_filesz ); 00119 return -ENOEXEC; 00120 } 00121 bzimg->rm_memsz = BZI_ASSUMED_RM_SIZE; 00122 00123 /* Calculate size of protected-mode portion */ 00124 bzimg->pm_sz = ( image->len - bzimg->rm_filesz ); 00125 syssize = ( ( bzimg->pm_sz + 15 ) / 16 ); 00126 00127 /* Check for signatures and determine version */ 00128 if ( bzimg->bzhdr.boot_flag != BZI_BOOT_FLAG ) { 00129 DBGC ( image, "bzImage %p missing 55AA signature\n", image ); 00130 return -ENOEXEC; 00131 } 00132 if ( bzimg->bzhdr.header == BZI_SIGNATURE ) { 00133 /* 2.00+ */ 00134 bzimg->version = bzimg->bzhdr.version; 00135 } else { 00136 /* Pre-2.00. Check that the syssize field is correct, 00137 * as a guard against accepting arbitrary binary data, 00138 * since the 55AA check is pretty lax. Note that the 00139 * syssize field is unreliable for protocols between 00140 * 2.00 and 2.03 inclusive, so we should not always 00141 * check this field. 00142 */ 00143 bzimg->version = 0x0100; 00144 if ( bzimg->bzhdr.syssize != syssize ) { 00145 DBGC ( image, "bzImage %p bad syssize %x (expected " 00146 "%x)\n", image, bzimg->bzhdr.syssize, syssize ); 00147 return -ENOEXEC; 00148 } 00149 } 00150 00151 /* Determine image type */ 00152 is_bzimage = ( ( bzimg->version >= 0x0200 ) ? 00153 ( bzimg->bzhdr.loadflags & BZI_LOAD_HIGH ) : 0 ); 00154 00155 /* Calculate load address of real-mode portion */ 00156 bzimg->rm_kernel_seg = ( is_bzimage ? 0x1000 : 0x9000 ); 00157 bzimg->rm_kernel = real_to_user ( bzimg->rm_kernel_seg, 0 ); 00158 00159 /* Allow space for the stack and heap */ 00160 bzimg->rm_memsz += BZI_STACK_SIZE; 00161 bzimg->rm_heap = bzimg->rm_memsz; 00162 00163 /* Allow space for the command line */ 00164 bzimg->rm_cmdline = bzimg->rm_memsz; 00165 bzimg->rm_memsz += BZI_CMDLINE_SIZE; 00166 00167 /* Calculate load address of protected-mode portion */ 00168 bzimg->pm_kernel = phys_to_user ( is_bzimage ? BZI_LOAD_HIGH_ADDR 00169 : BZI_LOAD_LOW_ADDR ); 00170 00171 /* Extract video mode */ 00172 bzimg->vid_mode = bzimg->bzhdr.vid_mode; 00173 00174 /* Extract memory limit */ 00175 bzimg->mem_limit = ( ( bzimg->version >= 0x0203 ) ? 00176 bzimg->bzhdr.initrd_addr_max : BZI_INITRD_MAX ); 00177 00178 /* Extract command line size */ 00179 bzimg->cmdline_size = ( ( bzimg->version >= 0x0206 ) ? 00180 bzimg->bzhdr.cmdline_size : BZI_CMDLINE_SIZE ); 00181 00182 DBGC ( image, "bzImage %p version %04x RM %#lx+%#zx PM %#lx+%#zx " 00183 "cmdlen %zd\n", image, bzimg->version, 00184 user_to_phys ( bzimg->rm_kernel, 0 ), bzimg->rm_filesz, 00185 user_to_phys ( bzimg->pm_kernel, 0 ), bzimg->pm_sz, 00186 bzimg->cmdline_size ); 00187 00188 return 0; 00189 }
| static void bzimage_update_header | ( | struct image * | image, | |
| struct bzimage_context * | bzimg, | |||
| userptr_t | dst | |||
| ) | [static] |
Update bzImage header in loaded kernel.
| image | bzImage file | |
| bzimg | bzImage context | |
| dst | bzImage to update |
Definition at line 198 of file bzimage.c.
References bzimage_context::bzhdr, BZI_CAN_USE_HEAP, BZI_CMDLINE_MAGIC, BZI_CMDLINE_OFFSET, BZI_HDR_OFFSET, BZI_LOADER_TYPE_GPXE, bzimage_header::cmd_line_ptr, bzimage_context::cmdline_magic, copy_to_user(), DBGC, bzimage_header::heap_end_ptr, bzimage_header::loadflags, bzimage_cmdline::magic, bzimage_cmdline::offset, bzimage_context::ramdisk_image, bzimage_header::ramdisk_image, bzimage_context::ramdisk_size, bzimage_header::ramdisk_size, bzimage_context::rm_cmdline, bzimage_context::rm_heap, bzimage_context::rm_kernel, bzimage_context::rm_memsz, bzimage_header::setup_move_size, bzimage_header::type_of_loader, user_to_phys(), bzimage_context::version, bzimage_context::vid_mode, and bzimage_header::vid_mode.
Referenced by bzimage_exec(), and bzimage_load().
00200 { 00201 00202 /* Set loader type */ 00203 if ( bzimg->version >= 0x0200 ) 00204 bzimg->bzhdr.type_of_loader = BZI_LOADER_TYPE_GPXE; 00205 00206 /* Set heap end pointer */ 00207 if ( bzimg->version >= 0x0201 ) { 00208 bzimg->bzhdr.heap_end_ptr = ( bzimg->rm_heap - 0x200 ); 00209 bzimg->bzhdr.loadflags |= BZI_CAN_USE_HEAP; 00210 } 00211 00212 /* Set command line */ 00213 if ( bzimg->version >= 0x0202 ) { 00214 bzimg->bzhdr.cmd_line_ptr = user_to_phys ( bzimg->rm_kernel, 00215 bzimg->rm_cmdline ); 00216 } else { 00217 bzimg->cmdline_magic.magic = BZI_CMDLINE_MAGIC; 00218 bzimg->cmdline_magic.offset = bzimg->rm_cmdline; 00219 bzimg->bzhdr.setup_move_size = bzimg->rm_memsz; 00220 } 00221 00222 /* Set video mode */ 00223 bzimg->bzhdr.vid_mode = bzimg->vid_mode; 00224 00225 /* Set initrd address */ 00226 if ( bzimg->version >= 0x0200 ) { 00227 bzimg->bzhdr.ramdisk_image = bzimg->ramdisk_image; 00228 bzimg->bzhdr.ramdisk_size = bzimg->ramdisk_size; 00229 } 00230 00231 /* Write out header structures */ 00232 copy_to_user ( dst, BZI_CMDLINE_OFFSET, &bzimg->cmdline_magic, 00233 sizeof ( bzimg->cmdline_magic ) ); 00234 copy_to_user ( dst, BZI_HDR_OFFSET, &bzimg->bzhdr, 00235 sizeof ( bzimg->bzhdr ) ); 00236 00237 DBGC ( image, "bzImage %p vidmode %d\n", image, bzimg->vid_mode ); 00238 }
| static int bzimage_parse_cmdline | ( | struct image * | image, | |
| struct bzimage_context * | bzimg, | |||
| const char * | cmdline | |||
| ) | [static] |
Parse kernel command line for bootloader parameters.
| rc | Return status code |
Definition at line 248 of file bzimage.c.
References BZI_VID_MODE_ASK, BZI_VID_MODE_EXT, BZI_VID_MODE_NORMAL, DBGC, bzimage_context::mem_limit, strcmp(), strstr(), strtoul(), and bzimage_context::vid_mode.
Referenced by bzimage_exec().
00250 { 00251 char *vga; 00252 char *mem; 00253 00254 /* Look for "vga=" */ 00255 if ( ( vga = strstr ( cmdline, "vga=" ) ) ) { 00256 vga += 4; 00257 if ( strcmp ( vga, "normal" ) == 0 ) { 00258 bzimg->vid_mode = BZI_VID_MODE_NORMAL; 00259 } else if ( strcmp ( vga, "ext" ) == 0 ) { 00260 bzimg->vid_mode = BZI_VID_MODE_EXT; 00261 } else if ( strcmp ( vga, "ask" ) == 0 ) { 00262 bzimg->vid_mode = BZI_VID_MODE_ASK; 00263 } else { 00264 bzimg->vid_mode = strtoul ( vga, &vga, 0 ); 00265 if ( *vga && ( *vga != ' ' ) ) { 00266 DBGC ( image, "bzImage %p strange \"vga=\"" 00267 "terminator '%c'\n", image, *vga ); 00268 } 00269 } 00270 } 00271 00272 /* Look for "mem=" */ 00273 if ( ( mem = strstr ( cmdline, "mem=" ) ) ) { 00274 mem += 4; 00275 bzimg->mem_limit = strtoul ( mem, &mem, 0 ); 00276 switch ( *mem ) { 00277 case 'G': 00278 case 'g': 00279 bzimg->mem_limit <<= 10; 00280 case 'M': 00281 case 'm': 00282 bzimg->mem_limit <<= 10; 00283 case 'K': 00284 case 'k': 00285 bzimg->mem_limit <<= 10; 00286 break; 00287 case '\0': 00288 case ' ': 00289 break; 00290 default: 00291 DBGC ( image, "bzImage %p strange \"mem=\" " 00292 "terminator '%c'\n", image, *mem ); 00293 break; 00294 } 00295 bzimg->mem_limit -= 1; 00296 } 00297 00298 return 0; 00299 }
| static int bzimage_set_cmdline | ( | struct image * | image, | |
| struct bzimage_context * | bzimg, | |||
| const char * | cmdline | |||
| ) | [static] |
Set command line.
| rc | Return status code |
Definition at line 309 of file bzimage.c.
References bzimage_context::cmdline_size, copy_to_user(), DBGC, bzimage_context::rm_cmdline, bzimage_context::rm_kernel, and strlen().
Referenced by bzimage_exec().
00311 { 00312 size_t cmdline_len; 00313 00314 /* Copy command line down to real-mode portion */ 00315 cmdline_len = ( strlen ( cmdline ) + 1 ); 00316 if ( cmdline_len > bzimg->cmdline_size ) 00317 cmdline_len = bzimg->cmdline_size; 00318 copy_to_user ( bzimg->rm_kernel, bzimg->rm_cmdline, 00319 cmdline, cmdline_len ); 00320 DBGC ( image, "bzImage %p command line \"%s\"\n", image, cmdline ); 00321 00322 return 0; 00323 }
| static size_t bzimage_load_initrd | ( | struct image * | image, | |
| struct image * | initrd, | |||
| userptr_t | address | |||
| ) | [static] |
Load initrd.
| len | Length of loaded image, rounded up to 4 bytes |
Definition at line 333 of file bzimage.c.
References cpio_header::c_filesize, cpio_header::c_magic, cpio_header::c_mode, cpio_header::c_namesize, cpio_header::c_nlink, image::cmdline, copy_to_user(), CPIO_MAGIC, cpio_set_field(), image::data, DBGC, image::len, memcpy, memcpy_user(), memset(), offset, strlen(), and user_to_phys().
Referenced by bzimage_load_initrds().
00335 { 00336 char *filename = initrd->cmdline; 00337 struct cpio_header cpio; 00338 size_t offset = 0; 00339 00340 /* Do not include kernel image itself as an initrd */ 00341 if ( initrd == image ) 00342 return 0; 00343 00344 /* Create cpio header before non-prebuilt images */ 00345 if ( filename && filename[0] ) { 00346 size_t name_len = ( strlen ( filename ) + 1 ); 00347 00348 DBGC ( image, "bzImage %p inserting initrd %p as %s\n", 00349 image, initrd, filename ); 00350 memset ( &cpio, '0', sizeof ( cpio ) ); 00351 memcpy ( cpio.c_magic, CPIO_MAGIC, sizeof ( cpio.c_magic ) ); 00352 cpio_set_field ( cpio.c_mode, 0100644 ); 00353 cpio_set_field ( cpio.c_nlink, 1 ); 00354 cpio_set_field ( cpio.c_filesize, initrd->len ); 00355 cpio_set_field ( cpio.c_namesize, name_len ); 00356 if ( address ) { 00357 copy_to_user ( address, offset, &cpio, 00358 sizeof ( cpio ) ); 00359 } 00360 offset += sizeof ( cpio ); 00361 if ( address ) { 00362 copy_to_user ( address, offset, filename, 00363 name_len ); 00364 } 00365 offset += name_len; 00366 offset = ( ( offset + 0x03 ) & ~0x03 ); 00367 } 00368 00369 /* Copy in initrd image body */ 00370 if ( address ) 00371 memcpy_user ( address, offset, initrd->data, 0, initrd->len ); 00372 offset += initrd->len; 00373 if ( address ) { 00374 DBGC ( image, "bzImage %p has initrd %p at [%lx,%lx)\n", 00375 image, initrd, user_to_phys ( address, 0 ), 00376 user_to_phys ( address, offset ) ); 00377 } 00378 00379 /* Round up to 4-byte boundary */ 00380 offset = ( ( offset + 0x03 ) & ~0x03 ); 00381 return offset; 00382 }
| static int bzimage_load_initrds | ( | struct image * | image, | |
| struct bzimage_context * | bzimg | |||
| ) | [static] |
Load initrds, if any.
| rc | Return status code |
Definition at line 391 of file bzimage.c.
References BZI_LOAD_HIGH_ADDR, bzimage_load_initrd(), image::data, DBGC, ENOBUFS, for_each_image, image::len, bzimage_context::mem_limit, phys_to_user(), prep_segment(), bzimage_context::ramdisk_image, bzimage_context::ramdisk_size, UNULL, and user_to_phys().
Referenced by bzimage_exec().
00392 { 00393 struct image *initrd; 00394 size_t total_len = 0; 00395 physaddr_t address; 00396 int rc; 00397 00398 /* Add up length of all initrd images */ 00399 for_each_image ( initrd ) 00400 total_len += bzimage_load_initrd ( image, initrd, UNULL ); 00401 00402 /* Give up if no initrd images found */ 00403 if ( ! total_len ) 00404 return 0; 00405 00406 /* Find a suitable start address. Try 1MB boundaries, 00407 * starting from the downloaded kernel image itself and 00408 * working downwards until we hit an available region. 00409 */ 00410 for ( address = ( user_to_phys ( image->data, 0 ) & ~0xfffff ) ; ; 00411 address -= 0x100000 ) { 00412 /* Check that we're not going to overwrite the 00413 * kernel itself. This check isn't totally 00414 * accurate, but errs on the side of caution. 00415 */ 00416 if ( address <= ( BZI_LOAD_HIGH_ADDR + image->len ) ) { 00417 DBGC ( image, "bzImage %p could not find a location " 00418 "for initrd\n", image ); 00419 return -ENOBUFS; 00420 } 00421 /* Check that we are within the kernel's range */ 00422 if ( ( address + total_len - 1 ) > bzimg->mem_limit ) 00423 continue; 00424 /* Prepare and verify segment */ 00425 if ( ( rc = prep_segment ( phys_to_user ( address ), 0, 00426 total_len ) ) != 0 ) 00427 continue; 00428 /* Use this address */ 00429 break; 00430 } 00431 00432 /* Record initrd location */ 00433 bzimg->ramdisk_image = address; 00434 bzimg->ramdisk_size = total_len; 00435 00436 /* Construct initrd */ 00437 DBGC ( image, "bzImage %p constructing initrd at [%lx,%lx)\n", 00438 image, address, ( address + total_len ) ); 00439 for_each_image ( initrd ) { 00440 address += bzimage_load_initrd ( image, initrd, 00441 phys_to_user ( address ) ); 00442 } 00443 00444 return 0; 00445 }
| static int bzimage_exec | ( | struct image * | image | ) | [static] |
Execute bzImage image.
| rc | Return status code |
Definition at line 453 of file bzimage.c.
References __asm__(), assert, bzimage_load_initrds(), bzimage_parse_cmdline(), bzimage_parse_header(), bzimage_set_cmdline(), bzimage_update_header(), image::cmdline, DBGC, ECANCELED, image::priv, REAL_CODE, bzimage_context::rm_heap, bzimage_context::rm_kernel, bzimage_context::rm_kernel_seg, shutdown(), SHUTDOWN_BOOT, and image::user.
00453 { 00454 struct bzimage_context bzimg; 00455 const char *cmdline = ( image->cmdline ? image->cmdline : "" ); 00456 int rc; 00457 00458 /* Read and parse header from loaded kernel */ 00459 if ( ( rc = bzimage_parse_header ( image, &bzimg, 00460 image->priv.user ) ) != 0 ) 00461 return rc; 00462 assert ( bzimg.rm_kernel == image->priv.user ); 00463 00464 /* Parse command line for bootloader parameters */ 00465 if ( ( rc = bzimage_parse_cmdline ( image, &bzimg, cmdline ) ) != 0) 00466 return rc; 00467 00468 /* Store command line */ 00469 if ( ( rc = bzimage_set_cmdline ( image, &bzimg, cmdline ) ) != 0 ) 00470 return rc; 00471 00472 /* Load any initrds */ 00473 if ( ( rc = bzimage_load_initrds ( image, &bzimg ) ) != 0 ) 00474 return rc; 00475 00476 /* Update kernel header */ 00477 bzimage_update_header ( image, &bzimg, bzimg.rm_kernel ); 00478 00479 /* Prepare for exiting */ 00480 shutdown ( SHUTDOWN_BOOT ); 00481 00482 DBGC ( image, "bzImage %p jumping to RM kernel at %04x:0000 " 00483 "(stack %04x:%04zx)\n", image, ( bzimg.rm_kernel_seg + 0x20 ), 00484 bzimg.rm_kernel_seg, bzimg.rm_heap ); 00485 00486 /* Jump to the kernel */ 00487 __asm__ __volatile__ ( REAL_CODE ( "movw %w0, %%ds\n\t" 00488 "movw %w0, %%es\n\t" 00489 "movw %w0, %%fs\n\t" 00490 "movw %w0, %%gs\n\t" 00491 "movw %w0, %%ss\n\t" 00492 "movw %w1, %%sp\n\t" 00493 "pushw %w2\n\t" 00494 "pushw $0\n\t" 00495 "lret\n\t" ) 00496 : : "r" ( bzimg.rm_kernel_seg ), 00497 "r" ( bzimg.rm_heap ), 00498 "r" ( bzimg.rm_kernel_seg + 0x20 ) ); 00499 00500 /* There is no way for the image to return, since we provide 00501 * no return address. 00502 */ 00503 assert ( 0 ); 00504 00505 return -ECANCELED; /* -EIMPOSSIBLE */ 00506 }
| int bzimage_load | ( | struct image * | image | ) |
Load bzImage image into memory.
| image | bzImage file |
| rc | Return status code |
Definition at line 514 of file bzimage.c.
References bzimage_parse_header(), bzimage_update_header(), image::data, DBGC, memcpy_user(), bzimage_context::pm_kernel, bzimage_context::pm_sz, prep_segment(), image::priv, bzimage_context::rm_filesz, bzimage_context::rm_kernel, bzimage_context::rm_memsz, strerror(), image::type, and image::user.
00514 { 00515 struct bzimage_context bzimg; 00516 int rc; 00517 00518 /* Read and parse header from image */ 00519 if ( ( rc = bzimage_parse_header ( image, &bzimg, 00520 image->data ) ) != 0 ) 00521 return rc; 00522 00523 /* This is a bzImage image, valid or otherwise */ 00524 if ( ! image->type ) 00525 image->type = &bzimage_image_type; 00526 00527 /* Prepare segments */ 00528 if ( ( rc = prep_segment ( bzimg.rm_kernel, bzimg.rm_filesz, 00529 bzimg.rm_memsz ) ) != 0 ) { 00530 DBGC ( image, "bzImage %p could not prepare RM segment: %s\n", 00531 image, strerror ( rc ) ); 00532 return rc; 00533 } 00534 if ( ( rc = prep_segment ( bzimg.pm_kernel, bzimg.pm_sz, 00535 bzimg.pm_sz ) ) != 0 ) { 00536 DBGC ( image, "bzImage %p could not prepare PM segment: %s\n", 00537 image, strerror ( rc ) ); 00538 return rc; 00539 } 00540 00541 /* Load segments */ 00542 memcpy_user ( bzimg.rm_kernel, 0, image->data, 00543 0, bzimg.rm_filesz ); 00544 memcpy_user ( bzimg.pm_kernel, 0, image->data, 00545 bzimg.rm_filesz, bzimg.pm_sz ); 00546 00547 /* Update and write out header */ 00548 bzimage_update_header ( image, &bzimg, bzimg.rm_kernel ); 00549 00550 /* Record real-mode segment in image private data field */ 00551 image->priv.user = bzimg.rm_kernel; 00552 00553 return 0; 00554 }
1.5.7.1