comboot.c File Reference

SYSLINUX COMBOOT (16-bit) image format. More...

#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <strings.h>
#include <errno.h>
#include <assert.h>
#include <realmode.h>
#include <basemem.h>
#include <comboot.h>
#include <gpxe/uaccess.h>
#include <gpxe/image.h>
#include <gpxe/segment.h>
#include <gpxe/init.h>
#include <gpxe/features.h>

Go to the source code of this file.

Data Structures

struct  comboot_psp
 COMBOOT PSP, copied to offset 0 of code segment. More...

Defines

#define COMBOOT_PSP_CMDLINE_OFFSET   0x81
 Offset in PSP of command line.
#define COMBOOT_MAX_CMDLINE_LEN   125
 Maximum length of command line in PSP (127 bytes minus space and CR).

Functions

 FILE_LICENCE (GPL2_OR_LATER)
 FEATURE (FEATURE_IMAGE,"COMBOOT", DHCP_EB_FEATURE_COMBOOT, 1)
struct image_type
comboot_image_type 
__image_type (PROBE_NORMAL)
 SYSLINUX COMBOOT (16-bit) image type.
static void comboot_copy_cmdline (struct image *image, userptr_t seg_userptr)
 Copy command line to PSP.
static void comboot_init_psp (struct image *image, userptr_t seg_userptr)
 Initialize PSP.
static int comboot_exec (struct image *image)
 Execute COMBOOT image.
static int comboot_identify (struct image *image)
 Check image name extension.
static int comboot_prepare_segment (struct image *image)
 Load COMBOOT image into memory, preparing a segment and returning it.
static int comboot_load (struct image *image)
 Load COMBOOT image into memory.


Detailed Description

SYSLINUX COMBOOT (16-bit) image format.

Definition in file comboot.c.


Define Documentation

#define COMBOOT_PSP_CMDLINE_OFFSET   0x81

Offset in PSP of command line.

Definition at line 58 of file comboot.c.

Referenced by comboot_copy_cmdline().

#define COMBOOT_MAX_CMDLINE_LEN   125

Maximum length of command line in PSP (127 bytes minus space and CR).

Definition at line 62 of file comboot.c.

Referenced by comboot_copy_cmdline().


Function Documentation

FILE_LICENCE ( GPL2_OR_LATER   ) 

FEATURE ( FEATURE_IMAGE  ,
"COMBOOT"  ,
DHCP_EB_FEATURE_COMBOOT  ,
 
)

struct image_type comboot_image_type __image_type ( PROBE_NORMAL   )  [read]

SYSLINUX COMBOOT (16-bit) image type.

static void comboot_copy_cmdline ( struct image image,
userptr_t  seg_userptr 
) [static]

Copy command line to PSP.

Parameters:
image COMBOOT image

Definition at line 70 of file comboot.c.

References image::cmdline, COMBOOT_MAX_CMDLINE_LEN, COMBOOT_PSP_CMDLINE_OFFSET, copy_to_user(), cr, and strlen().

Referenced by comboot_init_psp().

00070                                                                                  {
00071         const char *cmdline = ( image->cmdline ? image->cmdline : "" );
00072         int cmdline_len = strlen ( cmdline );
00073         if( cmdline_len > COMBOOT_MAX_CMDLINE_LEN )
00074                 cmdline_len = COMBOOT_MAX_CMDLINE_LEN;
00075         uint8_t len_byte = cmdline_len;
00076         char spc = ' ', cr = '\r';
00077 
00078         /* Copy length to byte before command line */
00079         copy_to_user ( seg_userptr, COMBOOT_PSP_CMDLINE_OFFSET - 1,
00080                        &len_byte, 1 );
00081 
00082         /* Command line starts with space */
00083         copy_to_user ( seg_userptr,
00084                        COMBOOT_PSP_CMDLINE_OFFSET,
00085                        &spc, 1 );
00086 
00087         /* Copy command line */
00088         copy_to_user ( seg_userptr,
00089                        COMBOOT_PSP_CMDLINE_OFFSET + 1,
00090                        cmdline, cmdline_len );
00091 
00092         /* Command line ends with CR */
00093         copy_to_user ( seg_userptr,
00094                        COMBOOT_PSP_CMDLINE_OFFSET + cmdline_len + 1,
00095                        &cr, 1 );
00096 }

static void comboot_init_psp ( struct image image,
userptr_t  seg_userptr 
) [static]

Initialize PSP.

Parameters:
image COMBOOT image
seg_userptr segment to initialize

Definition at line 104 of file comboot.c.

References comboot_copy_cmdline(), copy_to_user(), DBGC, comboot_psp::first_non_free_para, get_fbms(), and comboot_psp::int20.

Referenced by comboot_exec().

00104                                                                              {
00105         struct comboot_psp psp;
00106 
00107         /* Fill PSP */
00108 
00109         /* INT 20h instruction, byte order reversed */
00110         psp.int20 = 0x20CD;
00111 
00112         /* get_fbms() returns BIOS free base memory counter, which is in
00113          * kilobytes; x * 1024 / 16 == x * 64 == x << 6 */
00114         psp.first_non_free_para = get_fbms() << 6;
00115 
00116         DBGC ( image, "COMBOOT %p: first non-free paragraph = 0x%x\n",
00117                image, psp.first_non_free_para );
00118 
00119         /* Copy the PSP to offset 0 of segment.
00120          * The rest of the PSP was already zeroed by
00121          * comboot_prepare_segment. */
00122         copy_to_user ( seg_userptr, 0, &psp, sizeof( psp ) );
00123 
00124         /* Copy the command line to the PSP */
00125         comboot_copy_cmdline ( image, seg_userptr );
00126 }

static int comboot_exec ( struct image image  )  [static]

Execute COMBOOT image.

Parameters:
image COMBOOT image
Return values:
rc Return status code

Definition at line 134 of file comboot.c.

References __asm__(), assert, COMBOOT_EXIT, COMBOOT_EXIT_COMMAND, COMBOOT_EXIT_RUN_KERNEL, comboot_force_text_mode(), comboot_init_psp(), COMBOOT_PSP_SEG, comboot_replacement_image, comboot_return, DBGC, hook_comboot_interrupts(), image_autoload(), NULL, REAL_CODE, real_to_user(), image::replacement, rmsetjmp, unhook_comboot_interrupts(), and unregister_image().

00134                                                 {
00135         userptr_t seg_userptr = real_to_user ( COMBOOT_PSP_SEG, 0 );
00136         int state;
00137 
00138         state = rmsetjmp ( comboot_return );
00139 
00140         switch ( state ) {
00141         case 0: /* First time through; invoke COMBOOT program */
00142 
00143                 /* Initialize PSP */
00144                 comboot_init_psp ( image, seg_userptr );
00145 
00146                 /* Hook COMBOOT API interrupts */
00147                 hook_comboot_interrupts();
00148 
00149                 DBGC ( image, "executing 16-bit COMBOOT image at %4x:0100\n",
00150                        COMBOOT_PSP_SEG );
00151 
00152                 /* Unregister image, so that a "boot" command doesn't
00153                  * throw us into an execution loop.  We never
00154                  * reregister ourselves; COMBOOT images expect to be
00155                  * removed on exit.
00156                  */
00157                 unregister_image ( image );
00158 
00159                 /* Store stack segment at 0x38 and stack pointer at 0x3A
00160                  * in the PSP and jump to the image */
00161                 __asm__ __volatile__ (
00162                     REAL_CODE ( /* Save return address with segment on old stack */
00163                                     "popw %%ax\n\t"
00164                                     "pushw %%cs\n\t"
00165                                     "pushw %%ax\n\t"
00166                                     /* Set DS=ES=segment with image */
00167                                     "movw %w0, %%ds\n\t"
00168                                     "movw %w0, %%es\n\t"
00169                                     /* Set SS:SP to new stack (end of image segment) */
00170                                     "movw %w0, %%ss\n\t"
00171                                     "xor %%sp, %%sp\n\t"
00172                                     "pushw $0\n\t"
00173                                     "pushw %w0\n\t"
00174                                     "pushw $0x100\n\t"
00175                                     /* Zero registers (some COM files assume GP regs are 0) */
00176                                     "xorw %%ax, %%ax\n\t"
00177                                     "xorw %%bx, %%bx\n\t"
00178                                     "xorw %%cx, %%cx\n\t"
00179                                     "xorw %%dx, %%dx\n\t"
00180                                     "xorw %%si, %%si\n\t"
00181                                     "xorw %%di, %%di\n\t"
00182                                     "xorw %%bp, %%bp\n\t"
00183                                     "lret\n\t" )
00184                                          : : "r" ( COMBOOT_PSP_SEG ) : "eax" );
00185                 DBGC ( image, "COMBOOT %p: returned\n", image );
00186                 break;
00187 
00188         case COMBOOT_EXIT:
00189                 DBGC ( image, "COMBOOT %p: exited\n", image );
00190                 break;
00191 
00192         case COMBOOT_EXIT_RUN_KERNEL:
00193                 DBGC ( image, "COMBOOT %p: exited to run kernel %p\n",
00194                        image, comboot_replacement_image );
00195                 image->replacement = comboot_replacement_image;
00196                 comboot_replacement_image = NULL;
00197                 image_autoload ( image->replacement );
00198                 break;
00199 
00200         case COMBOOT_EXIT_COMMAND:
00201                 DBGC ( image, "COMBOOT %p: exited after executing command\n",
00202                        image );
00203                 break;
00204 
00205         default:
00206                 assert ( 0 );
00207                 break;
00208         }
00209 
00210         unhook_comboot_interrupts();
00211         comboot_force_text_mode();
00212 
00213         return 0;
00214 }

static int comboot_identify ( struct image image  )  [static]

Check image name extension.

Parameters:
image COMBOOT image
Return values:
rc Return status code

Definition at line 222 of file comboot.c.

References DBGC, ENOEXEC, image::name, strcasecmp(), and strrchr().

Referenced by comboot_load().

00222                                                     {
00223         const char *ext;
00224 
00225         ext = strrchr( image->name, '.' );
00226 
00227         if ( ! ext ) {
00228                 DBGC ( image, "COMBOOT %p: no extension\n",
00229                        image );
00230                 return -ENOEXEC;
00231         }
00232 
00233         ++ext;
00234 
00235         if ( strcasecmp( ext, "com" ) && strcasecmp( ext, "cbt" ) ) {
00236                 DBGC ( image, "COMBOOT %p: unrecognized extension %s\n",
00237                        image, ext );
00238                 return -ENOEXEC;
00239         }
00240 
00241         return 0;
00242 }

static int comboot_prepare_segment ( struct image image  )  [static]

Load COMBOOT image into memory, preparing a segment and returning it.

Parameters:
image COMBOOT image
Return values:
rc Return status code

Definition at line 249 of file comboot.c.

References COMBOOT_PSP_SEG, image::data, DBGC, image::len, memcpy_user(), memset_user(), prep_segment(), real_to_user(), and strerror().

Referenced by comboot_load().

00250 {
00251         userptr_t seg_userptr;
00252         size_t filesz, memsz;
00253         int rc;
00254 
00255         /* Load image in segment */
00256         seg_userptr = real_to_user ( COMBOOT_PSP_SEG, 0 );
00257 
00258         /* Allow etra 0x100 bytes before image for PSP */
00259         filesz = image->len + 0x100; 
00260 
00261         /* Ensure the entire 64k segment is free */
00262         memsz = 0xFFFF;
00263 
00264         /* Prepare, verify, and load the real-mode segment */
00265         if ( ( rc = prep_segment ( seg_userptr, filesz, memsz ) ) != 0 ) {
00266                 DBGC ( image, "COMBOOT %p: could not prepare segment: %s\n",
00267                        image, strerror ( rc ) );
00268                 return rc;
00269         }
00270 
00271         /* Zero PSP */
00272         memset_user ( seg_userptr, 0, 0, 0x100 );
00273 
00274         /* Copy image to segment:0100 */
00275         memcpy_user ( seg_userptr, 0x100, image->data, 0, image->len );
00276 
00277         return 0;
00278 }

static int comboot_load ( struct image image  )  [static]

Load COMBOOT image into memory.

Parameters:
image COMBOOT image
Return values:
rc Return status code

Definition at line 286 of file comboot.c.

References comboot_identify(), comboot_prepare_segment(), DBGC, ENOEXEC, image::len, image::name, and image::type.

00286                                                 {
00287         int rc;
00288 
00289         DBGC ( image, "COMBOOT %p: name '%s'\n",
00290                image, image->name );
00291 
00292         /* Check if this is a COMBOOT image */
00293         if ( ( rc = comboot_identify ( image ) ) != 0 ) {
00294                 
00295                 return rc;
00296         }
00297 
00298         /* This is a 16-bit COMBOOT image, valid or otherwise */
00299         if ( ! image->type )
00300                 image->type = &comboot_image_type;
00301         
00302         /* Sanity check for filesize */
00303         if( image->len >= 0xFF00 ) {
00304                 DBGC( image, "COMBOOT %p: image too large\n",
00305                       image );
00306                 return -ENOEXEC;
00307         }
00308 
00309         /* Prepare segment and load image */
00310         if ( ( rc = comboot_prepare_segment ( image ) ) != 0 ) {
00311                 return rc;
00312         }
00313 
00314         return 0;
00315 }


Generated on Tue Apr 6 20:01:12 2010 for gPXE by  doxygen 1.5.7.1