wok-stable annotate gpxe/stuff/default_boot.u @ rev 2178

Add synergy (thanks Matthew)
author Pascal Bellard <pascal.bellard@slitaz.org>
date Sun Feb 08 16:53:08 2009 +0000 (2009-02-08)
parents c1b6596e8b33
children 7f1f7efb4ddb
rev   line source
pascal@1001 1 --- gpxe-0.9.3/src/arch/i386/interface/pxe/pxe_call.c
pascal@1001 2 +++ gpxe-0.9.3/src/arch/i386/interface/pxe/pxe_call.c
pascal@1001 3 @@ -96,6 +96,8 @@
pascal@1001 4 PXENV_EXIT_t ( * file_select ) ( struct s_PXENV_FILE_SELECT * );
pascal@1001 5 PXENV_EXIT_t ( * file_read ) ( struct s_PXENV_FILE_READ * );
pascal@1001 6 PXENV_EXIT_t ( * get_file_size ) ( struct s_PXENV_GET_FILE_SIZE * );
pascal@1001 7 + PXENV_EXIT_t ( * file_exec ) ( struct s_PXENV_FILE_EXEC * );
pascal@1001 8 + PXENV_EXIT_t ( * file_api_check ) ( struct s_PXENV_FILE_API_CHECK * );
pascal@1001 9 };
pascal@1001 10
pascal@1001 11 /**
pascal@1001 12 @@ -294,6 +296,14 @@
pascal@1001 13 pxenv_call.get_file_size = pxenv_get_file_size;
pascal@1001 14 param_len = sizeof ( pxenv_any.get_file_size );
pascal@1001 15 break;
pascal@1001 16 + case PXENV_FILE_EXEC:
pascal@1001 17 + pxenv_call.file_exec = pxenv_file_exec;
pascal@1001 18 + param_len = sizeof ( pxenv_any.file_exec );
pascal@1001 19 + break;
pascal@1001 20 + case PXENV_FILE_API_CHECK:
pascal@1001 21 + pxenv_call.file_api_check = pxenv_file_api_check;
pascal@1001 22 + param_len = sizeof ( pxenv_any.file_api_check );
pascal@1001 23 + break;
pascal@1001 24 default:
pascal@1001 25 DBG ( "PXENV_UNKNOWN_%hx", opcode );
pascal@1001 26 pxenv_call.unknown = pxenv_unknown;
pascal@1001 27
pascal@962 28 --- gpxe-0.9.3/src/arch/i386/prefix/lkrnprefix.S
pascal@962 29 +++ gpxe-0.9.3/src/arch/i386/prefix/lkrnprefix.S
pascal@1010 30 @@ -197,7 +197,7 @@
pascal@1010 31 */
pascal@1010 32
pascal@1010 33 /* Jump to loaded copy */
pascal@1010 34 - ljmp $SYSSEG, $run_etherboot
pascal@1010 35 + ljmp $SYSSEG, $run_etherboot2
pascal@1010 36
pascal@1010 37 endseg: .word SYSSEG + _load_size_pgh
pascal@1010 38 .section ".zinfo.fixup", "a" /* Compressor fixup information */
pascal@1010 39 @@ -441,11 +441,16 @@
pascal@962 40 /* Calculated lcall to _start with %cs:0000 = image start */
pascal@962 41 lret
pascal@962 42
pascal@962 43 +boot_url:
pascal@1001 44 + .space 256, 0
pascal@962 45
pascal@962 46 .org PREFIXSIZE
pascal@962 47 /*
pascal@1010 48 We're now at the beginning of the kernel proper.
pascal@1010 49 */
pascal@1010 50 +run_etherboot2:
pascal@1010 51 + push %cs
pascal@1010 52 + pop %ds
pascal@1010 53 run_etherboot:
pascal@1010 54 call install
pascal@1010 55
pascal@1010 56 @@ -453,6 +458,13 @@
pascal@962 57 movw %bx, %ss
pascal@962 58 movw $_estack16, %sp
pascal@962 59
pascal@962 60 + /* Copy our boot_url structure to the forced_url variable */
pascal@962 61 + movw %bx, %es
pascal@962 62 + movw $forced_url, %di
pascal@962 63 + movw $boot_url, %si
pascal@1001 64 + movw $256, %cx
pascal@962 65 + rep movsb
pascal@962 66 +
pascal@962 67 /* Jump to .text16 segment */
pascal@962 68 pushw %ax
pascal@962 69 pushw $1f
pascal@962 70 --- gpxe-0.9.3/src/arch/i386/prefix/pxeprefix.S
pascal@962 71 +++ gpxe-0.9.3/src/arch/i386/prefix/pxeprefix.S
pascal@1001 72 @@ -19,6 +19,9 @@
pascal@962 73 .section ".prefix"
pascal@962 74 /* Set up our non-stack segment registers */
pascal@962 75 jmp $0x7c0, $1f
pascal@1001 76 +#define PXELOADER_KEEP_UNDI
pascal@962 77 +boot_url:
pascal@1001 78 + .space 256, 0
pascal@962 79 1: movw %cs, %ax
pascal@962 80 movw %ax, %ds
pascal@962 81 movw $0x40, %ax /* BIOS data segment access */
pascal@1001 82 @@ -703,16 +706,22 @@
pascal@962 83 /* Set up real-mode stack */
pascal@962 84 movw %bx, %ss
pascal@962 85 movw $_estack16, %sp
pascal@962 86 -
pascal@962 87 + movw %bx, %es
pascal@962 88 +
pascal@962 89 #ifdef PXELOADER_KEEP_UNDI
pascal@962 90 /* Copy our undi_device structure to the preloaded_undi variable */
pascal@962 91 - movw %bx, %es
pascal@962 92 movw $preloaded_undi, %di
pascal@962 93 movw $undi_device, %si
pascal@962 94 movw $undi_device_size, %cx
pascal@962 95 rep movsb
pascal@962 96 #endif
pascal@962 97
pascal@962 98 + /* Copy our boot_url structure to the forced_url variable */
pascal@962 99 + movw $forced_url, %di
pascal@962 100 + movw $boot_url, %si
pascal@1001 101 + movw $256, %cx
pascal@962 102 + rep movsb
pascal@962 103 +
pascal@962 104 /* Jump to .text16 segment with %ds pointing to .data16 */
pascal@962 105 movw %bx, %ds
pascal@962 106 pushw %ax
pascal@962 107
pascal@1001 108 --- gpxe-0.9.3/src/include/pxe_api.h
pascal@1001 109 +++ gpxe-0.9.3/src/include/pxe_api.h
pascal@1001 110 @@ -1684,6 +1684,54 @@
pascal@1001 111
pascal@1001 112 /** @} */ /* pxenv_get_file_size */
pascal@1001 113
pascal@1001 114 +/** @defgroup pxenv_file_exec PXENV_FILE_EXEC
pascal@1001 115 + *
pascal@1001 116 + * FILE EXEC
pascal@1001 117 + *
pascal@1001 118 + * @{
pascal@1001 119 + */
pascal@1001 120 +
pascal@1001 121 +/** PXE API function code for pxenv_file_exec() */
pascal@1001 122 +#define PXENV_FILE_EXEC 0x00e5
pascal@1001 123 +
pascal@1001 124 +/** Parameter block for pxenv_file_exec() */
pascal@1001 125 +struct s_PXENV_FILE_EXEC {
pascal@1001 126 + PXENV_STATUS_t Status; /**< PXE status code */
pascal@1001 127 + SEGOFF16_t Command; /**< Command to execute */
pascal@1001 128 +} PACKED;
pascal@1001 129 +
pascal@1001 130 +typedef struct s_PXENV_FILE_EXEC PXENV_FILE_EXEC_t;
pascal@1001 131 +
pascal@1001 132 +extern PXENV_EXIT_t pxenv_file_exec ( struct s_PXENV_FILE_EXEC *file_exec );
pascal@1001 133 +
pascal@1001 134 +/** @} */ /* pxenv_file_exec */
pascal@1001 135 +
pascal@1001 136 +/** @defgroup pxenv_file_api_check PXENV_FILE_API_CHECK
pascal@1001 137 + *
pascal@1001 138 + * FILE API CHECK
pascal@1001 139 + *
pascal@1001 140 + * @{
pascal@1001 141 + */
pascal@1001 142 +
pascal@1001 143 +/** PXE API function code for pxenv_file_api_check() */
pascal@1001 144 +#define PXENV_FILE_API_CHECK 0x00e6
pascal@1001 145 +
pascal@1001 146 +/** Parameter block for pxenv_file_api_check() */
pascal@1001 147 +struct s_PXENV_FILE_API_CHECK {
pascal@1001 148 + PXENV_STATUS_t Status; /**< PXE status code */
pascal@1001 149 + UINT16_t Size; /**< Size of structure */
pascal@1001 150 + UINT32_t Magic; /**< Magic number */
pascal@1001 151 + UINT32_t Provider; /**< Implementation identifier */
pascal@1001 152 + UINT32_t APIMask; /**< Supported API functions */
pascal@1001 153 + UINT32_t Flags; /**< Reserved for the future */
pascal@1001 154 +} PACKED;
pascal@1001 155 +
pascal@1001 156 +typedef struct s_PXENV_FILE_API_CHECK PXENV_FILE_API_CHECK_t;
pascal@1001 157 +
pascal@1001 158 +extern PXENV_EXIT_t pxenv_file_api_check ( struct s_PXENV_FILE_API_CHECK *file_api_check );
pascal@1001 159 +
pascal@1001 160 +/** @} */ /* pxenv_file_api_check */
pascal@1001 161 +
pascal@1001 162 /** @} */ /* pxe_file_api */
pascal@1001 163
pascal@1001 164 /** @defgroup pxe_loader_api PXE Loader API
pascal@1001 165
pascal@1001 166 --- gpxe-0.9.3/src/include/pxe.h
pascal@1001 167 +++ gpxe-0.9.3/src/include/pxe.h
pascal@1001 168 @@ -63,6 +63,8 @@
pascal@1001 169 struct s_PXENV_FILE_SELECT file_select;
pascal@1001 170 struct s_PXENV_FILE_READ file_read;
pascal@1001 171 struct s_PXENV_GET_FILE_SIZE get_file_size;
pascal@1001 172 + struct s_PXENV_FILE_EXEC file_exec;
pascal@1001 173 + struct s_PXENV_FILE_API_CHECK file_api_check;
pascal@1001 174 };
pascal@1001 175
pascal@1001 176 typedef union u_PXENV_ANY PXENV_ANY_t;
pascal@1001 177
pascal@1001 178 --- gpxe-0.9.3/src/interface/pxe/pxe_file.c
pascal@1001 179 +++ gpxe-0.9.3/src/interface/pxe/pxe_file.c
pascal@1001 180 @@ -31,7 +31,7 @@
pascal@1001 181 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
pascal@1001 182 */
pascal@1001 183
pascal@1001 184 -FEATURE ( FEATURE_MISC, "PXEXT", DHCP_EB_FEATURE_PXE_EXT, 1 );
pascal@1001 185 +FEATURE ( FEATURE_MISC, "PXEXT", DHCP_EB_FEATURE_PXE_EXT, 2 );
pascal@1001 186
pascal@1001 187 /**
pascal@1001 188 * FILE OPEN
pascal@1005 189 @@ -148,12 +148,14 @@
pascal@1005 190
pascal@1005 191 buffer = real_to_user ( file_read->Buffer.segment,
pascal@1005 192 file_read->Buffer.offset );
pascal@1005 193 - if ( ( len = read_user ( file_read->FileHandle, buffer, 0,
pascal@1005 194 + while ( ( len = read_user ( file_read->FileHandle, buffer, 0,
pascal@1005 195 file_read->BufferSize ) ) < 0 ) {
pascal@1005 196 file_read->Status = PXENV_STATUS ( len );
pascal@1005 197 + if (len == (ssize_t) -1309286401 /* -EWOULDBLOCK */ ) {
pascal@1005 198 + continue;
pascal@1005 199 + }
pascal@1005 200 return PXENV_EXIT_FAILURE;
pascal@1005 201 }
pascal@1005 202 -
pascal@1005 203 DBG ( " read %04zx", ( ( size_t ) len ) );
pascal@1005 204
pascal@1005 205 file_read->BufferSize = len;
pascal@1005 206 @@ -189,3 +191,76 @@
pascal@1001 207 get_file_size->Status = PXENV_STATUS_SUCCESS;
pascal@1001 208 return PXENV_EXIT_SUCCESS;
pascal@1001 209 }
pascal@1001 210 +
pascal@1001 211 +/**
pascal@1001 212 + * FILE EXEC
pascal@1001 213 + *
pascal@1001 214 + * @v file_exec Pointer to a struct s_PXENV_FILE_EXEC
pascal@1001 215 + * @v s_PXENV_FILE_EXEC::Command Command to execute
pascal@1001 216 + * @ret #PXENV_EXIT_SUCCESS Command was executed successfully
pascal@1001 217 + * @ret #PXENV_EXIT_FAILURE Command was not executed successfully
pascal@1001 218 + * @ret s_PXENV_FILE_EXEC::Status PXE status code
pascal@1001 219 + *
pascal@1001 220 + */
pascal@1001 221 +PXENV_EXIT_t pxenv_file_exec ( struct s_PXENV_FILE_EXEC *file_exec ) {
pascal@1001 222 + userptr_t command;
pascal@1001 223 + size_t command_len;
pascal@1001 224 + int rc;
pascal@1001 225 +
pascal@1001 226 + DBG ( "PXENV_FILE_EXEC" );
pascal@1001 227 +
pascal@1001 228 + /* Copy name from external program, and exec it */
pascal@1001 229 + command = real_to_user ( file_exec->Command.segment,
pascal@1001 230 + file_exec->Command.offset );
pascal@1001 231 + command_len = strlen_user ( command, 0 );
pascal@1001 232 + {
pascal@1001 233 + char command_string[ command_len + 1 ];
pascal@1001 234 +
pascal@1001 235 + copy_from_user ( command_string, command, 0,
pascal@1001 236 + sizeof ( command_string ) );
pascal@1001 237 + DBG ( " %s", command_string );
pascal@1001 238 +
pascal@1001 239 + if ( ( rc = system ( command_string ) ) != 0 ) {
pascal@1001 240 + file_exec->Status = PXENV_STATUS ( rc );
pascal@1001 241 + return PXENV_EXIT_FAILURE;
pascal@1001 242 + }
pascal@1001 243 + }
pascal@1001 244 +
pascal@1001 245 + file_exec->Status = PXENV_STATUS_SUCCESS;
pascal@1001 246 + return PXENV_EXIT_SUCCESS;
pascal@1001 247 +}
pascal@1001 248 +
pascal@1001 249 +/**
pascal@1001 250 + * FILE API CHECK
pascal@1001 251 + *
pascal@1001 252 + * @v file_exec Pointer to a struct s_PXENV_FILE_API_CHECK
pascal@1001 253 + * @v s_PXENV_FILE_API_CHECK::Magic Inbound magic number (0x91d447b2)
pascal@1001 254 + * @ret #PXENV_EXIT_SUCCESS Command was executed successfully
pascal@1001 255 + * @ret #PXENV_EXIT_FAILURE Command was not executed successfully
pascal@1001 256 + * @ret s_PXENV_FILE_API_CHECK::Status PXE status code
pascal@1001 257 + * @ret s_PXENV_FILE_API_CHECK::Magic Outbound magic number (0xe9c17b20)
pascal@1001 258 + * @ret s_PXENV_FILE_API_CHECK::Provider "gPXE" (0x45585067)
pascal@1001 259 + * @ret s_PXENV_FILE_API_CHECK::APIMask API function bitmask
pascal@1001 260 + * @ret s_PXENV_FILE_API_CHECK::Flags Reserved
pascal@1001 261 + *
pascal@1001 262 + */
pascal@1001 263 +PXENV_EXIT_t pxenv_file_api_check ( struct s_PXENV_FILE_API_CHECK *file_api_check ) {
pascal@1001 264 + DBG ( "PXENV_FILE_API_CHECK" );
pascal@1001 265 +
pascal@1001 266 + if ( file_api_check->Magic != 0x91d447b2 ) {
pascal@1001 267 + file_api_check->Status = PXENV_STATUS_BAD_FUNC;
pascal@1001 268 + return PXENV_EXIT_FAILURE;
pascal@1001 269 + } else if ( file_api_check->Size <
pascal@1001 270 + sizeof(struct s_PXENV_FILE_API_CHECK) ) {
pascal@1001 271 + file_api_check->Status = PXENV_STATUS_OUT_OF_RESOURCES;
pascal@1001 272 + return PXENV_EXIT_FAILURE;
pascal@1001 273 + } else {
pascal@1001 274 + file_api_check->Status = PXENV_STATUS_SUCCESS;
pascal@1001 275 + file_api_check->Size = sizeof(struct s_PXENV_FILE_API_CHECK);
pascal@1001 276 + file_api_check->Magic = 0xe9c17b20;
pascal@1001 277 + file_api_check->Provider = 0x45585067; /* "gPXE" */
pascal@1001 278 + file_api_check->APIMask = 0x0000007f; /* Functions e0-e6 */
pascal@1001 279 + file_api_check->Flags = 0; /* None defined */
pascal@1001 280 + return PXENV_EXIT_SUCCESS;
pascal@1001 281 + }
pascal@1001 282 +}
pascal@955 283 --- gpxe-0.9.3/src/usr/autoboot.c
pascal@955 284 +++ gpxe-0.9.3/src/usr/autoboot.c
pascal@1001 285 @@ -120,6 +120,28 @@
pascal@962 286 return -ENOTSUP;
pascal@962 287 }
pascal@962 288
pascal@1001 289 +static void set_url ( char buf[], const char url[] ) {
pascal@1001 290 + int i, d = 0;
pascal@1001 291 +
pascal@1001 292 + for (i = 0; url[i] >= ' '; i++) {
pascal@1001 293 + if (url[i] == '/') d = i;
pascal@1001 294 + buf[i] = url[i];
pascal@1001 295 + }
pascal@1001 296 + buf[i] = 0;
pascal@1001 297 + if (strstr(buf,"pxelinux")) {
pascal@1001 298 + struct dhcp_option_block *options = list_entry (
pascal@1001 299 + dhcp_option_blocks.next, typeof ( *options ), list );
pascal@1001 300 +
pascal@1001 301 + set_dhcp_option( options, 208, "\xF1\x00\x74\x7E", 4 );
pascal@1001 302 + set_dhcp_option( options, 210, buf, d+1 );
pascal@1001 303 + }
pascal@1001 304 +}
pascal@1001 305 +
pascal@962 306 +struct _forced_url {
pascal@1001 307 + char url[256];
pascal@962 308 +};
pascal@962 309 +struct _forced_url __data16 ( forced_url );
pascal@962 310 +#define forced_url __use_data16 ( forced_url )
pascal@962 311 /**
pascal@962 312 * Boot from a network device
pascal@962 313 *
pascal@1001 314 @@ -148,6 +170,12 @@
pascal@962 315 /* Try to download and boot whatever we are given as a filename */
pascal@962 316 dhcp_snprintf ( buf, sizeof ( buf ),
pascal@955 317 find_global_dhcp_option ( DHCP_BOOTFILE_NAME ) );
pascal@1001 318 +
pascal@1001 319 + if ( forced_url.url[0] != 0 ) {
pascal@1001 320 + /* Try to boot a forced url if we have one */
pascal@1001 321 + set_url ( buf, forced_url.url );
pascal@1001 322 + }
pascal@962 323 + while (1) {
pascal@955 324 if ( buf[0] ) {
pascal@962 325 printf ( "Booting from filename \"%s\"\n", buf );
pascal@962 326 return boot_filename ( buf );
pascal@1001 327 @@ -162,7 +190,8 @@
pascal@962 328 }
pascal@962 329
pascal@955 330 printf ( "No filename or root path specified\n" );
pascal@955 331 - return -ENOENT;
pascal@1001 332 + set_url ( buf, "http://boot.slitaz.org/gpxe" );
pascal@962 333 + }
pascal@955 334 }
pascal@962 335
pascal@962 336 /**
pascal@1005 337
pascal@1005 338 --- gpxe-0.9.3/src/interface/pxe/pxe_tftp.c
pascal@1005 339 +++ gpxe-0.9.3/src/interface/pxe/pxe_tftp.c
pascal@1005 340 @@ -189,7 +189,7 @@
pascal@1005 341 if ( blksize < TFTP_DEFAULT_BLKSIZE )
pascal@1005 342 blksize = TFTP_DEFAULT_BLKSIZE;
pascal@1005 343 snprintf ( uri_string, sizeof ( uri_string ),
pascal@1005 344 - "tftp://%s:%d%s%s?blksize=%d",
pascal@1005 345 + "tftp://%s:%d%s%s?blksize=%zd",
pascal@1005 346 inet_ntoa ( address ), ntohs ( port ),
pascal@1005 347 ( ( filename[0] == '/' ) ? "" : "/" ), filename, blksize );
pascal@1005 348 DBG ( " %s", uri_string );
pascal@1005 349 --- gpxe-0.9.3/src/core/posix_io.c
pascal@1005 350 +++ gpxe-0.9.3/src/core/posix_io.c
pascal@1005 351 @@ -114,7 +114,7 @@
pascal@1005 352 static int
pascal@1005 353 posix_file_xfer_deliver_iob ( struct xfer_interface *xfer,
pascal@1005 354 struct io_buffer *iobuf,
pascal@1005 355 - struct xfer_metadata *meta __unused ) {
pascal@1005 356 + struct xfer_metadata *meta ) {
pascal@1005 357 struct posix_file *file =
pascal@1005 358 container_of ( xfer, struct posix_file, xfer );
pascal@1005 359
pascal@1005 360 @@ -125,7 +125,12 @@
pascal@1005 361 if ( file->filesize < file->pos )
pascal@1005 362 file->filesize = file->pos;
pascal@1005 363
pascal@1005 364 - list_add_tail ( &iobuf->list, &file->data );
pascal@1005 365 + if ( iob_len ( iobuf ) ) {
pascal@1005 366 + list_add_tail ( &iobuf->list, &file->data );
pascal@1005 367 + } else {
pascal@1005 368 + free_iob ( iobuf );
pascal@1005 369 + }
pascal@1005 370 +
pascal@1005 371 return 0;
pascal@1005 372 }
pascal@1005 373
pascal@1005 374 @@ -293,12 +298,15 @@
pascal@1005 375 free_iob ( iobuf );
pascal@1005 376 }
pascal@1005 377 file->pos += len;
pascal@1005 378 + assert ( len != 0 );
pascal@1005 379 return len;
pascal@1005 380 }
pascal@1005 381
pascal@1005 382 /* If file has completed, return (after returning all data) */
pascal@1005 383 - if ( file->rc != -EINPROGRESS )
pascal@1005 384 + if ( file->rc != -EINPROGRESS ) {
pascal@1005 385 + assert ( list_empty ( &file->data ) );
pascal@1005 386 return file->rc;
pascal@1005 387 + }
pascal@1005 388
pascal@1005 389 /* No data ready and file still in progress; return -WOULDBLOCK */
pascal@1005 390 return -EWOULDBLOCK;