Procházet zdrojové kódy

Add 32-bit support.

Generate DHCP data block for images.
tags/v0.9.3
Michael Brown před 17 roky
rodič
revize
0d9b3e2dd2
1 změnil soubory, kde provedl 70 přidání a 13 odebrání
  1. 70
    13
      src/arch/i386/image/nbi.c

+ 70
- 13
src/arch/i386/image/nbi.c Zobrazit soubor

@@ -3,9 +3,12 @@
3 3
 #include <realmode.h>
4 4
 #include <gateA20.h>
5 5
 #include <memsizes.h>
6
+#include <dhcp_basemem.h>
6 7
 #include <gpxe/uaccess.h>
7 8
 #include <gpxe/segment.h>
8 9
 #include <gpxe/shutdown.h>
10
+#include <gpxe/netdevice.h>
11
+#include <gpxe/dhcp.h>
9 12
 #include <gpxe/image.h>
10 13
 
11 14
 /** @file
@@ -302,7 +305,6 @@ static int nbi_boot16 ( struct image *image, struct imgheader *imgheader ) {
302 305
 
303 306
 	gateA20_unset();
304 307
 
305
-#warning "Should be providing bootp data"
306 308
 	__asm__ __volatile__ (
307 309
 		REAL_CODE ( "pushw %%ds\n\t"	/* far pointer to bootp data */
308 310
 			    "pushw %%bx\n\t"
@@ -318,7 +320,8 @@ static int nbi_boot16 ( struct image *image, struct imgheader *imgheader ) {
318 320
 		: "=a" ( rc ), "=D" ( discard_D ), "=S" ( discard_S ),
319 321
 		  "=b" ( discard_b )
320 322
 		: "D" ( imgheader->execaddr.segoff ),
321
-		  "S" ( imgheader->location ), "b" ( 0 /* bootp data */ )
323
+		  "S" ( imgheader->location ),
324
+		  "b" ( __from_data16 ( dhcp_basemem ) )
322 325
 		: "ecx", "edx", "ebp" );
323 326
 
324 327
 	gateA20_set();
@@ -333,6 +336,7 @@ static int nbi_boot16 ( struct image *image, struct imgheader *imgheader ) {
333 336
  * @ret rc		Return status code, if image returns
334 337
  */
335 338
 static int nbi_boot32 ( struct image *image, struct imgheader *imgheader ) {
339
+	int discard_D, discard_S, discard_b;
336 340
 	int rc;
337 341
 
338 342
 	DBGC ( image, "NBI %p executing 32-bit image at %lx\n",
@@ -340,26 +344,73 @@ static int nbi_boot32 ( struct image *image, struct imgheader *imgheader ) {
340 344
 
341 345
 	/* no gateA20_unset for PM call */
342 346
 
343
-#warning "Should be providing bootp data"
344
-
345 347
 	/* Jump to OS with flat physical addressing */
346 348
 	__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"
349
+		PHYS_CODE ( "pushl %%ebx\n\t" /* bootp data */
350
+			    "pushl %%esi\n\t" /* imgheader */
351
+			    "pushl %%eax\n\t" /* loaderinfo */
352
+			    "call *%%edi\n\t"
352 353
 			    "addl $12, %%esp\n\t" /* clean up stack */ )
353
-		: "=a" ( rc )
354
+		: "=a" ( rc ), "=D" ( discard_D ), "=S" ( discard_S ),
355
+		  "=b" ( discard_b )
354 356
 		: "D" ( imgheader->execaddr.linear ),
355
-		  "a" ( virt_to_phys ( &loaderinfo ) ),
356 357
 		  "S" ( ( imgheader->location.segment << 4 ) +
357
-			imgheader->location.offset )
358
-		: "ebx", "ecx", "edx", "ebp", "memory" );
358
+			imgheader->location.offset ),
359
+		  "b" ( virt_to_phys ( dhcp_basemem ) ),
360
+		  "a" ( virt_to_phys ( &loaderinfo ) )
361
+		: "ecx", "edx", "ebp", "memory" );
359 362
 
360 363
 	return rc;
361 364
 }
362 365
 
366
+/**
367
+ * Guess boot network device
368
+ *
369
+ * @ret netdev		Boot network device
370
+ */
371
+static struct net_device * guess_boot_netdev ( void ) {
372
+	struct net_device *boot_netdev;
373
+
374
+	/* Just use the first network device */
375
+	for_each_netdev ( boot_netdev ) {
376
+		return boot_netdev;
377
+	}
378
+
379
+	return NULL;
380
+}
381
+
382
+/**
383
+ * Prepare DHCP parameter block for NBI image
384
+ *
385
+ * @v image		NBI image
386
+ * @ret rc		Return status code
387
+ */
388
+static int nbi_prepare_dhcp ( struct image *image ) {
389
+	struct dhcp_packet dhcppkt;
390
+	struct net_device *boot_netdev;
391
+	int rc;
392
+
393
+	boot_netdev = guess_boot_netdev();
394
+	if ( ! boot_netdev ) {
395
+		DBGC ( image, "NBI %p could not identify a network device\n",
396
+		       image );
397
+		return -ENODEV;
398
+	}
399
+
400
+	if ( ( rc = create_dhcp_packet ( boot_netdev, DHCPACK,
401
+					 dhcp_basemem, sizeof ( dhcp_basemem ),
402
+					 &dhcppkt ) ) != 0 ) {
403
+		DBGC ( image, "NBI %p failed to build DHCP packet\n", image );
404
+		return rc;
405
+	}
406
+	if ( ( rc = copy_dhcp_packet_options ( &dhcppkt, NULL ) ) != 0 ) {
407
+		DBGC ( image, "NBI %p failed to copy DHCP options\n", image );
408
+		return rc;
409
+	}
410
+
411
+	return 0;
412
+}
413
+
363 414
 /**
364 415
  * Execute a loaded NBI image
365 416
  *
@@ -374,10 +425,16 @@ static int nbi_exec ( struct image *image ) {
374 425
 	copy_from_user ( &imgheader, image->priv.user, 0,
375 426
 			 sizeof ( imgheader ) );
376 427
 
428
+	/* Prepare DHCP option block */
429
+	if ( ( rc = nbi_prepare_dhcp ( image ) ) != 0 )
430
+		return rc;
431
+
432
+	/* Shut down now if NBI image will not return */
377 433
 	may_return = NBI_PROGRAM_RETURNS ( imgheader.flags );
378 434
 	if ( ! may_return )
379 435
 		shutdown();
380 436
 
437
+	/* Execute NBI image */
381 438
 	if ( NBI_LINEAR_EXEC_ADDR ( imgheader.flags ) ) {
382 439
 		rc = nbi_boot32 ( image, &imgheader );
383 440
 	} else {

Načítá se…
Zrušit
Uložit