Parcourir la source

Support 32-bit (linear) NBI images. We don't yet provide a bootp data

block, so first32.c dies immediately.
tags/v0.9.3
Michael Brown il y a 17 ans
Parent
révision
5578d3b2de
1 fichiers modifiés avec 44 ajouts et 33 suppressions
  1. 44
    33
      src/arch/i386/image/nbi.c

+ 44
- 33
src/arch/i386/image/nbi.c Voir le fichier

@@ -5,6 +5,7 @@
5 5
 #include <memsizes.h>
6 6
 #include <gpxe/uaccess.h>
7 7
 #include <gpxe/segment.h>
8
+#include <gpxe/shutdown.h>
8 9
 #include <gpxe/image.h>
9 10
 
10 11
 /** @file
@@ -289,13 +290,11 @@ int nbi_load ( struct image *image ) {
289 290
  * Boot a 16-bit NBI image
290 291
  *
291 292
  * @v imgheader		Image header information
292
- * @ret Never		NBI program booted successfully
293
- * @ret False		NBI program returned
294
- * @err ECANCELED	NBI program returned
295
- *
293
+ * @ret rc		Return status code, if image returns
296 294
  */
297 295
 static int nbi_boot16 ( struct image *image, struct imgheader *imgheader ) {
298 296
 	int discard_D, discard_S, discard_b;
297
+	int rc;
299 298
 
300 299
 	DBGC ( image, "NBI %p executing 16-bit image at %04x:%04x\n", image,
301 300
 	       imgheader->execaddr.segoff.segment,
@@ -316,27 +315,22 @@ static int nbi_boot16 ( struct image *image, struct imgheader *imgheader ) {
316 315
 			    "lret\n\t"
317 316
 			    "\n2:\n\t"
318 317
 			    "addw $8,%%sp\n\t"	/* clean up stack */ )
319
-		: "=D" ( discard_D ), "=S" ( discard_S ), "=b" ( discard_b )
318
+		: "=a" ( rc ), "=D" ( discard_D ), "=S" ( discard_S ),
319
+		  "=b" ( discard_b )
320 320
 		: "D" ( imgheader->execaddr.segoff ),
321 321
 		  "S" ( imgheader->location ), "b" ( 0 /* bootp data */ )
322
-		: "eax", "ecx", "edx", "ebp" );
323
-	
324
-	return -ECANCELED;
322
+		: "ecx", "edx", "ebp" );
323
+
324
+	gateA20_set();
325
+
326
+	return rc;
325 327
 }
326 328
 
327 329
 /**
328 330
  * Boot a 32-bit NBI image
329 331
  *
330 332
  * @v imgheader		Image header information
331
- * @ret False		NBI program should not have returned
332
- * @ret other		As returned by NBI program
333
- * @err ECANCELED	NBI program should not have returned
334
- *
335
- * To distinguish between the case of an NBI program returning false,
336
- * and an NBI program that should not have returned, check errno.
337
- * errno will be set to ECANCELED only if the NBI program should not
338
- * have returned.
339
- *
333
+ * @ret rc		Return status code, if image returns
340 334
  */
341 335
 static int nbi_boot32 ( struct image *image, struct imgheader *imgheader ) {
342 336
 	int rc;
@@ -347,21 +341,21 @@ static int nbi_boot32 ( struct image *image, struct imgheader *imgheader ) {
347 341
 	/* no gateA20_unset for PM call */
348 342
 
349 343
 #warning "Should be providing bootp data"
350
-#warning "xstart32 no longer exists"
351
-#if 0
352
-	rc = xstart32 ( imgheader->execaddr.linear,
353
-			virt_to_phys ( &loaderinfo ),
354
-			( ( imgheader->location.segment << 4 ) +
355
-			  imgheader->location.offset ),
356
-			0 /* bootp data */ );
357
-#endif
358
-
359
-	DBGC ( image, "NBI %p returned %d\n", image, rc );
360 344
 
361
-	if ( ! NBI_PROGRAM_RETURNS ( imgheader->flags ) ) {
362
-		/* We shouldn't have returned */
363
-		rc = -ECANCELED;
364
-	}
345
+	/* Jump to OS with flat physical addressing */
346
+	__asm__ __volatile__ (
347
+		PHYS_CODE ( "pushl $0\n\t" /* bootp data */
348
+			    "pushl %3\n\t" /* imgheader */
349
+			    "pushl %2\n\t" /* loaderinfo */
350
+			    "xchgw %%bx,%%bx\n\t"
351
+			    "call *%1\n\t"
352
+			    "addl $12, %%esp\n\t" /* clean up stack */ )
353
+		: "=a" ( rc )
354
+		: "D" ( imgheader->execaddr.linear ),
355
+		  "a" ( virt_to_phys ( &loaderinfo ) ),
356
+		  "S" ( ( imgheader->location.segment << 4 ) +
357
+			imgheader->location.offset )
358
+		: "ebx", "ecx", "edx", "ebp", "memory" );
365 359
 
366 360
 	return rc;
367 361
 }
@@ -374,15 +368,32 @@ static int nbi_boot32 ( struct image *image, struct imgheader *imgheader ) {
374 368
  */
375 369
 static int nbi_exec ( struct image *image ) {
376 370
 	struct imgheader imgheader;
371
+	int may_return;
372
+	int rc;
377 373
 
378 374
 	copy_from_user ( &imgheader, image->priv.user, 0,
379 375
 			 sizeof ( imgheader ) );
380 376
 
377
+	may_return = NBI_PROGRAM_RETURNS ( imgheader.flags );
378
+	if ( ! may_return )
379
+		shutdown();
380
+
381 381
 	if ( NBI_LINEAR_EXEC_ADDR ( imgheader.flags ) ) {
382
-		return nbi_boot32 ( image, &imgheader );
382
+		rc = nbi_boot32 ( image, &imgheader );
383 383
 	} else {
384
-		return nbi_boot16 ( image, &imgheader );
384
+	        rc = nbi_boot16 ( image, &imgheader );
385
+	}
386
+
387
+	if ( ! may_return ) {
388
+		/* Cannot continue after shutdown() called */
389
+		DBGC ( image, "NBI %p returned %d from non-returnable image\n",
390
+		       image, rc  );
391
+		while ( 1 ) {}
385 392
 	}
393
+
394
+	DBGC ( image, "NBI %p returned %d\n", image, rc );
395
+
396
+	return rc;
386 397
 }
387 398
 
388 399
 /** NBI image type */

Chargement…
Annuler
Enregistrer