#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. | |
Definition in file com32.c.
| 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.
| 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.
| 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.
| 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.
| 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.
| 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 }
1.5.7.1