#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. | |
Definition in file comboot.c.
| #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().
| FILE_LICENCE | ( | GPL2_OR_LATER | ) |
| FEATURE | ( | FEATURE_IMAGE | , | |
| "COMBOOT" | , | |||
| DHCP_EB_FEATURE_COMBOOT | , | |||
| 1 | ||||
| ) |
| struct image_type comboot_image_type __image_type | ( | PROBE_NORMAL | ) | [read] |
SYSLINUX COMBOOT (16-bit) image type.
Copy command line to PSP.
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 }
Initialize PSP.
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.
| 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.
| 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.
| 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.
| 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 }
1.5.7.1