Annotation of qemu/roms/ipxe/src/arch/i386/image/bzimage.c, revision 1.1

1.1     ! root        1: /*
        !             2:  * Copyright (C) 2007 Michael Brown <[email protected]>.
        !             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., 675 Mass Ave, Cambridge, MA 02139, USA.
        !            17:  */
        !            18: 
        !            19: FILE_LICENCE ( GPL2_OR_LATER );
        !            20: 
        !            21: /**
        !            22:  * @file
        !            23:  *
        !            24:  * Linux bzImage image format
        !            25:  *
        !            26:  */
        !            27: 
        !            28: #include <stdint.h>
        !            29: #include <stdlib.h>
        !            30: #include <string.h>
        !            31: #include <errno.h>
        !            32: #include <assert.h>
        !            33: #include <realmode.h>
        !            34: #include <bzimage.h>
        !            35: #include <ipxe/uaccess.h>
        !            36: #include <ipxe/image.h>
        !            37: #include <ipxe/segment.h>
        !            38: #include <ipxe/init.h>
        !            39: #include <ipxe/cpio.h>
        !            40: #include <ipxe/features.h>
        !            41: 
        !            42: FEATURE ( FEATURE_IMAGE, "bzImage", DHCP_EB_FEATURE_BZIMAGE, 1 );
        !            43: 
        !            44: /**
        !            45:  * bzImage context
        !            46:  */
        !            47: struct bzimage_context {
        !            48:        /** Boot protocol version */
        !            49:        unsigned int version;
        !            50:        /** Real-mode kernel portion load segment address */
        !            51:        unsigned int rm_kernel_seg;
        !            52:        /** Real-mode kernel portion load address */
        !            53:        userptr_t rm_kernel;
        !            54:        /** Real-mode kernel portion file size */
        !            55:        size_t rm_filesz;
        !            56:        /** Real-mode heap top (offset from rm_kernel) */
        !            57:        size_t rm_heap;
        !            58:        /** Command line (offset from rm_kernel) */
        !            59:        size_t rm_cmdline;
        !            60:        /** Command line maximum length */
        !            61:        size_t cmdline_size;
        !            62:        /** Real-mode kernel portion total memory size */
        !            63:        size_t rm_memsz;
        !            64:        /** Non-real-mode kernel portion load address */
        !            65:        userptr_t pm_kernel;
        !            66:        /** Non-real-mode kernel portion file and memory size */
        !            67:        size_t pm_sz;
        !            68:        /** Video mode */
        !            69:        unsigned int vid_mode;
        !            70:        /** Memory limit */
        !            71:        uint64_t mem_limit;
        !            72:        /** Initrd address */
        !            73:        physaddr_t ramdisk_image;
        !            74:        /** Initrd size */
        !            75:        physaddr_t ramdisk_size;
        !            76: 
        !            77:        /** Command line magic block */
        !            78:        struct bzimage_cmdline cmdline_magic;
        !            79:        /** bzImage header */
        !            80:        struct bzimage_header bzhdr;
        !            81: };
        !            82: 
        !            83: /**
        !            84:  * Parse bzImage header
        !            85:  *
        !            86:  * @v image            bzImage file
        !            87:  * @v bzimg            bzImage context
        !            88:  * @v src              bzImage to parse
        !            89:  * @ret rc             Return status code
        !            90:  */
        !            91: static int bzimage_parse_header ( struct image *image,
        !            92:                                  struct bzimage_context *bzimg,
        !            93:                                  userptr_t src ) {
        !            94:        unsigned int syssize;
        !            95:        int is_bzimage;
        !            96: 
        !            97:        /* Sanity check */
        !            98:        if ( image->len < ( BZI_HDR_OFFSET + sizeof ( bzimg->bzhdr ) ) ) {
        !            99:                DBGC ( image, "bzImage %p too short for kernel header\n",
        !           100:                       image );
        !           101:                return -ENOEXEC;
        !           102:        }
        !           103: 
        !           104:        /* Read in header structures */
        !           105:        memset ( bzimg, 0, sizeof ( *bzimg ) );
        !           106:        copy_from_user ( &bzimg->cmdline_magic, src, BZI_CMDLINE_OFFSET,
        !           107:                         sizeof ( bzimg->cmdline_magic ) );
        !           108:        copy_from_user ( &bzimg->bzhdr, src, BZI_HDR_OFFSET,
        !           109:                         sizeof ( bzimg->bzhdr ) );
        !           110: 
        !           111:        /* Calculate size of real-mode portion */
        !           112:        bzimg->rm_filesz = ( ( ( bzimg->bzhdr.setup_sects ?
        !           113:                                 bzimg->bzhdr.setup_sects : 4 ) + 1 ) << 9 );
        !           114:        if ( bzimg->rm_filesz > image->len ) {
        !           115:                DBGC ( image, "bzImage %p too short for %zd byte of setup\n",
        !           116:                       image, bzimg->rm_filesz );
        !           117:                return -ENOEXEC;
        !           118:        }
        !           119:        bzimg->rm_memsz = BZI_ASSUMED_RM_SIZE;
        !           120: 
        !           121:        /* Calculate size of protected-mode portion */
        !           122:        bzimg->pm_sz = ( image->len - bzimg->rm_filesz );
        !           123:        syssize = ( ( bzimg->pm_sz + 15 ) / 16 );
        !           124: 
        !           125:        /* Check for signatures and determine version */
        !           126:        if ( bzimg->bzhdr.boot_flag != BZI_BOOT_FLAG ) {
        !           127:                DBGC ( image, "bzImage %p missing 55AA signature\n", image );
        !           128:                return -ENOEXEC;
        !           129:        }
        !           130:        if ( bzimg->bzhdr.header == BZI_SIGNATURE ) {
        !           131:                /* 2.00+ */
        !           132:                bzimg->version = bzimg->bzhdr.version;
        !           133:        } else {
        !           134:                /* Pre-2.00.  Check that the syssize field is correct,
        !           135:                 * as a guard against accepting arbitrary binary data,
        !           136:                 * since the 55AA check is pretty lax.  Note that the
        !           137:                 * syssize field is unreliable for protocols between
        !           138:                 * 2.00 and 2.03 inclusive, so we should not always
        !           139:                 * check this field.
        !           140:                 */
        !           141:                bzimg->version = 0x0100;
        !           142:                if ( bzimg->bzhdr.syssize != syssize ) {
        !           143:                        DBGC ( image, "bzImage %p bad syssize %x (expected "
        !           144:                               "%x)\n", image, bzimg->bzhdr.syssize, syssize );
        !           145:                        return -ENOEXEC;
        !           146:                }
        !           147:        }
        !           148: 
        !           149:        /* Determine image type */
        !           150:        is_bzimage = ( ( bzimg->version >= 0x0200 ) ?
        !           151:                       ( bzimg->bzhdr.loadflags & BZI_LOAD_HIGH ) : 0 );
        !           152: 
        !           153:        /* Calculate load address of real-mode portion */
        !           154:        bzimg->rm_kernel_seg = ( is_bzimage ? 0x1000 : 0x9000 );
        !           155:        bzimg->rm_kernel = real_to_user ( bzimg->rm_kernel_seg, 0 );
        !           156: 
        !           157:        /* Allow space for the stack and heap */
        !           158:        bzimg->rm_memsz += BZI_STACK_SIZE;
        !           159:        bzimg->rm_heap = bzimg->rm_memsz;
        !           160: 
        !           161:        /* Allow space for the command line */
        !           162:        bzimg->rm_cmdline = bzimg->rm_memsz;
        !           163:        bzimg->rm_memsz += BZI_CMDLINE_SIZE;
        !           164: 
        !           165:        /* Calculate load address of protected-mode portion */
        !           166:        bzimg->pm_kernel = phys_to_user ( is_bzimage ? BZI_LOAD_HIGH_ADDR
        !           167:                                        : BZI_LOAD_LOW_ADDR );
        !           168: 
        !           169:        /* Extract video mode */
        !           170:        bzimg->vid_mode = bzimg->bzhdr.vid_mode;
        !           171: 
        !           172:        /* Extract memory limit */
        !           173:        bzimg->mem_limit = ( ( bzimg->version >= 0x0203 ) ?
        !           174:                             bzimg->bzhdr.initrd_addr_max : BZI_INITRD_MAX );
        !           175: 
        !           176:        /* Extract command line size */
        !           177:        bzimg->cmdline_size = ( ( bzimg->version >= 0x0206 ) ?
        !           178:                                bzimg->bzhdr.cmdline_size : BZI_CMDLINE_SIZE );
        !           179: 
        !           180:        DBGC ( image, "bzImage %p version %04x RM %#lx+%#zx PM %#lx+%#zx "
        !           181:               "cmdlen %zd\n", image, bzimg->version,
        !           182:               user_to_phys ( bzimg->rm_kernel, 0 ), bzimg->rm_filesz,
        !           183:               user_to_phys ( bzimg->pm_kernel, 0 ), bzimg->pm_sz,
        !           184:               bzimg->cmdline_size );
        !           185: 
        !           186:        return 0;
        !           187: }
        !           188: 
        !           189: /**
        !           190:  * Update bzImage header in loaded kernel
        !           191:  *
        !           192:  * @v image            bzImage file
        !           193:  * @v bzimg            bzImage context
        !           194:  * @v dst              bzImage to update
        !           195:  */
        !           196: static void bzimage_update_header ( struct image *image,
        !           197:                                    struct bzimage_context *bzimg,
        !           198:                                    userptr_t dst ) {
        !           199: 
        !           200:        /* Set loader type */
        !           201:        if ( bzimg->version >= 0x0200 )
        !           202:                bzimg->bzhdr.type_of_loader = BZI_LOADER_TYPE_IPXE;
        !           203: 
        !           204:        /* Set heap end pointer */
        !           205:        if ( bzimg->version >= 0x0201 ) {
        !           206:                bzimg->bzhdr.heap_end_ptr = ( bzimg->rm_heap - 0x200 );
        !           207:                bzimg->bzhdr.loadflags |= BZI_CAN_USE_HEAP;
        !           208:        }
        !           209: 
        !           210:        /* Set command line */
        !           211:        if ( bzimg->version >= 0x0202 ) {
        !           212:                bzimg->bzhdr.cmd_line_ptr = user_to_phys ( bzimg->rm_kernel,
        !           213:                                                           bzimg->rm_cmdline );
        !           214:        } else {
        !           215:                bzimg->cmdline_magic.magic = BZI_CMDLINE_MAGIC;
        !           216:                bzimg->cmdline_magic.offset = bzimg->rm_cmdline;
        !           217:                bzimg->bzhdr.setup_move_size = bzimg->rm_memsz;
        !           218:        }
        !           219: 
        !           220:        /* Set video mode */
        !           221:        bzimg->bzhdr.vid_mode = bzimg->vid_mode;
        !           222: 
        !           223:        /* Set initrd address */
        !           224:        if ( bzimg->version >= 0x0200 ) {
        !           225:                bzimg->bzhdr.ramdisk_image = bzimg->ramdisk_image;
        !           226:                bzimg->bzhdr.ramdisk_size = bzimg->ramdisk_size;
        !           227:        }
        !           228: 
        !           229:        /* Write out header structures */
        !           230:        copy_to_user ( dst, BZI_CMDLINE_OFFSET, &bzimg->cmdline_magic,
        !           231:                       sizeof ( bzimg->cmdline_magic ) );
        !           232:        copy_to_user ( dst, BZI_HDR_OFFSET, &bzimg->bzhdr,
        !           233:                       sizeof ( bzimg->bzhdr ) );
        !           234: 
        !           235:        DBGC ( image, "bzImage %p vidmode %d\n", image, bzimg->vid_mode );
        !           236: }
        !           237: 
        !           238: /**
        !           239:  * Parse kernel command line for bootloader parameters
        !           240:  *
        !           241:  * @v image            bzImage file
        !           242:  * @v bzimg            bzImage context
        !           243:  * @v cmdline          Kernel command line
        !           244:  * @ret rc             Return status code
        !           245:  */
        !           246: static int bzimage_parse_cmdline ( struct image *image,
        !           247:                                   struct bzimage_context *bzimg,
        !           248:                                   const char *cmdline ) {
        !           249:        char *vga;
        !           250:        char *mem;
        !           251: 
        !           252:        /* Look for "vga=" */
        !           253:        if ( ( vga = strstr ( cmdline, "vga=" ) ) ) {
        !           254:                vga += 4;
        !           255:                if ( strcmp ( vga, "normal" ) == 0 ) {
        !           256:                        bzimg->vid_mode = BZI_VID_MODE_NORMAL;
        !           257:                } else if ( strcmp ( vga, "ext" ) == 0 ) {
        !           258:                        bzimg->vid_mode = BZI_VID_MODE_EXT;
        !           259:                } else if ( strcmp ( vga, "ask" ) == 0 ) {
        !           260:                        bzimg->vid_mode = BZI_VID_MODE_ASK;
        !           261:                } else {
        !           262:                        bzimg->vid_mode = strtoul ( vga, &vga, 0 );
        !           263:                        if ( *vga && ( *vga != ' ' ) ) {
        !           264:                                DBGC ( image, "bzImage %p strange \"vga=\""
        !           265:                                       "terminator '%c'\n", image, *vga );
        !           266:                        }
        !           267:                }
        !           268:        }
        !           269: 
        !           270:        /* Look for "mem=" */
        !           271:        if ( ( mem = strstr ( cmdline, "mem=" ) ) ) {
        !           272:                mem += 4;
        !           273:                bzimg->mem_limit = strtoul ( mem, &mem, 0 );
        !           274:                switch ( *mem ) {
        !           275:                case 'G':
        !           276:                case 'g':
        !           277:                        bzimg->mem_limit <<= 10;
        !           278:                case 'M':
        !           279:                case 'm':
        !           280:                        bzimg->mem_limit <<= 10;
        !           281:                case 'K':
        !           282:                case 'k':
        !           283:                        bzimg->mem_limit <<= 10;
        !           284:                        break;
        !           285:                case '\0':
        !           286:                case ' ':
        !           287:                        break;
        !           288:                default:
        !           289:                        DBGC ( image, "bzImage %p strange \"mem=\" "
        !           290:                               "terminator '%c'\n", image, *mem );
        !           291:                        break;
        !           292:                }
        !           293:                bzimg->mem_limit -= 1;
        !           294:        }
        !           295: 
        !           296:        return 0;
        !           297: }
        !           298: 
        !           299: /**
        !           300:  * Set command line
        !           301:  *
        !           302:  * @v image            bzImage image
        !           303:  * @v bzimg            bzImage context
        !           304:  * @v cmdline          Kernel command line
        !           305:  * @ret rc             Return status code
        !           306:  */
        !           307: static int bzimage_set_cmdline ( struct image *image,
        !           308:                                 struct bzimage_context *bzimg,
        !           309:                                 const char *cmdline ) {
        !           310:        size_t cmdline_len;
        !           311: 
        !           312:        /* Copy command line down to real-mode portion */
        !           313:        cmdline_len = ( strlen ( cmdline ) + 1 );
        !           314:        if ( cmdline_len > bzimg->cmdline_size )
        !           315:                cmdline_len = bzimg->cmdline_size;
        !           316:        copy_to_user ( bzimg->rm_kernel, bzimg->rm_cmdline,
        !           317:                       cmdline, cmdline_len );
        !           318:        DBGC ( image, "bzImage %p command line \"%s\"\n", image, cmdline );
        !           319: 
        !           320:        return 0;
        !           321: }
        !           322: 
        !           323: /**
        !           324:  * Load initrd
        !           325:  *
        !           326:  * @v image            bzImage image
        !           327:  * @v initrd           initrd image
        !           328:  * @v address          Address at which to load, or UNULL
        !           329:  * @ret len            Length of loaded image, rounded up to 4 bytes
        !           330:  */
        !           331: static size_t bzimage_load_initrd ( struct image *image,
        !           332:                                    struct image *initrd,
        !           333:                                    userptr_t address ) {
        !           334:        char *filename = initrd->cmdline;
        !           335:        struct cpio_header cpio;
        !           336:         size_t offset = 0;
        !           337: 
        !           338:        /* Do not include kernel image itself as an initrd */
        !           339:        if ( initrd == image )
        !           340:                return 0;
        !           341: 
        !           342:        /* Create cpio header before non-prebuilt images */
        !           343:        if ( filename && filename[0] ) {
        !           344:                size_t name_len = ( strlen ( filename ) + 1 );
        !           345: 
        !           346:                DBGC ( image, "bzImage %p inserting initrd %p as %s\n",
        !           347:                       image, initrd, filename );
        !           348:                memset ( &cpio, '0', sizeof ( cpio ) );
        !           349:                memcpy ( cpio.c_magic, CPIO_MAGIC, sizeof ( cpio.c_magic ) );
        !           350:                cpio_set_field ( cpio.c_mode, 0100644 );
        !           351:                cpio_set_field ( cpio.c_nlink, 1 );
        !           352:                cpio_set_field ( cpio.c_filesize, initrd->len );
        !           353:                cpio_set_field ( cpio.c_namesize, name_len );
        !           354:                if ( address ) {
        !           355:                        copy_to_user ( address, offset, &cpio,
        !           356:                                       sizeof ( cpio ) );
        !           357:                }
        !           358:                offset += sizeof ( cpio );
        !           359:                if ( address ) {
        !           360:                        copy_to_user ( address, offset, filename,
        !           361:                                       name_len );
        !           362:                }
        !           363:                offset += name_len;
        !           364:                offset = ( ( offset + 0x03 ) & ~0x03 );
        !           365:        }
        !           366: 
        !           367:        /* Copy in initrd image body */
        !           368:        if ( address )
        !           369:                memcpy_user ( address, offset, initrd->data, 0, initrd->len );
        !           370:        offset += initrd->len;
        !           371:        if ( address ) {
        !           372:                DBGC ( image, "bzImage %p has initrd %p at [%lx,%lx)\n",
        !           373:                       image, initrd, user_to_phys ( address, 0 ),
        !           374:                       user_to_phys ( address, offset ) );
        !           375:        }
        !           376: 
        !           377:        /* Round up to 4-byte boundary */
        !           378:        offset = ( ( offset + 0x03 ) & ~0x03 );
        !           379:        return offset;
        !           380: }
        !           381: 
        !           382: /**
        !           383:  * Load initrds, if any
        !           384:  *
        !           385:  * @v image            bzImage image
        !           386:  * @v bzimg            bzImage context
        !           387:  * @ret rc             Return status code
        !           388:  */
        !           389: static int bzimage_load_initrds ( struct image *image,
        !           390:                                  struct bzimage_context *bzimg ) {
        !           391:        struct image *initrd;
        !           392:        size_t total_len = 0;
        !           393:        physaddr_t address;
        !           394:        int rc;
        !           395: 
        !           396:        /* Add up length of all initrd images */
        !           397:        for_each_image ( initrd )
        !           398:                total_len += bzimage_load_initrd ( image, initrd, UNULL );
        !           399: 
        !           400:        /* Give up if no initrd images found */
        !           401:        if ( ! total_len )
        !           402:                return 0;
        !           403: 
        !           404:        /* Find a suitable start address.  Try 1MB boundaries,
        !           405:         * starting from the downloaded kernel image itself and
        !           406:         * working downwards until we hit an available region.
        !           407:         */
        !           408:        for ( address = ( user_to_phys ( image->data, 0 ) & ~0xfffff ) ; ;
        !           409:              address -= 0x100000 ) {
        !           410:                /* Check that we're not going to overwrite the
        !           411:                 * kernel itself.  This check isn't totally
        !           412:                 * accurate, but errs on the side of caution.
        !           413:                 */
        !           414:                if ( address <= ( BZI_LOAD_HIGH_ADDR + image->len ) ) {
        !           415:                        DBGC ( image, "bzImage %p could not find a location "
        !           416:                               "for initrd\n", image );
        !           417:                        return -ENOBUFS;
        !           418:                }
        !           419:                /* Check that we are within the kernel's range */
        !           420:                if ( ( address + total_len - 1 ) > bzimg->mem_limit )
        !           421:                        continue;
        !           422:                /* Prepare and verify segment */
        !           423:                if ( ( rc = prep_segment ( phys_to_user ( address ), 0,
        !           424:                                           total_len ) ) != 0 )
        !           425:                        continue;
        !           426:                /* Use this address */
        !           427:                break;
        !           428:        }
        !           429: 
        !           430:        /* Record initrd location */
        !           431:        bzimg->ramdisk_image = address;
        !           432:        bzimg->ramdisk_size = total_len;
        !           433: 
        !           434:        /* Construct initrd */
        !           435:        DBGC ( image, "bzImage %p constructing initrd at [%lx,%lx)\n",
        !           436:               image, address, ( address + total_len ) );
        !           437:        for_each_image ( initrd ) {
        !           438:                address += bzimage_load_initrd ( image, initrd,
        !           439:                                                 phys_to_user ( address ) );
        !           440:        }
        !           441: 
        !           442:        return 0;
        !           443: }
        !           444: 
        !           445: /**
        !           446:  * Execute bzImage image
        !           447:  *
        !           448:  * @v image            bzImage image
        !           449:  * @ret rc             Return status code
        !           450:  */
        !           451: static int bzimage_exec ( struct image *image ) {
        !           452:        struct bzimage_context bzimg;
        !           453:        const char *cmdline = ( image->cmdline ? image->cmdline : "" );
        !           454:        int rc;
        !           455: 
        !           456:        /* Read and parse header from image */
        !           457:        if ( ( rc = bzimage_parse_header ( image, &bzimg,
        !           458:                                           image->data ) ) != 0 )
        !           459:                return rc;
        !           460: 
        !           461:        /* Prepare segments */
        !           462:        if ( ( rc = prep_segment ( bzimg.rm_kernel, bzimg.rm_filesz,
        !           463:                                   bzimg.rm_memsz ) ) != 0 ) {
        !           464:                DBGC ( image, "bzImage %p could not prepare RM segment: %s\n",
        !           465:                       image, strerror ( rc ) );
        !           466:                return rc;
        !           467:        }
        !           468:        if ( ( rc = prep_segment ( bzimg.pm_kernel, bzimg.pm_sz,
        !           469:                                   bzimg.pm_sz ) ) != 0 ) {
        !           470:                DBGC ( image, "bzImage %p could not prepare PM segment: %s\n",
        !           471:                       image, strerror ( rc ) );
        !           472:                return rc;
        !           473:        }
        !           474: 
        !           475:        /* Load segments */
        !           476:        memcpy_user ( bzimg.rm_kernel, 0, image->data,
        !           477:                      0, bzimg.rm_filesz );
        !           478:        memcpy_user ( bzimg.pm_kernel, 0, image->data,
        !           479:                      bzimg.rm_filesz, bzimg.pm_sz );
        !           480: 
        !           481:        /* Update and write out header */
        !           482:        bzimage_update_header ( image, &bzimg, bzimg.rm_kernel );
        !           483: 
        !           484:        /* Parse command line for bootloader parameters */
        !           485:        if ( ( rc = bzimage_parse_cmdline ( image, &bzimg, cmdline ) ) != 0)
        !           486:                return rc;
        !           487: 
        !           488:        /* Store command line */
        !           489:        if ( ( rc = bzimage_set_cmdline ( image, &bzimg, cmdline ) ) != 0 )
        !           490:                return rc;
        !           491: 
        !           492:        /* Load any initrds */
        !           493:        if ( ( rc = bzimage_load_initrds ( image, &bzimg ) ) != 0 )
        !           494:                return rc;
        !           495: 
        !           496:        /* Update kernel header */
        !           497:        bzimage_update_header ( image, &bzimg, bzimg.rm_kernel );
        !           498: 
        !           499:        /* Prepare for exiting */
        !           500:        shutdown_boot();
        !           501: 
        !           502:        DBGC ( image, "bzImage %p jumping to RM kernel at %04x:0000 "
        !           503:               "(stack %04x:%04zx)\n", image, ( bzimg.rm_kernel_seg + 0x20 ),
        !           504:               bzimg.rm_kernel_seg, bzimg.rm_heap );
        !           505: 
        !           506:        /* Jump to the kernel */
        !           507:        __asm__ __volatile__ ( REAL_CODE ( "movw %w0, %%ds\n\t"
        !           508:                                           "movw %w0, %%es\n\t"
        !           509:                                           "movw %w0, %%fs\n\t"
        !           510:                                           "movw %w0, %%gs\n\t"
        !           511:                                           "movw %w0, %%ss\n\t"
        !           512:                                           "movw %w1, %%sp\n\t"
        !           513:                                           "pushw %w2\n\t"
        !           514:                                           "pushw $0\n\t"
        !           515:                                           "lret\n\t" )
        !           516:                               : : "r" ( bzimg.rm_kernel_seg ),
        !           517:                                   "r" ( bzimg.rm_heap ),
        !           518:                                   "r" ( bzimg.rm_kernel_seg + 0x20 ) );
        !           519: 
        !           520:        /* There is no way for the image to return, since we provide
        !           521:         * no return address.
        !           522:         */
        !           523:        assert ( 0 );
        !           524: 
        !           525:        return -ECANCELED; /* -EIMPOSSIBLE */
        !           526: }
        !           527: 
        !           528: /**
        !           529:  * Probe bzImage image
        !           530:  *
        !           531:  * @v image            bzImage file
        !           532:  * @ret rc             Return status code
        !           533:  */
        !           534: int bzimage_probe ( struct image *image ) {
        !           535:        struct bzimage_context bzimg;
        !           536:        int rc;
        !           537: 
        !           538:        /* Read and parse header from image */
        !           539:        if ( ( rc = bzimage_parse_header ( image, &bzimg,
        !           540:                                           image->data ) ) != 0 )
        !           541:                return rc;
        !           542: 
        !           543:        return 0;
        !           544: }
        !           545: 
        !           546: /** Linux bzImage image type */
        !           547: struct image_type bzimage_image_type __image_type ( PROBE_NORMAL ) = {
        !           548:        .name = "bzImage",
        !           549:        .probe = bzimage_probe,
        !           550:        .exec = bzimage_exec,
        !           551: };

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.