com32.c File Reference

SYSLINUX COM32 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/memmap.h>

Go to the source code of this file.

Functions

 FILE_LICENCE (GPL2_OR_LATER)
struct image_type com32_image_type __image_type (PROBE_NORMAL)
 SYSLINUX COM32 image type.
static int com32_exec (struct image *image)
 Execute COMBOOT image.
static int com32_identify (struct image *image)
 Check image name extension.
static int comboot_load_image (struct image *image)
 Load COM32 image into memory.
static int comboot_prepare_bounce_buffer (struct image *image)
 Prepare COM32 low memory bounce buffer.
static int com32_load (struct image *image)
 Load COM32 image into memory.


Detailed Description

SYSLINUX COM32 image format.

Definition in file com32.c.


Function Documentation

FILE_LICENCE ( GPL2_OR_LATER   ) 

struct image_type com32_image_type __image_type ( PROBE_NORMAL   )  [read]

SYSLINUX COM32 image type.

static int com32_exec ( struct image image  )  [static]

Execute COMBOOT image.

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

Definition at line 51 of file com32.c.

References __asm__(), assert, image::cmdline, COM32_BOUNCE_SEG, com32_cfarcall_wrapper(), com32_external_esp, com32_farcall_wrapper(), com32_intcall_wrapper(), COM32_START_PHYS, COMBOOT_EXIT, COMBOOT_EXIT_COMMAND, COMBOOT_EXIT_RUN_KERNEL, comboot_force_text_mode(), comboot_replacement_image, comboot_return, memory_map::count, DBGC, memory_region::end, get_fbms(), get_memmap(), hook_comboot_interrupts(), image_autoload(), image::len, NULL, phys_to_virt(), memory_map::regions, image::replacement, rmsetjmp, memory_region::start, unhook_comboot_interrupts(), unregister_image(), and virt_to_phys().

00051                                               {
00052         struct memory_map memmap;
00053         unsigned int i;
00054         int state;
00055         uint32_t avail_mem_top;
00056 
00057         state = rmsetjmp ( comboot_return );
00058 
00059         switch ( state ) {
00060         case 0: /* First time through; invoke COM32 program */
00061 
00062                 /* Get memory map */
00063                 get_memmap ( &memmap );
00064 
00065                 /* Find end of block covering COM32 image loading area */
00066                 for ( i = 0, avail_mem_top = 0 ; i < memmap.count ; i++ ) {
00067                         if ( (memmap.regions[i].start <= COM32_START_PHYS) &&
00068                              (memmap.regions[i].end > COM32_START_PHYS + image->len) ) {
00069                                 avail_mem_top = memmap.regions[i].end;
00070                                 break;
00071                         }
00072                 }
00073 
00074                 DBGC ( image, "COM32 %p: available memory top = 0x%x\n",
00075                        image, avail_mem_top );
00076 
00077                 assert ( avail_mem_top != 0 );
00078 
00079                 com32_external_esp = phys_to_virt ( avail_mem_top );
00080 
00081                 /* Hook COMBOOT API interrupts */
00082                 hook_comboot_interrupts();
00083 
00084                 /* Unregister image, so that a "boot" command doesn't
00085                  * throw us into an execution loop.  We never
00086                  * reregister ourselves; COMBOOT images expect to be
00087                  * removed on exit.
00088                  */
00089                 unregister_image ( image );
00090 
00091                 __asm__ __volatile__ (
00092                         "movl %%esp, (com32_internal_esp)\n\t" /* Save internal virtual address space ESP */
00093                         "movl (com32_external_esp), %%esp\n\t" /* Switch to COM32 ESP (top of available memory) */
00094                         "call _virt_to_phys\n\t"               /* Switch to flat physical address space */
00095                         "pushl %0\n\t"                         /* Pointer to CDECL helper function */
00096                         "pushl %1\n\t"                         /* Pointer to FAR call helper function */
00097                         "pushl %2\n\t"                         /* Size of low memory bounce buffer */
00098                         "pushl %3\n\t"                         /* Pointer to low memory bounce buffer */
00099                         "pushl %4\n\t"                         /* Pointer to INT call helper function */
00100                         "pushl %5\n\t"                         /* Pointer to the command line arguments */
00101                         "pushl $6\n\t"                         /* Number of additional arguments */
00102                         "call *%6\n\t"                         /* Execute image */
00103                         "call _phys_to_virt\n\t"               /* Switch back to internal virtual address space */
00104                         "movl (com32_internal_esp), %%esp\n\t" /* Switch back to internal stack */
00105                 :
00106                 :
00107                         /* %0 */ "r" ( virt_to_phys ( com32_cfarcall_wrapper ) ),
00108                         /* %1 */ "r" ( virt_to_phys ( com32_farcall_wrapper ) ),
00109                         /* %2 */ "r" ( get_fbms() * 1024 - (COM32_BOUNCE_SEG << 4) ),
00110                         /* %3 */ "i" ( COM32_BOUNCE_SEG << 4 ),
00111                         /* %4 */ "r" ( virt_to_phys ( com32_intcall_wrapper ) ),
00112                         /* %5 */ "r" ( virt_to_phys ( image->cmdline ) ),
00113                         /* %6 */ "r" ( COM32_START_PHYS )
00114                 :
00115                         "memory" );
00116                 DBGC ( image, "COM32 %p: returned\n", image );
00117                 break;
00118 
00119         case COMBOOT_EXIT:
00120                 DBGC ( image, "COM32 %p: exited\n", image );
00121                 break;
00122 
00123         case COMBOOT_EXIT_RUN_KERNEL:
00124                 DBGC ( image, "COM32 %p: exited to run kernel %p\n",
00125                        image, comboot_replacement_image );
00126                 image->replacement = comboot_replacement_image;
00127                 comboot_replacement_image = NULL;
00128                 image_autoload ( image->replacement );
00129                 break;
00130 
00131         case COMBOOT_EXIT_COMMAND:
00132                 DBGC ( image, "COM32 %p: exited after executing command\n",
00133                        image );
00134                 break;
00135 
00136         default:
00137                 assert ( 0 );
00138                 break;
00139         }
00140 
00141         unhook_comboot_interrupts();
00142         comboot_force_text_mode();
00143 
00144         return 0;
00145 }

static int com32_identify ( struct image image  )  [static]

Check image name extension.

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

Definition at line 153 of file com32.c.

References copy_from_user(), image::data, DBGC, ENOEXEC, image::len, memcmp(), image::name, strcasecmp(), and strrchr().

Referenced by com32_load().

00153                                                   {
00154         const char *ext;
00155         static const uint8_t magic[] = { 0xB8, 0xFF, 0x4C, 0xCD, 0x21 };
00156         uint8_t buf[5];
00157         
00158         if ( image->len >= 5 ) {
00159                 /* Check for magic number
00160                  * mov eax,21cd4cffh
00161                  * B8 FF 4C CD 21
00162                  */
00163                 copy_from_user ( buf, image->data, 0, sizeof(buf) );
00164                 if ( ! memcmp ( buf, magic, sizeof(buf) ) ) {
00165                         DBGC ( image, "COM32 %p: found magic number\n",
00166                                image );
00167                         return 0;
00168                 }
00169         }
00170 
00171         /* Magic number not found; check filename extension */
00172 
00173         ext = strrchr( image->name, '.' );
00174 
00175         if ( ! ext ) {
00176                 DBGC ( image, "COM32 %p: no extension\n",
00177                        image );
00178                 return -ENOEXEC;
00179         }
00180 
00181         ++ext;
00182 
00183         if ( strcasecmp( ext, "c32" ) ) {
00184                 DBGC ( image, "COM32 %p: unrecognized extension %s\n",
00185                        image, ext );
00186                 return -ENOEXEC;
00187         }
00188 
00189         return 0;
00190 }

static int comboot_load_image ( struct image image  )  [static]

Load COM32 image into memory.

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

Definition at line 198 of file com32.c.

References COM32_START_PHYS, image::data, DBGC, image::len, memcpy_user(), phys_to_user(), prep_segment(), and strerror().

Referenced by com32_load().

00198                                                       {
00199         size_t filesz, memsz;
00200         userptr_t buffer;
00201         int rc;
00202 
00203         filesz = image->len;
00204         memsz = filesz;
00205         buffer = phys_to_user ( COM32_START_PHYS );
00206         if ( ( rc = prep_segment ( buffer, filesz, memsz ) ) != 0 ) {
00207                 DBGC ( image, "COM32 %p: could not prepare segment: %s\n",
00208                        image, strerror ( rc ) );
00209                 return rc;
00210         }
00211 
00212         /* Copy image to segment */
00213         memcpy_user ( buffer, 0, image->data, 0, filesz );
00214 
00215         return 0;
00216 }

static int comboot_prepare_bounce_buffer ( struct image image  )  [static]

Prepare COM32 low memory bounce buffer.

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

Definition at line 223 of file com32.c.

References COM32_BOUNCE_SEG, DBGC, prep_segment(), real_to_user(), and strerror().

Referenced by com32_load().

00223                                                                   {
00224         unsigned int seg;
00225         userptr_t seg_userptr;
00226         size_t filesz, memsz;
00227         int rc;
00228 
00229         seg = COM32_BOUNCE_SEG;
00230         seg_userptr = real_to_user ( seg, 0 );
00231 
00232         /* Ensure the entire 64k segment is free */
00233         memsz = 0xFFFF;
00234         filesz = 0;
00235 
00236         /* Prepare, verify, and load the real-mode segment */
00237         if ( ( rc = prep_segment ( seg_userptr, filesz, memsz ) ) != 0 ) {
00238                 DBGC ( image, "COM32 %p: could not prepare bounce buffer segment: %s\n",
00239                        image, strerror ( rc ) );
00240                 return rc;
00241         }
00242 
00243         return 0;
00244 }

static int com32_load ( struct image image  )  [static]

Load COM32 image into memory.

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

Definition at line 252 of file com32.c.

References image::cmdline, com32_identify(), comboot_load_image(), comboot_prepare_bounce_buffer(), DBGC, image::name, and image::type.

00252                                               {
00253         int rc;
00254 
00255         DBGC ( image, "COM32 %p: name '%s', cmdline '%s'\n",
00256                image, image->name, image->cmdline );
00257 
00258         /* Check if this is a COMBOOT image */
00259         if ( ( rc = com32_identify ( image ) ) != 0 ) {
00260                 return rc;
00261         }
00262 
00263         /* This is a COM32 image, valid or otherwise */
00264         if ( ! image->type )
00265                 image->type = &com32_image_type;
00266 
00267         /* Load image */
00268         if ( ( rc = comboot_load_image ( image ) ) != 0 ) {
00269                 return rc;
00270         }
00271 
00272         /* Prepare bounce buffer segment */
00273         if ( ( rc = comboot_prepare_bounce_buffer ( image ) ) != 0 ) {
00274                 return rc;
00275         }
00276 
00277         return 0;
00278 }


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